示例#1
0
 def throw_bomb(self):
     angle = self.knight.angle
     direction = Vector2()
     direction.from_polar((1, math.degrees(angle)))
     pos = Vector2(*self.knight.pos) + self.radius * direction
     vel = self.v + direction * Bomb.SPEED
     self.level.spawn_bomb(pos, vel)
示例#2
0
    def update(self, dt):
        self.v *= self.DRAG ** dt   # drag

        if self.accel:
            # New acceleration this frame
            self.v += self.ACCELERATION * self.accel * dt

        da, accel_angle = self.accel.as_polar()
        accel_angle = math.radians(accel_angle)

        delta = angle_diff(accel_angle, self.knight.angle)
        if delta < 0:
            self.knight.angle += max(dt * da * -self.TURN, delta)
        else:
            self.knight.angle += min(dt * da * self.TURN, delta)

        # Keep within the play area
        sz = Vector2(self.knight.radius, self.knight.radius)
        scene = self.knight.scene
        self.knight.pos = np.clip(
            self.knight.pos + self.v * dt,
            sz,
            Vector2(scene.width, scene.height) - sz
        )
        self.knight.v = self.v

        self.accel *= 0.0
示例#3
0
    def update(self, dt):
        """Update the knight this frame."""

        if self.last_pos:
            displacement = Vector2(*self.pos - self.last_pos)
            distance = displacement.length()
            num = np.random.poisson(distance * self.SMOKE_RATE)
            if num:
                stern = self.pos - displacement.normalize() * 10
                if self.game.use_particles:
                    self.scene.smoke.emit(
                        num=num,
                        pos=stern,
                        pos_spread=2,
                        vel=displacement * 0.3,
                        spin_spread=1,
                        size=7,
                        angle=self.knight.angle,
                        angle_spread=3,
                    )

            self.step += distance

            # Scale the knight to simulate gait
            bob = 1.1 + 0.1 * np.sin(self.step / 500)
            self.knight.scale = bob
        self.last_pos = Vector2(*self.pos)
示例#4
0
    def __init__(self, level, color=(1, 1, 1, 1)):
        self.level = level
        self.game = level.game
        scene = self.scene = level.scene
        shield_sprite = scene.layers[Layers.ENTITIES].add_sprite('shield')
        sword_sprite = scene.layers[Layers.UPPER_EFFECTS].add_sprite('sword-gripped')
        sword_sprite.color = (1.4, 1.4, 1.4, 1)
        self.knight = scene.layers[Layers.ENTITIES].add_sprite(
            'knight',
            color=color
        )

        self.shield = Hand(
            sprite=shield_sprite,
            knight=self,
            radius=12,
            angle=-1.5,
        )
        self.sword = Hand(
            sprite=sword_sprite,
            knight=self,
            radius=25,
            angle=0,
        )
        self.sword.attack = False
        self.v = Vector2()

        self.pos = Vector2(scene.width, scene.height) * 0.5
        self.last_pos = None

        # The distance the knight has travelled; this is used in
        # calculating his gait
        self.step = 0
示例#5
0
def update(keyboard):
    x, y = alien.fpos
    vx, vy = alien.v

    y += vy
    alien.fpos.y = y

    eps = 1e-4

    br, bl, tl, tr = bounds()

    if alien.stood:
        belowl = bl + Vector2(0, 1)
        belowr = br + Vector2(0, 1)
        if not (collide_point(belowl, belowr)):
            alien.stood = False
            alien.image = 'pc_standing'
            vy += GRAVITY
    else:
        if vy + eps > y - tile_floor(y) > 0:
            if collide_point(bl, br):
                alien.image = 'pc_standing'
                alien.stood = True
                vy = 0
                y = tile_floor(y)
            else:
                alien.image = 'pc_falling'
        elif vy - eps < tl.y - tile_ceil(tl.y) < 0:
            if collide_point(tl, tr):
                print("oof")
                vy = 0
                y = tile_ceil(y)
        if not alien.stood:
            vy += GRAVITY

    if not alien.crouch:
        if keyboard.left:
            vx -= ACCEL
        elif keyboard.right:
            vx += ACCEL
    vx *= DRAG
    x += vx
    alien.fpos.x = x

    br, bl, tl, tr = bounds()

    if vx + eps > tr.x - tile_floor(tr.x) > 0:
        alien.scale_x = 1
        if collide_point(tr, br):
            vx = 0
            x = tile_floor(tr.x) - 11
    elif vx - eps < tl.x - tile_ceil(tl.x) < 0:
        alien.scale_x = -1
        if collide_point(tl, bl):
            vx = 0
            x = tile_ceil(tl.x) + 10
    alien.fpos.x = vx

    alien.v = Vector2(vx, vy)
    alien.pos = alien.fpos = Vector2(x, y)
示例#6
0
 def accelerate(self, v):
     if self.can_move:
         self.accel += Vector2(v)
         if self.accel.length_squared() > 1:
             self.accel.normalize_ip()
     else:
         v = Vector2(v)
         if self.v and v:
             side = self.v.normalize().rotate(90)
             self.accel += 0.3 * v * abs(side.dot(v.normalize()))
示例#7
0
文件: ship.py 项目: tjguk/wasabi2d
async def thrust(duration):
    """Fire a little burst of thrust."""
    prev_pos = Vector2(*ship.pos)
    async for _ in clock.coro.frames(seconds=duration):
        v = Vector2(*ship.pos) - prev_pos
        num = v.length() // 50
        if num:
            trail.emit(
                num,
                pos=ship.pos,
                vel=-v.normalize() * 100,
                vel_spread=10,
                size=3,
                color='#80ffff',
            )
示例#8
0
文件: run.py 项目: tjguk/wasabi2d
async def enemy():
    color = colorsys.hsv_to_rgb(random.random(), 1, 1)
    pos = Vector2(random.uniform(50, scene.width - 50),
                  random.uniform(50, scene.height - 50))
    e = scene.layers[0].add_circle(
        radius=10,
        color=color,
        pos=pos,
    )
    e.scale = 0.1
    await animate(
        e,
        duration=0.3,
        scale=1,
    )
    async for dt in clock.coro.frames_dt():
        to_target = target - pos
        if to_target.magnitude() < e.radius:
            break
        pos += to_target.normalize() * 100 * dt
        e.pos = pos

    await animate(e,
                  duration=0.5,
                  scale=4,
                  tween='accelerate',
                  color=(*color, 0))

    e.delete()
示例#9
0
def on_key_down(key, mod):
    if key == key.F12:
        if mod & SHIFT:
            scene.toggle_recording()
        else:
            scene.screenshot()

    if key == key.F11:
        import pdb
        pdb.set_trace()

    elif key == key.K_1:
        lbl.align = 'left'
    elif key == key.K_2:
        lbl.align = 'center'
    elif key == key.K_3:
        lbl.align = 'right'

    elif key == key.SPACE:
        bullet = scene.layers[0].add_sprite('tiny_bullet', pos=ship.pos)
        bullet.color = (1, 0, 0, 1)
        bullet.vel = Vector2(600, 0).rotate_rad(ship.angle)
        bullet.power = 1.0
        bullets.append(bullet)
        w2d.sounds.laser.play()
示例#10
0
def update(dt):
    fps.text = f'FPS: {scene.fps:0.1f}'
    dt = min(dt, 0.5)
    dead = set()

    for o in objects:
        if o is star:
            continue

        sep = Vector2(*star.pos - o.pos)
        dist = sep.magnitude()
        if dist > 1500:
            # If it's flying off into space, kill it
            dead.add(o)
            o.silent = True
        o_u = o.v
        o.v += GRAVITY / (dist * dist) * sep.normalize() * dt
        o.pos += (o_u + o.v) * 0.5 * dt

    for a, b in collision_pairs(objects):
        dead |= {a, b}
    dead.discard(star)
    objects[:] = [o for o in objects if o not in dead]

    for o in dead:
        particles.emit(o.radius**2,
                       size=1,
                       pos=o.pos,
                       pos_spread=o.radius * 0.7,
                       vel=o.v * 0.2,
                       vel_spread=50,
                       color=GREEN)

    for obj, up, left, right, _ in controls:
        if obj in dead:
            dead.discard(obj)
            w2d.tone.play(20, 1.0, waveform='square')
            w2d.clock.coro.run(respawn(obj))
            continue
        elif obj.dead:
            continue

        if up():
            obj.v += forward(obj, ACCEL * dt)
            particles.emit(np.random.poisson(30 * dt),
                           size=2,
                           pos=obj.pos + forward(obj, -7),
                           vel=obj.v + forward(obj, -100),
                           vel_spread=4,
                           color=GREEN)

        if left():
            obj.angle -= ROTATION_SPEED * dt
        elif right():
            obj.angle += ROTATION_SPEED * dt

    for o in dead:
        if not getattr(o, 'silent', False):
            w2d.tone.play(30, 0.3, waveform='square')
        o.delete()
示例#11
0
    def resolve_collisions(self):
        """Push actors apart. This is O(n^2) and can be improved.

        Note that this will not completely separate everything every frame
        due to a later collision causing a new intrusion on a previously
        resolved one. However over multiple frames this gives the desired
        effect.

        """
        player = self.player
        for mob in self.enemies[:]:
            collision = player.compute_collision_with_bad_guy(mob)

            if collision == CollisionType.ZONE:
                player.on_collision_zone(mob)
                mob.on_collide_zone()
            elif collision == CollisionType.PLAYER:
                player.on_collision_body(mob)
                mob.on_collide_player()
            else:
                penetration_vector = self.detect_wall_collisions(mob)
                if penetration_vector:
                    if mob.die_on_any_collision:
                        mob.delete()
                        return
                    mob.pos -= penetration_vector
                    mob.shape.pos = mob.pos

        for i, mob1 in enumerate(self.enemies):
            p1 = mob1.pos
            r1 = mob1.radius
            for mob2 in self.enemies[i + 1:]:
                r2 = mob2.radius
                r = r1 + r2
                p2 = mob2.pos
                sep = Vector2(*p2 - p1)
                if sep.magnitude_squared() < r * r:
                    mag = sep.magnitude()
                    overlap = r - mag
                    if mag:
                        sep.normalize_ip()
                    else:
                        sep = Vector2(0, 1)
                    frac = (r1 * r1) / (r1 * r1 + r2 * r2)
                    mob1.pos = p1 - sep * overlap * (1.0 - frac)
                    mob2.pos = p2 + sep * overlap * frac
示例#12
0
 def apply_damage(self):
     pos = Vector2(*self.pos)
     for mob in self.level.enemies:
         sep = mob.pos - pos
         mag = sep.magnitude
         dmg = 100 / (1 + mag)
         if mag < 150:
             mob.die(sep * 4)
         else:
             # TODO: apply impulse, rather than affecting position
             mob.move_delta(sep.normalized() * dmg)
示例#13
0
    def booster_on(self):
        """ When booster is firing we accelerate in the opposite direction, 180 degrees, from the way the ship is facing """
        self.booster = True
        self.sprite.image = 'lander-thrust'

        angle_r = math.radians(self.angle + 180)

        accel = Vector2(math.sin(angle_r), math.cos(angle_r))

        self.acceleration[:] = Ship.booster_power * accel

        self.particles.emit(
            5,
            pos=self.position,
            pos_spread=2,
            vel=accel * -200 + Vector2(*self.velocity) * 60,
            vel_spread=50,
            size=2,
            color='#fff0c0',
        )
        self.fuel -= 2
示例#14
0
def make_player(pos, angle=0):
    ship = scene.layers[0].add_polygon(
        SHIP_PTS,
        fill=False,
        color=GREEN,
        stroke_width=LINE_W,
    )
    ship.pos = ship.initial_pos = pos
    ship.angle = ship.initial_angle = angle
    ship.v = forward(ship, 160)
    ship.initial_v = Vector2(ship.v)
    ship.radius = 7
    ship.dead = False
    return ship
示例#15
0
 def _charge(self, dt):
     self.charge_t += dt
     angle = self.knight.angle
     c, s = np.cos(angle), np.sin(angle)
     self.knight.accel = Vector2(c, s) * 2
     x, y = self.knight.pos
     radius = self.knight.radius
     scene = self.knight.scene
     if self.charge_t > 1.5 or \
             x < radius or x > scene.width - radius or \
             y < radius or y > scene.height - radius:
         clock.unschedule(self._charge)
         self.sword.attack = False
         self.can_act.unlock()
         self.can_move.unlock()
示例#16
0
    def test_attacks(self):
        for pc in self.pcs:
            if not pc.sword.attack:
                continue

            pos = pc.pos
            sword = pc.sword.angle
            dir = Vector2(np.cos(sword), np.sin(sword))
            start = pos + dir * 12

            new_mobs = []
            for mob in self.mobs:
                if line_segment_intersects_circle(start, dir * 40, mob.pos,
                                                  20) is not None:
                    sep = mob.pos - pc.pos
                    mob.die(pc.v + sep.normalize() * 30)
                else:
                    new_mobs.append(mob)
            self.mobs[:] = new_mobs
