示例#1
0
    def move(self, vkeys, new_vkeys):
        from itertools import chain
        self.player.move(vkeys, new_vkeys)
        want_to_open_door = False

        try:
            next_enemy = next(
                self.enemy_factory) if self.enemy_factory else None
        except StopIteration:
            self.enemy_factory = None
            want_to_open_door = True
        else:
            if next_enemy:
                self.enemies.append(next_enemy)
        self.player_projectiles = [
            t for t in self.player_projectiles if t and t.pos
        ]
        self.enemy_projectiles = [
            t for t in self.enemy_projectiles if t and t.pos
        ]
        for t in chain(self.player_projectiles, self.enemies,
                       self.enemy_projectiles):
            t.move()
        if self.chip_factory and self.chip_factory.move():
            want_to_open_door = True
            self.chip_factory = None

        if want_to_open_door:
            chipsfx.fxq('opendoor')
            spawn_x, spawn_y = self.exitpos
            self.pf.setcol(spawn_x, spawn_y - 1, (14, 15))
示例#2
0
文件: enemy.py 项目: pinobatch/pyfhbg
 def onhit(self):
     if self.damaged == 0 and self.crouch_time > 0:
         self.stun_time = 0
         self.damaged = 1
         self.mercy_time = 15
         fxq('sneakerdmg')
         return
     BaseEnemyWalkingCritter.onhit(self)
