# HG changeset patch # User Jeremy Thurgood # Date 1378550015 -7200 # Node ID d7bd9adb105aa2f688321a4e478df579d2830771 # Parent 180c27514619a99db0f282321ab0d1ec0f4712b4 Sheep! (And refactoring!) diff -r 180c27514619 -r d7bd9adb105a data/images/creatures/alien_sheep_1.png Binary file data/images/creatures/alien_sheep_1.png has changed diff -r 180c27514619 -r d7bd9adb105a data/images/creatures/alien_sheep_2.png Binary file data/images/creatures/alien_sheep_2.png has changed diff -r 180c27514619 -r d7bd9adb105a data/images/creatures/sheep_1.png Binary file data/images/creatures/sheep_1.png has changed diff -r 180c27514619 -r d7bd9adb105a data/images/creatures/sheep_2.png Binary file data/images/creatures/sheep_2.png has changed diff -r 180c27514619 -r d7bd9adb105a data/levels/start --- a/data/levels/start Sat Sep 07 11:21:54 2013 +0200 +++ b/data/levels/start Sat Sep 07 12:33:35 2013 +0200 @@ -1,5 +1,8 @@ base_tile: tiles/floor.png -enemies: [] +enemies: +- args: + - [300, 300] + classname: Sheep game_objects: - args: - [725, 300] diff -r 180c27514619 -r d7bd9adb105a nagslang/constants.py --- a/nagslang/constants.py Sat Sep 07 11:21:54 2013 +0200 +++ b/nagslang/constants.py Sat Sep 07 12:33:35 2013 +0200 @@ -24,6 +24,7 @@ COLLISION_TYPE_DOOR = 6 COLLISION_TYPE_PROJECTILE = 7 COLLISION_TYPE_WEREWOLF_ATTACK = 8 +COLLISION_TYPE_SHEEP = 9 SWITCH_PUSHERS = [COLLISION_TYPE_PLAYER, COLLISION_TYPE_FURNITURE] @@ -34,6 +35,7 @@ COLLISION_TYPE_FURNITURE, COLLISION_TYPE_ENEMY, COLLISION_TYPE_DOOR, + COLLISION_TYPE_SHEEP, ] NON_GAME_OBJECT_COLLIDERS = [ diff -r 180c27514619 -r d7bd9adb105a nagslang/enemies.py --- a/nagslang/enemies.py Sat Sep 07 11:21:54 2013 +0200 +++ b/nagslang/enemies.py Sat Sep 07 12:33:35 2013 +0200 @@ -5,8 +5,9 @@ import pymunk.pygame_util from nagslang import render -from nagslang.constants import (COLLISION_TYPE_ENEMY, COLLISION_TYPE_FURNITURE, - ACID_SPEED, ACID_DAMAGE, ZORDER_MID) +from nagslang.constants import ( + COLLISION_TYPE_ENEMY, COLLISION_TYPE_FURNITURE, COLLISION_TYPE_SHEEP, + ACID_SPEED, ACID_DAMAGE, ZORDER_MID) from nagslang.game_object import (GameObject, SingleShapePhysicser, Result, Bullet, make_body) from nagslang.mutators import FLIP_H @@ -35,12 +36,15 @@ enemy_damage = None health = None impulse_factor = None + random_move_time = 0.3 def __init__(self, space, world, position): super(Enemy, self).__init__( self.make_physics(space, position), self.make_renderer()) self.world = world self.angle = 0 + self.add_timer('random_move', self.random_move_time) + self._last_random_direction = (0, 0) def make_physics(self, space, position): raise NotImplementedError @@ -55,12 +59,16 @@ get_alien_image(self.enemy_type, '2', FLIP_H)], 3), }) - def attack(self): - raise NotImplementedError + def get_render_angle(self): + # No image rotation when rendering, please. + return 0 - @classmethod - def requires(cls): - return [("name", "string"), ("position", "coordinates")] + def get_facing_direction(self): + # Enemies can face left or right. + if - math.pi / 2 < self.angle <= math.pi / 2: + return 'right' + else: + return 'left' def hit(self, weapon): self.lose_health(weapon.damage) @@ -101,14 +109,10 @@ return None return target - pos - def ranged_attack(self, range_, speed, damage, type_, reload_time, - result=None): - if result is None: - result = Result() - + def ranged_attack(self, range_, speed, damage, type_, reload_time, result): vec = self.range_to_visible_protagonist() if vec is None: - return result + return if not self.check_timer('reload_time'): self.start_timer('reload_time', reload_time) @@ -117,7 +121,6 @@ result.add += (Bullet( self.get_space(), self.physicser.position, vec, damage, type_, COLLISION_TYPE_ENEMY),) - return result def greedy_move(self, target): """Simple greedy path finder""" @@ -135,9 +138,17 @@ def random_move(self): """Random move""" - x_step = random.choice([-1, 0, 1]) - y_step = random.choice([-1, 0, 1]) - return x_step, y_step + if not self.check_timer('random_move'): + self.start_timer('random_move') + self._last_random_direction = ( + random.choice([-1, 0, 1]), random.choice([-1, 0, 1])) + return self._last_random_direction + + def attack(self, result): + pass + + def move(self, result): + pass def update(self, dt): super(Enemy, self).update(dt) @@ -147,8 +158,14 @@ result.add += (DeadEnemy(self.get_space(), self.world, self.physicser.position, self.enemy_type),) + self.move(result) + self.attack(result) return result + @classmethod + def requires(cls): + return [("name", "string"), ("position", "coordinates")] + class DeadEnemy(GameObject): def __init__(self, space, world, position, enemy_type='A'): @@ -190,25 +207,13 @@ shape.collision_type = COLLISION_TYPE_ENEMY return SingleShapePhysicser(space, shape) - def get_render_angle(self): - # No image rotation when rendering, please. - return 0 - - def get_facing_direction(self): - # Enemies can face left or right. - if - math.pi / 2 < self.angle <= math.pi / 2: - return 'right' - else: - return 'left' - def _switch_direction(self): if self._direction == 'away': self._direction = 'towards' else: self._direction = 'away' - def update(self, dt): - # Calculate the step every frame + def move(self, result): if self._direction == 'away': target = self._end_pos else: @@ -217,8 +222,9 @@ if abs(x_step) < 1 and abs(y_step) < 1: self._switch_direction() self.set_direction(x_step, y_step) - result = self.ranged_attack(300, ACID_SPEED, ACID_DAMAGE, 'acid', 0.2) - return result.merge(super(PatrollingAlien, self).update(dt)) + + def attack(self, result): + self.ranged_attack(300, ACID_SPEED, ACID_DAMAGE, 'acid', 0.2, result) @classmethod def requires(cls): @@ -246,18 +252,7 @@ shape.collision_type = COLLISION_TYPE_ENEMY return SingleShapePhysicser(space, shape) - def get_render_angle(self): - # No image rotation when rendering, please. - return 0 - - def get_facing_direction(self): - # Enemies can face left or right. - if - math.pi / 2 < self.angle <= math.pi / 2: - return 'right' - else: - return 'left' - - def _calc_movement(self): + def move(self, result): pos = self.physicser.position target = self.world.protagonist.get_shape().body.position if pos.get_distance(target) > self._range: @@ -266,15 +261,10 @@ return 0, 0 self.is_moving = True dx, dy = self.greedy_move(target) - return dx, dy + self.set_direction(dx, dy) - def update(self, dt): - # Calculate the step every frame - # Distance to the protagonist - result = self.ranged_attack(300, ACID_SPEED, ACID_DAMAGE, 'acid', 0.2) - dx, dy = self._calc_movement() - self.set_direction(dx, dy) - return result.merge(super(ChargingAlien, self).update(dt)) + def attack(self, result): + self.ranged_attack(300, ACID_SPEED, ACID_DAMAGE, 'acid', 0.2, result) @classmethod def requires(cls): @@ -288,12 +278,6 @@ impulse_factor = 90 is_moving = True - def __init__(self, space, world, position, attack_range=100): - super(RunAndGunAlien, self).__init__(space, world, position, - attack_range) - self.count = 0 - self._old_move = (0, 0) - def make_physics(self, space, position): body = make_body(10, pymunk.inf, position, 0.8) shape = pymunk.Circle(body, 30) @@ -302,22 +286,46 @@ shape.collision_type = COLLISION_TYPE_ENEMY return SingleShapePhysicser(space, shape) - def _calc_movement(self): + def move(self, result): pos = self.physicser.position target = self.world.protagonist.get_shape().body.position if pos.get_distance(target) < self._range: - if self.count > 10: - self._old_move = self.random_move() - self.count = 0 - return self._old_move + step = self.random_move() else: - return self.greedy_move(target) - - def update(self, dt): - self.count += 1 - return super(RunAndGunAlien, self).update(dt) + step = self.greedy_move(target) + self.set_direction(*step) @classmethod def requires(cls): return [("name", "string"), ("position", "coordinates"), ("attack_range", "distance")] + + +class Sheep(Enemy): # Only because we don't have a DeliciousCreature class. + is_moving = True # Always walking. + enemy_type = 'sheep' + health = 10 + impulse_factor = 50 + + vision_range = 100 + + def make_physics(self, space, position): + body = make_body(10, pymunk.inf, position, 0.8) + shape = pymunk.Circle(body, 30) + shape.elasticity = 1.0 + shape.friction = 0.05 + shape.collision_type = COLLISION_TYPE_SHEEP + return SingleShapePhysicser(space, shape) + + def move(self, result): + vec = self.range_to_visible_protagonist() + if vec is not None and vec.length < self.vision_range: + # TODO: Run away! Wander towards! + step = (0, 0) + else: + step = self.random_move() + self.set_direction(*step) + + @classmethod + def requires(cls): + return [("name", "string"), ("position", "coordinates")] diff -r 180c27514619 -r d7bd9adb105a source/images/creatures/alien_sheep_1.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/images/creatures/alien_sheep_1.svg Sat Sep 07 12:33:35 2013 +0200 @@ -0,0 +1,690 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 180c27514619 -r d7bd9adb105a source/images/creatures/alien_sheep_2.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/images/creatures/alien_sheep_2.svg Sat Sep 07 12:33:35 2013 +0200 @@ -0,0 +1,720 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 180c27514619 -r d7bd9adb105a source/images/creatures/sheep_1.svg --- a/source/images/creatures/sheep_1.svg Sat Sep 07 11:21:54 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,690 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r 180c27514619 -r d7bd9adb105a source/images/creatures/sheep_2.svg --- a/source/images/creatures/sheep_2.svg Sat Sep 07 11:21:54 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,720 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -