def on_joybutton_down(button): if button in range(4): pad = pads[button] pad.radius = BIG pad.color = colors[button] w2d.animate(pad, duration=0.1, radius=SMALL, color=darker(pad.color)) particles.emit( 100, pos=pad.pos, pos_spread=SMALL, vel_spread=300, color=pad.color, ) elif button == 4: pad = pads[button] pad.radius = mid pad.color = (0.8, 0.8, 0.8, 1.0) w2d.animate(pad, radius=mid / 2, duration=0.3, color=(0, 0, 0, 1.0)) particles.emit( 100, pos=pad.pos, pos_spread=100, vel_spread=400, color=(1, 1, 1, 1.0), ) if 0 <= button <= 4: sounds[button].play()
def on_joybutton_down(instance_id, button): _, group = controllers[instance_id] if button >= 4: return b = group[3 + button] b.color = b.on_color w2d.animate(b, 'out_elastic', scale=1.3)
def on_joybutton_up(instance_id, button): _, group = controllers[instance_id] if button >= 4: return b = group[3 + button] b.color = darker(b.on_color) w2d.animate(b, duration=0.1, scale=1)
def create_gamepad(device_index): stick = joystick.Joystick(device_index) instance = stick.get_instance_id() if instance in controllers: print("Duplicate", instance) return group = w2d.Group([ scene.layers[0].add_sprite('gamepad_base'), scene.layers[0].add_sprite( 'stick', pos=LSTICK_CENTER), scene.layers[0].add_sprite( 'stick', pos=RSTICK_CENTER), scene.layers[0].add_sprite( 'button', pos=(72, -19)), scene.layers[0].add_sprite( 'button', pos=(89, -36)), scene.layers[0].add_sprite( 'button', pos=(56, -36)), scene.layers[0].add_sprite('button', pos=(72, -52)), scene.layers[0].add_label(stick.get_name(), pos=(0, 80), color='black', fontsize=14, align="center") ], pos=(midline, len(controllers) * 200 + 100), scale=0.01) for button, color in zip(group[3:7], colors): button.color = darker(color) button.on_color = color w2d.animate(group, tween="out_elastic", scale=1.0) controllers[stick.get_instance_id()] = (stick, group)
async def explode(pos): """Create an explosion at pos.""" scene.camera.screen_shake() sprite = scene.layers[1].add_sprite('explosion', pos=pos) sprite.color = (1, 1, 1, 0) # Explode phase animate( sprite, duration=0.9, angle=10, ) await animate( sprite, duration=0.3, tween='accelerate', scale=3, color=(1, 1, 1, 1), ) # Twist phase await clock.coro.sleep(0.1) # Collapse phase await animate( sprite, duration=0.5, scale=1, color=(0, 0, 0, 0), ) # Delete it again sprite.delete()
def update(dt, keyboard): ball.pos += ball.vel * dt x, y = ball.pos if y < BALL_RADIUS: ball.vel.y = abs(ball.vel.y) play_thud() elif y > scene.height - BALL_RADIUS: ball.vel.y = -abs(ball.vel.y) play_thud() if x < -BALL_RADIUS: scene.camera.screen_shake() blue_score.text += 1 w2d.clock.coro.run(start(1)) w2d.sounds.airhorn.play() elif x > scene.width + BALL_RADIUS: w2d.clock.coro.run(start(-1)) scene.camera.screen_shake() red_score.text += 1 w2d.sounds.airhorn.play() for stick, bat in zip(sticks, (red, blue)): sy = stick.get_axis(1) w2d.animate(bat, duration=0.1, y=center.y + sy * (center.y - 40)) for bat in (red, blue): if keyboard[bat.up_key]: bat.y -= SPEED * dt elif keyboard[bat.down_key]: bat.y += SPEED * dt collide_bat(bat) bat.last_y = bat.y
def set_inputs(self, inputs): """Pass information from the controller.""" defend, attack, charge, bomb = inputs if not self.can_act: return if defend: self.can_act.lock(0.3) animate(self.shield, duration=0.1, angle=-0.2, radius=8) animate(self.sword, duration=0.3, angle=1.3, radius=25) elif bomb: self.can_act.lock(0.5) self.knight.throw_bomb() elif charge: self.can_move.lock(1.8) self.can_act.lock(1.8) animate(self.shield, duration=0.1, angle=0, radius=10) animate(self.sword, duration=0.1, angle=0, radius=20) clock.schedule(self._start_charge, 0.3) elif attack: self.can_act.lock(0.5) animate( self.sword, 'accel_decel', duration=0.05, angle=2.5, on_finished=self._start_attack ) else: self.normal_stance()
def explode(self): self.scene.camera.screen_shake() self.level.objects.remove(self) self.sprite.delete() self.pos = self.sprite.pos if self.game.use_particles: for pgroup in (self.scene.sparks,): pgroup.emit( num=100, pos=self.pos, vel_spread=200, spin_spread=1, size=8, angle_spread=3, ) expl = self.scene.layers[1].add_sprite( 'spark', pos=self.pos, ) expl.scale = 0.1 animate( expl, 'accelerate', duration=0.3, scale=10, color=(1, 1, 1, 0), on_finished=expl.delete ) sounds.explosion2.play() self.apply_damage()
def update_step(dt): x, y = ball.pos vx, vy = ball.vel if ball.top > HEIGHT: reset() return # Update ball based on previous velocity x += vx * dt y += vy * dt ball.pos = (x, y) # Check for and resolve collisions if ball.left < 0: vx = abs(vx) ball.left = -ball.left elif ball.right > WIDTH: vx = -abs(vx) ball.right -= 2 * (ball.right - WIDTH) if ball.top < 0: vy = abs(vy) ball.top *= -1 if ball.colliderect(bat): vy = -abs(vy) # Add some spin off the paddle vx += -30 * bat.vx else: # Find first collision idx = ball.collidelist(bricks) if idx != -1: scene.camera.screen_shake() brick = bricks[idx] # Work out what side we collided on dx = (ball.centerx - brick.centerx) / BRICK_W dy = (ball.centery - brick.centery) / BRICK_H if abs(dx) > abs(dy): vx = copysign(abs(vx), dx) else: vy = copysign(abs(vy), dy) del bricks[idx] rect = brick.prim animate( rect, tween='bounce_end', scale=0 ) animate( rect, on_finished=rect.delete, color=(0, 0, 0, 1), angle=random.uniform(-1, 1), ) ball.vel = (vx, vy)
def rotate_star(): """Animate the rotation of the star.""" animate( star, 'bounce_end', duration=1.0, angle=star.angle + math.pi / 3, )
def on_joystick_detached(instance_id): try: stick, group = controllers.pop(instance_id) except KeyError: print("Detached", instance_id) return stick.quit() w2d.animate(group, duration=0.1, scale=0, on_finished=group.delete) organise()
def notify(self, obj: observer.Observable, message: observer.Message) -> None: pc = cast(hero.Hero, obj) target = (pc.x * ROOM_SPACING, pc.y * ROOM_SPACING) animate(self.sprite, pos=target) animate(self.scene.camera, duration=0.2, pos=target) if pc.damage > self.prev_damage: self.hurt.emit(1, pos=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2), vel_spread=5, size=30) self.prev_damage = pc.damage
def _start_attack(self): """Initiate the attack.""" self.sword.attack = True animate(self.shield, duration=0.08, angle=-1.3) animate( self.sword, duration=0.15, tween='accel_decel', angle=-1.5, radius=30, on_finished=self._end_attack )
async def animit(): animate(rect, color=(1, 1, 1, 0.95), duration=0.2) await animate(label, color=(*THAT_BLUE, 1), duration=0.2) await clock.coro.sleep(0.5 + len(message) / 15) animate(rect, color=(1, 1, 1, 0)) await animate(label, color=(*THAT_BLUE, 0)) await clock.coro.sleep(1) try: rect.delete() label.delete() except Exception: # XXX : why? pass
def give_bonus_pairs(dt=None): to_check = set() for die in self.dice: for other in set(to_check): if die.face == other.face: line = self.line_layer.add_line( (die.pos[:2], other.pos[:2]), color=(np.array(die.color) + other.color) / 2, stroke_width=0, ) to_check.discard(other) animate(line, stroke_width=5) bonuses = Counter(BONUSES[die.face]) + Counter( BONUSES[other.face]) + Counter(magic=3) if BONUSES[die.face] == {'magic': 1}: bonuses['magic'] += 6 midpos = (die.pos[:2] + other.pos[:2]) / 2 self.game.info.give(**bonuses, pos=midpos, sleep=1.5, outline=True, hoffset=0.5) animate(die, size=die.size * 1.1) animate(other, size=other.size * 1.1) break else: to_check.add(die) for left_die in set(to_check): animate(left_die, size=left_die.size * 0.99) self.on_finish(speedup=1.1)
def flip(self): animate( self.prim, duration=0.05, scale=0, ) if self.prim.image == 'card_back': self.prim.image = self.title elif self.prim.image == 'checkmark': pass else: self.prim.image = 'card_back' animate( self.prim, duration=0.5, scale=1., )
async def coro(): self.input_locked = True try: if speedup == 1: tween = 'accelerate' efs = getattr(self.activity, 'end_fadeout_scale', 100 / 64) else: tween = 'linear' efs = 0 self.fade_circ.color = (0, 0, 0, 1) self.fade_circ.scale = hypot(self.scene.width, self.scene.height) // 2 / 50 ani = animate(self.fade_circ, scale=efs, duration=5 / speedup, tween=tween) self.scene.chain = [ chain.Fill(color=(.1, .1, .1, 1)), chain.Mask( mask=self.fade_layers, paint=[ chain.Fill(color=self.scene.background), self.action_layers ], ), self.info_node, ] if extra_delay: await clock.coro.sleep(extra_delay) self.info.give(sleep=1, **bonus) await ani if old_activity: old_activity.active = False if self.fade_circ.scale: await clock.coro.sleep(1) await animate(self.fade_circ, scale=0, duration=self.fade_circ.scale, tween='accelerate') self.scene.chain = [ *self.island_layers, self.fade_layers, self.info_node, ] self.fade_rect.color = (0, 0, 0, 1) await animate(self.fade_rect, color=(0, 0, 0, 0), duration=0.25, tween='accelerate') for i in range(5): self.scene.layers.pop(i, None) finally: self.input_locked = False self.return_to_island()
async def play_obstacle(sprite_name=None): if sprite_name is None: sprite_name = random.choice( ['wall', 'crate', 'sign', 'fence', 'cactus', 'rock'], ) sprite = main_layer.add_sprite( sprite_name, pos=(scene.width + 100, floor), anchor_y='bottom' ) start = scene.width + 100 async for t in w2d.clock.coro.frames(): x = start - round(SPEED * t) sprite.x = x if sprite.bounds.right < 0: break in_order = sorted(chars, key=lambda c: c.slot) out_order = [] for i, c in enumerate(in_order): out_order.append(c) try: bounds = c.sprite.bounds except TypeError: continue if not c.was_hit and bounds.colliderect(sprite.bounds): c.hit() c = out_order.pop() try: prev = out_order.pop() except IndexError: out_order.append(c) else: out_order.extend([c, prev]) if out_order != in_order: for c, slot in zip(out_order, slots): c.slot = slot w2d.animate(c.sprite, duration=0.3, x=slot) sprite.delete()
def show_message(self, text): scene = self.scene self.erase_message() screen_center = Vector2D(scene.width, scene.height) * 0.5 fill = scene.layers[Layers.TEXTBG].add_rect( width=scene.width + 100, height=scene.height + 100, pos=screen_center, color=(0, 0, 0, 0), ) animate(fill, duration=0.1, color=(0, 0, 0, 0.33)) lines = text.count('\n') fontsize = 48 pos = screen_center - Vector2D(0, 1.3 * fontsize) * (lines - 0.5) * 0.5 scene.layers[Layers.TEXT].add_label( text=text, fontsize=fontsize, align="center", pos=pos, font='magic_medieval', )
def __set__(self, obj, value): prev = getattr(obj, self.storage_name, 0) setattr(obj, self.storage_name, value) sprite = obj.sprites[self.name] label = obj.labels[self.name] if value: animate(sprite, color=(*sprite.color[:3], 1), duration=.2) animate(label, color=(*label.color[:3], 1), duration=.2) else: animate(sprite, color=(*sprite.color[:3], 0), duration=.2) animate(label, color=(*label.color[:3], 0), duration=.2) label.text = str(value) #if value > prev: # play_sound('resource-get', volume=0.2) if obj.game.island: obj.game.island.on_wealth_changed()
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 = vec2(600, 0).rotated(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))
async def go_one(i): sprite = self.temp_layer.add_sprite(name, pos=(x + w + i * w, y), color=COLORS[name], scale=0) await animate(sprite, scale=1, duration=0.25) await clock.coro.sleep(total / 8 + sleep) anim = animate(sprite, duration=1, tween='accelerate', pos=self.sprites[name].pos, scale=self.sprites[name].scale) await clock.coro.sleep(.6) setattr(self, name, getattr(self, name) + 1) await anim sprite.delete() tasks.append(anim)
duration=0.5, scale=1., ) def complete(self): self.prim.image = 'checkmark' board = [] # initialize the board for row in range(ROWS): new_row = [] for col in range(COLS): image_name = START_IMAGES.pop() temp = Card(image_name) angle = temp.prim.angle = random.uniform(-1, 1) animate(temp, duration=0.3, topleft=(col * IMSIZE, row * IMSIZE)) animate( temp.prim, duration=0.3, angle=0.1 * angle, ) new_row.append(temp) board.append(new_row) def findTile(pos): y, x = pos result = x // IMSIZE, y // IMSIZE return result
async def animate_title(): w2d.animate(title, tween='bounce_end', y=cy - 80) await w2d.clock.coro.sleep(1 / 2.75) w2d.animate(title, tween='decelerate', duration=0.6, angle=0.1) await w2d.clock.coro.sleep(0.2) w2d.animate(subtitle, tween='bounce_end', y=cy + 200)
def _anim(obj, *args, duration=1, **kwargs): if duration == 0: for name, value in kwargs.items(): setattr(obj, name, value) else: animate(obj, *args, duration=duration, **kwargs)
def organise(): for idx, (_, (_, group)) in enumerate(controllers.items()): w2d.animate(group, duration=0.2, tween="decelerate", y=idx * 200 + 100)
def on_mouse_down(pos): w2d.animate(mask, tween='decelerate', duration=0.2, scale=2)
def update_active_piece(): """Make the sprites for the active piece reflect their grid coordinates.""" for sprite, pos in zip(active_piece_sprites, active_piece): w2d.animate(sprite, duration=0.1, pos=grid_to_screen(*pos))
def on_mouse_down(pos): orbiter_pos = ship.world_to_local(pos) w2d.animate(ship[0], pos=orbiter_pos)
def on_mouse_up(pos): w2d.animate(mask, tween='bounce_end', duration=0.5, scale=1)