Browse Source

Map has collision data. Player collides with map, but all janky. Cam is now object in Game class. Debug map layers and other stuff. Sprites can be mirrored. Idk what else.

master
rf 4 months ago
parent
commit
d62c628c8b
9 changed files with 233 additions and 67 deletions
  1. +21
    -7
      data/tio_amar_pack/tiled_map1.json
  2. +29
    -12
      game.py
  3. +5
    -1
      gfx/images.py
  4. +1
    -1
      helper_scripts/gen_tile_sheet.py
  5. +17
    -3
      obj/entities.py
  6. +7
    -5
      obj/levels.py
  7. +54
    -13
      obj/maps.py
  8. +61
    -21
      obj/objects.py
  9. +38
    -4
      util/json_loaders.py

+ 21
- 7
data/tio_amar_pack/tiled_map1.json View File

@@ -49,11 +49,13 @@
"id":15,
"name":"bg vegetation",
"opacity":1,
"type":"tilelayer",
"type":"spritelayer",
"visible":true,
"width":26,
"x":0,
"y":0
"y":0,
"halign": "left",
"valign": "bottom"
},
{
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
@@ -61,11 +63,13 @@
"id":16,
"name":"clouds",
"opacity":1,
"type":"tilelayer",
"type":"spritelayer",
"visible":true,
"width":26,
"x":0,
"y":0
"y":0,
"halign": "left",
"valign": "bottom"
},
{
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0],
@@ -97,11 +101,13 @@
"id":19,
"name":"stage vegetation",
"opacity":1,
"type":"tilelayer",
"type":"spritelayer",
"visible":true,
"width":26,
"x":0,
"y":0
"y":0,
"halign": "left",
"valign": "bottom"
},
{
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
@@ -114,8 +120,16 @@
"width":26,
"x":0,
"y":0
},
{
"data":[{"x":0, "y":1664, "width":3200, "height":128}],
"id":21,
"name":"foreground collision",
"type":"collision",
"x":0,
"y":0
}],
"nextlayerid":21,
"nextlayerid":22,
"nextobjectid":1,
"orientation":"orthogonal",
"renderorder":"right-down",

+ 29
- 12
game.py View File

@@ -48,8 +48,13 @@ class Game:

# --------------------------- game objects ----------------------------

Game.cam = Camera()
Game.cam.move_to((0, 1200))

Game.level = Level.example()

Game.player_group = pygame.sprite.GroupSingle()
Game.player = PlayerChar("panda-walk", Game.screen.area, scale=100, speed=5)
Game.player = PlayerChar("panda-walk", Game.level.area, scale=100, speed=5)
# Game.player2 = PlayerChar("hello", Game.screen.area, scale=300, speed=5)
Game.player.move_to(Game.screen.area.center, centered=True)
Game.player_group.add(Game.player)
@@ -60,13 +65,12 @@ class Game:
#Explode.loadExplosions()
#Explode.initExplosion("expl_03")

Game.level = Level.example()

# ---------------------------- misc vars ------------------------------
Game.paused = Boolean(False)
Game.debug_draw = Boolean(False)
Game.step_through = Boolean(False)
Game.back_to_menu = False
Game.debug_layer = None

# ---------------------------- input setup ----------------------------

@@ -78,14 +82,15 @@ class Game:
Game.controls.registerKeypress(K_RIGHT, lambda: Game.player.move(90))
Game.controls.registerKeypress(K_UP, lambda: Game.player.move(0))
Game.controls.registerKeypress(K_DOWN, lambda: Game.player.move(180))
Game.controls.registerKeypress(K_a, lambda: Game.level.cam.move(-90))
Game.controls.registerKeypress(K_d, lambda: Game.level.cam.move(90))
Game.controls.registerKeypress(K_w, lambda: Game.level.cam.move(0))
Game.controls.registerKeypress(K_s, lambda: Game.level.cam.move(180))
Game.controls.registerKeypress(K_a, lambda: Game.cam.move(-90))
Game.controls.registerKeypress(K_d, lambda: Game.cam.move(90))
Game.controls.registerKeypress(K_w, lambda: Game.cam.move(0))
Game.controls.registerKeypress(K_s, lambda: Game.cam.move(180))