示例#3
0
文件: enemy.py 项目: pinobatch/pyfhbg
 def collect(self, pos):
     row = int(pos[1] // 16)
     try:
         self.y_lru.remove(row)
     except IndexError:
         pass
     else:
         fxq('getchip')
         num = 9 - len(self.y_lru)
         if 1 <= num <= 8:
             dig = FloatingDigit(self.game, self.view, pos[0], pos[1], num)
             self.game.enemy_projectiles.append(dig)
示例#4
0
文件: enemy.py 项目: pinobatch/pyfhbg
 def move(self):
     if not self.pos:
         return
     if self.stun_time > 0:
         self.stun_time -= 1
     elif self.facing_left:
         self.pos[0] -= self.x_spd
         if self.pos[0] < 0:
             self.reposition()
     else:
         self.pos[0] += self.x_spd
         if self.pos[0] >= 256:
             self.reposition()
     if self.mercy_time > 0:
         self.mercy_time -= 1
     elif self.stun_test():
         fxq('knock')
         self.stun_time = 200
         self.mercy_time = 15
示例#5
0
文件: enemy.py 项目: pinobatch/pyfhbg
 def onhit(self):
     fxq('knock')
     self.stun_time = 200
     self.mercy_time = 15
示例#6
0
文件: enemy.py 项目: pinobatch/pyfhbg
    def move(self, vkeys, new_vkeys):
        if not self.pos:
            return
        if vkeys & VK_RIGHT:
            self.pos[0] += self.x_spd
            if self.state == self.ST_WALKING:
                self.walking_frame += 32
            if self.facing_left and self.state == self.ST_HANGING:
                self.state = self.ST_JUMPING
            self.facing_left = False
        elif vkeys & VK_LEFT:
            self.pos[0] -= self.x_spd
            if self.state == self.ST_WALKING:
                self.walking_frame += 32
            if not self.facing_left and self.state == self.ST_HANGING:
                self.state = self.ST_JUMPING
            self.facing_left = True
        elif self.state == self.ST_WALKING:
            self.walking_frame = 128

        if self.state == self.ST_ON_LADDER:
            self.yvel = (-self.x_spd / 2 if vkeys & VK_UP else self.x_spd /
                         2 if vkeys & VK_DOWN else 0)
            if (self.getblkat(self.pos[0], self.pos[1] - 8) != 8
                    and self.getblkat(self.pos[0], self.pos[1] + 1) != 8):
                self.state = self.ST_WALKING
        else:
            self.yvel = min(4, self.yvel + 0.125)
            if (new_vkeys & (VK_UP | VK_DOWN)) and not self.carrying_block:
                laddercheckoffset = 1 if new_vkeys & VK_DOWN else -1
                laddercheckblk = self.getblkat(self.pos[0],
                                               self.pos[1] + laddercheckoffset)
                if laddercheckblk == 8:
                    self.state = self.ST_ON_LADDER
        self.pos[1] = self.yvel + self.pos[1]

        # Treat ladders below player as solid if not already on a ladder
        ladders_below_are_solid = self.state not in (self.ST_ON_LADDER,
                                                     self.ST_JUMPING)
        pushed = four_corner_collide(self.game.pf, self.pos[0],
                                     self.pos[1] - 8, self.hitbox_width, 8,
                                     ladders_below_are_solid,
                                     self.state == self.ST_ON_LADDER)
        on_floor = False
        can_jump = False
        if pushed:
            self.pos[0] += pushed[0]
            if pushed[1] > 0 or self.yvel > 0:
                self.pos[1] += pushed[1]
            if pushed[1] < 0:
                if self.yvel >= 0:
                    if self.yvel >= 0.25:
                        self.onland()
                    self.yvel = min(0, self.yvel)
                    on_floor = True
            elif pushed[1] > 0:
                self.yvel = max(0, self.yvel)

        if on_floor:
            can_jump = True
            if (self.state in (self.ST_JUMPING, self.ST_HANGING)
                    or (self.state == self.ST_ON_LADDER and self.yvel > 0.25)):
                self.state = self.ST_WALKING
                self.walking_frame = 128
        elif (self.can_hang and self.yvel > 0 and not (vkeys & VK_DOWN)
              and not self.carrying_block):
            ledgetestx = self.pos[0] + (-5 if self.facing_left else 5)
            ledgesolidlo = 16 <= self.getblkat(ledgetestx,
                                               self.pos[1] - 14) < 32
            ledgesolidhi = 16 <= self.getblkat(ledgetestx,
                                               self.pos[1] - 18) < 32
            if ledgesolidlo and not ledgesolidhi:
                self.state = self.ST_HANGING
                self.yvel = 0
                self.pos[1] = (self.pos[1] + 8) // 16 * 16
                can_jump = True
        elif self.state == self.ST_ON_LADDER:
            can_jump = True

        if can_jump:
            jump_mask = ((VK_UP
                          | VK_A) if self.state != self.ST_ON_LADDER else VK_A)
            if new_vkeys & jump_mask:
                self.yvel = (-self.hang_jump_power if self.state
                             == self.ST_HANGING else -self.jump_power)
                self.state = self.ST_JUMPING
                if self.yvel < 0:
                    fxq('jump')

        return pushed
示例#7
0
    def move(self, vkeys, new_vkeys):
        if (self.state == self.ST_WALKING and (new_vkeys & VK_UP)
                and self.getblkat(self.pos[0], self.pos[1] - 16) == 9):
            self.state = self.ST_ENTERING_DOOR
            self.walking_frame = 0
            return
        elif (self.state == self.ST_WALKING
              and self.getblkat(self.pos[0], self.pos[1] - 8) == 15):
            self.state = self.ST_ENTERING_DOOR
            self.walking_frame = 0
            return
        elif self.state == self.ST_ENTERING_DOOR:
            ecks = self.pos[0] // 1 % 16 - 8
            if ecks < 0:
                self.pos[0] += 1
            elif ecks > 0:
                self.pos[0] -= 1
            self.walking_frame += 1
            return

        pushed = BaseWalkingCritter.move(self, vkeys, new_vkeys)
        if new_vkeys & VK_B and self.state in (self.ST_WALKING,
                                               self.ST_JUMPING):
            if self.carrying_block:
                fxq('throwblock')
                self.state = self.ST_THROWING
                self.walking_frame = 0
                self.carrying_block = False
                blk = TossedBlock(self.pos[0], self.pos[1] - 28,
                                  self.facing_left)
                self.game.player_projectiles.append(blk)
            elif self.state == self.ST_WALKING:
                fxq('makeblock')
                self.carrying_block = True
        if self.state == self.ST_THROWING:
            self.walking_frame += 64

        self.pos[0] = min(248, max(8, self.pos[0]))
        if self.pos[1] >= 192:
            self.pos[1] -= 192

        collidables = chain(self.game.enemies, self.game.enemy_projectiles)
        for e in collidables:
            if not e or not e.pos:
                continue
            dx = e.pos[0] - self.pos[0]
            dy = e.pos[1] - e.hitbox_height - self.pos[1] + self.hitbox_height
            if (not e.hitbox_width or not e.hitbox_height
                    or abs(dx) >= e.hitbox_width + self.hitbox_width
                    or abs(dy) >= e.hitbox_height + self.hitbox_height):
                continue
            destroyed = False
            if e.stun_time > 0:
                destroyed = True
                fxq('destroyed')
            elif self.mercy_time == 0:
                self.health -= 1
                self.mercy_time = 60
                destroyed = True
                fxq('hurt')
            if destroyed:
                self.yvel = min(self.yvel, -2)
                from enemy import Poof
                bullet = Poof(self.game, self.view, e.pos[0], e.pos[1])
                self.game.enemy_projectiles.append(bullet)
                e.pos = None

        if self.mercy_time > 0:
            self.mercy_time -= 1
示例#8
0
    def move(self, ballpos):
        if not self.vel:
            return
        displ = [self.pos[0] - ballpos[0], self.pos[1] - ballpos[1]]
        r, theta, pull = clip_vel_to_cable(displ, self.vel, self.length)
        self.vel[1] = plus_gravity(self.vel[1])
        self.pos = [
            displ[0] + ballpos[0] + self.vel[0],
            displ[1] + ballpos[1] + self.vel[1]
        ]
        if self.pos[0] < 0:
            # if hit top of play area
            self.pos[0] = 0
            self.vel[0] = 0
        if self.pos[1] >= 192 and self.vel[1] > 0:
            # if falling below
            self.pos = self.vel = self.length = None
            return

        halftilex = int(self.pos[0]) // 8
        halftiley = int(self.pos[1]) // 8
        anchortile = (halftilex // 2, halftiley // 2)
        balltile = (int(ballpos[0] // 16), int(ballpos[1] // 16))
        wraptest_near = 1 if self.pos[0] > ballpos[0] else 15
        t = (0 if halftiley < 0 else 1 if halftiley >= 24 else self.getcell(
            *anchortile))

        # hack to wrap around #5 (pole top) if anchor is to the right
        # of and above player
        wrap_include_last = (anchortile[1] < balltile[1]
                             and anchortile[0] > balltile[0] and t == 5)
        rhalfTiles = (6, )
        lhalfTiles = (5, 7)
        grabTiles = set((5, 6 if displ[0] > 0 else 7))
        grabTiles.update(solidTiles)
        if self.vel[1] > 0 and self.pos[1] % 16 < 3:
            grabTiles.update(downSolidTiles)
        bhalfTiles = (5, )
        if ((t in rhalfTiles and not (halftilex & 1))
                or (t in lhalfTiles and (halftilex & 1))
                or (t in bhalfTiles and not (halftiley & 1))):
            t = 0
        if t in noGrappleTiles:
            self.vel = self.pos = None
            return
        if t in grabTiles:
            self.vel = None
            ##            print("latch here at (%d, %d)" % (self.pos[0], self.pos[1]))
            self.length = max(self.MIN_CABLELEN, r)

            # if hit top of near block, latch to the near corner
            upsolid = (0 <= anchortile[1] < 12 and self.getcell(
                anchortile[0], anchortile[1] - 1) in solidTiles)
            facing_left = self.pos[0] < ballpos[0]
            nearsolidx = anchortile[0] + (1 if facing_left else -1)
            neartile = (self.getcell(nearsolidx, anchortile[1])
                        if 0 < anchortile[1] < 12 and 0 <= nearsolidx else 0)
            nearsolid = neartile in solidTiles
            if (t in solidTiles and self.pos[1] % 16 < 3 and not nearsolid
                    and not upsolid):
                self.pos[0] = anchortile[0] * 16 + wraptest_near
            chipsfx.fxq('anchor')

        # test whether rope has wrapped around a block
        wrapkey = self.get_wrapkey(ballpos)
        if self.vel and wrapkey != self.wrapkey:
            self.wrapkey = wrapkey
            coords = [
                (x, y, self.getcell(x, y) if 0 <= x and 0 <= y < 12 else None)
                for (x, y) in wraptest_trace(balltile[0], balltile[1],
                                             anchortile[0], anchortile[1])
            ]
        else:
            coords = []

        if anchortile[1] > anchortile[0]:
            grabTiles.update(downSolidTiles)
        coords = [
            row for row in coords if row[2] in grabTiles and (
                wrap_include_last or row[0:2] != anchortile)
            and row[0:2] != balltile
        ]
        if coords and coords[0][2] in noGrappleTiles:
            self.pos = self.vel = 0
            return
        coords = [
            (16 * x + max(min(wraptest_near, 7 if t in lhalfTiles else 15),
                          8 if t in rhalfTiles else 0),
             16 * y + (8 if t in bhalfTiles else 0)) for (x, y, t) in coords
        ]
        if coords:
            ##            print("latch wrap at %s" % repr(coords[0]))
            self.vel = None
            self.length = r - 8
            self.pos = coords[0]
            chipsfx.fxq('anchor')