예제 #1
0
    def getPlayerSkill(self):
        playerEntity = EntityFinder.findPlayer(self.world)
        if playerEntity is None:
            return None

        meGroupId = self.world.component_for_entity(playerEntity,
                                                    system.groupid.GroupId)

        offensiveSkillEntity = EntityFinder.findOffensiveSkillByGroupId(
            self.world, meGroupId.getId())

        return offensiveSkillEntity
    def checkForAttack(self):
        messages = messaging.get()
        for message in messages:
            # PlayerAttack - Player
            if message.type == MessageType.PlayerAttack:
                playerEntity = EntityFinder.findPlayer(self.world)
                playerRenderable = self.world.component_for_entity(
                    playerEntity, system.graphics.renderable.Renderable)

                playerRenderable.texture.changeAnimation(
                    message.data['characterAttackAnimationType'],
                    playerRenderable.direction,
                    interrupt=True)

            # EntityAttack - Enemies
            if message.type == MessageType.EntityAttack:
                entity = EntityFinder.findCharacterByGroupId(
                    self.world, message.groupId)
                entityRenderable = self.world.component_for_entity(
                    entity, system.graphics.renderable.Renderable)

                entityRenderable.texture.changeAnimation(
                    CharacterAnimationType.hitting,
                    entityRenderable.direction,
                    interrupt=True)

            # EntityAttack - Enemies
            if message.type == MessageType.EntityStanding:
                entity = EntityFinder.findCharacterByGroupId(
                    self.world, message.groupId)
                entityRenderable = self.world.component_for_entity(
                    entity, system.graphics.renderable.Renderable)

                entityRenderable.texture.changeAnimation(
                    CharacterAnimationType.standing,
                    entityRenderable.direction,
                    interrupt=True)

            # attackWindup- only for Enemies
            if message.type == MessageType.attackWindup:
                entity = EntityFinder.findCharacterByGroupId(
                    self.world, message.groupId)
                entityRenderable = self.world.component_for_entity(
                    entity, system.graphics.renderable.Renderable)

                entityRenderable.texture.changeAnimation(
                    CharacterAnimationType.hitwindup,
                    entityRenderable.direction,
                    interrupt=True)
예제 #3
0
    def getPlayerAttack(self):
        # find player
        playerEntity = EntityFinder.findPlayer(self.world)
        if playerEntity is None:
            return None, None

        mePlayer = self.world.component_for_entity(
            playerEntity, system.gamelogic.player.Player)

        # find characterattack for player
        meGroupId = self.world.component_for_entity(
            playerEntity, system.groupid.GroupId)
        ret = EntityFinder.findOffensiveAttackByGroupId(self.world, meGroupId.getId())

        return ret, mePlayer
예제 #4
0
    def chooseDestination(self):
        meRenderable = self.brain.owner.world.component_for_entity(
            self.brain.owner.entity, system.graphics.renderable.Renderable)

        # if true:  go to a static point close to the current enemy position
        # if false: go to a point relative to the enemy
        # self.destIsPoint = random.choice([True, False])

        # note that getLocation() will return a reference. we need to copy it here.
        playerEntity = EntityFinder.findPlayer(self.brain.owner.world)
        if not playerEntity:
            return
        playerRenderable = self.brain.owner.world.component_for_entity(
            playerEntity, system.graphics.renderable.Renderable)
        self.destCoord = AiHelper.pickDestAroundPlayer(
            playerRenderable,
            distanceX=meRenderable.texture.width,
            distanceY=meRenderable.texture.height)
        if Config.showEnemyWanderDest:
            messaging.add(
                type=MessageType.EmitTextureMinimal,
                data={
                    'char': '.',
                    'timeout': self.timer,
                    'coordinate': self.destCoord,
                    'color': Color.grey
                }
            )
    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)