示例#17
0
async def respawn(obj):
    obj.score_label.value += 1
    obj.score_label.text = str(obj.score_label.value)

    obj.dead = True
    obj.color = INVISIBLE
    await w2d.clock.coro.sleep(3)

    ring = scene.layers[0].add_circle(
        radius=40,
        pos=obj.initial_pos,
        color=TRANSPARENT_GREEN,
        fill=False,
        stroke_width=LINE_W,
    )
    w2d.tone.play(256, 1.0)
    await w2d.animate(
        ring,
        'accelerate',
        duration=0.5,
        scale=0.1,
        color=GREEN,
        stroke_width=10,
    )
    ring.delete()

    objects.append(obj)
    obj.dead = False
    obj.angle = obj.initial_angle
    obj.pos = obj.initial_pos
    obj.v = Vector2(obj.initial_v)
    for i in range(11):
        obj.color = INVISIBLE if i % 2 else GREEN
        await w2d.clock.coro.sleep(0.1)
        if obj.dead:
            return
示例#18
0
def on_key_down(key, mod):
    if key == key.F11:
        import pdb
        pdb.set_trace()

    elif key == key.K_1:
        lbl.align = 'left'
    elif key == key.K_2:
        lbl.align = 'center'
    elif key == key.K_3:
        lbl.align = 'right'

    elif key == key.SPACE:
        bullet = scene.layers[0].add_sprite('tiny_bullet', pos=ship.pos)
        bullet.color = (1, 0, 0, 1)
        bullet.vel = Vector2(600, 0).rotate_rad(ship.angle)
        bullet.power = 1.0
        bullets.append(bullet)
        w2d.sounds.laser.play()

        w2d.animate(ship[0], 'accel_decel', 0.5, pos=next(orbiter_positions))
    elif key == key.Z:
        pos = ship.local_to_world((-10, 0))
        w2d.clock.coro.run(bomb(pos))
示例#19
0
grid = set()
grid.update((x, TILES_H) for x in range(TILES_W))
grid.update((-1, y) for y in range(-TILES_H, TILES_H))
grid.update((TILES_W, y) for y in range(-TILES_H, TILES_H))

scene = w2d.Scene(width=TILE * TILES_W, height=TILE * TILES_H, scaler=True)
scene.background = '#5e81a2'
scene.layers[1].set_effect('dropshadow', radius=2, offset=(0, 1))

alien = scene.layers[1].add_sprite(
    'pc_standing',
    anchor_x=10,
    anchor_y=21,
    pos=(210, TILE * 9)
)
alien.fpos = Vector2(*alien.pos)
alien.v = Vector2(0, 0)
alien.stood = True
alien.crouch = False


def create_platform(x1, x2, y):
    length = x2 - x1
    if length == 1:
        grid.add((x1, y))
        scene.layers[1].add_sprite(
            'platform_single',
            pos=(x1 * TILE, y * TILE),
            anchor_x=0,
            anchor_y=0,
        )
示例#20
0
 def __post_init__(self):
     self.v = Vector2()
     self.accel = Vector2()  # direction of the acceleration
示例#21
0
def forward(ship, length=1) -> Vector2:
    """Get a vector in the direction of the ship."""
    v = Vector2()
    v.from_polar((length, math.degrees(ship.angle)))
    return v
示例#22
0
def collides(a, b) -> bool:
    """Test if two objects have collided."""
    sep = a.pos - b.pos
    radii = a.radius + b.radius

    return Vector2(*sep).length_squared() < radii * radii
示例#23
0
    ship.pos = ship.initial_pos = pos
    ship.angle = ship.initial_angle = angle
    ship.v = forward(ship, 160)
    ship.initial_v = Vector2(ship.v)
    ship.radius = 7
    ship.dead = False
    return ship


scene = w2d.Scene(1200, 800)
scene.chain = [
    w2d.LayerRange().wrap_effect('trails', alpha=0.4,
                                 fade=0.08).wrap_effect('bloom', radius=8)
]

center = Vector2(scene.width, scene.height) * 0.5

score1 = scene.layers[0].add_label('0', pos=(10, 40), fontsize=30, color=GREEN)
score2 = scene.layers[0].add_label('0',
                                   pos=(scene.width - 10, 40),
                                   align='right',
                                   fontsize=30,
                                   color=GREEN)
score1.value = score2.value = 0

fps = scene.layers[0].add_label(
    'FPS: 60',
    pos=(10, scene.height - 10),
    fontsize=20,
    color=GREEN,
)
示例#24
0
poly.stroke_width = 0

