| import pygame |
| import json |
| import time |
| import math |
|
|
| |
| WIDTH, HEIGHT = 800, 600 |
| FPS = 60 |
| WHITE = (255, 255, 255) |
| CYAN = (0, 255, 204) |
| PINK = (255, 0, 85) |
| GOLD = (255, 215, 0) |
| BLACK = (5, 5, 5) |
|
|
| pygame.init() |
| screen = pygame.display.set_mode((WIDTH, HEIGHT)) |
| clock = pygame.time.Clock() |
| font = pygame.font.SysFont("Courier New", 18, bold=True) |
|
|
| |
| class GameState: |
| def __init__(self): |
| self.current_level = 0 |
| self.jumps = 0 |
| self.pb = self.load_pb() |
| self.editing = False |
| self.loading = False |
| self.levels = self.load_levels() |
| self.reset_player() |
|
|
| def reset_player(self): |
| self.px, self.py = 50, 500 |
| self.vx, self.vy = 0, 0 |
| self.grounded = False |
|
|
| def load_pb(self): |
| try: |
| with open("pb.txt", "r") as f: return int(f.read()) |
| except: return float('inf') |
|
|
| def save_pb(self): |
| if self.jumps < self.pb: |
| with open("pb.txt", "w") as f: f.write(str(self.jumps)) |
| self.pb = self.jumps |
|
|
| def load_levels(self): |
| try: |
| with open("levels.json", "r") as f: return json.load(f) |
| except: |
| |
| return [[{"rect": [0, 550, 200, 20], "type": "normal"}, |
| {"rect": [720, 100, 50, 50], "type": "goal"}]] |
|
|
| def save_levels(self): |
| with open("levels.json", "w") as f: json.dump(self.levels, f) |
|
|
| state = GameState() |
|
|
| |
| def draw_tesseract_loader(): |
| start_time = time.time() |
| angle = 0 |
| while time.time() - start_time < 3: |
| screen.fill(BLACK) |
| angle += 0.05 |
| center = (WIDTH // 2, HEIGHT // 2) |
| |
| |
| s1 = 40 + math.sin(angle) * 10 |
| s2 = 80 |
| |
| for s in [s1, s2]: |
| pts = [ |
| (center[0]-s, center[1]-s), (center[0]+s, center[1]-s), |
| (center[0]+s, center[1]+s), (center[0]-s, center[1]+s) |
| ] |
| pygame.draw.lines(screen, CYAN, True, pts, 2) |
| |
| |
| for i in [-1, 1]: |
| for j in [-1, 1]: |
| pygame.draw.line(screen, CYAN, (center[0]+i*s1, center[1]+j*s1), (center[0]+i*s2, center[1]+j*s2), 1) |
|
|
| txt = font.render("STABILIZING DIMENSIONS...", True, CYAN) |
| screen.blit(txt, (WIDTH//2 - 120, HEIGHT//2 + 120)) |
| pygame.display.flip() |
| clock.tick(FPS) |
|
|
| |
| running = True |
| new_plat_start = None |
| current_type = "normal" |
|
|
| while running: |
| screen.fill(BLACK) |
| dt = clock.tick(FPS) |
| |
| for event in pygame.event.get(): |
| if event.type == pygame.QUIT: |
| running = False |
| |
| |
| if event.type == pygame.KEYDOWN: |
| if event.key == pygame.K_e: state.editing = not state.editing |
| if event.key == pygame.K_s and state.editing: state.save_levels() |
| if event.key == pygame.K_n and state.editing: |
| state.levels.append([{"rect": [0, 550, 200, 20], "type": "normal"}]) |
| state.current_level = len(state.levels) - 1 |
| |
| if state.editing: |
| if event.type == pygame.MOUSEBUTTONDOWN: |
| if event.button == 1: new_plat_start = event.pos |
| if event.button == 3: |
| types = ["normal", "bouncy", "goal"] |
| current_type = types[(types.index(current_type) + 1) % 3] |
| if event.type == pygame.MOUSEBUTTONUP and event.button == 1: |
| end_x, end_y = event.pos |
| x, y = min(new_plat_start[0], end_x), min(new_plat_start[1], end_y) |
| w, h = abs(new_plat_start[0] - end_x), abs(new_plat_start[1] - end_y) |
| state.levels[state.current_level].append({"rect": [x, y, w, h], "type": current_type}) |
| new_plat_start = None |
|
|
| if not state.editing: |
| |
| keys = pygame.key.get_pressed() |
| if keys[pygame.K_a] or keys[pygame.K_LEFT]: state.vx -= 0.8 |
| if keys[pygame.K_d] or keys[pygame.K_RIGHT]: state.vx += 0.8 |
| if (keys[pygame.K_SPACE] or keys[pygame.K_UP] or keys[pygame.K_w]) and state.grounded: |
| state.vy = -11 |
| state.jumps += 1 |
| state.grounded = False |
|
|
| state.vy += 0.5 |
| state.vx *= 0.85 |
| state.px += state.vx |
| state.py += state.vy |
|
|
| |
| if state.px < 0: state.px = WIDTH |
| if state.px > WIDTH: state.px = 0 |
| if state.py > HEIGHT: state.reset_player() |
|
|
| |
| state.grounded = False |
| for p in state.levels[state.current_level]: |
| r = pygame.Rect(p["rect"]) |
| player_rect = pygame.Rect(state.px - 10, state.py - 10, 20, 20) |
| if player_rect.colliderect(r): |
| if p["type"] == "goal": |
| state.save_pb() |
| if state.current_level < len(state.levels) - 1: |
| state.current_level += 1 |
| draw_tesseract_loader() |
| state.reset_player() |
| else: |
| print("All Levels Clear!") |
| running = False |
| elif state.vy > 0 and state.py < r.top + 10: |
| state.py = r.top - 10 |
| state.vy *= -1.4 if p["type"] == "bouncy" else -0.5 |
| if abs(state.vy) < 1: |
| state.vy = 0 |
| state.grounded = True |
|
|
| |
| |
| for p in state.levels[state.current_level]: |
| color = CYAN if p["type"] == "normal" else (PINK if p["type"] == "bouncy" else GOLD) |
| pygame.draw.rect(screen, color, p["rect"]) |
| |
| |
| pygame.draw.circle(screen, WHITE, (int(state.px), int(state.py)), 10) |
|
|
| |
| mode_txt = "EDITOR MODE (S: Save, R-Click: Change Type)" if state.editing else f"LEVEL: {state.current_level+1} | JUMPS: {state.jumps}" |
| pb_txt = f"PB: {state.pb if state.pb != float('inf') else '--'}" |
| screen.blit(font.render(mode_txt, True, WHITE), (10, 10)) |
| screen.blit(font.render(pb_txt, True, WHITE), (10, 35)) |
| if state.editing: |
| screen.blit(font.render(f"TYPE: {current_type.upper()}", True, GOLD), (10, 60)) |
|
|
| pygame.display.flip() |
|
|
| pygame.quit() |