예제 #6
0
    def printAttackbar(self, color, attr, bgcolor, playerEntity):
        playerGroupId = self.world.world.component_for_entity(
            playerEntity, GroupId)
        playerOffensiveAttack = EntityFinder.findOffensiveAttackByGroupId(
            self.world.world, playerGroupId.getId())

        weaponIdx = 42
        self.viewport.addstrStatic(1,
                                   weaponIdx,
                                   'W:' + playerOffensiveAttack.getWeaponStr(),
                                   color,
                                   attr,
                                   bg=bgcolor)

        weaponIdx = 52
        self.viewport.addstrStatic(1,
                                   weaponIdx,
                                   'APM:' + str(int(apm.getApm() * 60)),
                                   color,
                                   attr,
                                   bg=bgcolor)

        weaponIdx = 62
        self.viewport.addstrStatic(1,
                                   weaponIdx,
                                   'DMG/s:' +
                                   str(int(damageStat.getDamageStat())),
                                   color,
                                   attr,
                                   bg=bgcolor)
예제 #7
0
    def drawStatusbar(self):
        # fps = 0
        # if n > 100:
        #    fps = 1000 * (float)(n) / (float)(current_milli_time() - self.startTime)
        #    #fps = self.workTime * 1000.0
        playerEntity = EntityFinder.findPlayer(self.world.world)
        if playerEntity is None:
            # No player here yet
            return

        #self.viewport.erase()
        #self.viewport.border()
        playerAttackable = self.world.world.component_for_entity(
            playerEntity, Attackable)
        player = self.world.world.component_for_entity(playerEntity, Player)

        color, attr = ColorPalette.getColorByColor(Color.black)
        bgcolor, _ = ColorPalette.getColorByColor(Color.white)

        s = " Health: " + str(playerAttackable.getHealth())
        s += "  Points: " + str(player.points)
        s += " " * (Config.columns - 2 - len(s))
        #s += "  FPS: %.0f" % (fps)
        self.viewport.addstrStatic(1, 1, s, color, attr, bg=bgcolor)

        self.printSkillbar(color, attr, bgcolor, playerEntity)
        self.printAttackbar(color, attr, bgcolor, playerEntity)
예제 #8
0
    def advance(self, deltaTime):
        playerEntity = EntityFinder.findPlayer(self.world)
        if playerEntity is None:
            return
        player = self.world.component_for_entity(playerEntity, Player)

        player.advance(deltaTime)
예제 #9
0
    def setSomeSpawnCoordinates(self, renderable, direction):
        # X
        if direction is Direction.right:
            myx = self.viewport.getx() + Config.columns + 1
        else:
            myx = self.viewport.getx() - 1 - renderable.texture.width

        minY = Config.areaMoveable['miny']
        maxY = Config.areaMoveable['maxy']
        myy = random.randint(minY, maxY)

        renderable.setLocation(Coordinates(myx, myy))

        # if enemies overlap, move them sideway away from player
        spotFree = False
        while not spotFree:
            if EntityFinder.isDestinationEmpty(
                world=self.world, renderable=renderable
            ):
                spotFree = True
            else:
                if direction is Direction.right:
                    renderable.coordinates.x += 3
                else:
                    renderable.coordinates.x -= 3
예제 #10
0
    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'])
예제 #11
0
    def deathAnimation(self):
        playerEntity = EntityFinder.findPlayer(self.world)
        meRenderable = self.world.component_for_entity(
            playerEntity, system.graphics.renderable.Renderable)

        meRenderable.texture.changeAnimation(
            characterAnimationType=CharacterAnimationType.dying,
            direction=meRenderable.direction,
            subtype=0,
            interrupt=False)
예제 #12
0
    def advance(self, dt):
        for particle in self.particleEmiter.particleActive:
            particle.advance(dt)
            if not EntityFinder.isDestinationEmptyForParticle(
                    self.world, particle):
                # Note: it already did damage and everything
                particle.setActive(False)

            if not particle.isActive():
                self.particleEmiter.unuse(particle)
예제 #13
0
    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)
