feat(sim): projectiles, items and inventory
This commit is contained in:
1 parent
9f40874f53
commit
8c5c8b8fe0
3 files changed
+114
No files matched your search
@@ -0,0 +1,31 @@
|
||||
class Inventory:
|
||||
def __init__(self):
|
||||
self.counts = {}
|
||||
self.keys = 0
|
||||
|
||||
def add(self, kind, amount=1):
|
||||
self.counts[kind] = self.counts.get(kind, 0) + amount
|
||||
if kind == "key":
|
||||
self.keys += amount
|
||||
return self.counts[kind]
|
||||
|
||||
def count(self, kind):
|
||||
return self.counts.get(kind, 0)
|
||||
|
||||
def has(self, kind, amount=1):
|
||||
return self.count(kind) >= amount
|
||||
|
||||
def consume(self, kind, amount=1):
|
||||
if self.count(kind) < amount:
|
||||
return False
|
||||
self.counts[kind] -= amount
|
||||
if kind == "key":
|
||||
self.keys -= amount
|
||||
return True
|
||||
|
||||
def asDict(self):
|
||||
return {"counts": dict(self.counts), "keys": self.keys}
|
||||
|
||||
def loadDict(self, record):
|
||||
self.counts = dict(record.get("counts", {}))
|
||||
self.keys = record.get("keys", 0)
|
||||
@@ -0,0 +1,51 @@
|
||||
from ..constants import tileSize
|
||||
from .geometry import Aabb
|
||||
|
||||
itemDefs = {
|
||||
"coin": {"score": 100, "size": 12, "bob": True},
|
||||
"gem": {"score": 500, "size": 12, "bob": True},
|
||||
"key": {"score": 50, "size": 12, "bob": False},
|
||||
"heart": {"score": 0, "size": 14, "bob": True, "heal": 2},
|
||||
}
|
||||
|
||||
|
||||
class Collectible:
|
||||
def __init__(self, kind, x, y):
|
||||
self.kind = kind
|
||||
self.x = float(x)
|
||||
self.y = float(y)
|
||||
self.collected = False
|
||||
definition = itemDefs.get(kind, itemDefs["coin"])
|
||||
self.size = definition["size"]
|
||||
self.score = definition["score"]
|
||||
self.heal = definition.get("heal", 0)
|
||||
self.bob = definition.get("bob", False)
|
||||
self.bobPhase = 0.0
|
||||
|
||||
@property
|
||||
def aabb(self):
|
||||
pad = (tileSize - self.size) * 0.5
|
||||
return Aabb(self.x + pad, self.y + pad, self.size, self.size)
|
||||
|
||||
def update(self):
|
||||
if self.bob:
|
||||
self.bobPhase = (self.bobPhase + 0.15) % 6.2831853
|
||||
|
||||
def collect(self, player, world):
|
||||
if self.collected:
|
||||
return
|
||||
self.collected = True
|
||||
player.score += self.score
|
||||
world.score += self.score
|
||||
if self.kind == "coin":
|
||||
player.coins += 1
|
||||
world.coins += 1
|
||||
elif self.heal:
|
||||
player.heal(self.heal)
|
||||
player.inventory.add(self.kind)
|
||||
world.playSound("pickup", self.x)
|
||||
world.spawnBurst("pickup", self.x + tileSize * 0.5, self.y + tileSize * 0.5, 5)
|
||||
|
||||
@classmethod
|
||||
def fromSpawn(cls, spawn):
|
||||
return cls(spawn.kind, spawn.x, spawn.y)
|
||||
@@ -0,0 +1,32 @@
|
||||
from .. import constants
|
||||
from .entity import Actor
|
||||
from . import physics
|
||||
|
||||
|
||||
class Projectile(Actor):
|
||||
def __init__(self, x, y, vx, vy, owner="enemy", damage=1):
|
||||
super().__init__(x, y, 6, 6)
|
||||
self.vx = vx
|
||||
self.vy = vy
|
||||
self.owner = owner
|
||||
self.damage = damage
|
||||
self.life = constants.projectileLife
|
||||
self.gravityScale = 0.0
|
||||
|
||||
def update(self, world):
|
||||
self.life -= 1
|
||||
if self.life <= 0:
|
||||
self.alive = False
|
||||
return
|
||||
if self.gravityScale:
|
||||
self.vy += constants.gravity * self.gravityScale
|
||||
self.x += self.vx
|
||||
self.y += self.vy
|
||||
box = self.aabb
|
||||
for tileBox in physics.solidTilesOverlapping(world.level, box):
|
||||
if box.intersects(tileBox):
|
||||
self.alive = False
|
||||
world.spawnBurst("spark", self.centerX, self.centerY, 4)
|
||||
return
|
||||
if self.centerX < -32 or self.centerX > world.level.pixelWidth() + 32:
|
||||
self.alive = False
|
||||
Reference in new issue
Block a user