Changeset 368:57895217bd74 for nagslang


Ignore:
Timestamp:
Sep 6, 2013, 7:26:57 PM (7 years ago)
Author:
Neil Muller <drnlmuller@…>
Branch:
default
rebase_source:
f7f5231f9ad746d0bad80d1a9938c95a4987c328
Message:

Start refactoring alien movement

File:
1 edited

Legend:

Unmodified
Added
Removed
  • nagslang/enemies.py

    r366 r368  
    11import math
     2import random
    23
    34import pymunk
     
    105106                               COLLISION_TYPE_ENEMY)
    106107                self._last_fired = self.lifetime
     108
     109    def greedy_move(self, target):
     110        """Simple greedy path finder"""
     111        def _calc_step(tp, pp):
     112            if (tp < pp):
     113                step = max(-1, tp - pp)
     114            elif (tp > pp):
     115                step = min(1, tp - pp)
     116            if abs(step) < 0.5:
     117                step = 0
     118            return step
     119        x_step = _calc_step(target[0], self.physicser.position[0])
     120        y_step = _calc_step(target[1], self.physicser.position[1])
     121        return (x_step, y_step)
     122
     123    def random_move(self):
     124        """Random move"""
     125        x_step = random.choice([-1, 0, 1])
     126        y_step = random.choice([-1, 0, 1])
     127        return x_step, y_step
    107128
    108129
     
    170191        else:
    171192            target = self._start_pos
    172         x_step = 0
    173         y_step = 0
    174         if (target[0] < self.physicser.position[0]):
    175             x_step = max(-1, target[0] - self.physicser.position[0])
    176         elif (target[0] > self.physicser.position[0]):
    177             x_step = min(1, target[0] - self.physicser.position[0])
    178         if abs(x_step) < 0.5:
    179             x_step = 0
    180         if (target[1] < self.physicser.position[1]):
    181             y_step = max(-1, target[1] - self.physicser.position[1])
    182         elif (target[1] > self.physicser.position[1]):
    183             y_step = min(1, target[1] - self.physicser.position[1])
    184         if abs(y_step) < 0.5:
    185             y_step = 0
     193        x_step, y_step = self.greedy_move(target)
    186194        if abs(x_step) < 1 and abs(y_step) < 1:
    187195            self._switch_direction()
     
    227235            return 'left'
    228236
    229     def update(self, dt):
    230         # Calculate the step every frame
    231         # Distance to the protagonist
    232         self.ranged_attack(300, ACID_SPEED, ACID_DAMAGE, 'acid', 0.2)
     237    def _calc_movement(self):
    233238        pos = self.physicser.position
    234239        target = self.world.protagonist.get_shape().body.position
     
    236241            # stop
    237242            self.is_moving = False
    238             return
     243            return 0, 0
    239244        self.is_moving = True
    240         dx = target.x - pos.x
    241         dy = target.y - pos.y
     245        dx, dy = self.greedy_move(target)
     246        return dx, dy
     247
     248    def update(self, dt):
     249        # Calculate the step every frame
     250        # Distance to the protagonist
     251        self.ranged_attack(300, ACID_SPEED, ACID_DAMAGE, 'acid', 0.2)
     252        dx, dy = self._calc_movement()
    242253        self.set_direction(dx, dy)
    243254        super(ChargingAlien, self).update(dt)
     
    247258        return [("name", "string"), ("position", "coordinates"),
    248259                ("attack_range", "distance")]
     260
     261
     262class RunAndGunAlien(ChargingAlien):
     263    # Simplistic shooter
     264    # Move until we're in range, and then randomly
     265    impulse_factor = 90
     266    is_moving = True
     267
     268    def __init__(self, space, world, position, attack_range=100):
     269        super(RunAndGunAlien, self).__init__(space, world, position,
     270                                             attack_range)
     271        self.count = 0
     272        self._old_move = (0, 0)
     273
     274    def make_physics(self, space, position):
     275        body = make_body(10, pymunk.inf, position, 0.8)
     276        shape = pymunk.Circle(body, 30)
     277        shape.elasticity = 1.0
     278        shape.friction = 0.05
     279        shape.collision_type = COLLISION_TYPE_ENEMY
     280        return SingleShapePhysicser(space, shape)
     281
     282    def _calc_movement(self):
     283        pos = self.physicser.position
     284        target = self.world.protagonist.get_shape().body.position
     285        if pos.get_distance(target) < self._range:
     286            if self.count > 10:
     287                self._old_move = self.random_move()
     288                self.count = 0
     289            return self._old_move
     290        else:
     291            return self.greedy_move(target)
     292
     293    def update(self, dt):
     294        super(RunAndGunAlien, self).update(dt)
     295        self.count += 1
     296
     297    @classmethod
     298    def requires(cls):
     299        return [("name", "string"), ("position", "coordinates"),
     300                ("attack_range", "distance")]
Note: See TracChangeset for help on using the changeset viewer.