Mercurial > nagslang
changeset 333:3dd32686dbc3
Better wolf claw attack.
author | Jeremy Thurgood <firxen@gmail.com> |
---|---|
date | Fri, 06 Sep 2013 10:49:19 +0200 |
parents | ffefb93127c5 |
children | a3f1b2f0e3fb |
files | nagslang/constants.py nagslang/enemies.py nagslang/events.py nagslang/game_object.py nagslang/protagonist.py nagslang/screens/area.py |
diffstat | 6 files changed, 60 insertions(+), 61 deletions(-) [+] |
line wrap: on
line diff
--- a/nagslang/constants.py Fri Sep 06 03:10:04 2013 +0200 +++ b/nagslang/constants.py Fri Sep 06 10:49:19 2013 +0200 @@ -51,3 +51,6 @@ WEREWOLF_SOAK_FACTOR = 10 PROTAGONIST_HEALTH_MAX_LEVEL = 100 PROTAGONIST_HEALTH_MIN_LEVEL = 0 + +BULLET_DAMAGE = 10 +CLAW_DAMAGE = 5
--- a/nagslang/enemies.py Fri Sep 06 03:10:04 2013 +0200 +++ b/nagslang/enemies.py Fri Sep 06 10:49:19 2013 +0200 @@ -24,6 +24,7 @@ class Enemy(GameObject): """A base class for mobile enemies""" enemy_type = None # Image to use for dead Enemy + enemy_damage = None def __init__(self, space, world, position): self._setup_physics(space, position) @@ -61,6 +62,13 @@ self.remove = True EnemyDeathEvent.post(self.physicser.position, self.enemy_type) + def collide_with_protagonist(self, protagonist): + if self.enemy_damage is not None: + protagonist.lose_health(self.enemy_damage) + + def collide_with_claw_attack(self, claw_attack): + self.lose_health(claw_attack.damage) + class DeadEnemy(GameObject): def __init__(self, space, world, position, enemy_type='A'): @@ -135,7 +143,7 @@ self._body.apply_impulse( (dx * self.impulse_factor, dy * self.impulse_factor)) - def update(self, seconds): + def update(self, dt): # Calculate the step every frame if self._direction == 'away': target = self._end_pos @@ -158,10 +166,7 @@ if abs(x_step) < 1 and abs(y_step) < 1: self._switch_direction() self.set_direction(x_step, y_step) - super(PatrollingAlien, self).update(seconds) - - def collide_with_protagonist(self, protagonist): - protagonist.lose_health(15) + super(PatrollingAlien, self).update(dt) @classmethod def requires(cls): @@ -216,7 +221,7 @@ self._body.apply_impulse( (dx * self.impulse_factor, dy * self.impulse_factor)) - def update(self, seconds): + def update(self, dt): # Calculate the step every frame # Distance to the protagonist pos = self._body.position @@ -241,10 +246,7 @@ if abs(y_step) < 0.5: y_step = 0 self.set_direction(x_step, y_step) - super(ChargingAlien, self).update(seconds) - - def collide_with_protagonist(self, protagonist): - protagonist.lose_health(20) + super(ChargingAlien, self).update(dt) @classmethod def requires(cls):
--- a/nagslang/events.py Fri Sep 06 03:10:04 2013 +0200 +++ b/nagslang/events.py Fri Sep 06 10:49:19 2013 +0200 @@ -63,6 +63,5 @@ class ClawEvent(UserEvent): @classmethod - def post(cls, source, vector, source_collision_type): - super(ClawEvent, cls).post(source=source, vector=vector, - source_collision_type=source_collision_type) + def post(cls, source, vector, damage): + super(ClawEvent, cls).post(source=source, vector=vector, damage=damage)
--- a/nagslang/game_object.py Fri Sep 06 03:10:04 2013 +0200 +++ b/nagslang/game_object.py Fri Sep 06 10:49:19 2013 +0200 @@ -2,7 +2,6 @@ import pymunk.pygame_util import math -import time from nagslang import environment from nagslang import puzzle @@ -111,6 +110,7 @@ def __init__(self, physicser, renderer, puzzler=None, overlay=None, interactible=None): + self.lifetime = 0 self.physicser = physicser physicser.set_game_object(self) self.physicser.add_to_space() @@ -147,8 +147,9 @@ def render(self, surface): return self.renderer.render(surface) - def update(self, seconds): - self.renderer.update(seconds) + def update(self, dt): + self.lifetime += dt + self.renderer.update(dt) def hit(self, weapon): '''Was hit with a weapon (such as a bullet)''' @@ -165,6 +166,9 @@ def collide_with_furniture(self, furniture): return True + def collide_with_claw_attack(self, claw_attack): + return True + @classmethod def requires(cls): """Hints for the level editor""" @@ -364,8 +368,8 @@ ) self.physicser.apply_impulse(impulse) - def update(self, seconds): - super(Bullet, self).update(seconds) + def update(self, dt): + super(Bullet, self).update(dt) position = (self.physicser.position.x, self.physicser.position.y) r = self.get_space().segment_query(self.last_position, position) self.last_position = position @@ -414,33 +418,22 @@ class ClawAttack(GameObject): - def __init__(self, space, position, vector, source_collision_type): - body = make_body(1, pymunk.inf, position) - self.last_position = position + def __init__(self, space, position, vector, damage): + body = make_body(1, pymunk.inf, position + vector) + body.angle = vector.angle self.shape = pymunk.Circle(body, 30) self.shape.sensor = True self.shape.collision_type = COLLISION_TYPE_WEREWOLF_ATTACK - self.source_collision_type = source_collision_type + self.damage = damage super(ClawAttack, self).__init__( SingleShapePhysicser(space, self.shape), - render.ImageRenderer(resources.get_image - ('objects', 'werewolf_SW_claw_attack.png')), + render.ImageRenderer(resources.get_image( + 'objects', 'werewolf_SW_claw_attack.png', + transforms=(FLIP_H,))), ) - self.time_created = time.time() - def update(self, seconds): - super(ClawAttack, self).update(seconds) - position = (self.physicser.position.x, self.physicser.position.y) - r = self.get_space().segment_query(self.last_position, position) - self.last_position = position - for collision in r: - shape = collision.shape - if (shape.collision_type == self.source_collision_type - or shape == self.physicser.get_shape() - or shape.sensor): - continue - if hasattr(shape, 'physicser'): - shape.physicser.game_object.hit(self) - if time.time() - self.time_created > 0.2: + def update(self, dt): + super(ClawAttack, self).update(dt) + if self.lifetime > 0.2: self.physicser.remove_from_space() self.remove = True
--- a/nagslang/protagonist.py Fri Sep 06 03:10:04 2013 +0200 +++ b/nagslang/protagonist.py Fri Sep 06 10:49:19 2013 +0200 @@ -6,7 +6,7 @@ from nagslang.constants import ( COLLISION_TYPE_PLAYER, ZORDER_MID, WEREWOLF_SOAK_FACTOR, PROTAGONIST_HEALTH_MIN_LEVEL, PROTAGONIST_HEALTH_MAX_LEVEL, - NON_GAME_OBJECT_COLLIDERS, COLLISION_TYPE_WEREWOLF_ATTACK) + NON_GAME_OBJECT_COLLIDERS, BULLET_DAMAGE, CLAW_DAMAGE) from nagslang.events import FireEvent, ClawEvent from nagslang.game_object import GameObject, Physicser, make_body from nagslang.mutators import FLIP_H @@ -59,7 +59,6 @@ self.health_level = 100 self.go_human() - self._time = 0 def _make_physics(self, space, position): body = make_body(10, pymunk.inf, position, 0.8) @@ -262,15 +261,14 @@ vec = Vec2d.unit() vec.angle = self.angle vec.length = 1000 - FireEvent.post(self.physicser.position, vec, 10, COLLISION_TYPE_PLAYER) + FireEvent.post( + self.physicser.position, vec, BULLET_DAMAGE, COLLISION_TYPE_PLAYER) def claw(self): vec = Vec2d.unit() vec.angle = self.angle - vec.length = 100 - ClawEvent.post(self.physicser.position, vec, - COLLISION_TYPE_WEREWOLF_ATTACK) - print "Claw", self.physicser.position, vec + vec.length = 30 + ClawEvent.post(self.physicser.position, vec, CLAW_DAMAGE) def in_wolf_form(self): return self.form == self.WOLF_FORM @@ -310,9 +308,7 @@ self.health_level = PROTAGONIST_HEALTH_MAX_LEVEL def update(self, dt): - last_secs = int(self._time) - self._time += dt - secs = int(self._time) - if self.form == self.WOLF_FORM and secs > last_secs: - self.gain_health(1) + if int(self.lifetime + dt) > int(self.lifetime): + if self.form == self.WOLF_FORM: + self.gain_health(1) super(Protagonist, self).update(dt)
--- a/nagslang/screens/area.py Fri Sep 06 03:10:04 2013 +0200 +++ b/nagslang/screens/area.py Fri Sep 06 10:49:19 2013 +0200 @@ -6,10 +6,10 @@ from nagslang.constants import ( COLLISION_TYPE_WALL, COLLISION_TYPE_PLAYER, CALLBACK_COLLIDERS, - COLLISION_TYPE_FURNITURE) + COLLISION_TYPE_FURNITURE, COLLISION_TYPE_WEREWOLF_ATTACK) from nagslang.enemies import DeadEnemy -from nagslang.events import ScreenChange, DoorEvent, FireEvent, \ - EnemyDeathEvent, ClawEvent +from nagslang.events import ( + ScreenChange, DoorEvent, FireEvent, EnemyDeathEvent, ClawEvent) from nagslang.level import Level from nagslang.screens.base import Screen from nagslang.game_object import Bullet, ClawAttack @@ -93,9 +93,13 @@ # The collision handler must return `True` or `False`. We don't want to # accidentally reject collisions from handlers that return `None`, so # we explicitly check for `False` and treate everything else as `True`. - if result is False: - return False - return True + return result is not False + + def _claw_attack_collision_pre_solve_handler(self, space, arbiter): + claw = arbiter.shapes[0].physicser.game_object + gobj = arbiter.shapes[1].physicser.game_object + result = gobj.collide_with_claw_attack(claw) + return result is not False def _furniture_collision_pre_solve_handler(self, space, arbiter): furniture = arbiter.shapes[0].physicser.game_object @@ -111,6 +115,9 @@ self.space.add_collision_handler( COLLISION_TYPE_FURNITURE, collision_type, pre_solve=self._furniture_collision_pre_solve_handler) + self.space.add_collision_handler( + COLLISION_TYPE_WEREWOLF_ATTACK, collision_type, + pre_solve=self._claw_attack_collision_pre_solve_handler) def add_walls(self): self.walls = [] @@ -173,7 +180,7 @@ self._drawables.add(dead_enemy) elif ClawEvent.matches(ev): claw_attack = ClawAttack(self.space, ev.source, ev.vector, - ev.source_collision_type) + ev.damage) self._drawables.add(claw_attack) self.keys.handle_event(ev) @@ -234,11 +241,10 @@ health_box_colour = pygame.color.THECOLORS['red'] else: health_box_colour = pygame.color.THECOLORS['white'] - pygame.draw.rect(surface, health_box_colour, rect, 0) + pygame.draw.rect(surface, health_box_colour, rect, 0) if self.protagonist.in_human_form(): health_colour = pygame.color.THECOLORS['red'] else: health_colour = pygame.color.THECOLORS['purple'] rect = pygame.Rect(55, 505, self.protagonist.get_health_level(), 40) - pygame.draw.rect(surface, health_colour, - rect, 0) + pygame.draw.rect(surface, health_colour, rect, 0)