예제 #15
0
    def tryAttacking(self):
        if self.canAttackTimer.timeIsUp():
            logger.debug("{}: Check if i can attack player".format(self.name))
            if self.canAttackPlayer():
                if (EntityFinder.numEnemiesInState(self.brain.owner.world,
                                                   'attack') <
                        Config.maxEnemiesInStateAttacking):
                    self.brain.pop()
                    self.brain.push("attackwindup")

            self.canAttackTimer.reset()
예제 #16
0
파일: game.py 프로젝트: dobin/nkeyrollover
    def drawStats(self):
        x = 2
        y = 1
        color, attr = ColorPalette.getColorByColorType(ColorType.menu)

        o = []

        enemiesAlive = EntityFinder.numEnemies(world=self.world)
        enemiesAttacking = EntityFinder.numEnemiesInState(world=self.world,
                                                          state='attack')
        enemiesChasing = EntityFinder.numEnemiesInState(world=self.world,
                                                        state='chase')
        enemiesWandering = EntityFinder.numEnemiesInState(world=self.world,
                                                          state='wander')

        o.append("Enemies:")
        o.append("  Alive     : {}".format(enemiesAlive))
        o.append("  Attacking : {}".format(enemiesAttacking))
        o.append("  Chasing   : {}".format(enemiesChasing))
        o.append("  Wandering: {}".format(enemiesWandering))

        playerEntity = EntityFinder.findPlayer(self.world)
        playerRenderable = self.world.component_for_entity(
            playerEntity, Renderable)

        o.append('Player:')
        o.append('  Location:' + str(playerRenderable.getLocation()))

        o.append('Scene:')
        o.append('  Name:' + self.sceneManager.currentScene.name)
        o.append('  Scne State:' + str(self.sceneProcessor.state))
        o.append('  Enemies Alive:' +
                 str(self.sceneProcessor.numEnemiesAlive()))
        o.append('  Enemies Visible:' +
                 str(self.sceneProcessor.numEnemiesVisible()))

        n = 0
        while n < len(o):
            self.viewport.addstr(y + n, x, o[n], color=color, attr=attr)
            n += 1
    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 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()
예제 #19
0
    def showDestAroundPlayer(self):
        playerEntity = EntityFinder.findPlayer(self.world)
        meRenderable = self.world.component_for_entity(
            playerEntity, system.graphics.renderable.Renderable)

        destCoord = AiHelper.pickDestAroundPlayer(
            meRenderable,
            distanceX=meRenderable.texture.width,
            distanceY=meRenderable.texture.height)
        messaging.add(type=MessageType.EmitTextureMinimal,
                      data={
                          'char': '.',
                          'timeout': 10.0,
                          'coordinate': destCoord,
                          'color': Color.grey
                      })
예제 #20
0
    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()
예제 #21
0
    def canAttackPlayer(self):
        if self.lastKnownPlayerPosition is None:
            # we may not yet have received a location.
            # find it directly via player entity
            # this is every time we go into chase state
            playerEntity = EntityFinder.findPlayer(self.brain.owner.world)
            # player not spawned
            if playerEntity is not None:
                playerRenderable = self.brain.owner.world.component_for_entity(
                    playerEntity, system.graphics.renderable.Renderable)
                self.lastKnownPlayerPosition = playerRenderable.getLocationAndSize(
                )

        canAttack = AiHelper.canAttackPlayer(self.brain.owner,
                                             self.lastKnownPlayerPosition)

        return canAttack
예제 #22
0
    def on_enter(self):
        self.cooldownTimer.setTimer(0.5)
        self.attackingTimer.setTimer(4.0)

        playerEntity = EntityFinder.findPlayer(self.brain.owner.world)
        if playerEntity is None:
            return

        meRenderable = self.brain.owner.world.component_for_entity(
            self.brain.owner.entity, system.graphics.renderable.Renderable)
        meGroupId = self.brain.owner.world.component_for_entity(
            self.brain.owner.entity, system.groupid.GroupId)

        self.turnIfNecessary(playerEntity, meRenderable, meGroupId)

        # attack
        messaging.add(type=MessageType.EntityAttack,
                      groupId=meGroupId.getId(),
                      data=None)
