py_yugi_clone/scripts/entities.py

78 lines
3.3 KiB
Python
Raw Normal View History

2024-07-10 20:08:18 +02:00
import pygame
import numpy as np
2024-07-12 16:56:47 +02:00
from scripts.utils import to_isometric_pixel
2024-07-10 20:08:18 +02:00
class Entity:
def __init__(self, game, e_type, pos, size):
self.game = game
self.type = e_type
self.pos = np.array(pos)
2024-07-12 22:04:31 +02:00
self.size = np.array(size)
2024-07-10 20:08:18 +02:00
self.velocity = np.array([0,0], dtype=np.float32)
2024-07-12 22:04:31 +02:00
def update(self, tilemap, movement = np.array([0,0])):
2024-07-10 20:08:18 +02:00
frame_movement = self.velocity + movement
2024-07-12 22:04:31 +02:00
self.pos[0] += frame_movement[0]
entity_rect = self.rect()
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)
2024-07-13 15:29:03 +02:00
class Partner(Entity):
def __init__(self, game, pos, size):
super().__init__(game, 'partner', pos, size)
self.player = game.player #player a cui è linkato
def update(self):
R = 50
player_pos = self.player.pos
if np.linalg.norm(player_pos-self.pos) <= R:
return
a = np.stack([player_pos, self.pos])
if np.linalg.det(a) == 0:
line_coeffs = np.append(np.linalg.lstsq(a,np.array([[0.0],[0.0]]),rcond=None)[0],0)
else:
line_coeffs = np.append(np.linalg.lstsq(a,np.array([[1.0],[1.0]]),rcond=None)[0],1)
if np.abs(line_coeffs[1])<1e-7:
P3 = np.array([self.pos[0], player_pos[1] + R]) #np.sqrt(R ** 2 - (x - player_pos[0]) ** 2)
P4 = np.array([self.pos[0], player_pos[1] - R])
theta = 0
delta = 0
else:
m = - line_coeffs[0] / line_coeffs[1]
theta = np.arctan(m)
delta = R * np.array([np.cos(theta),np.sin(theta)])
P3 = player_pos + delta
P4 = player_pos - delta
P = (P3 if (np.linalg.norm(P3-self.pos) < np.linalg.norm(P4-self.pos)) else P4)
#super().update(tilemap, P - self.pos) #nice idea but sometimes gets blocked and needs to tp to the player
self.pos = P
class GroupEntities:
def __init__(self, game, entities):
self.game = game
self.entities = entities #sorted(entities, key=(lambda x: x.pos[1]))
def add_entity(self, entity):
self.entities.append(entity)
#def update()
def render(self, surface, offset=np.array([0.,0.])):
self.entities.sort(key = (lambda x: x.pos[1]))
for entity in self.entities:
entity.render(surface, offset)