Comprobamos movimiento en vista isometrica
This commit is contained in:
parent
fd5b041242
commit
7dd9fac0c8
@ -48,8 +48,8 @@ El Vortex avanza automáticamente de forma constante hacia arriba. Si encuentra
|
|||||||
|
|
||||||
1. Clona este repositorio:
|
1. Clona este repositorio:
|
||||||
```bash
|
```bash
|
||||||
git clone https://gitea.soloconlinux.org.es/luisgulo/Hightway_Vector.git
|
git clone https://gitea.soloconlinux.org.es/luisgulo/Highway_Vector.git
|
||||||
cd highway-vector
|
cd Highway_Vector
|
||||||
```
|
```
|
||||||
2. Crea y activa un entorno virtual para las librerias de Python:
|
2. Crea y activa un entorno virtual para las librerias de Python:
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
239
highway_vector.py
Normal file
239
highway_vector.py
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
import sys
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
# Inicialización de Pygame
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
# Constantes de Pantalla
|
||||||
|
SCREEN_WIDTH = 800
|
||||||
|
SCREEN_HEIGHT = 600
|
||||||
|
FPS = 60
|
||||||
|
|
||||||
|
# Configuración de Cuadrícula e Isometría
|
||||||
|
TILE_WIDTH = 64
|
||||||
|
TILE_HEIGHT = 32
|
||||||
|
GRID_SIZE_X = 8
|
||||||
|
GRID_SIZE_Y = 100 # Largo de la autopista
|
||||||
|
|
||||||
|
# Colores (Paleta Retro Spectrum/Amstrad)
|
||||||
|
COLOR_BG = (10, 10, 15)
|
||||||
|
COLOR_GRID = (40, 40, 60)
|
||||||
|
COLOR_ROAD = (60, 60, 80)
|
||||||
|
COLOR_VORTEX = (0, 255, 200)
|
||||||
|
COLOR_PLAYER = (255, 200, 0)
|
||||||
|
COLOR_BLOCK = (200, 50, 50)
|
||||||
|
COLOR_WALL = (100, 100, 120)
|
||||||
|
|
||||||
|
|
||||||
|
def grid_to_iso(gx, gy, gz=0):
|
||||||
|
"""Convierte coordenadas de cuadrícula 3D (x, y, z) a coordenadas de pantalla 2D."""
|
||||||
|
iso_x = (gx - gy) * (TILE_WIDTH // 2)
|
||||||
|
iso_y = (gx + gy) * (TILE_HEIGHT // 2) - (gz * 16)
|
||||||
|
return iso_x, iso_y
|
||||||
|
|
||||||
|
|
||||||
|
class Entity:
|
||||||
|
|
||||||
|
def __init__(self, gx, gy, color, is_solid=True):
|
||||||
|
self.gx = float(gx)
|
||||||
|
self.gy = float(gy)
|
||||||
|
self.gz = 0
|
||||||
|
self.color = color
|
||||||
|
self.is_solid = is_solid
|
||||||
|
self.radius = 0.4
|
||||||
|
|
||||||
|
def draw(self, surface, camera_offset_x, camera_offset_y):
|
||||||
|
screen_x, screen_y = grid_to_iso(self.gx, self.gy, self.gz)
|
||||||
|
draw_x = screen_x + camera_offset_x
|
||||||
|
draw_y = screen_y + camera_offset_y
|
||||||
|
|
||||||
|
# Dibujar un bloque o personaje estilo isométrico
|
||||||
|
points = [
|
||||||
|
(draw_x, draw_y - 20),
|
||||||
|
(draw_x + TILE_WIDTH // 2, draw_y - 20 + TILE_HEIGHT // 2),
|
||||||
|
(draw_x, draw_y - 20 + TILE_HEIGHT),
|
||||||
|
(draw_x - TILE_WIDTH // 2, draw_y - 20 + TILE_HEIGHT // 2),
|
||||||
|
]
|
||||||
|
pygame.draw.polygon(surface, self.color, points)
|
||||||
|
pygame.draw.polygon(
|
||||||
|
surface, (255, 255, 255), points, 2
|
||||||
|
) # Borde brillante
|
||||||
|
|
||||||
|
|
||||||
|
class PushBlock(Entity):
|
||||||
|
|
||||||
|
def __init__(self, gx, gy):
|
||||||
|
super().__init__(gx, gy, COLOR_BLOCK, is_solid=True)
|
||||||
|
|
||||||
|
def push(self, dx, dy, entities):
|
||||||
|
new_gx = self.gx + dx
|
||||||
|
new_gy = self.gy + dy
|
||||||
|
|
||||||
|
# Comprobar límites de la carretera
|
||||||
|
if not (0 <= new_gx < GRID_SIZE_X and 0 <= new_gy < GRID_SIZE_Y):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Comprobar colisión con otras entidades
|
||||||
|
for entity in entities:
|
||||||
|
if entity != self and entity.is_solid:
|
||||||
|
if (
|
||||||
|
abs(entity.gx - new_gx) < 0.6
|
||||||
|
and abs(entity.gy - new_gy) < 0.6
|
||||||
|
):
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.gx = new_gx
|
||||||
|
self.gy = new_gy
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class Player(Entity):
|
||||||
|
|
||||||
|
def __init__(self, gx, gy):
|
||||||
|
super().__init__(gx, gy, COLOR_PLAYER, is_solid=True)
|
||||||
|
self.speed = 0.08
|
||||||
|
|
||||||
|
def update(self, keys, entities):
|
||||||
|
dx, dy = 0, 0
|
||||||
|
if keys[pygame.K_LEFT] or keys[pygame.K_a]:
|
||||||
|
dx -= self.speed
|
||||||
|
if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
|
||||||
|
dx += self.speed
|
||||||
|
if keys[pygame.K_UP] or keys[pygame.K_w]:
|
||||||
|
dy -= self.speed
|
||||||
|
if keys[pygame.K_DOWN] or keys[pygame.K_s]:
|
||||||
|
dy += self.speed
|
||||||
|
|
||||||
|
if dx != 0 or dy != 0:
|
||||||
|
target_gx = self.gx + dx
|
||||||
|
target_gy = self.gy + dy
|
||||||
|
|
||||||
|
# Limites horizontales
|
||||||
|
if not (0 <= target_gx < GRID_SIZE_X):
|
||||||
|
dx = 0
|
||||||
|
if not (0 <= target_gy < GRID_SIZE_Y):
|
||||||
|
dy = 0
|
||||||
|
|
||||||
|
# Intento de movimiento y colisión con bloques
|
||||||
|
for entity in entities:
|
||||||
|
if entity != self and entity.is_solid:
|
||||||
|
if (
|
||||||
|
abs(entity.gx - (self.gx + dx)) < 0.6
|
||||||
|
and abs(entity.gy - (self.gy + dy)) < 0.6
|
||||||
|
):
|
||||||
|
# Intentar empujar si es un PushBlock
|
||||||
|
if isinstance(entity, PushBlock):
|
||||||
|
push_dx = 0.1 if dx > 0 else (-0.1 if dx < 0 else 0)
|
||||||
|
push_dy = 0.1 if dy > 0 else (-0.1 if dy < 0 else 0)
|
||||||
|
if not entity.push(push_dx, push_dy, entities):
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
return # Bloqueado
|
||||||
|
|
||||||
|
self.gx += dx
|
||||||
|
self.gy += dy
|
||||||
|
|
||||||
|
|
||||||
|
class Vortex(Entity):
|
||||||
|
|
||||||
|
def __init__(self, gx, gy):
|
||||||
|
super().__init__(gx, gy, COLOR_VORTEX, is_solid=True)
|
||||||
|
self.speed = 0.015 # Avance constante automático
|
||||||
|
|
||||||
|
def update(self, entities):
|
||||||
|
target_gy = self.gy - self.speed
|
||||||
|
|
||||||
|
# Verificar si hay algún obstáculo al avanzar
|
||||||
|
blocked = False
|
||||||
|
for entity in entities:
|
||||||
|
if entity != self and entity.is_solid:
|
||||||
|
if (
|
||||||
|
abs(entity.gx - self.gx) < 0.7
|
||||||
|
and abs(entity.gy - target_gy) < 0.7
|
||||||
|
):
|
||||||
|
blocked = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if not blocked and target_gy >= 0:
|
||||||
|
self.gy = target_gy
|
||||||
|
|
||||||
|
|
||||||
|
class Game:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
|
||||||
|
pygame.display.set_caption("Highway Encounter Python Remake")
|
||||||
|
self.clock = pygame.time.Clock()
|
||||||
|
|
||||||
|
self.vortex = Vortex(3.5, 95)
|
||||||
|
self.player = Player(3.5, 92)
|
||||||
|
|
||||||
|
self.entities = [self.vortex, self.player]
|
||||||
|
|
||||||
|
# Generar bloques de prueba a lo largo de la autopista
|
||||||
|
for y in range(10, 90, 5):
|
||||||
|
self.entities.append(PushBlock(y % GRID_SIZE_X, y))
|
||||||
|
self.entities.append(PushBlock((y + 3) % GRID_SIZE_X, y + 2))
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
running = True
|
||||||
|
while running:
|
||||||
|
self.clock.tick(FPS)
|
||||||
|
|
||||||
|
# 1. Procesar Eventos
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
running = False
|
||||||
|
|
||||||
|
# 2. Actualizar Estado
|
||||||
|
keys = pygame.key.get_pressed()
|
||||||
|
self.player.update(keys, self.entities)
|
||||||
|
self.vortex.update(self.entities)
|
||||||
|
|
||||||
|
# 3. Calcular desplazamiento de cámara (centrada en el VORTEX o el jugador)
|
||||||
|
iso_x, iso_y = grid_to_iso(self.player.gx, self.player.gy)
|
||||||
|
camera_offset_x = SCREEN_WIDTH // 2 - iso_x
|
||||||
|
camera_offset_y = SCREEN_HEIGHT // 2 - iso_y + 100
|
||||||
|
|
||||||
|
# 4. Renderizado
|
||||||
|
self.screen.fill(COLOR_BG)
|
||||||
|
|
||||||
|
# Dibujar suelo (Autopista)
|
||||||
|
for gy in range(0, GRID_SIZE_Y):
|
||||||
|
for gx in range(0, GRID_SIZE_X):
|
||||||
|
sx, sy = grid_to_iso(gx, gy)
|
||||||
|
draw_x = sx + camera_offset_x
|
||||||
|
draw_y = sy + camera_offset_y
|
||||||
|
|
||||||
|
# Solo dibujar si está visible en pantalla
|
||||||
|
if -100 < draw_x < SCREEN_WIDTH + 100 and -100 < draw_y < SCREEN_HEIGHT + 100:
|
||||||
|
pts = [
|
||||||
|
(draw_x, draw_y),
|
||||||
|
(
|
||||||
|
draw_x + TILE_WIDTH // 2,
|
||||||
|
draw_y + TILE_HEIGHT // 2,
|
||||||
|
),
|
||||||
|
(draw_x, draw_y + TILE_HEIGHT),
|
||||||
|
(
|
||||||
|
draw_x - TILE_WIDTH // 2,
|
||||||
|
draw_y + TILE_HEIGHT // 2,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
pygame.draw.polygon(self.screen, COLOR_ROAD, pts)
|
||||||
|
pygame.draw.polygon(self.screen, COLOR_GRID, pts, 1)
|
||||||
|
|
||||||
|
# Ordenar entidades por coordenada 'gy' descendente para renderizar correctamente la profundidad
|
||||||
|
sorted_entities = sorted(
|
||||||
|
self.entities, key=lambda e: e.gy, reverse=True
|
||||||
|
)
|
||||||
|
for entity in sorted_entities:
|
||||||
|
entity.draw(self.screen, camera_offset_x, camera_offset_y)
|
||||||
|
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
Game().run()
|
||||||
BIN
img-versiones/version_0.1.png
Normal file
BIN
img-versiones/version_0.1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Loading…
x
Reference in New Issue
Block a user