submarine game
This commit is contained in:
parent
872f8a0406
commit
bc92df3242
@ -15,7 +15,6 @@ def send_screen():
|
||||
s.send(len(data).to_bytes(4, byteorder='big') + data)
|
||||
except:
|
||||
break
|
||||
time.sleep(0.5)
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect(("127.0.0.1", 9999)) # Replace with actual IP
|
||||
|
204
submarine/main.py
Normal file
204
submarine/main.py
Normal file
@ -0,0 +1,204 @@
|
||||
import pygame
|
||||
import math
|
||||
import random
|
||||
import sys
|
||||
|
||||
pygame.init()
|
||||
|
||||
# Constants
|
||||
WIDTH, HEIGHT = 1000, 600
|
||||
FPS = 60
|
||||
BLIP_FADE_TIME = 4000 # milliseconds
|
||||
|
||||
# Init
|
||||
screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
||||
pygame.display.set_caption("Polished Submarine Simulator")
|
||||
clock = pygame.time.Clock()
|
||||
|
||||
# Colors
|
||||
BLACK = (10, 10, 20)
|
||||
DARK_GRAY = (40, 40, 60)
|
||||
GRAY = (100, 100, 120)
|
||||
LIGHT_GRAY = (160, 160, 180)
|
||||
WHITE = (255, 255, 255)
|
||||
GREEN = (0, 255, 0)
|
||||
RED = (255, 100, 100)
|
||||
YELLOW = (255, 255, 0)
|
||||
BLUE = (10, 40, 80)
|
||||
CYAN = (0, 255, 255)
|
||||
SONAR_BLIP = (0, 255, 180)
|
||||
|
||||
# Fonts
|
||||
font = pygame.font.SysFont("consolas", 14)
|
||||
|
||||
# Submarine state
|
||||
sub_x = 500
|
||||
sub_depth = 100.0
|
||||
speed = 0.0
|
||||
heading = 0.0
|
||||
|
||||
# Terrain
|
||||
terrain_width = 5000
|
||||
seafloor = []
|
||||
def generate_seafloor():
|
||||
y = 300
|
||||
for _ in range(terrain_width):
|
||||
y += random.uniform(-20, 20)
|
||||
y = max(100, min(500, y))
|
||||
seafloor.append(y)
|
||||
generate_seafloor()
|
||||
|
||||
# Sonar system
|
||||
sonar_angle = 0
|
||||
sonar_radius = 120
|
||||
sonar_center = (WIDTH - 180, HEIGHT - 180)
|
||||
sonar_speed = 90
|
||||
blips = []
|
||||
sonar_mode = "active" # can be 'active' or 'passive'
|
||||
|
||||
# Player system
|
||||
interior_rect = pygame.Rect(50, 50, 600, 200)
|
||||
pilot_seat = pygame.Rect(90, 210, 30, 30)
|
||||
player = pygame.Rect(150, 210, 20, 40)
|
||||
player_vel = 100
|
||||
sitting = False
|
||||
|
||||
# Personal stats
|
||||
oxygen = 100.0
|
||||
stamina = 100.0
|
||||
health = 100.0
|
||||
room_sealed = True
|
||||
|
||||
# Draw gauges
|
||||
def draw_gauge(x, y, radius, label, value, min_val, max_val, unit, color):
|
||||
pygame.draw.circle(screen, GRAY, (x, y), radius)
|
||||
pygame.draw.circle(screen, BLUE, (x, y), radius - 6)
|
||||
for i in range(11):
|
||||
angle = math.radians(135 - i * 27)
|
||||
dx = math.cos(angle) * (radius - 10)
|
||||
dy = math.sin(angle) * (radius - 10)
|
||||
pygame.draw.line(screen, WHITE, (x + int(dx), y + int(dy)), (x + int(dx / 2), y + int(dy / 2)), 2)
|
||||
pct = (value - min_val) / (max_val - min_val)
|
||||
angle = math.radians(135 - pct * 270)
|
||||
dx = math.cos(angle) * (radius - 15)
|
||||
dy = math.sin(angle) * (radius - 15)
|
||||
pygame.draw.line(screen, color, (x, y), (x + int(dx), y + int(dy)), 4)
|
||||
screen.blit(font.render(label, True, WHITE), (x - 25, y - radius + 5))
|
||||
screen.blit(font.render(f"{value:.0f} {unit}", True, WHITE), (x - 30, y + radius - 20))
|
||||
|
||||
# Main loop
|
||||
running = True
|
||||
while running:
|
||||
dt = clock.tick(FPS) / 1000.0
|
||||
now = pygame.time.get_ticks()
|
||||
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
running = False
|
||||
elif event.type == pygame.KEYDOWN:
|
||||
if event.key == pygame.K_e and not sitting and player.colliderect(pilot_seat):
|
||||
sitting = True
|
||||
player.topleft = pilot_seat.topleft
|
||||
elif event.key == pygame.K_ESCAPE and sitting:
|
||||
sitting = False
|
||||
elif event.key == pygame.K_TAB:
|
||||
sonar_mode = "passive" if sonar_mode == "active" else "active"
|
||||
|
||||
keys = pygame.key.get_pressed()
|
||||
|
||||
if not sitting:
|
||||
if keys[pygame.K_a] or keys[pygame.K_LEFT]: player.x -= int(player_vel * dt)
|
||||
if keys[pygame.K_d] or keys[pygame.K_RIGHT]: player.x += int(player_vel * dt)
|
||||
player.x = max(interior_rect.left, min(interior_rect.right - player.width, player.x))
|
||||
if not room_sealed:
|
||||
oxygen = max(0, oxygen - 10 * dt)
|
||||
else:
|
||||
if keys[pygame.K_w]: speed += 20 * dt
|
||||
if keys[pygame.K_s]: speed -= 20 * dt
|
||||
if keys[pygame.K_q]: heading -= 90 * dt
|
||||
if keys[pygame.K_e]: heading += 90 * dt
|
||||
if keys[pygame.K_r]: sub_depth -= 50 * dt
|
||||
if keys[pygame.K_f]: sub_depth += 50 * dt
|
||||
|
||||
# Clamp values
|
||||
speed = max(0, min(speed, 30))
|
||||
sub_depth = max(0, min(sub_depth, 500))
|
||||
heading %= 360
|
||||
sub_x += math.cos(math.radians(heading)) * speed * dt
|
||||
|
||||
# Sonar logic
|
||||
sonar_angle += sonar_speed * dt
|
||||
sonar_angle %= 360
|
||||
sweep_radians = math.radians(sonar_angle)
|
||||
dx = math.cos(sweep_radians)
|
||||
dy = math.sin(sweep_radians)
|
||||
if sonar_mode == "active":
|
||||
for i in range(20, sonar_radius):
|
||||
ray_x = sub_x + dx * i
|
||||
ray_y = sub_depth + dy * i
|
||||
if 0 <= int(ray_x) < len(seafloor):
|
||||
if ray_y >= seafloor[int(ray_x)]:
|
||||
blips.append((sonar_angle, i, now))
|
||||
break
|
||||
elif sonar_mode == "passive":
|
||||
# Passive sonar "listens" and picks up nearby terrain noise randomly
|
||||
for _ in range(2):
|
||||
angle = random.uniform(0, 360)
|
||||
distance = random.randint(30, sonar_radius)
|
||||
rad = math.radians(angle)
|
||||
px = sub_x + math.cos(rad) * distance
|
||||
py = sub_depth + math.sin(rad) * distance
|
||||
if 0 <= int(px) < len(seafloor) and py >= seafloor[int(px)]:
|
||||
blips.append((angle, distance, now))
|
||||
|
||||
# Clean expired blips
|
||||
blips = [(a, d, t) for a, d, t in blips if now - t < BLIP_FADE_TIME]
|
||||
|
||||
# Draw everything
|
||||
screen.fill(BLACK)
|
||||
pygame.draw.rect(screen, DARK_GRAY, interior_rect, border_radius=15)
|
||||
pygame.draw.rect(screen, LIGHT_GRAY, pilot_seat, border_radius=5)
|
||||
pygame.draw.rect(screen, (220, 220, 255), player)
|
||||
pygame.draw.line(screen, GRAY, (interior_rect.left + 10, interior_rect.bottom), (interior_rect.right - 10, interior_rect.bottom), 2)
|
||||
pygame.draw.circle(screen, GRAY, (pilot_seat.centerx, pilot_seat.top - 10), 4)
|
||||
|
||||
# UI overlays
|
||||
if sitting:
|
||||
draw_gauge(100, HEIGHT - 120, 60, "Depth", sub_depth, 0, 500, "m", GREEN)
|
||||
draw_gauge(220, HEIGHT - 120, 60, "Speed", speed, 0, 30, "kt", RED)
|
||||
draw_gauge(340, HEIGHT - 120, 60, "Heading", heading, 0, 360, "°", YELLOW)
|
||||
else:
|
||||
draw_gauge(100, HEIGHT - 120, 60, "O₂", oxygen, 0, 100, "%", GREEN)
|
||||
draw_gauge(220, HEIGHT - 120, 60, "Stamina", stamina, 0, 100, "%", YELLOW)
|
||||
draw_gauge(340, HEIGHT - 120, 60, "Health", health, 0, 100, "%", RED)
|
||||
|
||||
# Sonar
|
||||
pygame.draw.circle(screen, (0, 60, 100), sonar_center, sonar_radius)
|
||||
pygame.draw.circle(screen, CYAN, sonar_center, sonar_radius, 2)
|
||||
for angle, dist, timestamp in blips:
|
||||
fade = max(0, min(255, 255 - ((now - timestamp) / BLIP_FADE_TIME) * 255))
|
||||
rad = math.radians(angle)
|
||||
bx = sonar_center[0] + math.cos(rad) * dist
|
||||
by = sonar_center[1] + math.sin(rad) * dist
|
||||
surf = pygame.Surface((4, 4), pygame.SRCALPHA)
|
||||
pygame.draw.circle(surf, SONAR_BLIP + (int(fade),), (2, 2), 2)
|
||||
screen.blit(surf, (bx - 2, by - 2))
|
||||
end_x = sonar_center[0] + math.cos(sweep_radians) * sonar_radius
|
||||
end_y = sonar_center[1] + math.sin(sweep_radians) * sonar_radius
|
||||
pygame.draw.line(screen, CYAN, sonar_center, (end_x, end_y), 2)
|
||||
pygame.draw.circle(screen, CYAN, sonar_center, 3)
|
||||
mode_text = font.render(f"Sonar: {sonar_mode.upper()} (TAB)", True, WHITE)
|
||||
screen.blit(mode_text, (sonar_center[0] - 60, sonar_center[1] + sonar_radius + 10))
|
||||
|
||||
# Prompts
|
||||
if not sitting and player.colliderect(pilot_seat):
|
||||
msg = font.render("Press E to sit", True, WHITE)
|
||||
screen.blit(msg, (pilot_seat.x, pilot_seat.y - 20))
|
||||
elif sitting:
|
||||
msg = font.render("Press ESC to stand", True, WHITE)
|
||||
screen.blit(msg, (pilot_seat.x, pilot_seat.y - 20))
|
||||
|
||||
pygame.display.flip()
|
||||
|
||||
pygame.quit()
|
||||
sys.exit()
|
Loading…
Reference in New Issue
Block a user