zoria/src/game.py

125 lines
4.6 KiB
Python
Raw Normal View History

2020-02-10 13:18:27 -08:00
import pygame
import math, os, sys
2020-02-19 11:26:07 -08:00
2020-02-10 13:18:27 -08:00
# Init
pygame.init()
pygame.font.init()
winsize = [800, 600]
screen = pygame.display.set_mode(winsize, pygame.RESIZABLE)
2020-05-01 23:02:03 -07:00
# Load all assets
from . import assets
2021-01-29 14:01:20 -08:00
for filename in os.listdir(os.path.join(os.getcwd(), "assets")):
2020-05-01 23:02:03 -07:00
assets.load(filename)
2020-02-24 16:33:22 -08:00
pygame.display.set_caption("Zoria")
pygame.display.set_icon(assets.load("icon.png"))
# Constants
SCALE = 2
METER = 32
FPS = 60
2020-02-10 13:18:27 -08:00
2020-05-02 14:17:35 -07:00
from . import controller, fade, register, spritesheet, vector
2020-05-01 23:02:03 -07:00
from .map import Map
from .player import Player
2020-02-10 13:18:27 -08:00
# Map
2020-02-24 16:46:30 -08:00
map = Map(METER)
2020-04-30 00:09:03 -07:00
map.generate(0)
2020-02-12 13:40:25 -08:00
2020-02-24 18:20:51 -08:00
# Player
2020-05-02 14:17:35 -07:00
player = Player(spritesheet.SpriteSheet(assets.get("character.png"), 32, 48), pygame.Rect(8, 32, 16, 16))
2020-02-20 21:36:17 -08:00
# TODO: Use asset loader for spritesheets
2020-05-01 23:02:03 -07:00
player.texture.set_animation(0, 0, 0)
2020-04-30 01:06:45 -07:00
mroom = map.generators[0].rooms[int(math.ceil(len(map.generators[0].rooms) / 2))]
player.set_pos(mroom.cx, mroom.cy)
2020-03-04 11:23:23 -08:00
2020-02-20 18:59:04 -08:00
CENTER = [winsize[0] / 2, winsize[1] / 2]
2020-05-02 12:38:55 -07:00
BGCOLOR = pygame.Color("#2d1003")
2020-05-02 14:33:32 -07:00
# Fade from/to black
2020-05-02 14:17:35 -07:00
player.fade = fade.Fade(255, -96)
2020-05-01 23:02:03 -07:00
def get_screenpos(x, y):
return [
camera[0] + round((x * METER - (player.pos.x * METER)) * SCALE),
camera[1] + round((y * METER - (player.pos.y * METER)) * SCALE)
]
2020-02-10 13:18:27 -08:00
# Mainloop
2020-02-19 11:26:07 -08:00
clock = pygame.time.Clock()
2020-02-10 13:18:27 -08:00
while 1:
2020-02-19 11:26:07 -08:00
dtime = clock.tick(FPS) / 1000.0
2020-02-10 13:18:27 -08:00
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
2020-05-02 14:33:32 -07:00
elif event.type == pygame.VIDEORESIZE: # This is currently broken on Linux (SDL2)
winsize = event.size
SCALE = 2 * (winsize[0] / 800)
CENTER = [winsize[0] / 2, winsize[1] / 2]
screen = pygame.display.set_mode(winsize, pygame.RESIZABLE)
2020-02-10 13:18:27 -08:00
screen.fill(BGCOLOR)
2020-02-10 13:18:27 -08:00
2020-02-20 18:59:04 -08:00
player.update(dtime, map)
2020-02-20 21:36:17 -08:00
spritesheet.update(dtime)
2020-02-19 11:10:56 -08:00
2020-02-19 13:19:07 -08:00
# Move the map based on player position
2020-05-01 23:02:03 -07:00
psize = player.rect.size
camera = [int(CENTER[0] - (psize[0] / 2 * SCALE)), int(CENTER[1] - (psize[1] / 2 * SCALE))]
player_rendered = False
2020-02-19 13:19:07 -08:00
2020-05-02 14:33:32 -07:00
# Render loops
2020-04-30 00:09:03 -07:00
for z in range(player.z - 1, player.z + 1):
if z < len(map.map):
for y in range(len(map.map[z])):
for x in range(len(map.map[z][y])):
tile = map.get_tile(x, y, z)
if tile:
# NOTE: Rotations are clockwise due to Y+ down rendering
# Will this break if there is no texture for the given rotation? Yes.
# Do I care? No.
texture = assets.get(tile.textures[tile.get_rotation()])
tilesize = texture.get_rect().size
scaledsize = [tilesize[0] * SCALE, tilesize[1] * SCALE]
tilex = (x * METER) - ((tilesize[0] / 2) - (METER / 2))
tiley = (y * METER) - (tilesize[1] - METER)
2020-05-01 23:02:03 -07:00
pos = get_screenpos(tilex / METER, tiley / METER)
2020-04-30 00:09:03 -07:00
# Only render tile if on-screen
if pos[0] + scaledsize[0] >= 0 and pos[0] <= winsize[0] and \
pos[1] + scaledsize[1] >= 0 and pos[1] <= winsize[1]:
tile.on_step(dtime, map, player)
screen.blit(pygame.transform.scale(texture, [round(scaledsize[0]) + 1, round(scaledsize[1]) + 1]), pos)
2020-05-01 23:02:03 -07:00
if not player_rendered and z == player.z and y == math.ceil(player.pos.y + 1 + player.rect[3] / METER):
2020-04-30 00:09:03 -07:00
# Draw player
2020-05-01 23:02:03 -07:00
screen.blit(pygame.transform.scale(player.texture.frame, [round(SCALE * player.texture.width), round(SCALE * player.texture.height)]), camera)
2020-04-30 00:09:03 -07:00
player_rendered = True
2020-05-01 23:02:03 -07:00
# Draw sprites
if z < len(map.sprites):
for sprite in map.sprites[z]:
if y == math.ceil(sprite.pos.y):
2020-05-02 14:33:32 -07:00
# Do on_step within 10 meter radius
2020-05-01 23:02:03 -07:00
if vector.distance(sprite.pos, player.pos) <= 10:
sprite.on_step(dtime, map, player)
2020-05-02 14:33:32 -07:00
# Only render if on-screen
2020-05-01 23:02:03 -07:00
scaledsize = [round(SCALE * sprite.texture.width), round(SCALE * sprite.texture.height)]
pos = get_screenpos(sprite.pos.x, sprite.pos.y)
if pos[0] + scaledsize[0] >= 0 and pos[0] <= winsize[0] and \
pos[1] + scaledsize[1] >= 0 and pos[1] <= winsize[1]:
2020-05-02 02:28:38 -07:00
screen.blit(pygame.transform.rotate(pygame.transform.scale(sprite.texture.frame, scaledsize), sprite.rot), pos)
2020-05-01 23:02:03 -07:00
2020-04-28 02:37:53 -07:00
player.hud.render(screen, SCALE)
2020-05-02 14:17:35 -07:00
player.fade.update(screen, dtime)
pygame.display.update()