added camera and collidable tiles

This commit is contained in:
StochasticMouse 2024-07-12 22:04:31 +02:00
parent 338e24357f
commit 97c3074737
6 changed files with 98 additions and 48 deletions

View File

@ -1,21 +1,21 @@
3,1,1,1,1,1,1,1,1,1,1,1,1,1,4 3,2,2,2,2,2,2,2,2,2,2,2,2,2,4
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
1,2,2,2,2,2,2,2,2,2,2,2,2,2,1 2,1,1,1,1,1,1,1,1,1,1,1,1,1,2
5,1,1,1,1,1,1,1,1,1,1,1,1,1,6 5,2,2,2,2,2,2,2,2,2,2,2,2,2,6

1 3 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 4
2 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
3 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
4 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
5 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
6 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
7 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
8 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
9 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
10 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
11 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
12 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
13 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
14 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
15 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
16 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
17 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
18 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
19 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
20 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2
21 5 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6

27
game.py
View File

@ -2,7 +2,8 @@ import pygame
import numpy as np import numpy as np
from scripts.tiles import Tilemap from scripts.tiles import Tilemap
from scripts.entities import Entity from scripts.entities import Entity
from scripts.utils import load_image, load_images from scripts.utils import load_image, load_images, to_isometric_pixel
from scripts.camera import Camera
# SETTINGS # SETTINGS
WIDTH = 1280 WIDTH = 1280
@ -18,14 +19,15 @@ class Game:
pygame.display.set_caption(TITLE) pygame.display.set_caption(TITLE)
self.clock = pygame.time.Clock() self.clock = pygame.time.Clock()
self.player = Entity(self, 'player', (50.0,200.0), (8, 15)) self.player = Entity(self, 'player', (64., 64.), (28, 42))
self.assets = { self.assets = {
'player' : load_image('entities/player.png'), 'player' : load_image('entities/player.png'),
#'grass' : load_images('tiles/grass/'), #'grass' : load_images('tiles/grass/'),
#'stone' : load_images('tiles/stone/') #'stone' : load_images('tiles/stone/')
'iso' : load_images('tiles/iso/') 'iso' : load_images('tiles/iso/')
} }
self.tilemap = Tilemap(self, (64,32), 'map_1.csv') self.tilemap = Tilemap(self, (64,32), 'map_1.csv')
self.camera = Camera(self)
def run(self): def run(self):
self.status = True self.status = True
while self.status: while self.status:
@ -36,17 +38,20 @@ class Game:
self.status = False self.status = False
keys = pygame.key.get_pressed() keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]: if keys[pygame.K_LEFT]:
delta[0] -= 1 delta[0] -= 5
if keys[pygame.K_RIGHT]: if keys[pygame.K_RIGHT]:
delta[0] += 1 delta[0] += 5
if keys[pygame.K_UP]: if keys[pygame.K_UP]:
delta[1] -= 0.5 delta[1] -= 5
if keys[pygame.K_DOWN]: if keys[pygame.K_DOWN]:
delta[1] += 0.5 delta[1] += 5
self.player.update(delta) #print(self.tilemap.physics_rects_around(self.player.pos))
self.tilemap.render(self.display) print(self.player.pos)
self.player.render(self.display) self.camera.update()
self.screen.blit(pygame.transform.scale_by(self.display,2), (0,0)) self.player.update(self.tilemap, delta)
self.tilemap.render(self.display, offset = self.camera.scroll)
self.player.render(self.display, offset = self.camera.scroll)
self.screen.blit(pygame.transform.scale(self.display,self.screen.get_size()), (0,0))
pygame.display.update() pygame.display.update()
self.clock.tick(60) self.clock.tick(60)
pygame.quit() pygame.quit()

10
scripts/camera.py Normal file
View File

@ -0,0 +1,10 @@
import pygame
import numpy as np
from scripts.utils import to_isometric_pixel
class Camera:
def __init__(self, game, scroll = np.array([0.,0.])):
self.scroll = scroll
self.game = game
def update(self):
self.scroll += (to_isometric_pixel(self.game.player.pos-np.array([48,80]))*np.array([1,0.5]) - np.array(self.game.display.get_size())/2 - self.scroll)/30

View File

