def update(self, data, common_data, dt): speed = 0.3 # if doing something that can't be interrupted then countdown to end of it if self.coolDown(data, dt): pass else: if data.health <= 0: self.setState(data, common_data, px_entity.eStates.dead) return self.setState(data, common_data, px_entity.eStates.stationary) if rand_num(10)==0: # self.setState(data, common_data, eStates.stationary) data.vel = Vec3(0,0,0) data.cooldown = rand_num(10)/8.0+0.3 else: # chase hero target = common_data.game.requestTarget(common_data.pos) if(target.x<common_data.pos.x): # self.setState(data, common_data, eStates.runLeft) data.vel = Vec3(-speed, 0, 0) data.facing = px_entity.eDirections.left else: # self.setState(data, common_data, eStates.runRight) data.vel = Vec3(speed, 0, 0) data.facing = px_entity.eDirections.right if(target.z<common_data.pos.z): data.vel.z = -speed else: data.vel.z = speed if common_data.pos.distSq(Vec3(target.x,target.y,common_data.pos.y))<800: data.vel.y = 0 # drop on target elif (common_data.pos.z<80) and (data.vel.z<3): data.vel.y += 2 # otherwise flap # common_data.entity.graphics.startAnim(data = common_data.entity.graphics_data) self.setState(data, common_data, px_entity.eStates.stationary, force_new_state=True) common_data.entity.sounds.playEvent(data, common_data, eEvents.flap) data.cooldown = 0.2 if common_data.pos.y>0: px_controller.friction(data.vel, 0.01) else: px_controller.friction(data.vel, 0.1) px_controller.basic_gravity(data.vel) px_controller.basic_physics(common_data.pos, data.vel) background.restrictToArena(common_data.pos, data.vel)
def update(self, data, common_data, dt): speed = 0.3 # if doing something that can't be interrupted then countdown to end of it if self.coolDown(data, dt): pass else: if data.health <= 0: self.setState(data, common_data, eStates.dead) return self.setState(data, common_data, eStates.stationary) if rand_num(10) == 0: # self.setState(data, common_data, eStates.stationary) data.vel = Vec3(0, 0, 0) data.cooldown = rand_num(5) / 10.0 + 0.1 else: # chase hero target = common_data.game.requestTarget(common_data.pos) if (target.x < common_data.pos.x): # self.setState(data, common_data, eStates.runLeft) data.vel = Vec3(-speed, 0, 0) data.facing = eDirections.left else: # self.setState(data, common_data, eStates.runRight) data.vel = Vec3(speed, 0, 0) data.facing = eDirections.right if (target.y < common_data.pos.y): data.vel.y = -speed else: data.vel.y = speed if common_data.pos.distSq( Vec3(target.x, target.y, common_data.pos.z)) < 800: data.vel.z = 0 # drop on target elif (common_data.pos.z < 80) and (data.vel.z < 3): data.vel.z += 2 # otherwise flap common_data.entity.graphics.startAnim( data=common_data.entity.graphics_data) data.cooldown = 0.2 if common_data.pos.z > 0: friction(data.vel, 0.01) else: friction(data.vel, 0.1) basic_gravity(data.vel) basic_physics(common_data.pos, data.vel) restrictToArena(common_data.pos, data.vel)
def update(self, data, common_data, dt): speed = 0.3 # if doing something that can't be interrupted then countdown to end of it if self.coolDown(data, dt): pass else: if data.health <= 0: self.setState(data, common_data, eStates.dead) return self.setState(data, common_data, eStates.stationary) if rand_num(10) == 0: # self.setState(data, common_data, eStates.stationary) data.vel = Vec3(0, 0, 0) data.cooldown = rand_num(5) / 8.0 + 0.3 else: # chase hero if data.target_cool <= 0: data.target = Vec3(rand_num(600), rand_num(200), rand_num(200)) data.target_cool = rand_num(20) else: data.target_cool -= 1 if (data.target.x < common_data.pos.x): # self.setState(data, common_data, eStates.runLeft) data.vel = Vec3(-speed, 0, 0) data.facing = eDirections.left else: # self.setState(data, common_data, eStates.runRight) data.vel = Vec3(speed, 0, 0) data.facing = eDirections.right if (data.target.z < common_data.pos.z): data.vel.z = -speed else: data.vel.z = speed if common_data.pos.distSq( Vec3(data.target.x, data.target.y, common_data.pos.z)) < 800: data.vel.y = 0 # drop on target elif (common_data.pos.z < 80 + rand_num(200)) and (data.vel.z < 3): data.vel.y += 2 + rand_num(5) # otherwise flap self.setState(data, common_data, eStates.stationary, force_new_state=True) data.cooldown = 0.2 if common_data.pos.y > 0: px_controller.friction(data.vel, 0.01) else: px_controller.friction(data.vel, 0.1) px_controller.basic_gravity(data.vel) px_controller.basic_physics(common_data.pos, data.vel) restrictToArena(common_data.pos, data.vel)
def advanceAnim(self, anim_instance, time): anim_instance.current_time += time while anim_instance.current_time > self.frames[ anim_instance.current_frame].time: anim_instance.current_time -= self.frames[ anim_instance.current_frame].time anim_instance.current_frame = rand_num(len(self.frames))
def receiveCollision(self, data, common_data, message): if message: if message.damage > 0: common_data.game.setGameMode(px_game.eGameModes.win) for num in range(0, 20): bfly = common_data.game.requestNewEntity( entity_template=self.butterfly_templates[rand_num(3)], pos=common_data.pos, parent=common_data.entity, name=f"Butterfly {num}")
def update(self, data, common_data, dt): speed = 0.3 # if doing something that can't be interrupted then countdown to end of it if self.coolDown(data, dt): pass else: if data.health <= 0: self.setState(data, common_data, eStates.dead) return if rand_num(10) == 0: self.setState(data, common_data, eStates.stationary) data.vel = Vec3(0, 0, 0) data.cooldown = rand_num(1) + 2 else: # chase hero target = common_data.game.requestTarget(common_data.pos) if (target.x < common_data.pos.x): self.setState(data, common_data, eStates.runLeft) data.vel = Vec3(-speed, 0, 0) data.facing = eDirections.left else: self.setState(data, common_data, eStates.runRight) data.vel = Vec3(speed, 0, 0) data.facing = eDirections.right if (target.y < common_data.pos.y): data.vel.y = -speed else: data.vel.y = speed data.cooldown = 0.5 basic_physics(common_data.pos, data.vel) restrictToArena(common_data.pos, data.vel) friction(data.vel)
def initEntity(self, entity, data=False): # values for each instance entity.cooldown = -1 entity.pause = 7 entity.vel = Vec3(0.0,0.0,0.0) entity.queued_vel = Vec3(0.0,0.0,0.0) entity.facing = False entity.queued_facing = 4 entity.health = 3 entity.state = PacBun.eStates.idle entity.queued_state = entity.state entity.AI_cooldown = 1 + px_vector.rand_num(15) / 5. entity.type = data['type'] entity.fox_speed = 1
def update(self, data, common_data, dt): fire_cool = 1.4 if self.coolDown(data, dt): if data.fired and (common_data.state not in [ px_entity.eStates.fallLeft, px_entity.eStates.fallRight, px_entity.eStates.dead ]): if data.cooldown < 0.9: self.shoot(data, common_data, data.facingleft) data.fired = False else: if data.health <= 0: self.setState(data, common_data, px_entity.eStates.dead) return # fire at hero if in range target = common_data.game.requestTarget(common_data.pos) data.facingleft = (target.x < common_data.pos.x) if abs(target.x - common_data.pos.x) < 200 and abs( target.z - common_data.pos.z) < 20: self.setState( data, common_data, px_entity.eStates.attackSmallLeft if data.facingleft else px_entity.eStates.attackSmallRight) data.fired = True data.cooldown = fire_cool else: self.setState( data, common_data, px_entity.eStates.standLeft if data.facingleft else px_entity.eStates.standRight) data.cooldown = rand_num(1) + 2 px_controller.friction(data.vel) px_controller.basic_gravity(data.vel) px_controller.basic_physics(common_data.pos, data.vel) background.restrictToArena(common_data.pos, data.vel)
def KFEvents(self): return [ # wait a bit Delay(2), # first wave SpawnEnemies([ SpawnEntity(self.reaper_t, Vec3(300, 35, 0), False, "Reaper 2"), ]), Delay(rand_num(1) + 0.5), # spawn second wave SpawnEnemies([ SpawnEntity(self.reaper_t, Vec3(20, 35, 0), False, "Reaper 2"), ]), # wait until all monsters destroyed WaitForNoEnemies(), # wait a bit Delay(4), # second wave SpawnEnemies([ SpawnEntity(self.bat_t, Vec3(30, 35, 5), False, "Bat 1"), ]), Delay(rand_num(1) + 0.5), # spawn other half of wave SpawnEnemies([ SpawnEntity(self.bat_t, Vec3(300, 35, 5), False, "Bat 1"), ]), Delay(rand_num(1) + 0.5), SpawnEnemies([ SpawnEntity(self.bat_t, Vec3(155, 110, 5), False, "Bat 1"), ]), Delay(rand_num(1) + 0.5), # spawn other half of wave SpawnEnemies([ SpawnEntity(self.bat_t, Vec3(300, 35, 5), False, "Bat 1"), ]), Delay(rand_num(1) + 0.5), SpawnEnemies([ SpawnEntity(self.bat_t, Vec3(30, 35, 5), False, "Bat 1"), ]), Delay(rand_num(1) + 0.5), # spawn other half of wave SpawnEnemies([ SpawnEntity(self.bat_t, Vec3(155, 110, 5), False, "Bat 1"), ]), # wait until all monsters destroyed WaitForNoEnemies(), # wait a bit Delay(2), # ... WaitForNoEnemies(), # wait a bit Delay(2), # signal game complete EndGame() ]
def update(self, dt): if self.game_mode == eGameModes.init: pass ################################################## elif self.game_mode == eGameModes.title: pass ################################################## elif self.game_mode == eGameModes.start: # set up new game and clean up anything from last game self.num_monsters = 0 self.killPlayEntities() self.cleanUpDead() self.director = self.requestNewEntity( entity_template=self.director_t) self.director.controller_data.events = self.KFEvents() # make hero self.hero = self.requestNewEntity(entity_template=self.hero_t, pos=Vec3(160, 60, 0), parent=False, name="Hero") self.hero.setGamePad(self.input.getGamePad(0)) # set up life indicator in top left for n in range(1, 6): heart = self.entity_manager.makeEntity(self.heart_t, "Heart") heart.setPos(Vec3(10 * n, 0, 190)) self.drawables.append(heart) self.updatables.append(heart) heart.common_data.parent = self.hero heart.common_data.state = eStates.fade heart.controller_data.health_num = n self.rain_cooldown = 500 self.setGameMode(eGameModes.play) ################################################## elif self.game_mode == eGameModes.play: # rain if self.raining: if (rand_num(10) == 0): rain = self.entity_manager.makeEntity(self.rain_t) rain.setState(RainController.state_fall) rain.setPos(Vec3(rand_num(320), rand_num(64), 200)) self.drawables.append(rain) self.updatables.append(rain) self.rain_cooldown -= 1 if self.rain_cooldown <= 0: self.rain_cooldown = rand_num(500) + 500 self.raining = not self.raining if self.hero.getState() == eStates.dead: self.setGameMode(eGameModes.game_over) self.restart_cooldown = 3 #################################################### elif self.game_mode == eGameModes.game_over: self.director.setState(eStates.dead) self.restart_cooldown -= dt self.title.setState(eTitleStates.game_over) if self.restart_cooldown <= 0: self.setGameMode(eGameModes.title) self.cleanUpDead() #################################################### elif self.game_mode == eGameModes.win: self.restart_cooldown -= dt self.title.setState(eTitleStates.win) if self.restart_cooldown <= 0: self.setGameMode(eGameModes.title) self.cleanUpDead() # Always do this, unless paused: if self.game_mode != eGameModes.paused: for index, updatable in reversed(list(enumerate(self.updatables))): updatable.update(dt) self.collision_manager.doCollisions( ) # collisions between monsters # clean up dead entities self.cleanUpDead() else: self.title.update(dt)
def update(self, dt): if self.game_mode == eGameModes.init: pass ################################################## elif self.game_mode == eGameModes.title: pass ################################################## elif self.game_mode == eGameModes.start: # set up new game and clean up anything from last game self.num_monsters = 0 self.killPlayEntities() self.cleanUpDead() self.director = self.requestNewEntity( entity_template=self.director_t) self.director.controller_data.events = self.KFEvents() # make bunny self.bunny = self.requestNewEntity(entity_template=self.bunny_t, pos=Vec3(190, 60, 0), parent=False, name="Bunny") self.bunny.setGamePad(self.input.getGamePad(0)) self.present = self.requestNewEntity( entity_template=self.present_t, pos=Vec3(400, 60, 0), parent=self, name="present") self.present.controller.setButterflyTemplates(self.bfly_templates) self.rain_cooldown = 500 self.restart_cooldown = 60 self.setGameMode(eGameModes.play) ################################################## elif self.game_mode == eGameModes.play: if (rand_num(10) == 0 and len(self.drawables) < 5): bfly = self.entity_manager.makeEntity( self.bfly_templates[rand_num(3)]) bfly.setPos(Vec3(rand_num(640), rand_num(270), 500)) self.drawables.append(bfly) self.updatables.append(bfly) # rain if False: #self.raining: if (rand_num(20) == 0): rain = self.entity_manager.makeEntity(self.rain_t) rain.setState(RainController.state_fall) rain.setPos(Vec3(rand_num(1920), rand_num(270), 500)) self.drawables.append(rain) self.updatables.append(rain) self.rain_cooldown -= 1 if self.rain_cooldown <= 0: self.rain_cooldown = rand_num(500) + 500 self.raining = not self.raining # if self.hero.getState()==eStates.dead: # self.setGameMode(eGameModes.game_over) # self.restart_cooldown=3 ############### # scroll view # ############### if self.scroll: offset = self.renlayer.getOrigin( ) - self.bunny.common_data.pos + Vec3(self.res_x / 2, self.res_y / 2, 0) if offset.magsq() > 100: self.renlayer.origin -= offset / 40.0 self.renlayer.origin.z = 0 # make current ground level when can if self.renlayer.origin.y < 0: self.renlayer.origin.y = 0 #################################################### elif self.game_mode == eGameModes.game_over: self.director.setState(eStates.dead) self.restart_cooldown -= dt self.title.setState(eTitleStates.game_over) if self.restart_cooldown <= 0: self.setGameMode(eGameModes.title) self.cleanUpDead() #################################################### elif self.game_mode == eGameModes.win: self.restart_cooldown -= dt if self.restart_cooldown <= 0: self.setGameMode(eGameModes.title) self.cleanUpDead() #################################################### elif self.game_mode == eGameModes.quit: self.quit_cooldown -= dt self.title.setState(eTitleStates.quit) if self.quit_cooldown <= 0: self.running = False return # Always do this, unless paused: if self.game_mode != eGameModes.paused: for index, updatable in reversed(list(enumerate(self.updatables))): updatable.update(dt) for audible in self.audibles: audible.sounds.play(audible.sounds_data, audible.common_data) self.collision_manager.doCollisions( ) # collisions between monsters # clean up dead entities self.cleanUpDead() else: self.title.update(dt)
def update(self, dt): if self.game_mode == eGameModes.init: pass ################################################## elif self.game_mode == eGameModes.title: pass ################################################## elif self.game_mode == eGameModes.start: # set up new game and clean up anything from last game self.num_monsters = 0 self.killPlayEntities() self.cleanUpDead() self.director = self.requestNewEntity( entity_template=self.director_t) self.director.controller_data.events = KFdirector.KFEvents(self) # make hero self.hero = self.requestNewEntity(entity_template=self.hero_t, pos=Vec3(150, 0, 60), parent=False, name="Hero") self.hero.setGamePad(self.input.getGamePad(0)) # make hero 2 game_pad = self.input.getGamePad(1) if game_pad: self.hero2 = self.requestNewEntity(entity_template=self.hero_t, pos=Vec3(170, 0, 60), parent=False, name="Hero 2") self.hero2.setGamePad(game_pad) # set up life indicator in top left for n in range(1, 6): heart = self.entity_manager.makeEntity(self.heart_t, "Heart") heart.setPos(Vec3(10 * n, 190, 0)) self.drawables.append(heart) self.updatables.append(heart) heart.common_data.parent = self.hero heart.common_data.state = eStates.fade heart.controller_data.health_num = n self.rain_cooldown = 500 self.setGameMode(eGameModes.play) ################################################## elif self.game_mode == eGameModes.play: # rain if self.raining: if (rand_num(10) == 0): raindrop = self.entity_manager.makeEntity(self.rain_t) raindrop.setState(rain.eRainStates.state_fall) raindrop.setPos(Vec3(rand_num(320), 200, rand_num(64))) self.drawables.append(raindrop) self.updatables.append(raindrop) self.rain_cooldown -= 1 if self.rain_cooldown <= 0: self.rain_cooldown = rand_num(500) + 500 self.raining = not self.raining if self.hero.getState() == eStates.dead: self.setGameMode(eGameModes.game_over) self.restart_cooldown = 3 ############### # scroll view # ############### if self.scroll: offset = self.renlayer.getOrigin( ) - self.hero.common_data.pos + Vec3(160, 64, 0) if offset.magsq() > 1000: self.renlayer.origin -= offset / 40.0 self.renlayer.origin.z = 0 # make current ground level when can #################################################### elif self.game_mode == eGameModes.game_over: self.director.setState(eStates.dead) self.restart_cooldown -= dt self.title.setState(title.eTitleStates.game_over) if self.restart_cooldown <= 0: self.setGameMode(eGameModes.title) self.cleanUpDead() #################################################### elif self.game_mode == eGameModes.win: self.restart_cooldown -= dt self.title.setState(title.eTitleStates.win) if self.restart_cooldown <= 0: self.setGameMode(eGameModes.title) self.cleanUpDead() #################################################### elif self.game_mode == eGameModes.quit: self.quit_cooldown -= dt self.title.setState(title.eTitleStates.quit) if self.quit_cooldown <= 0: self.running = False return # Always do this, unless paused: if self.game_mode != eGameModes.paused: for index, updatable in reversed(list(enumerate(self.updatables))): updatable.update(dt) for audible in self.audibles: audible.sounds.play(audible.sounds_data, audible.common_data) self.collision_manager.doCollisions( ) # collisions between monsters # clean up dead entities self.cleanUpDead() else: self.title.update(dt)
def startAnim(self, entity, frame=0): entity.current_time = 0 entity.current_frame = rand_num(len(self.frames))
def KFEvents(game): return[ # wait a bit Delay(2), SpawnEnemies([ SpawnEntity(game.bat_t, Vec3(290, 5, 35), False, "Bat 1"), ]), SpawnEnemies([ SpawnEntity(game.goblin_archer_t, Vec3(292, 0, 35), False, "Goblin Archer"), ]), SpawnEnemies([ SpawnEntity(game.goblin_archer_t, Vec3(25, 0, 35), False, "Goblin Archer"), ]), # wait a bit Delay(0.7), SpawnEnemies([ SpawnEntity(game.reaper_t, Vec3(30, 0, 35), False, "Reaper"), ]), Delay(rand_num(1)+0.5), # wait until all monsters destroyed WaitForNoEnemies(), # wait a bit Delay(4), # first wave SpawnEnemies([ SpawnEntity(game.reaper_t, Vec3(300, 0, 35), False, "Reaper 2"), ]), Delay(rand_num(1)+0.5), SpawnEnemies([ SpawnEntity(game.reaper_t, Vec3(20, 0, 35), False, "Reaper 2"), ]), # wait until all monsters destroyed WaitForNoEnemies(), # wait a bit Delay(4), # second wave SpawnEnemies([ SpawnEntity(game.bat_t, Vec3(30, 5, 35), False, "Bat 1"), ]), Delay(rand_num(1)+0.5), # spawn other half of wave SpawnEnemies([ SpawnEntity(game.bat_t, Vec3(300, 5, 35), False, "Bat 1"), ]), Delay(rand_num(1)+0.5), SpawnEnemies([ SpawnEntity(game.bat_t, Vec3(155, 5, 110), False, "Bat 1"), ]), Delay(rand_num(1)+0.5), # spawn other half of wave SpawnEnemies([ SpawnEntity(game.bat_t, Vec3(300, 5, 35), False, "Bat 1"), ]), Delay(rand_num(1)+0.5), SpawnEnemies([ SpawnEntity(game.bat_t, Vec3(30, 5, 35), False, "Bat 1"), ]), Delay(rand_num(1)+0.5), # spawn other half of wave SpawnEnemies([ SpawnEntity(game.bat_t, Vec3(155, 5, 110), False, "Bat 1"), ]), # wait until all monsters destroyed WaitForNoEnemies(), # wait a bit Delay(2), # ... WaitForNoEnemies(), # wait a bit Delay(2), # signal game complete EndGame() ]
def update(self, dt): if self.game_mode == px_game.eGameModes.init: pass ################################################## elif self.game_mode == px_game.eGameModes.title: pass ################################################## elif self.game_mode == px_game.eGameModes.start: # set up new game and clean up anything from last game self.num_monsters = 0 self.killPlayEntities() self.cleanUpDead() self.director = self.requestNewEntity( entity_template=self.director_t) self.director.controller_data.events = self.KFEvents() self.back = self.requestNewEntity(entity_template=self.back_t, pos=Vec3(0, -500, 500), parent=self, name="back") for n in (0, 100, 200, 300, 400): for m in (0, 12, 24, 36, 48, 60): self.platform = self.requestNewEntity( entity_template=self.platform_t, pos=Vec3(300 + n / 2, n / 5 - 5, 50 + m), parent=self, name="platform") # make bunnies self.oreo = self.requestNewEntity(entity_template=self.oreo_t, pos=Vec3(500, 0, 60), parent=False, name="Oreo") self.oreo.setGamePad(self.input.getGamePad(1)) self.macaroon = self.requestNewEntity( entity_template=self.macaroon_t, pos=Vec3(190, 50, 60), parent=False, name="Macaroon") self.macaroon.setGamePad(self.input.getGamePad(0)) self.control_macaroon = True self.rain_cooldown = 500 self.restart_cooldown = 60 self.setGameMode(px_game.eGameModes.play) ################################################## elif self.game_mode == px_game.eGameModes.play: if (rand_num(10) == 0 and len(self.drawables) < 55): bfly = self.entity_manager.makeEntity( self.bfly_templates[rand_num(3)]) bfly.setPos( Vec3(rand_num(self.res_x), 500, rand_num(self.res_y))) self.drawables.append(bfly) self.updatables.append(bfly) # rain if self.raining: if (rand_num(20) == 0): raindrop = self.entity_manager.makeEntity(self.rain_t) raindrop.setState(rain.Controller.state_fall) raindrop.setPos(Vec3(rand_num(1920), 500, rand_num(270))) self.drawables.append(raindrop) self.updatables.append(raindrop) self.rain_cooldown -= 1 if self.rain_cooldown <= 0: self.rain_cooldown = rand_num(500) + 500 self.raining = not self.raining # if self.hero.getState()==entity.eStates.dead: # self.setGameMode(game.eGameModes.game_over) # self.restart_cooldown=3 #################################################### elif self.game_mode == px_game.eGameModes.game_over: self.director.setState(px_entity.eStates.dead) self.restart_cooldown -= dt self.title.setState(title.eTitlentity.eStates.game_over) if self.restart_cooldown <= 0: self.setGameMode(px_game.eGameModes.title) self.cleanUpDead() #################################################### elif self.game_mode == px_game.eGameModes.win: self.restart_cooldown -= dt if self.restart_cooldown <= 0: self.setGameMode(px_game.eGameModes.title) self.cleanUpDead() #################################################### elif self.game_mode == px_game.eGameModes.quit: self.quit_cooldown -= dt self.title.setState(title.eTitleStates.quit) if self.quit_cooldown <= 0: self.running = False return # Always do this, unless paused: if self.game_mode != px_game.eGameModes.paused: for index, updatable in reversed(list(enumerate(self.updatables))): updatable.update(dt) for audible in self.audibles: audible.sounds.play(audible.sounds_data, audible.common_data) self.collision_manager.doCollisions( ) # collisions between monsters # clean up dead entities self.cleanUpDead() else: self.title.update(dt)
def update(self, entity, dt): if entity.state in [PacBun.eStates.caughtBlue,PacBun.eStates.caughtBowie,PacBun.eStates.caughtPacBun,PacBun.eStates.caughtPinkie]: return # pause foxes every so often # todo: foxes shouldn't pause if the bunny is in sight entity.AI_cooldown -= dt if entity.AI_cooldown<=0: entity.AI_cooldown= 10 + px_vector.rand_num(10) if entity.fox_speed==1: entity.fox_speed=0 entity.AI_cooldown = entity.pause if entity.pause>0: entity.pause -=1 self.setState(entity, [PacBun.eStates.idle, PacBun.eStates.idle, PacBun.eStates.idle, PacBun.eStates.idle, PacBun.eStates.idle, PacBun.eStates.cleanRight, PacBun.eStates.cleanLeft][px_vector.rand_num(7)] # todo: find better way to make idle more likely ) else: entity.fox_speed=1 if entity.fox_speed==0: return fox_speed = entity.fox_speed map_controller = entity.parent.getComponent('controller') entity.bunny = map_controller.getNearestBunny(entity.parent, entity.pos) bunny_pos = copy.deepcopy(entity.bunny.getPos()) if entity.type==eFoxTypes.ahead: # aim at a position ahead of the bunny if entity.bunny.facing: bunny_pos+= ( Vec3(0,-96,0), Vec3(-96,0, 0), Vec3(0, 96, 0), Vec3(96, 0, 0), )[entity.bunny.facing] current_tile = map_controller.getTileFromPos(entity.parent, entity.pos) exits = current_tile.process('getExits') x_in_tile = entity.pos.x % 16 y_in_tile = entity.pos.y % 16 # work out preferred direction if bunny_pos.x>entity.pos.x: pref_dir=px_entity.eDirections.right else: pref_dir = px_entity.eDirections.left if bunny_pos.y > entity.pos.y: sec_dir = px_entity.eDirections.up else: sec_dir = px_entity.eDirections.down if (abs(bunny_pos.x-entity.pos.x)<abs(bunny_pos.y-entity.pos.y)): # choose most optimal axis pref_dir, sec_dir = sec_dir, pref_dir if entity.type==eFoxTypes.axis_swap: # swap to less optimal axis for this fox pref_dir, sec_dir = sec_dir, pref_dir elif entity.type==eFoxTypes.cowardly: # reverse directions so fox runs away pref_dir = ( px_entity.eDirections.up, px_entity.eDirections.right, px_entity.eDirections.down, px_entity.eDirections.left, )[pref_dir] sec_dir = ( px_entity.eDirections.up, px_entity.eDirections.right, px_entity.eDirections.down, px_entity.eDirections.left, )[sec_dir] # try to go that way if ((x_in_tile-8)%16==0) and ((y_in_tile-8)%16==0): if pref_dir in exits: entity.facing = pref_dir elif sec_dir in exits: entity.facing = sec_dir else: entity.facing = exits[0] entity.vel = ( Vec3(0,-fox_speed,0), Vec3(-fox_speed,0, 0), Vec3(0, fox_speed, 0), Vec3(fox_speed,0, 0), )[entity.facing] self.setState(entity,( PacBun.eStates.runDown, PacBun.eStates.runLeft, PacBun.eStates.runUp, PacBun.eStates.runRight )[entity.facing]) px_controller.basic_physics(entity.pos, entity.vel)