예제 #23
0
    def advance(self, dt):
        self.time += dt

        if len(self.speechBubbles) > 0:
            speechEntry = self.speechBubbles[0]
            if self.time > speechEntry['timeSpawn']:
                playerEnt = EntityFinder.findPlayer(self.world)
                playerGroupId = self.world.component_for_entity(
                    playerEnt, system.groupid.GroupId)

                directMessaging.add(
                    groupId = playerGroupId.getId(),
                    type = DirectMessageType.activateSpeechBubble,
                    data = {
                        'text': speechEntry['text'],
                        'time': speechEntry['timeShow'],
                        'waitTime': 0,
                    }
                )
                self.speechBubbles.pop(0)
예제 #24
0
    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")
예제 #25
0
    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)
예제 #26
0
    def movePlayer(self):
        playerEntity = EntityFinder.findPlayer(self.world)
        if playerEntity is None:
            return

        for msg in directMessaging.getByType(DirectMessageType.movePlayer):
            # usually just one msg...
            playerGroupId = self.world.component_for_entity(
                playerEntity, system.groupid.GroupId)
            playerRenderable = self.world.component_for_entity(
                playerEntity, system.graphics.renderable.Renderable)

            x = msg.data['x']
            y = msg.data['y']
            dontChangeDirection = msg.data['dontChangeDirection']
            whenMoved = msg.data['whenMoved']

            # only turn, dont walk
            if not dontChangeDirection and Config.turnOnSpot:
                if playerRenderable.direction is Direction.left and x > 0:
                    self.updateRenderableDirection(playerRenderable,
                                                   Direction.right,
                                                   playerGroupId.getId())
                    continue
                if playerRenderable.direction is Direction.right and x < 0:
                    self.updateRenderableDirection(playerRenderable,
                                                   Direction.left,
                                                   playerGroupId.getId())
                    continue

            playerRenderable.storeCoords()
            playerRenderable.changeLocationFromStored(x, y)

            canMove = EntityFinder.isDestinationEmpty(self.world,
                                                      playerRenderable)
            if not canMove:
                # try with one step, instead of the original two
                if x > 0:
                    x -= 1
                    playerRenderable.changeLocationFromStored(x, y)
                elif x < 0:
                    x += 1
                    playerRenderable.changeLocationFromStored(x, y)

                canMove = EntityFinder.isDestinationEmpty(
                    self.world, playerRenderable)
                if not canMove:
                    # we are stuck
                    playerRenderable.restoreCoords()
                    continue
                else:
                    # can move with new coordinates
                    pass

            playerRenderable.restoreCoords()

            didMove = self.moveRenderable(playerRenderable,
                                          playerGroupId.getId(), x, y,
                                          dontChangeDirection)

            if didMove:
                if whenMoved == "showAppearEffect":
                    locCenter = playerRenderable.getLocationCenter()
                    messaging.add(type=MessageType.EmitMirageParticleEffect,
                                  data={
                                      'location': locCenter,
                                      'effectType': ParticleEffectType.appear,
                                      'damage': 0,
                                      'byPlayer': True,
                                      'direction': Direction.none,
                                  })
                if whenMoved == "showOnKnockback":
                    pass  # for now

                extcords = ExtCoordinates(playerRenderable.coordinates.x,
                                          playerRenderable.coordinates.y,
                                          playerRenderable.texture.width,
                                          playerRenderable.texture.height)
                messaging.add(type=MessageType.PlayerLocation, data=extcords)