Game.controls.registerInputEvent(pygame.KEYUP, K_F1, Game.paused.flip)
Game.controls.registerInputEvent(pygame.KEYUP, K_F2, Game.step_through.true)
Game.controls.registerInputEvent(pygame.KEYUP, K_F3, Game.debug_draw.flip)
Game.controls.registerInputEvent(pygame.KEYUP, K_l, Game.debug_layer_key)

def pause_game():

@@ -105,8 +110,15 @@ class Game:
elif choice == menu.Items.pause.RESUME:
return

def main():
def debug_layer_key():
if Game.debug_layer == None:
Game.debug_layer = 0
else:
Game.debug_layer += 1
if Game.debug_layer >= len(Game.level.map.layers):
Game.debug_layer = None

def main():

while True:

@@ -127,10 +139,12 @@ class Game:
while not Game.back_to_menu:

Game.controls.process()
Game.level.update()

Game.level.update(offset=-Game.cam.position)

Game.screen.clear(Game.bg_color)

Game.level.map.set_debug_layer(Game.debug_layer)
Game.level.render(Game.screen)

#screen.print_text(player.rect.bottomright, player.collrect)
@@ -138,7 +152,7 @@ class Game:
# ---------------------- game update ------------------------------
if Game.paused == False or Game.step_through == True:
# player_group.update()
Game.player.update()
Game.player.update(Game.level.map.active_collidables)
#Game.player2.update()
# bullets.update()
Game.step_through.false()
@@ -146,14 +160,17 @@ class Game:
# ----------------------- rendering -------------------------------

#player_group.draw(screen.surface)
Game.player.render(Game.screen)
Game.player.render(Game.screen, offset=-Game.cam.position, debug=True, text=f"{Game.player.collrect} {Game.player.vector} {Game.player.collided}")
#Game.player2.render(Game.screen)
# bullets.draw(screen.surface)
# Explode.drawExplosions(screen)

Game.screen.print_text((0, 0), f" {menu_choice} // FPS: {Game.screen.fps()}", color="black")
Game.screen.print_text((0, 16), f" {Game.level.cam.position} + {Game.controls.mousepos} = {Game.level.screen_to_level_pos(*Game.controls.mousepos)}", color="black")
Game.screen.print_text((0, 16), f" {Game.cam.position} + {Game.controls.mousepos} = {Game.level.screen_to_level_pos(*Game.controls.mousepos)}", color="black")
Game.screen.print_text((0, 32), f" {Game.level.tile_at(Game.controls.mousepos.x, Game.controls.mousepos.y)}", color="black")
Game.screen.print_text((0, 48), f" {Game.level.map.active_collidables}", color="black")
if Game.debug_layer != None:
Game.screen.print_text((0, 64), f"{Game.level.map.layers[Game.debug_layer].type} {Game.level.map.layers[Game.debug_layer].id} {Game.level.map.layers[Game.debug_layer].name}", color="black")

if Game.debug_draw == True:
for obj in (Game.player): #, Game.player2):

+ 5
- 1
gfx/images.py View File

@@ -70,7 +70,7 @@ class Images:
return anim.animation_from_frames(loop)
return None

def transform(name, angle=None, scale=None, alpha=None):
def transform(name, angle=None, scale=None, flipx=False, flipy=False, alpha=None):
""" rotate/scale with caching, correcting for bounding rect offset """

if name == "" or name == None:
@@ -103,6 +103,10 @@ class Images:
out_image.set_alpha(alpha)
else:
out_image = out_image.convert_alpha()

if flipx or flipy:
out_image = pygame.transform.flip(out_image, flipx, flipy)

offset = pre_rot_size - Vec2i(out_image.get_rect().size)
return out_image, offset


+ 1
- 1
helper_scripts/gen_tile_sheet.py View File

@@ -23,7 +23,7 @@ sheet = Tilesheet_Tiled(name, subf)
""" get a size distribution... """
size_dist = {}

for tile in sheet.tiles:
for tile in sheet.tiles.values():
#print(f"Tile: {tile.img} {(tile.w, tile.h)}")
if (tile.w, tile.h) in size_dist:
size_dist[(tile.w, tile.h)].append(tile)

+ 17
- 3
obj/entities.py View File

@@ -27,15 +27,29 @@ class PlayerChar(CollObject):
self.speed = speed
self.anim_speed = 12
self.fire_cooldown = 0
self.gravity = Vec2f(0.0, 0.5)

