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))
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)
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)
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
def onhit(self): fxq('knock') self.stun_time = 200 self.mercy_time = 15
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
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
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')