scene.layers[1].set_effect('bloom', threshold=0.9, radius=50)
particles = scene.layers[1].add_particle_group(
    texture='smoke',
    grow=3,
    max_age=2,
    gravity=(0, 100),
    drag=0.5,
)
particles.add_color_stop(0, (5, 0, 0, 1))
particles.add_color_stop(0.3, (1.5, 1.5, 0, 1))
particles.add_color_stop(1.0, 'gray')
particles.add_color_stop(2, (0.3, 0.3, 0.3, 0))

ship.vel = Vector2()

bullets = []

SHIFT = pygame.KMOD_LSHIFT | pygame.KMOD_RSHIFT


@event
def on_key_down(key, mod):
    if key == key.F12:
        if mod & SHIFT:
            scene.toggle_recording()
        else:
            scene.screenshot()

    elif key == key.K_1:
示例#25
0
文件: trails.py 项目: tjguk/wasabi2d
"""Example of the light bloom effect."""
from wasabi2d import run, Scene, event, Vector2
from wasabi2d.actor import Actor

scene = Scene()
scene.background = 'red'

logo = Actor(scene.layers[0].add_sprite(
    'wasabi2d',
    pos=(scene.width / 2, scene.height / 2),
))
logo.v = Vector2(1, -1)
scene.layers[0].set_effect('trails', fade=0.7)


@event
def update(dt):
    logo.pos += logo.v
    if logo.top < 0 or logo.bottom >= scene.height:
        logo.v.y *= -1
    if logo.left < 0 or logo.right >= scene.width:
        logo.v.x *= -1


run()
示例#26
0
"""Example of the light bloom effect."""
from wasabi2d import run, Scene, event, keys, Vector2
from wasabi2d.actor import Actor

scene = Scene()

logo = Actor(scene.layers[0].add_sprite(
    'wasabi2d',
    pos=(scene.width / 2, scene.height / 2),
))
logo.v = Vector2(100, -100)
scene.layers[0].set_effect('trails', fade=0.7)


@event
def update(dt):
    logo.pos += logo.v * dt
    if logo.top < 0 or logo.bottom >= scene.height:
        logo.v.y *= -1
    if logo.left < 0 or logo.right >= scene.width:
        logo.v.x *= -1


@event
def on_key_down(key, mod):
    if key == keys.F12:
        scene.screenshot()


run()
示例#27
0
文件: run.py 项目: tjguk/wasabi2d
def on_mouse_move(pos):
    global target
    target = Vector2(*pos)
示例#28
0
 def spawn_mobs(self, *, num: int):
     xs = np.random.uniform(30, self.scene.width - 30, size=num)
     ys = np.random.uniform(30, self.scene.height - 30, size=num)
     angles = np.random.uniform(-math.pi, math.pi, size=num)
     for x, y, angle in zip(xs, ys, angles):
         self.mobs.append(Mage(self, Vector2(x, y), angle))
示例#29
0
文件: run.py 项目: tjguk/wasabi2d
import random
import wasabi2d as w2d
import colorsys
from wasabi2d import clock, Vector2, animate, keyboard

scene = w2d.Scene(title="Run!")
scene.background = 'white'
target = Vector2(scene.width / 2, scene.height / 2)
scene.layers[0].set_effect('dropshadow', opacity=1, radius=1)


async def spawn_baddies():
    while True:
        clock.coro.run(enemy())
        await clock.coro.sleep(3)


async def enemy():
    color = colorsys.hsv_to_rgb(random.random(), 1, 1)
    pos = Vector2(random.uniform(50, scene.width - 50),
                  random.uniform(50, scene.height - 50))
    e = scene.layers[0].add_circle(
        radius=10,
        color=color,
        pos=pos,
    )
    e.scale = 0.1
    await animate(
        e,
        duration=0.3,
        scale=1,
示例#30
0
from wasabi2d import Scene, event, run, keys, Vector2
from ascend.triangle_intersect import polygon_collision
from pygame import joystick

scene = Scene()
scene.background = (0.2, ) * 3
scene.layers[0].set_effect('dropshadow', radius=1)

triangle = [Vector2(100, 200), Vector2(300, 300), Vector2(200, 400)]

scene.layers[0].add_polygon(triangle, fill=False, color='yellow')
circ = scene.layers[0].add_circle(radius=20, fill=False, color='red')


@event
def on_mouse_move(pos):
    circ.pos = pos
    pen = polygon_collision(triangle, pos, circ.radius)

    if pen:
        circ.pos -= pen
    circ.color = 'red' if pen else 'green'


run()