def update(self, collidables=[]):
if self.frect.left > self.oldrect.left:
self.mirrored = True
elif self.frect.left < self.oldrect.left:
self.mirrored = False

self.move_by(self.gravity)

super().update(collidables)

if self.collided:
self.gravity = Vec2f(0.0, 1.0)
else:
self.gravity *= 1.1

def update(self):
super().update()
if self.fire_cooldown > 0:
self.fire_cooldown -= 1

def move(self, angle=None):
""" wtf is going on here """
if self.angle != None:
self.set_vector_from_angle(self.angle, self.speed)
super().move(angle)
else:
if angle != None:

+ 7
- 5
obj/levels.py View File

@@ -2,29 +2,31 @@ from util.camera import Camera
from util.json_loaders import Tilesheet
from obj.maps import Map
from gfx.images import Images
import pygame

class Level:

def __init__(self, tilesheet=None, map=None):
self.size = (0, 0)
self.area = None
self.spawn = (0, 0)
self.map = ""
self.tileset = tilesheet
self.map = map
self.cam = Camera()

def example():
lvl = Level(Tilesheet("tio_amar_pack_tilesheet", "tio_amar_pack"), Map("tiled_map1", "tio_amar_pack"))
lvl.map.load_images()
lvl.map.set_tileset(lvl.tileset, "tio_amar_pack_tilesheet")
lvl.area = pygame.Rect(0, 0, lvl.map.w * lvl.map.tilew, lvl.map.h * lvl.map.tileh)

return lvl

def update(self):
self.map.move_to(-self.cam.position.x, -self.cam.position.y)
def update(self, offset=None):
if offset:
self.map.move_to(*offset)

def screen_to_level_pos(self, x, y):
return x + self.cam.position.x, y + self.cam.position.y
return x - self.map.x, y - self.map.y

def tile_at(self, x, y):
return self.map.tile_at(*self.screen_to_level_pos(x, y))

+ 54
- 13
obj/maps.py View File

@@ -1,7 +1,7 @@
import sys
from util.util import Util
import pygame
from util.json_loaders import Map_Tiled, Tilesheet
from util.json_loaders import Map_Tiled, Tilesheet, Tile
from gfx.images import Images
from gfx.geometry import Vec2i

@@ -10,23 +10,49 @@ class Map(Map_Tiled):
def __init__(self, name, subfolder=""):
super().__init__(name, subfolder)
self.tileset = None
self.images_needed = None
self.images_needed = []
self.active_collidables = []
self.debug_layer = None

for l in self.layers:
if l.type == "imagelayer":
if self.images_needed == None:
self.images_needed = []
self.images_needed.append(l.img)
if l.active == True:
if l.type == "imagelayer":
self.images_needed.append(l.img)
elif l.type == "collision":
self.active_collidables.append(*l.data)

def load_images(self):
if self.images_needed:
for img in self.images_needed:
Images.load(img, type=None, subfolder=self.subfolder)
for img in self.images_needed:
Images.load(img, type=None, subfolder=self.subfolder)

def set_tileset(self, set, imagename):
self.tileset = set
self.image = Images.get(imagename)

""" set up sprites on sprite layers with info about tiles. """
for l in self.layers:
if l.type == "spritelayer":
x = 0
y = 0
for id in l.data:
if id != 0:
# print(x, y, id)
tile = Tile.copy(self.tileset.tiles[id-1])
tile.x = x * self.tilew
if l.halign == "right":
tile.x += self.tilew - tile.w
tile.y = y * self.tileh
if l.valign == "bottom":
tile.y += self.tileh - tile.h
l.sprites.append(tile)
x += 1
if x >= l.width:
x = 0
y += 1

if y >= l.height:
break

def move_to(self, x, y):
self.x = x
self.y = y
@@ -50,7 +76,7 @@ class Map(Map_Tiled):
ty = y // self.tileh
tilepos = ty * layer.width + tx
tile = layer.data[tilepos]
print(tx, ty, tilepos, tile)
# print(tx, ty, tilepos, tile)
if tile == None or tile == 0:
layer = None
return tile, layer
@@ -60,9 +86,14 @@ class Map(Map_Tiled):
if self.layers[layer].active == True:
self.draw_layer(screen, layer) # , debug=True)

def set_debug_layer(self, layer):
self.debug_layer = layer

