209 lines
5.7 KiB
Python
209 lines
5.7 KiB
Python
import math, random, time
|
|
from . import assets, controller, sprite, spritesheet, tiles
|
|
from .vector import Vector
|
|
|
|
def is_collided(pos, map, player):
|
|
METER = map.METER
|
|
rect = player.rect
|
|
cx = player.pos.x + (rect[0] / METER)
|
|
cy = player.pos.y + (rect[1] / METER)
|
|
|
|
cw = cx + (rect[2] / METER)
|
|
ch = cy + (rect[3] / METER)
|
|
|
|
if cw >= pos[0] and cx <= (pos[0] + 1) and ch >= pos[1] and cy <= (pos[1] + 1):
|
|
return True
|
|
|
|
# Structure tiles
|
|
tiles.register_tile("map:floor", {
|
|
"textures": ["floor.png"],
|
|
})
|
|
|
|
tiles.register_tile("map:wall", {
|
|
"textures": [
|
|
"wall_0.png",
|
|
"wall_1.png",
|
|
"wall_2.png",
|
|
"wall_3.png",
|
|
],
|
|
})
|
|
|
|
tiles.register_tile("map:wall_corner_inner", {
|
|
"textures": [
|
|
"wall_corner_inner_0.png",
|
|
"wall_corner_inner_1.png",
|
|
"wall_corner_inner_2.png",
|
|
"wall_corner_inner_3.png",
|
|
],
|
|
})
|
|
|
|
tiles.register_tile("map:wall_corner_outer", {
|
|
"textures": [
|
|
"wall_corner_outer_0.png",
|
|
"wall_corner_outer_1.png",
|
|
"wall_corner_outer_2.png",
|
|
"wall_corner_outer_3.png",
|
|
],
|
|
})
|
|
|
|
# Stairs
|
|
def prev_level(self, dtime, map, player):
|
|
# Lazy distance check
|
|
if math.hypot(player.pos.x - self.pos[0], player.pos.y + 1 - self.pos[1]) <= 2 \
|
|
and player.pos.y + 0.5 > self.pos[1] and controller.is_down("shift") \
|
|
and time.time() - player.last_level_change > 0.5: # Prevent multiple shifts
|
|
player.z = max(1, player.z - 2)
|
|
generator = map.generators[player.z - 1]
|
|
|
|
player.set_pos(generator.exit[0], generator.exit[1] - 1)
|
|
player.dir = 2
|
|
player.last_level_change = time.time()
|
|
|
|
tiles.register_tile("map:stair_up", {
|
|
"textures": ["stair_up.png"],
|
|
"solid": True,
|
|
"on_step": prev_level,
|
|
})
|
|
|
|
def unlock_next(self, dtime, map, player):
|
|
if math.hypot(player.pos.x - self.pos[0], player.pos.y + 1 - self.pos[1]) <= 1 \
|
|
and player.key and controller.is_down("shift") and time.time() - player.last_level_change > 0.5:
|
|
|
|
map.set_tile(*self.pos, "map:stair_down")
|
|
player.hud.remove("key")
|
|
player.key = False
|
|
player.last_level_change = time.time()
|
|
|
|
tiles.register_tile("map:stair_down_locked", {
|
|
"textures": ["stair_down_locked.png"],
|
|
"solid": False,
|
|
"on_step": unlock_next,
|
|
})
|
|
|
|
def next_level(self, _, map, player):
|
|
if math.hypot(player.pos.x - self.pos[0], player.pos.y + 1 - self.pos[1]) <= 1 \
|
|
and controller.is_down("shift") and time.time() - player.last_level_change > 0.5:
|
|
player.z += 2
|
|
if not player.z - 1 in map.generators: # Generate level if new
|
|
map.generate(player.z - 1)
|
|
generator = map.generators[player.z - 1]
|
|
|
|
player.set_pos(generator.enterance[0], generator.enterance[1] + 0.1)
|
|
player.dir = 0
|
|
player.last_level_change = time.time()
|
|
|
|
tiles.register_tile("map:stair_down", {
|
|
"textures": ["stair_down.png"],
|
|
"solid": False,
|
|
"on_step": next_level,
|
|
})
|
|
|
|
# Items
|
|
def pick_up_key(self, dtime, map, player):
|
|
if is_collided(self.pos, map, player):
|
|
player.key = True
|
|
player.hud.add("key", [0, 0.6], {
|
|
"type": "image",
|
|
"texture": "key.png",
|
|
"scale": 1.5
|
|
})
|
|
map.set_tile(*self.pos, None)
|
|
|
|
tiles.register_tile("item:key", {
|
|
"textures": ["key.png"],
|
|
"solid": False,
|
|
"on_step": pick_up_key
|
|
})
|
|
|
|
# Loot
|
|
def pick_up_coin(self, dtime, map, player):
|
|
if is_collided(self.pos, map, player):
|
|
player.coins += random.randint(self.min_value, self.max_value)
|
|
player.hud.change("coincount", {
|
|
"text": player.coins
|
|
})
|
|
map.set_tile(*self.pos, None)
|
|
|
|
|
|
tiles.register_tile("loot:coins", {
|
|
"textures": ["loot_gold.png"],
|
|
"solid": False,
|
|
"min_value": 2,
|
|
"max_value": 5,
|
|
"on_step": pick_up_coin
|
|
})
|
|
|
|
tiles.register_tile("loot:pile", {
|
|
"textures": ["loot_pile.png"],
|
|
"solid": False,
|
|
"min_value": 6,
|
|
"max_value": 12,
|
|
"on_step": pick_up_coin
|
|
})
|
|
|
|
def pick_up_health(self, dtime, map, player):
|
|
if is_collided((self.pos.x, self.pos.y), map, player):
|
|
player.hp += 3
|
|
player.hud.change("hp", {
|
|
"text": player.hp
|
|
})
|
|
map.remove_sprite(self.id)
|
|
|
|
sprite.register_sprite("item:health", {
|
|
"texture": spritesheet.SpriteSheet(assets.get("health.png"), 32, 32),
|
|
"on_step": pick_up_health
|
|
})
|
|
|
|
def pick_up_xp(self, dtime, map, player):
|
|
if is_collided((self.pos.x, self.pos.y), map, player):
|
|
player.xp += self.amount
|
|
player.hud.change("xp", {
|
|
"text": player.xp
|
|
})
|
|
map.remove_sprite(self.id)
|
|
|
|
sprite.register_sprite("item:xp", {
|
|
"texture": spritesheet.SpriteSheet(assets.get("xp.png"), 32, 32),
|
|
"on_step": pick_up_xp
|
|
})
|
|
|
|
# Enemies
|
|
def spawn_slime(self, dtime, map, player):
|
|
map.set_tile(*self.pos, None)
|
|
sprite = map.add_sprite(*self.pos, "enemy:slime")
|
|
sprite.hp = 4 + (2 * sprite.z)
|
|
sprite.set_rect(0, 0, 32, 32)
|
|
sprite.texture.set_animation(0, 3, 4)
|
|
sprite.target_pos = Vector(self.pos[0], self.pos[1])
|
|
|
|
tiles.register_tile("enemy:slime", {
|
|
"textures": ["slime_spawner.png"],
|
|
"on_step": spawn_slime
|
|
})
|
|
|
|
tiles.register_tile("enemy:slime_dead", {
|
|
"textures": ["slime_dead.png"],
|
|
"solid": False,
|
|
})
|
|
|
|
from .slime import slime_logic
|
|
|
|
sprite.register_sprite("enemy:slime", {
|
|
"texture": spritesheet.SpriteSheet(assets.get("slime.png"), 32, 32),
|
|
"timer": 0,
|
|
"target_pos": Vector(0),
|
|
"on_step": slime_logic
|
|
})
|
|
|
|
# Effects
|
|
def slash(self, dtime, map, player):
|
|
self.timer += dtime
|
|
if self.timer >= 2 / 4:
|
|
map.remove_sprite(self.id)
|
|
|
|
sprite.register_sprite("player:slash", {
|
|
"texture": spritesheet.SpriteSheet(assets.get("magic_slash.png"), 32, 32),
|
|
"timer": 0,
|
|
"on_step": slash
|
|
})
|