예제 #27
0
    def moveEnemy(self):
        for msg in directMessaging.getByType(DirectMessageType.moveEnemy):
            entity = EntityFinder.findCharacterByGroupId(
                self.world, msg.groupId)
            if entity is None:
                # May be already deleted?
                continue

            meRenderable = self.world.component_for_entity(
                entity, system.graphics.renderable.Renderable)

            # these are the actual x/y position change we will use to move
            x = msg.data['x']
            y = msg.data['y']

            # turning on the spot
            if meRenderable.direction is Direction.left and x > 0:
                self.updateRenderableDirection(meRenderable, Direction.right,
                                               msg.groupId)
                continue
            if meRenderable.direction is Direction.right and x < 0:
                self.updateRenderableDirection(meRenderable, Direction.left,
                                               msg.groupId)
                continue

            meRenderable.storeCoords()
            meRenderable.changeLocationFromStored(x, y)

            if msg.data['force']:
                canMove = True

                # push player out of the way, if there
                isDestEmpty = EntityFinder.isDestinationEmpty(
                    self.world, meRenderable)
                if not isDestEmpty:
                    if EntityFinder.isDestinationWithPlayer(
                            self.world, meRenderable):
                        directMessaging.add(
                            groupId=0,
                            type=DirectMessageType.movePlayer,
                            data={
                                'x': x,
                                'y': 0,
                                'dontChangeDirection': True,
                                'whenMoved': None,
                            },
                        )

            else:
                canMove = EntityFinder.isDestinationEmpty(
                    self.world, meRenderable)

                if not canMove:
                    # seems we cannot move in the chose direction.
                    # if there are two components in the coordinates, just try one of
                    # them
                    if x != 0 and y != 0:
                        # try x. yes this is ugly, but fast
                        x = msg.data['x']
                        y = 0
                        meRenderable.changeLocationFromStored(x, y)
                        canMove = EntityFinder.isDestinationEmpty(
                            self.world, meRenderable)

                        if not canMove:
                            # try y... ugh
                            x = 0
                            y = msg.data['y']
                            meRenderable.changeLocationFromStored(x, y)
                            canMove = EntityFinder.isDestinationEmpty(
                                self.world, meRenderable)

                # check if we are stuck
                if not canMove:
                    meRenderable.restoreCoords()

                    isStuck = not EntityFinder.isDestinationEmpty(
                        self.world, meRenderable)
                    if isStuck:
                        logger.info(
                            "{}: Overlaps, force way out".format(meRenderable))
                        # force our way out of here. do intended path
                        x = msg.data['x']
                        y = msg.data['y']
                        canMove = True
                    else:
                        # not stuck, just wait until we are free,
                        # as another enemy most likely blocks our way
                        logger.info(
                            "{}: Does not overlap, wait until moving".format(
                                meRenderable))
                        pass

            meRenderable.restoreCoords()

            if canMove:
                self.moveRenderable(meRenderable, msg.groupId, x, y,
                                    msg.data['dontChangeDirection'],
                                    msg.data['updateTexture'])