def draw_layer(self, screen, layer_id, pos=None, debug=False):
l = self.layers[layer_id]

debug_layer = self.debug_layer != None and self.debug_layer == layer_id

if pos == None:
pos = Vec2i(self.x, self.y)
elif isinstance(pos, tuple):
@@ -90,12 +121,22 @@ class Map(Map_Tiled):
if t > 0:
tile = self.tileset.tiles[t-1]
a = tile.area # [0], tile.area[1], 8, 8)
if debug:
screen.rect((px, py, self.tilew, self.tileh), 'purple')
else:
if not debug:
screen.blit((px, py), self.image, area=a)
if debug or debug_layer:
screen.rect((px, py, self.tilew, self.tileh), 'red')
screen.print_text((px, py), f" {(px - pos.x - l.x, py - pos.y - l.y)}", color="red")
idx += 1
px += self.tilew
if idx % l.width == 0:
px = pos.x + l.x
py += self.tileh
elif l.type == "spritelayer":
for sprite in l.sprites:
px = pos.x + l.x + sprite.x
py = pos.y + l.y + sprite.y
if not debug:
screen.blit((px, py), self.image, area=sprite.area)
if debug or debug_layer:
screen.rect((px, py, sprite.w, sprite.h), 'red')
screen.print_text((px, py), f"{(px - pos.x - l.x, py - pos.y - l.y)} = {sprite.x} / {sprite.y}", color="red")

+ 61
- 21
obj/objects.py View File

@@ -36,7 +36,7 @@ class BaseObject:
# print(f"{speed} / {angle} = {self.speed}")

def update(self):
""" shall bw overridden """
""" shall be overridden """
pass

def move(self, angle=None):
@@ -91,7 +91,8 @@ class BaseObject:
where = (where[0] - self.rect.width/2, where[1] - self.rect.height/2)

if debug:
screen.rect(self.rect, 'red')
r = pygame.Rect(*where, self.rect.width, self.rect.height)
screen.rect(r, 'red')

if text:
if font == None:
@@ -128,6 +129,9 @@ class SpriteObject(pygame.sprite.Sprite, BaseObject):
self.image = Images.get(imgname)
self.is_anim = Images.is_anim(imgname)

self.upside_down = False
self.mirrored = False

self.rect = self.image.get_rect()

self.frect = ZRect(self.rect)
@@ -192,17 +196,20 @@ class SpriteObject(pygame.sprite.Sprite, BaseObject):
self.rect = self.frect.get_rect()
self.rect.move_ip(tuple(self.offset))

def render(self, screen, pos=None, text=None, centered=False, font=None, color=None, debug=False):
def render(self, screen, pos=None, offset=None, text=None, centered=False, font=None, color=None, debug=False):

if pos:
where = pos
else:
where = self.rect.topleft

if offset:
where += offset

if centered:
where = (where[0] - self.rect.width/2, where[1] - self.rect.height/2)

if self.src_image != None and not debug:
if self.src_image != None:
if not self.is_anim:
screen.blit(where, self.image)
else:
@@ -248,7 +255,7 @@ class RotScaleObject(SpriteObject):
self.angle += rotate_by

def transform(self):
self.image, self.offset = Images.transform(self.src_image, self.angle, self.scale, self.alpha)
self.image, self.offset = Images.transform(self.src_image, self.angle, self.scale, self.mirrored, self.upside_down, self.alpha)
self.offset /= 2
# self.offset = Vec2f(0.0, 0.0)
self.set_rect()
@@ -272,10 +279,35 @@ class CollObject(RotScaleObject):
# TODO: logger / debug output
# print(f"{speed} / {angle} = {self.speed}")

def update(self):
def update(self, collidables=[]):
super().update()
self.set_rect()
self.collide_bounds()
self.collided = False

movement = Vec2f(self.collrect.topleft) - Vec2f(self.oldrect.topleft)
movement = self.collide_bounds(movement)

self.move_to(self.oldrect.topleft)

moved_by = 0.0

if len(collidables) > 0:
while moved_by < 1.0:

moved_rect = self.collrect.move(*(movement * moved_by))

# print(moved_rect)
for collidable in collidables:
if moved_rect.colliderect(collidable):
# print(f"Hit: {collidable}")
self.collided = True
if self.collided:
break
moved_by += 0.1
else:
moved_by = 1.0
self.move_by(movement * moved_by)
self.clamp_bounds()

