def test_messaging(self): game.isunittest.setIsUnitTest() messaging.add(type=MessageType.Unittest, data={'test': 'test1'}) messaging.add(type=MessageType.Unittest, groupId=1, data={'test': 'test2'}) messaging.add(type=MessageType.AttackAt, data={'test': 'test3'}) self.assertTrue(len(messaging.get()) == 3) for (idx, msg) in enumerate(messaging.getByType(MessageType.Unittest)): if idx == 0: self.assertTrue(msg.data['test'] == 'test1') if idx == 1: self.assertTrue(msg.data['test'] == 'test2') self.assertTrue(idx <= 1) for (idx, msg) in enumerate(messaging.getByType(MessageType.AttackAt)): if idx == 0: self.assertTrue(msg.data['test'] == 'test3') self.assertTrue(idx <= 0) for (idx, msg) in enumerate(messaging.getByGroupId(1)): if idx == 0: self.assertTrue(msg.data['test'] == 'test2') self.assertTrue(idx <= 0) messaging.reset() self.assertTrue(len(messaging.get()) == 0)
def handleMessages(self): for message in messaging.getByType(MessageType.EmitTextureMinimal): self.textureEmiter.showCharAtPos( char=message.data['char'], timeout=message.data['timeout'], coordinate=message.data['coordinate'], color=message.data['color'], ) for message in messaging.getByType(MessageType.EmitTexture): self.textureEmiter.showEffect( effect=message.data['effect'], pos=message.data['pos'], frame=message.data['frame'], charDirection=message.data['charDirection'], ) for message in messaging.getByType(MessageType.EmitActionTexture): self.textureEmiter.makeActionTexture( actionTextureType=message.data['actionTextureType'], location=message.data['location'], fromPlayer=message.data['fromPlayer'], direction=message.data['direction'], physics=message.data['physics'], ) for message in messaging.getByType(MessageType.EmitPhenomenaTexture): self.textureEmiter.makePhenomenaTexture( phenomenaTextureType=message.data['phenomenaTextureType'], location=message.data['location'], staticLocation=message.data['staticLocation'], direction=message.data['direction'], physics=message.data['physics'], )
def checkMessages(self): for message in messaging.getByType(MessageType.ScreenMove): self.trySpawn() for message in messaging.getByType(MessageType.GameStart): self.environmentOrchestrator.loadEnvironment() self.trySpawn()
def checkForMove(self): for message in messaging.getByType(MessageType.EntityMoved): entity = EntityFinder.findCharacterByGroupId( self.world, message.groupId) renderable = self.world.component_for_entity( entity, system.graphics.renderable.Renderable) # just updated direction # NOTE this only works for CharacterTexture's if message.data['x'] == 0 and message.data['y'] == 0: renderable.texture.changeAnimation( renderable.texture.characterAnimationType, renderable.direction) continue if (renderable.texture.characterAnimationType is CharacterAnimationType.walking): if message.data['didChangeDirection']: renderable.texture.changeAnimation( CharacterAnimationType.walking, renderable.direction) else: renderable.texture.advanceStep() else: renderable.texture.changeAnimation( CharacterAnimationType.walking, renderable.direction)
def checkMessages(self): for message in messaging.getByType(MessageType.EmitParticleEffect): self.particleEmiter.emit(loc=message.data['location'], effectType=message.data['effectType'], direction=message.data['direction'], byPlayer=message.data['byPlayer'], damage=message.data['damage'])
def handleKeyboardInput(self): playerEntity = EntityFinder.findPlayer(self.world) if playerEntity is None: return player = self.world.component_for_entity( playerEntity, system.gamelogic.player.Player) renderable = self.world.component_for_entity( playerEntity, system.graphics.renderable.Renderable) attackable = self.world.component_for_entity( playerEntity, system.gamelogic.attackable.Attackable) # return if we cannot handle key, but cache it first if attackable.isStunned or player.isAttacking: for message in messaging.getByType(MessageType.PlayerKeypress): # store a few movement commands if len(self.keyCache) >= 1: del (self.keyCache[0]) self.keyCache.append(message) return if not player.isAlive: return didMove = False for message in self.keyCache: # identical to bottom loop atm apm.tick(message.data['time']) didMoveTmp = self.handleKeyPress(message.data['key'], player, renderable, playerEntity) if didMoveTmp: didMove = True self.keyCache.clear() for message in messaging.getByType(MessageType.PlayerKeypress): apm.tick(message.data['time']) didMoveTmp = self.handleKeyPress(message.data['key'], player, renderable, playerEntity) if didMoveTmp: didMove = True # to allow diagonal movement, we allow multiple movement keys per input # cycle, without resetting the timer. if didMove: self.movementTimer.reset()
def process(self, dt): self.dmgTimer.advance(dt) if self.dmgTimer.timeIsUp(): damageStat.addDamage(-10) self.dmgTimer.reset() damageSumPlayer = 0 for msg in messaging.getByType(MessageType.AttackAt): for entity, (meAtk, groupId, renderable) in self.world.get_components( Attackable, GroupId, Renderable ): hitLocations = msg.data['hitLocations'] damage = msg.data['damage'] byPlayer = msg.data['byPlayer'] direction = msg.data['direction'] knockback = msg.data['knockback'] stun = msg.data['stun'] if 'sourceRenderable' in msg.data: sourceRenderable = msg.data['sourceRenderable'] else: sourceRenderable = None if renderable.isHitBy(hitLocations): directMessaging.add( groupId=groupId.id, type=DirectMessageType.receiveDamage, data={ 'damage': damage, 'byPlayer': byPlayer, 'direction': direction, 'knockback': knockback, 'stun': stun, 'sourceRenderable': sourceRenderable, 'destinationEntity': entity, 'hitLocations': hitLocations, } ) if byPlayer: damageSumPlayer += damage # check if we should announce our awesomeness if damageSumPlayer > Config.announceDamage: # find player for ent, (groupId, player) in self.world.get_components( GroupId, Player ): directMessaging.add( groupId = groupId.getId(), type = DirectMessageType.activateSpeechBubble, data = { 'text': 'Cowabunga!', 'time': 1.0, } ) damageStat.addDamage(damageSumPlayer)
def checkAttack(self): for message in messaging.getByType(MessageType.PlayerAttack): # most likely just one such message playerEntity = EntityFinder.findPlayer(self.world) player = self.world.component_for_entity( playerEntity, system.gamelogic.player.Player) player.setAttacking( attackTime=message.data['attackAnimationLength'])
def checkDefenseMessages(self): for msg in messaging.getByType(MessageType.Defense): location = msg.data['location'] groupId = msg.data['groupId'] entity = EntityFinder.findByGroupId(self.world, groupId) defense = self.world.component_for_entity(entity, Defense) defense.coordinates = location defense.isActive = True defense.timer.reset()
def checkForKnockdown(self): for message in messaging.getByType(MessageType.EntityKnockdown): entity = EntityFinder.findCharacterByGroupId( self.world, message.groupId) meRenderable = self.world.component_for_entity( entity, system.graphics.renderable.Renderable) meRenderable.texture.changeAnimation( characterAnimationType=CharacterAnimationType.knockdown, direction=meRenderable.direction, interrupt=True)
def process(self, dt): for msg in messaging.getByType(MessageType.AttackAt): hitLocations = msg.data['hitLocations'] #damage = msg.data['damage'] byPlayer = msg.data['byPlayer'] direction = msg.data['direction'] sourceRenderable = msg.data['sourceRenderable'] #knockback = msg.data['knockback'] #stun = msg.data['stun'] # always show on hit effects currently self.handleOnHit(hitLocations, direction, byPlayer, sourceRenderable)
def checkForStun(self): for message in messaging.getByType(MessageType.EntityStun): entity = EntityFinder.findCharacterByGroupId( self.world, message.groupId) entityRenderable = self.world.component_for_entity( entity, system.graphics.renderable.Renderable) # here we also store the current animation # by interrupt=True entityRenderable.texture.changeAnimation( CharacterAnimationType.stun, entityRenderable.direction, interrupt=True) for message in messaging.getByType(MessageType.EntityEndStun): entity = EntityFinder.findCharacterByGroupId( self.world, message.groupId) entityRenderable = self.world.component_for_entity( entity, system.graphics.renderable.Renderable) # restore saved animation entityRenderable.texture.previousAnimationRestore()
def checkForDying(self): for message in messaging.getByType(MessageType.EntityDying): entity = EntityFinder.findCharacterByGroupId( self.world, message.groupId) meRenderable = self.world.component_for_entity( entity, system.graphics.renderable.Renderable) animationIndex = random.randint(0, 1) meRenderable.texture.changeAnimation( characterAnimationType=CharacterAnimationType.dying, direction=meRenderable.direction, subtype=animationIndex, interrupt=False)
def process(self, dt): meRenderable = self.brain.owner.world.component_for_entity( self.brain.owner.entity, system.graphics.renderable.Renderable) meAttackable = self.brain.owner.world.component_for_entity( self.brain.owner.entity, system.gamelogic.attackable.Attackable) meEnemy = self.brain.owner.world.component_for_entity( self.brain.owner.entity, system.gamelogic.enemy.Enemy) if meAttackable.isStunned: return self.lastInputTimer.advance(dt) if self.lastInputTimer.timeIsUp(): self.getInputWander() self.lastInputTimer.reset() if self.timeIsUp(): if (EntityFinder.numEnemiesInState(self.brain.owner.world, 'chase') < Config.maxEnemiesInStateChase): logger.info("{}: Too long wandering, chase again a bit".format( self.owner)) self.brain.pop() self.brain.push("chase") elif Utility.isIdentical(meRenderable.getLocation(), self.destCoord): # No reset of wander state atm, just a new location self.chooseDestination() else: # check if player is close for message in messaging.getByType(MessageType.PlayerLocation): distance = Utility.distance( message.data, meRenderable.getLocation()) if distance['sum'] < meEnemy.enemyInfo.wanderAttackDistance: logger.info("{}: Player is close, chasing".format(self.owner)) self.brain.pop() self.brain.push("chase")
def checkForNewPlayerPosition(self): # check if there are any new player position messages for message in messaging.getByType(MessageType.PlayerLocation): self.lastKnownPlayerPosition = message.data
def process(self, dt): self.screenMoveTimer.advance(dt) self.gameoverTimer.advance(dt) for message in messaging.getByType(MessageType.Gameover): self.gameoverTimer.reset() self.gameoverTimer.start() self.setState(State.gameover) messaging.add(type=MessageType.EmitPhenomenaTexture, data={ 'phenomenaTextureType': PhenomenaType.gameover, 'location': Coordinates(10, 10), 'staticLocation': True, 'direction': Direction.right, 'physics': False, }) if self.state is State.gameover: for message in messaging.getByType(MessageType.PlayerKeypress): if self.gameoverTimer.timeIsUp(): messaging.add(type=MessageType.ClearRenderables, data={}) self.setState(State.start) elif self.state is State.start: self.sceneManager.restartScene() self.setState(State.brawl) for message in messaging.getByType(MessageType.EntityDying): # if no enemies are alive, we want to go to the next akt if self.numEnemiesAlive() == 0: self.screenMoveTimer.start() if self.state is not State.gameover: self.setState(State.pushToNextScene) break for message in messaging.getByType(MessageType.PlayerLocation): self.lastKnownPlayerPos = message.data if self.state is State.pushToNextScene: # if suddenly enemies appear, let the player free if self.numEnemiesVisible() > 0: self.setState(State.brawl) if self.state is State.brawl: if (self.numEnemiesVisible() == 0 and not self.enemiesLeftOfChar(self.lastKnownPlayerPos.x)): self.screenMoveTimer.start() self.setState(State.pushToEnemies) if self.state is State.pushToEnemies: if self.numEnemiesVisible() > 0: self.setState(State.brawl) playerScreenCoords = self.viewport.getScreenCoords(message.data) # adjust viewport on move if self.state is State.pushToNextScene: # screen follows player # player is left side of screen (screen pushes player right) if playerScreenCoords.x != 10: distance = int(playerScreenCoords.x - 10) if distance < 0: self.adjustViewport(-1) self.screenMoveTimer.reset() elif distance > 0: self.adjustViewport(1) self.screenMoveTimer.reset() elif self.state is State.pushToEnemies: # screen follows player # player is middle of the screen if playerScreenCoords.x != self.xCenter: distance = int(playerScreenCoords.x - self.xCenter) if distance < 0: self.adjustViewport(-1) self.screenMoveTimer.reset() elif distance > 0: self.adjustViewport(1) self.screenMoveTimer.reset() elif self.state is State.brawl: if not self.enemiesLeftOfChar(self.lastKnownPlayerPos.x): # player can move freely # coming close to left/right of the screen will move it if playerScreenCoords.x >= Config.moveBorderRight: distance = playerScreenCoords.x - Config.moveBorderRight self.adjustViewport(distance) if playerScreenCoords.x <= Config.moveBorderLeft: distance = playerScreenCoords.x - Config.moveBorderLeft self.adjustViewport(distance) # /adjust viewport on move # let the scene decide if we need more enemies self.sceneManager.currentScene.handlePosition( message.data, self.viewport.getx(), self.numEnemiesAlive()) for message in messaging.getByType(MessageType.PlayerKeypress): key = message.data['key'] self.sceneManager.handlePlayerKeyPress(key) if key == ord('k'): logger.info("Scene: Kill All Enemies") self.killAllEnemies() if key == ord('n'): logger.info("Scene: Go to next part") self.killAllEnemies() enemyCell = self.sceneManager.currentScene.getNextEnemy() playerEntity = EntityFinder.findPlayer(self.world) meGroupId = self.world.component_for_entity( playerEntity, system.groupid.GroupId) renderable = self.world.component_for_entity( playerEntity, system.graphics.renderable.Renderable) distX = enemyCell.spawnX - renderable.coordinates.x directMessaging.add( groupId=meGroupId.getId(), type=DirectMessageType.movePlayer, data={ 'x': distX, 'y': 0, 'dontChangeDirection': False, 'whenMoved': None, }, ) # move screen animation if self.screenMoveTimer.timeIsUp( ) and self.lastKnownPlayerPos is not None: playerScreenCoords = self.viewport.getScreenCoords( self.lastKnownPlayerPos) if self.state is State.pushToNextScene: # screen follows player # player is left side of screen (screen pushes player right) if playerScreenCoords.x != 10: distance = int(playerScreenCoords.x - 10) if distance < 0: self.adjustViewport(-1) self.screenMoveTimer.reset() elif distance > 0: self.adjustViewport(1) self.screenMoveTimer.reset() else: self.screenMoveTimer.stop() elif self.state is State.pushToEnemies: # screen follows player # player is middle of the screen if playerScreenCoords.x != self.xCenter: distance = int(playerScreenCoords.x - self.xCenter) if distance < 0: self.adjustViewport(-1) self.screenMoveTimer.reset() elif distance > 0: self.adjustViewport(1) self.screenMoveTimer.reset() else: self.screenMoveTimer.stop() self.sceneManager.advance(dt)
def checkSpawn(self): for message in messaging.getByType(MessageType.SpawnEnemy): self.spawnEnemy(message.data)
def checkClearRenderables(self): for message in messaging.getByType(MessageType.ClearRenderables): for ent, rend in self.world.get_component(Renderable): renderableCache.addRenderable(rend, rend.texture.type) logger.info("Remove Entity A: {}".format(ent)) self.world.delete_entity(ent)
def handlePlayerAttackKeyPressMessage(self): for message in messaging.getByType(MessageType.PlayerKeypress): self.handlePlayerKeypress(message.data['key'])
def test_actionemiter(self): game.isunittest.setIsUnitTest() fileTextureLoader.loadFromFiles() self.viewport = MockWin(20, 10) self.world = esper.World() self.textureEmiter = TextureEmiter(viewport=self.viewport, world=self.world) renderableCache.init(viewport=self.viewport) particleEmiter = ParticleEmiter(viewport=self.viewport) renderableProcessor = RenderableProcessor( textureEmiter=self.textureEmiter, particleEmiter=particleEmiter) movementProcessor = MovementProcessor(mapManager=None) inputProcessor = InputProcessor() renderableMinimalProcessor = RenderableMinimalProcessor( viewport=self.viewport, textureEmiter=self.textureEmiter) self.world.add_processor(inputProcessor) self.world.add_processor(movementProcessor) self.world.add_processor(renderableMinimalProcessor) self.world.add_processor(renderableProcessor) location = Coordinates(10, 10) self.textureEmiter.makeActionTexture( actionTextureType=ActionType.unittest, location=location, fromPlayer=True, direction=Direction.right, physics=None) messages = messaging.getByType(MessageType.PlayerAttack) for message in messages: print(message.data['hitLocations']) hl = message.data['hitLocations'] self.assertTrue(hl[0].x == 12) self.assertTrue(hl[0].y == 11) self.assertTrue(hl[1].x == 12) self.assertTrue(hl[1].y == 12) self.assertTrue(hl[2].x == 13) self.assertTrue(hl[2].y == 11) self.assertTrue(hl[3].x == 13) self.assertTrue(hl[3].y == 12) # process it targetFrameTime = 1.0 / Config.fps self.world.process(targetFrameTime) self.assertTrue(self.viewport.peek(12, 11) == '>') self.assertTrue(self.viewport.peek(12, 12) == '>') self.assertTrue(self.viewport.peek(13, 11) == '>') self.assertTrue(self.viewport.peek(13, 12) == '>') self.world.process(0.1) # animation len self.assertTrue(self.viewport.peek(12, 11) == '-') self.assertTrue(self.viewport.peek(12, 12) == '-') self.assertTrue(self.viewport.peek(13, 11) == '-') self.assertTrue(self.viewport.peek(13, 12) == '-')
def checkSpawn(self): for message in messaging.getByType(MessageType.SpawnPlayer): self.spawnPlayer(message.data['coordinates'])