예제 #28
0
    def checkReceiveDamage(self):
        healthUpdated = False

        for msg in directMessaging.getByType(DirectMessageType.receiveDamage):
            entity = EntityFinder.findAttackableByGroupId(
                self.world, msg.groupId)
            if entity is None:
                # May be already deleted?
                continue

            meRenderable = self.world.component_for_entity(entity, Renderable)
            meAttackable = self.world.component_for_entity(entity, Attackable)
            meGroupId = self.world.component_for_entity(entity, GroupId)

            damage = msg.data['damage']
            byPlayer = msg.data['byPlayer']
            direction = msg.data['direction']
            knockback = msg.data['knockback']
            stun = msg.data['stun']
            isPlayer = self.world.has_component(entity, Player)

            # enemy can attack player, and vice-versa
            if not byPlayer ^ isPlayer:
                continue

            if damage == 0:
                continue

            # change health
            meAttackable.adjustHealth(-1 * damage)
            healthUpdated = True
            logger.info("{} got {} damage, new health: {}".format(
                meRenderable, damage, meAttackable.getHealth()))

            # gfx: show floating damage numbers
            if Config.showEnemyDamageNumbers:
                messaging.add(type=MessageType.EmitMirageParticleEffect,
                              data={
                                  'location':
                                  meRenderable.getLocationTopCenter(),
                                  'effectType':
                                  ParticleEffectType.floatingDamage,
                                  'damage': damage,
                                  'byPlayer': byPlayer,
                                  'direction': Direction.none,
                              })

            # gfx: emit on-hit particles
            if Config.showBurstOnImpact:
                if damage > Config.showBurstOnImpactDamage:
                    messaging.add(
                        type=MessageType.EmitMirageParticleEffect,
                        data={
                            'location':
                            meRenderable.getAttackBaseLocationInverted(),
                            'effectType':
                            ParticleEffectType.hitBurst,
                            'damage':
                            0,
                            'byPlayer':
                            byPlayer,
                            'direction':
                            direction,
                        })

            # no stun, knockdown, knockback, or new color if there is no health left
            # (animations may overwrite each other)
            if meAttackable.getHealth() <= 0.0:
                continue

            # gfx: set texture color
            healthPercentage = meAttackable.getHealthPercentage()
            if healthPercentage > 0.5:
                meRenderable.texture.setOverwriteColorFor(
                    Config.overwriteColorTime,
                    ColorPalette.getColorByColor(Color.yellow))
            else:
                meRenderable.texture.setOverwriteColorFor(
                    Config.overwriteColorTime,
                    ColorPalette.getColorByColor(Color.red))

            # handle: stun
            if stun and meAttackable.isStunnable():
                stunTime = meAttackable.stunTime
                meAttackable.stunTimer.setTimer(timerValue=stunTime)
                meAttackable.stunTimer.start()
                meAttackable.isStunned = True
                meAttackable.addStun(stunTime=stunTime)

                # handle: knockdown
                if random.random() < meAttackable.knockdownChance:
                    messaging.add(
                        type=MessageType.EntityKnockdown,
                        data={},
                        groupId=meGroupId.getId(),
                    )
                else:
                    messaging.add(
                        type=MessageType.EntityStun,
                        data={
                            'timerValue': stunTime,
                        },
                        groupId=meGroupId.getId(),
                    )

                # no additional effects
                continue

            # handle: knockback
            if knockback and random.random() < meAttackable.knockbackChance:
                if direction is Direction.left:
                    x = -2
                else:
                    x = 2

                if isPlayer:
                    directMessaging.add(
                        groupId=meGroupId.getId(),
                        type=DirectMessageType.movePlayer,
                        data={
                            'x': x,
                            'y': 0,
                            'dontChangeDirection': True,
                            'whenMoved': "showOnKnockback",
                        },
                    )
                else:
                    directMessaging.add(
                        groupId=meGroupId.getId(),
                        type=DirectMessageType.moveEnemy,
                        data={
                            'x': x,
                            'y': 0,
                            'dontChangeDirection': True,
                            'updateTexture': False,
                            'force': True,
                        },
                    )

                # no additional effects
                continue

        return healthUpdated
