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        )