在上篇中,如果运行了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
这就是运行的效果。
为了好看点,我给每张卡牌添加了一个背景。