예제 #29
0
    def checkHealth(self):
        # player
        playerEntity = EntityFinder.findPlayer(self.world)
        if playerEntity is not None:
            player = self.world.component_for_entity(playerEntity, Player)

            if player.isAlive:
                playerAttackable = self.world.component_for_entity(
                    playerEntity, Attackable)
                playerGroupId = self.world.component_for_entity(
                    playerEntity, GroupId)

                if playerAttackable.isActive and playerAttackable.getHealth(
                ) <= 0:
                    player.setAlive(False)
                    playerAttackable.setActive(False)

                    messaging.add(type=MessageType.EntityDying,
                                  groupId=playerGroupId.getId(),
                                  data={})
                    messaging.add(type=MessageType.Gameover, data={})

        # if enemies have less than 0 health, make them gonna die
        for ent, (meAtk, meEnemy, ai, meGroupId,
                  meRend) in self.world.get_components(Attackable, Enemy, Ai,
                                                       GroupId, Renderable):
            if meAtk.getHealth() <= 0:
                if ai.brain.state.name != 'dead' and ai.brain.state.name != 'dying':
                    # update state
                    ai.brain.pop()
                    ai.brain.push('dying')

                    messaging.add(type=MessageType.EntityDying,
                                  groupId=meGroupId.getId(),
                                  data={})

                    # 50% chance to display a fancy death animation
                    if random.choice([True, False]):
                        logger.info(meRend.name + " Death animation deluxe")

                        effect = random.choice([
                            TextureEmiterEffect.explode,
                            TextureEmiterEffect.pushback
                        ])
                        messaging.add(type=MessageType.EmitTexture,
                                      data={
                                          'effect':
                                          effect,
                                          'pos':
                                          meRend.getLocation(),
                                          'frame':
                                          meRend.texture.getCurrentFrameCopy(),
                                          'charDirection':
                                          meRend.direction,
                                      })

                        meRend.setActive(False)

        # environment
        for ent, (destructable, meAtk, meGroupId,
                  meRend) in self.world.get_components(Destructable,
                                                       Attackable, GroupId,
                                                       Renderable):
            if meAtk.getHealth() <= 0:
                meRend.texture.setActive(False)
            else:
                frameCount = meRend.texture.animation.frameCount - 1
                d = meAtk.getHealth() / (meAtk.initialHealth / frameCount)
                animationIndex = frameCount - int(d)

                if animationIndex != meRend.texture.frameIndex:
                    meRend.texture.advanceStep()
예제 #30
0
    def test_renderableCollisionDetection(self):
        game.isunittest.setIsUnitTest()
        fileTextureLoader.loadFromFiles()

        self.viewport = MockWin(20, 10)
        self.world = esper.World()
        self.textureEmiter = None

        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)

        # Player
        playerEntity = self.world.create_entity()
        texture = CharacterTexture(
            characterTextureType=CharacterTextureType.player,
            characterAnimationType=CharacterAnimationType.standing,
            name='Player')

        coordinates = Coordinates(10, 10)
        playerRenderable = Renderable(texture=texture,
                                      viewport=self.viewport,
                                      parent=None,
                                      coordinates=coordinates,
                                      direction=Direction.right,
                                      name='Player')
        physics = Physics()

        self.world.add_component(playerEntity, playerRenderable)
        self.world.add_component(playerEntity, physics)
        # /Player

        # Enemy
        enemyEntity = self.world.create_entity()
        texture = CharacterTexture(
            characterTextureType=CharacterTextureType.player,
            characterAnimationType=CharacterAnimationType.standing,
            name='Enemy')

        coordinates = Coordinates(10, 10)
        enemyRenderable = Renderable(texture=texture,
                                     viewport=self.viewport,
                                     parent=None,
                                     coordinates=coordinates,
                                     direction=Direction.right,
                                     name='Enemy')
        physics = Physics()

        self.world.add_component(enemyEntity, enemyRenderable)
        self.world.add_component(playerEntity, physics)
        # /Enemy

        # process it
        targetFrameTime = 1.0 / Config.fps

        # sprites overlap, but not with chars (foot is in shoulder)
        #               o
        #              /|\
        #             o/ \
        #            /|\
        #            / \
        enemyRenderable.coordinates.y -= 2
        enemyRenderable.coordinates.x += 2

        self.world.process(targetFrameTime)
        self.viewport.internalPrint()

        overlap = enemyRenderable.overlapsWith(playerRenderable)
        self.assertTrue(overlap)  # inprecise check, true

        overlap = playerRenderable.overlapsWithRenderablePixel(enemyRenderable)
        self.assertFalse(overlap)  # precise check, false

        overlap = enemyRenderable.overlapsWithRenderablePixel(playerRenderable)
        self.assertFalse(overlap)  # precise check, false

        empty = EntityFinder.isDestinationEmpty(self.world, enemyRenderable)
        self.assertTrue(empty)

        empty = EntityFinder.isDestinationEmpty(self.world, playerRenderable)
        self.assertTrue(empty)

        distance = enemyRenderable.distanceToBorder(playerRenderable)
        self.assertTrue(distance['x'] == -1)
        self.assertTrue(distance['y'] == -1)