[模拟炉石](一)让游戏过程显示到cocos2d中

 

在上篇中,如果运行了fireplace的tests/full_game.py,这个程序将一个游戏过程在终端上运行完成,可以看到整个过程,那么第一步要做的就是将这个过程显示到cocos2d创建的场景中去。

 创建一个游戏菜单场景。在testcocos.py中添加菜单,以及对应的方法。这个将是我们程序的入口。将后面需要用到的view,都放到gameview.py中。

class MainMenu(Menu):
    def __init__(self):
        super(MainMenu, self).__init__("HearthStone")
        self.font_title['font_size'] = 72
        self.font_title['color'] = (204,164,164,255)
        self.font_item['color'] = (255,255,255,255)
        self.font_item['font_size'] = 32
        self.font_item_selected['color'] = (255,255,255,255)
        self.font_item_selected['font_size'] = 46

        self.menu_anchor_y = CENTER
        self.menu_anchor_x = CENTER
        items = []
        items.append(MenuItem('StartGame',self.newGame))
        items.append(MenuItem('Quit',self.on_quit))
        self.create_menu( items, shake(), shake_back())
    def newGame(self):
        import gameview
        director.push(FlipAngular3DTransition(
            gameview.get_newgame(), 1.5))
    def on_quit(self):
        pyglet.app.exit()

入口:

if __name__ == "__main__":
    pyglet.resource.path.append('data')
    pyglet.resource.reindex()

    director.init(width = 800, height=600)
    #scene
    scene = Scene()
    scene.add(MultiplexLayer(MainMenu(),),z=1)

    director.run(scene)

在看看gameview.py, 有一个get_newgame()方法:

def get_newgame():
    scene = Scene()
    scene.add(BackgroundLayer(), z=0, name = "background")
    field1 = Field()
    field1.position = 50,190
    scene.add(field1, z=1, name="field1")
    field2 = Field()
    field2.position = 50,310
    scene.add(field2, z=1, name="field2")

    hand1 = Hand()
    hand1.position = 50,85
    scene.add(hand1, z=1, name="hand1")
    hand2 = Hand()
    hand2.position = 50,415
    scene.add(hand2, z=1, name="hand2")

    #model
    model = GameModel()
    #controller
    ctrl = GameCtrl(model)
    model.set_control(ctrl)
    model.set_field(field1, field2)
    model.set_hand(hand1, hand2)
    scene.add(ctrl, z=1, name = "controller")

    return scene

这个方法创建了这个游戏很多的相关的东西。比如手牌hand,场地field, 模型model, 控制器ctrl

控制器是写在了gamectrl.py中,

class GameCtrl(Layer):
    is_event_handler = True
    def __init__(self, model):
        super(GameCtrl, self).__init__()
        self.model = model
        #prepare game
        self.deck1 = random_draft(hero=MAGE)
        self.deck2 = random_draft(hero=WARRIOR)
        player1 = Player(name="Player1")
        player1.prepare_deck(self.deck1, MAGE)
        player2 = Player(name="Player2")
        player2.prepare_deck(self.deck2, WARRIOR)

        self.game = Game(players=(player1, player2))
        self.players = self.game.players
        self.player1 = self.players[0]
        self.field1 = self.player1.field
        self.hand1 = self.player1.hand
        self.player2 = self.players[1]
        self.field2 = self.player2.field
        self.hand2 = self.player2.hand
        self.game.start()
        #draw hero
        hero1 = self.game.players[0].hero
        cocosHero1 = CocosCard(hero1)
        cocosHero1.position = 350,-50
        self.add(cocosHero1, z =1)

        hero2 = self.game.players[1].hero
        cocosHero2 = CocosCard(hero2)
        cocosHero2.position = 350,450
        self.add(cocosHero2, z =1)

        for player in self.game.players:
            print("Can mulligan %r" % (player.choice.cards))
            mull_count = random.randint(0, len(player.choice.cards))
            cards_to_mulligan = random.sample(player.choice.cards, mull_count)
            player.choice.choose(*cards_to_mulligan)
        #draw cards in hand
        for player in self.game.players:
            print ("%r" % player)
            for card in player.hand:
                print("%r" % card)

        self.elapsed = 0
        self.schedule(self.step)
        self.elapsed2 = 0
        self.schedule(self.drawHandsAndFields)
    def step(self, dt):
        #print("step %r" % dt)
        self.elapsed += dt
        #control step time
        if self.elapsed > 1:
            self.elapsed = 0
            try:
                self.nextStep()
            except GameOver:
                print ("GAME OVER")
                self.unschedule(self.step)
    def nextStep(self):
        player = self.game.current_player
        heropower = player.hero.power
        if heropower.is_usable() and percent_chance(10):
            if heropower.has_target():
                heropower.use(target=random.choice(heropower.targets))
            else:
                heropower.use()
        # iterate over our hand and play whatever is playable
        for card in player.hand:
            if card.is_playable() and percent_chance(50):
                target = None
                if card.choose_cards:
                    card = random.choice(card.choose_cards)
                if card.has_target():
                    target = random.choice(card.targets)
                print("Playing %r on %r" % (card, target))
                card.play(target=target)

        # Randomly attack with whatever can attack
        for character in player.characters:
            if character.can_attack():
                character.attack(random.choice(character.targets))


        if player.choice:
            choice = random.choice(player.choice.cards)
            print("Choosing card %r" % (choice))
            player.choice.choose(choice)
        self.game.end_turn()

    def drawHandsAndFields(self, dt):
        self.elapsed2 += dt
        if self.elapsed2 > 1:
            self.model.draw_field()
            self.model.draw_hand()
            self.elapsed2 = 0

负责控制整个游戏过程。本身继承了Layer, 然后利用schedule()方法来实现调用绘制的逻辑。

但是绘制的具体实现是在gamemodel.py中。其中包含了两个类, 一个是GameModel,这个实现了绘制卡牌。但是卡牌本身有事放在了CocosCard这个类中。

具体代码见https://github.com/htwenning/mystone

[模拟炉石](一)让游戏过程显示到cocos2d中[模拟炉石](一)让游戏过程显示到cocos2d中

这就是运行的效果。

为了好看点,我给每张卡牌添加了一个背景。

[模拟炉石](一)让游戏过程显示到cocos2d中