From cd43dc8e3e3de97daf21025f37555a795ffe6e54 Mon Sep 17 00:00:00 2001 From: luisgulo Date: Sun, 4 Oct 2026 15:24:25 +0200 Subject: [PATCH] Ajuste de colision y vidas --- highway_vector.py | 58 ++++++++++++++-------------------- img-versiones/version_3.0.png | Bin 0 -> 17645 bytes 2 files changed, 23 insertions(+), 35 deletions(-) create mode 100644 img-versiones/version_3.0.png diff --git a/highway_vector.py b/highway_vector.py index cc4fb73..2fb09c4 100644 --- a/highway_vector.py +++ b/highway_vector.py @@ -68,7 +68,6 @@ def draw_isometric_prism(surface, color, width=40, height=35): (cx, cy + 2 * h2), ] - # Sombra/Sombreado para volumen c_top = color c_left = tuple(max(0, c - 40) for c in color) c_right = tuple(max(0, c - 70) for c in color) @@ -77,7 +76,6 @@ def draw_isometric_prism(surface, color, width=40, height=35): pygame.draw.polygon(surf, c_left, left_pts) pygame.draw.polygon(surf, c_right, right_pts) - # Bordes para definición pygame.draw.polygon(surf, (20, 20, 20), top_pts, 1) pygame.draw.polygon(surf, (20, 20, 20), left_pts, 1) pygame.draw.polygon(surf, (20, 20, 20), right_pts, 1) @@ -94,20 +92,18 @@ def create_placeholder_sprites(): base_pts = [(32, 48), (52, 38), (32, 28), (12, 38)] apex = (32, 8) - # Caras de la pirámide pygame.draw.polygon( surf_player, (200, 160, 0), [base_pts[3], base_pts[0], apex] - ) # Izquierda + ) pygame.draw.polygon( surf_player, (255, 215, 0), [base_pts[0], base_pts[1], apex] - ) # Derecha - pygame.draw.polygon(surf_player, (255, 235, 100), base_pts) # Base + ) + pygame.draw.polygon(surf_player, (255, 235, 100), base_pts) pygame.draw.line(surf_player, (50, 50, 0), apex, base_pts[0], 2) sprites["player"] = surf_player - # 2. VORTEX: Cubo amarillo con "bola" encima + # 2. VORTEX: Cubo amarillo con bola encima surf_vortex = draw_isometric_prism(None, COLOR_YELLOW, width=38, height=25) - # Bola superior pygame.draw.circle(surf_vortex, (255, 255, 200), (32, 12), 8) pygame.draw.circle(surf_vortex, (0, 0, 0), (32, 12), 8, 1) sprites["vortex"] = surf_vortex @@ -120,7 +116,7 @@ def create_placeholder_sprites(): None, COLOR_WHITE, width=32, height=35 ) - # 5. Enemigos Destructibles (Prismas por estado de vida) + # 5. Enemigos Destructibles sprites["enemy_red"] = draw_isometric_prism( None, COLOR_RED, width=32, height=35 ) @@ -261,12 +257,10 @@ class Enemy(Entity): def update(self, entities): target_gx = self.gx + (self.speed * self.direction) - # Rebotar en los bordes de la carretera if target_gx <= 0.5 or target_gx >= GRID_SIZE_X - 0.5: self.direction *= -1 return - # Comprobar bloqueos con bloques u otras entidades sólidas for entity in entities: if entity != self and entity.is_solid: if ( @@ -369,7 +363,7 @@ class Game: def __init__(self): self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) - pygame.display.set_caption("Highway Encounter - Custom Enemies & Shapes") + pygame.display.set_caption("Highway Encounter - Fixed Collision & Life System") self.clock = pygame.time.Clock() self.font = pygame.font.SysFont("monospace", 18, bold=True) self.sprite_mgr = SpriteManager() @@ -386,7 +380,6 @@ class Game: self.entities = [self.vortex, self.player] self.bullets = [] - # Escuadrón de reserva self.spares = [] for i in range(self.lives - 1): spare = Entity( @@ -398,41 +391,32 @@ class Game: ) self.spares.append(spare) - # Generar bloques y enemigos a lo largo de toda la autopista (de y = 10 hasta la salida) for y in range(10, GRID_SIZE_Y - 12): - # 1. Bloques de prueba blancos en diferentes carriles if y % 6 == 0: lane = (y * 3) % GRID_SIZE_X self.entities.append(PushBlock(lane, y)) - # 2. Enemigos destructibles (Prismas Rojos - 3 disparos) if y % 14 == 0: self.entities.append(Enemy(2.0, y, destructible=True)) - # 3. Enemigos indestructibles (Prismas Blancos - Solo bloqueables) if y % 20 == 0: self.entities.append(Enemy(5.0, y, destructible=False)) def handle_collisions(self): - # Muerte por contacto de un enemigo con el Jugador O con el VORTEX + # Detección precisa de colisión entre enemigos, jugador y VORTEX for entity in self.entities: if isinstance(entity, Enemy): - # Colisión con el Jugador - touch_player = ( - abs(entity.gx - self.player.gx) < 0.5 - and abs(entity.gy - self.player.gy) < 0.5 + player_hit = ( + abs(entity.gx - self.player.gx) < 0.6 + and abs(entity.gy - self.player.gy) < 0.6 ) - # Colisión con el VORTEX - touch_vortex = ( - abs(entity.gx - self.vortex.gx) < 0.6 - and abs(entity.gy - self.vortex.gy) < 0.6 + vortex_hit = ( + abs(entity.gx - self.vortex.gx) < 0.7 + and abs(entity.gy - self.vortex.gy) < 0.7 ) - if touch_player or touch_vortex: - self.lives -= 1 - if self.lives > 0: - self.reset_level() - return + if player_hit or vortex_hit: + return True # Devuelve True si hubo un impacto directo # Limpiar bloques destruidos y enemigos muertos for entity in self.entities[:]: @@ -440,6 +424,8 @@ class Game: self.entities.remove(entity) self.score += 200 + return False + def draw_hud(self): zone = int((GRID_SIZE_Y - self.vortex.gy) / 4) hud_text = f"ZONE: {zone:02d} | LIVES: {self.lives} | SCORE: {self.score:06d}" @@ -486,16 +472,19 @@ class Game: if not bullet.alive: self.bullets.remove(bullet) - self.handle_collisions() + # Verificar colisión y procesar pérdida de vida + if self.handle_collisions(): + self.lives -= 1 + if self.lives > 0: + self.reset_level() + continue # Reinicia el ciclo sin renderizar el estado fallido - # Desplazamiento de cámara centrado en 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 self.screen.fill(COLOR_BG) - # Dibujar suelo for gy in range(0, GRID_SIZE_Y): for gx in range(0, GRID_SIZE_X): sx, sy = grid_to_iso(gx, gy) @@ -521,7 +510,6 @@ class Game: pygame.draw.polygon(self.screen, COLOR_ROAD, pts) pygame.draw.polygon(self.screen, COLOR_GRID, pts, 1) - # Orden de renderizado por profundidad all_drawables = self.entities + self.bullets + self.spares sorted_entities = sorted( all_drawables, key=lambda e: e.gy, reverse=True diff --git a/img-versiones/version_3.0.png b/img-versiones/version_3.0.png new file mode 100644 index 0000000000000000000000000000000000000000..6c1c711a1505a8b10e1dc89450172b11acde326e GIT binary patch literal 17645 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 literal 0 HcmV?d00001