def set_rect(self, newrect=None):
super().set_rect(newrect)
@@ -303,29 +335,37 @@ class CollObject(RotScaleObject):
return not self.area.collidepoint(self.collrect.topleft) \
and not self.area.collidepoint(self.collrect.bottomright)

def collide_rect(a, b):
return a.collrect.colliderect(b.collrect)
def collide_rect(self, rect):
return self.collrect.colliderect(rect)

def collide_point(a, b):
return a.collrect.collidepoint(b.collrect.center)
def collide_object_rect(self, obj):
return self.collrect.colliderect(obj.collrect)

def rcollide_point(a, b):
return b.collrect.collidepoint(a.collrect.center)
def collide_point(self, point):
return self.collrect.collidepoint(point)

def collide_bounds(self):
if (self.vector.x < 0 and self.collrect.left < self.area.left) \
or (self.vector.x > 0 and self.collrect.right > self.area.width):
self.vector.x = 0
def collide_object_point(self, obj):
return self.collrect.collidepoint(obj.collrect.center)

if (self.vector.y < 0 and self.collrect.top < self.area.top) \
or (self.vector.y > 0 and self.collrect.bottom > self.area.height):
self.vector.y = 0
def collide_bounds(self, vec):
if (vec.x < 0 and self.collrect.left < self.area.left) \
or (vec.x > 0 and self.collrect.right > self.area.width):
vec.x = 0
self.collided = True

if (vec.y < 0 and self.collrect.top < self.area.top) \
or (vec.y > 0 and self.collrect.bottom > self.area.height):
vec.y = 0
self.collided = True

return vec

#print(f"{self.collrect} --> {self.collrect.right} > {self.area.width} & {self.collrect.bottom} > {self.area.height}")

def clamp_bounds(self):
# make sure we're really put back inside our area
clamped = self.collrect.clamp(self.area)
cx, cy = Vec2i(clamped.topleft) - Vec2i(self.collrect.topleft)
if (cx, cy) != (0, 0):
self.move_by(Vec2f(cx, cy))
pass
self.collided = True

+ 38
- 4
util/json_loaders.py View File

@@ -17,29 +17,63 @@ class Tile:
self.y = tile_dict['y'] if 'y' in tile_dict else None
self.area = (self.x, self.y, self.w, self.h)

def copy(tile):
new_tile = Tile({})
new_tile.id = tile.id
new_tile.img = tile.img
new_tile.w = tile.w
new_tile.h = tile.h
new_tile.x = tile.x
new_tile.y = tile.y
new_tile.area = tile.area
return new_tile

class Layer:
def __init__(self, layer_dict):
self.id = layer_dict['id']
self.x = layer_dict['x']
self.y = layer_dict['y']
self.opacity = float(layer_dict['opacity'])
self.visible = layer_dict['visible']
self.name = layer_dict['name']
self.type = layer_dict['type']
self.active = True

if self.type == "imagelayer":
self.img = layer_dict['image']
self.opacity = float(layer_dict['opacity'])
self.visible = layer_dict['visible']
elif self.type == "tilelayer":
self.data = layer_dict['data']
self.width = layer_dict['width']
self.height = layer_dict['height']
self.opacity = float(layer_dict['opacity'])
self.visible = layer_dict['visible']
elif self.type == "spritelayer":
self.data = layer_dict['data']
self.width = layer_dict['width']
self.height = layer_dict['height']
self.halign = layer_dict['halign'] if 'halign' in layer_dict else 'left'
self.valign = layer_dict['valign'] if 'valign' in layer_dict else 'top'
self.sprites = []
elif self.type == "collision":
self.data = []
for box in layer_dict['data']:
x = box['x']
y = box['y']
w = box['width']
h = box['height']
self.data.append(pygame.Rect(x, y, w, h))
else:
print(f"Warning: Loading Tiled layer of type {self.type} not implemented yet.")
print(f"Warning: Loading Tiled layer of type '{self.type}' not implemented yet.")

class Tilesheet_Tiled:
""" tile sheet from Tiled! """

"""
WARNING:
Not used by game; game uses Tilesheet class below. Generate from this
via helper script.
This class has self.tiles as an array from the json, but Tilesheet
below has self.tiles as a dict. I like confusing myself too.
"""

def __init__(self, name, subfolder=""):


Loading…
Cancel
Save