nodes/weapon.pyΒΆ
Part of Clear Code Zelda.
1"""Sword/weapon strike sprite: spawned in front of the player on attack."""
2
3from __future__ import annotations
4
5from settings import asset, weapon_data
6
7from simvx.core import Sprite2D, Vec2
8
9WEAPON_OFFSET = 36 # px from player centre to weapon centre
10WEAPON_SIZE = 48
11
12
13class Weapon(Sprite2D):
14 """A short-lived sprite drawn in front of the player while attacking.
15
16 The Level controls the lifetime: it spawns one of these when the player
17 emits ``attack_started`` and despawns it on ``attack_finished``.
18 """
19
20 def __init__(self, player, **kwargs):
21 weapon_name = player.weapon
22 graphic = weapon_data[weapon_name]["graphic"]
23 # Pick the directional sprite (down/up/left/right) for the player's facing.
24 direction = player.status.split("_")[0]
25 directional = graphic.replace("/full.png", f"/{direction}.png")
26 super().__init__(
27 texture=asset(directional),
28 width=WEAPON_SIZE,
29 height=WEAPON_SIZE,
30 name="Weapon",
31 **kwargs,
32 )
33 # Position relative to player.
34 face = player.facing_vector()
35 self.position = Vec2(
36 player.position.x + face.x * WEAPON_OFFSET,
37 player.position.y + face.y * WEAPON_OFFSET,
38 )
39 self.player = player
40 self.sprite_type = "weapon"
41 # AABB hitbox (centred on position)
42 self.hitbox_w = WEAPON_SIZE - 12
43 self.hitbox_h = WEAPON_SIZE - 12
44
45 def overlaps(self, other_pos, other_w, other_h) -> bool:
46 return (
47 abs(self.position.x - other_pos.x) <= (self.hitbox_w + other_w) * 0.5
48 and abs(self.position.y - other_pos.y) <= (self.hitbox_h + other_h) * 0.5
49 )