@ -7,10 +7,29 @@ class Entity:
self.game = game self.game = game
self.type = e_type self.type = e_type
self.pos = np.array(pos) self.pos = np.array(pos)
self.size = size self.size = np.array(size)
self.velocity = np.array([0,0], dtype=np.float32) self.velocity = np.array([0,0], dtype=np.float32)
def update(self, movement = np.array([0,0])): def update(self, tilemap, movement = np.array([0,0])):
frame_movement = self.velocity + movement frame_movement = self.velocity + movement
self.pos += frame_movement self.pos[0] += frame_movement[0]
def render(self, surface): entity_rect = self.rect()
surface.blit(self.game.assets[self.type], self.pos) for rect in tilemap.physics_rects_around(self.pos):
if entity_rect.colliderect(rect):
if frame_movement[0] > 0: #i was moving right
entity_rect.right = rect.left
if frame_movement[0] < 0: #i was moving left
entity_rect.left = rect.right
self.pos[0] = entity_rect.x
self.pos[1] += frame_movement[1]
entity_rect = self.rect()
for rect in tilemap.physics_rects_around(self.pos):
if entity_rect.colliderect(rect):
if frame_movement[1] > 0: #i was moving down
entity_rect.bottom = rect.top
if frame_movement[1] < 0: #i was moving up
entity_rect.top = rect.bottom
self.pos[1] = entity_rect.y
def render(self, surface, offset = np.array([0.,0.])):
surface.blit(self.game.assets[self.type], to_isometric_pixel(self.pos-np.array([48,80]))*np.array([1,0.5])-offset)
def rect(self):
return pygame.Rect(self.pos, self.size)

View File

@ -1,8 +1,10 @@
import pygame import pygame
import numpy as np import numpy as np
from scripts.utils import TILE_DICT, to_isometric from scripts.utils import TILE_DICT, to_isometric_pixel
BASE_MAP_PATH = 'data/maps/' BASE_MAP_PATH = 'data/maps/'
NEIGHBOR_OFFSETS = [np.array((i,j)) for i in (-1,0,1) for j in (-1,0,1)]
class Tilemap: class Tilemap:
def __init__(self, game, tile_size, map_path): def __init__(self, game, tile_size, map_path):
@ -17,11 +19,25 @@ class Tilemap:
for row in range(tile_arr.shape[0]): for row in range(tile_arr.shape[0]):
for col in range(tile_arr.shape[1]): for col in range(tile_arr.shape[1]):
type_var = TILE_DICT[tile_arr[row,col]] type_var = TILE_DICT[tile_arr[row,col]]
self.tilemap[row,col] = {'type' : type_var[0], 'variant' : type_var[1], 'pos': np.array([row,col])} self.tilemap[row,col] = {'type' : type_var[0], 'variant' : type_var[1], 'pos': np.array([row,col]), 'walkable': type_var[2]}
def render(self, surface): def render(self, surface, offset = np.array([0,0])):
for x in range(self.tilemap.shape[0]): for x in range(self.tilemap.shape[0]):
for y in range(self.tilemap.shape[1]): for y in range(self.tilemap.shape[1]):
tile = self.tilemap[x,y] tile = self.tilemap[x,y]
surface.blit(self.game.assets[tile['type']][tile['variant']],to_isometric(tile['pos'],self.tile_size)) surface.blit(self.game.assets[tile['type']][tile['variant']],(to_isometric_pixel(tile['pos'])*self.tile_size)-offset)
for tile in self.offgrid_tiles: for tile in self.offgrid_tiles:
surface.blit(self.game.assets[tile['type']][tile['variant']],to_isometric(tile['pos'],self.tile_size)) #this tile is written offgrid so no mult by tile_size surface.blit(self.game.assets[tile['type']][tile['variant']],(to_isometric_pixel(tile['pos'])*self.tile_size)-offset) #this tile is written offgrid so no mult by tile_size
def tiles_around(self,pos):
tiles = []
tile_loc = np.array(pos // np.array((self.tile_size[0],self.tile_size[0])),dtype=int) #gotta use this and not just self.tile_size to normalize wrt the change of variables for the isometric view
for offset in NEIGHBOR_OFFSETS:
check_loc = tile_loc + offset
if np.all(check_loc >= 0) and np.all(check_loc < self.tilemap.shape):
tiles.append(self.tilemap[tuple(check_loc)])
return tiles
def physics_rects_around(self,pos):
rects = []
for tile in self.tiles_around(pos):
if not tile['walkable']:
rects.append(pygame.Rect(tile['pos'] * np.array((self.tile_size[0],self.tile_size[0])), np.array((self.tile_size[0],self.tile_size[0]))))
return rects

View File

@ -2,12 +2,12 @@ import pygame
import os import os
import numpy as np import numpy as np
TILE_DICT = { TILE_DICT = {
1 : ('iso',0), 1 : ('iso',0,True),
2 : ('iso',1), 2 : ('iso',1,False),
3 : ('iso',2), 3 : ('iso',2,False),
4 : ('iso',3), 4 : ('iso',3,False),
5 : ('iso',4), 5 : ('iso',4,False),
6 : ('iso',5) 6 : ('iso',5,False)
} }
BASE_IMG_PATH = 'data/images/' BASE_IMG_PATH = 'data/images/'
def load_image(path): def load_image(path):