Guest User

Untitled

a guest
Sep 12th, 2026
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 22.94 KB | None | 0 0
  1. import json
  2. import math
  3. import os
  4. import random
  5.  
  6. import pygame
  7.  
  8. pygame.init()
  9.  
  10. # =========================
  11. # SCREEN
  12. # =========================
  13.  
  14. SCREEN_WIDTH = 1000
  15. SCREEN_HEIGHT = 600
  16.  
  17. screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
  18. pygame.display.set_caption("Dragon Adventure")
  19. clock = pygame.time.Clock()
  20.  
  21. # =========================
  22. # COLORS
  23. # =========================
  24.  
  25. SKY_BLUE = (135, 206, 235)
  26. OCEAN_BLUE = (35, 145, 210)
  27. SAND = (238, 218, 170)
  28. GRASS = (80, 170, 80)
  29. WHITE = (255, 255, 255)
  30. BLACK = (20, 20, 20)
  31. GOLD = (255, 215, 0)
  32. ENERGY_BLUE = (80, 200, 255)
  33. DARK_GRAY = (50, 50, 50)
  34. GRAY = (90, 90, 90)
  35. RED = (200, 60, 60)
  36. GREEN = (60, 180, 80)
  37.  
  38. # =========================
  39. # WORLD
  40. # =========================
  41.  
  42. WORLD_WIDTH = 2400
  43. WORLD_HEIGHT = 900
  44.  
  45. # =========================
  46. # STORMFIN IMAGE
  47. # =========================
  48.  
  49. IMAGE_PATH = r"C:\Users\johns\New folder\anime_art_of_Create_a_highly_d.png"
  50.  
  51. stormfin_image = None
  52.  
  53. if os.path.exists(IMAGE_PATH):
  54.     try:
  55.         stormfin_image = pygame.image.load(IMAGE_PATH).convert_alpha()
  56.     except pygame.error:
  57.         stormfin_image = None
  58.  
  59. # =========================
  60. # ALPHA PITY
  61. # =========================
  62.  
  63. ALPHA_CHANCE = 500
  64. ALPHA_PITY_LIMIT = 1000
  65. alpha_pity = 0
  66.  
  67. # =========================
  68. # STORMFIN GENERATION
  69. # =========================
  70. def generate_stormfin():
  71.     global alpha_pity
  72.  
  73.     # Guaranteed Alpha after 1000 failed rolls
  74.     if alpha_pity >= ALPHA_PITY_LIMIT:
  75.         alpha_pity = 0
  76.         return "Alpha"
  77.  
  78.     # Normal 1 in 500 Alpha chance
  79.     alpha_roll = random.randint(1, ALPHA_CHANCE)
  80.  
  81.     if alpha_roll == 389:
  82.         alpha_pity = 0
  83.         return "Alpha"
  84.  
  85.     # Failed Alpha roll
  86.     alpha_pity += 1
  87.  
  88.     # 50/50 Male or Female
  89.     sex_roll = random.randint(1, 2)
  90.  
  91.     if sex_roll == 1:
  92.         return "Male"
  93.     return "Female"
  94.  
  95.  
  96. stormfin_type = generate_stormfin()
  97.  
  98. # =========================
  99. # STORMFIN SIZE
  100. # =========================
  101.  
  102.  
  103. def get_stormfin_size(stormfin_type):
  104.     if stormfin_type == "Male":
  105.         return 100
  106.     if stormfin_type == "Female":
  107.         return 260
  108.     return 180
  109.  
  110.  
  111. stormfin_size = get_stormfin_size(stormfin_type)
  112.  
  113. # =========================
  114. # STORMFIN SPEED
  115. # =========================
  116.  
  117.  
  118. def get_stormfin_speed(stormfin_type):
  119.     if stormfin_type == "Male":
  120.         return 10
  121.     if stormfin_type == "Female":
  122.         return 2.5
  123.     return 5
  124.  
  125.  
  126. player_speed = get_stormfin_speed(stormfin_type)
  127.  
  128. # Sprint is exactly twice normal speed
  129. sprint_speed = player_speed * 2
  130.  
  131. # =========================
  132. # SPRINT ENERGY
  133. # =========================
  134.  
  135. SPRINT_ENERGY_COST = 1
  136. SPRINT_DRAIN_FRAMES = 20
  137. sprint_frame_counter = 0
  138.  
  139. # =========================
  140. # LIGHTNING RANGE
  141. # =========================
  142.  
  143. BASE_LIGHTNING_RANGE = 300
  144.  
  145.  
  146. def get_lightning_range(stormfin_type):
  147.     if stormfin_type == "Male":
  148.         return BASE_LIGHTNING_RANGE * 0.5
  149.     if stormfin_type == "Female":
  150.         return BASE_LIGHTNING_RANGE * 2
  151.     return BASE_LIGHTNING_RANGE
  152.  
  153.  
  154. lightning_range = get_lightning_range(stormfin_type)
  155.  
  156. # =========================
  157. # LIGHTNING ENERGY COST
  158. # =========================
  159.  
  160.  
  161. def get_lightning_cost(stormfin_type):
  162.     if stormfin_type == "Male":
  163.         return 5
  164.     if stormfin_type == "Female":
  165.         return 20
  166.     return 10
  167.  
  168.  
  169. lightning_cost = get_lightning_cost(stormfin_type)
  170.  
  171. # =========================
  172. # PLAYER
  173. # =========================
  174.  
  175. player_x = 1200
  176. player_y = 475
  177. facing_direction = 1
  178. jumping = False
  179. jump_velocity = 0
  180. gravity = 0.6
  181. jump_strength = 12
  182.  
  183. # =========================
  184. # ENERGY
  185. # =========================
  186.  
  187. MAX_ENERGY = 100
  188. energy = MAX_ENERGY
  189. ENERGY_REGEN_TIME = 2000
  190. last_energy_regen = pygame.time.get_ticks()
  191.  
  192. # =========================
  193. # ATTACK
  194. # =========================
  195.  
  196. ATTACK_DURATION = 150
  197. attacking = False
  198. attack_start_time = 0
  199.  
  200. # =========================
  201. # SAVE / LOAD
  202. # =========================
  203.  
  204. SAVE_FILE = "stormfin_save.json"
  205.  
  206.  
  207. def save_game():
  208.     data = {
  209.         "stormfin_type": stormfin_type,
  210.         "x": player_x,
  211.         "y": player_y,
  212.         "energy": energy,
  213.         "facing_direction": facing_direction,
  214.         "jumping": jumping,
  215.         "jump_velocity": jump_velocity,
  216.         "alpha_pity": alpha_pity,
  217.     }
  218.  
  219.     with open(SAVE_FILE, "w") as file:
  220.         json.dump(data, file, indent=4)
  221.  
  222.     print("Game saved.")
  223.  
  224.  
  225. def load_game():
  226.     global stormfin_type
  227.     global player_x
  228.     global player_y
  229.     global energy
  230.     global facing_direction
  231.     global jumping
  232.     global jump_velocity
  233.     global stormfin_size
  234.     global player_speed
  235.     global sprint_speed
  236.     global lightning_range
  237.     global lightning_cost
  238.     global sprint_frame_counter
  239.     global last_energy_regen
  240.     global alpha_pity
  241.  
  242.     if not os.path.exists(SAVE_FILE):
  243.         print("No save file found.")
  244.         return
  245.  
  246.     with open(SAVE_FILE, "r") as file:
  247.         data = json.load(file)
  248.  
  249.     stormfin_type = data["stormfin_type"]
  250.     player_x = data["x"]
  251.     player_y = data["y"]
  252.     energy = data["energy"]
  253.     facing_direction = data["facing_direction"]
  254.     jumping = data["jumping"]
  255.     jump_velocity = data["jump_velocity"]
  256.  
  257.     # Older save files may not have this
  258.     alpha_pity = data.get("alpha_pity", 0)
  259.  
  260.     stormfin_size = get_stormfin_size(stormfin_type)
  261.     player_speed = get_stormfin_speed(stormfin_type)
  262.     sprint_speed = player_speed * 2
  263.     lightning_range = get_lightning_range(stormfin_type)
  264.     lightning_cost = get_lightning_cost(stormfin_type)
  265.     sprint_frame_counter = 0
  266.     last_energy_regen = pygame.time.get_ticks()
  267.  
  268.     print("Game loaded.")
  269.  
  270.  
  271. # =========================
  272. # ISLAND
  273. # =========================
  274.  
  275. SAND_CENTER_X = 1200
  276. SAND_CENTER_Y = 500
  277. SAND_RADIUS_X = 950
  278. SAND_RADIUS_Y = 260
  279. GRASS_CENTER_X = 1200
  280. GRASS_CENTER_Y = 475
  281. GRASS_RADIUS_X = 850
  282. GRASS_RADIUS_Y = 220
  283.  
  284.  
  285. def point_inside_ellipse(x, y, center_x, center_y, radius_x, radius_y):
  286.     if radius_x == 0 or radius_y == 0:
  287.         return False
  288.  
  289.     value = ((x - center_x) ** 2) / (radius_x**2) + ((y - center_y) ** 2) / (
  290.         radius_y**2
  291.     )
  292.     return value <= 1
  293.  
  294.  
  295. def point_inside_island(x, y):
  296.     sand = point_inside_ellipse(
  297.         x,
  298.         y,
  299.         SAND_CENTER_X,
  300.         SAND_CENTER_Y,
  301.         SAND_RADIUS_X,
  302.         SAND_RADIUS_Y,
  303.     )
  304.     grass = point_inside_ellipse(
  305.         x,
  306.         y,
  307.         GRASS_CENTER_X,
  308.         GRASS_CENTER_Y,
  309.         GRASS_RADIUS_X,
  310.         GRASS_RADIUS_Y,
  311.     )
  312.     return sand or grass
  313.  
  314.  
  315. def stormfin_inside_island(x, y):
  316.     body_radius = stormfin_size * 0.25
  317.     points = [
  318.         (x, y),
  319.         (x - body_radius, y),
  320.         (x + body_radius, y),
  321.         (x, y - body_radius),
  322.         (x, y + body_radius),
  323.     ]
  324.  
  325.     for point_x, point_y in points:
  326.         if not point_inside_island(point_x, point_y):
  327.             return False
  328.  
  329.     return True
  330.  
  331.  
  332. # =========================
  333. # DECORATIONS
  334. # =========================
  335.  
  336. rocks = [
  337.     (300, 500),
  338.     (600, 360),
  339.     (900, 570),
  340.     (1300, 350),
  341.     (1600, 580),
  342.     (1900, 390),
  343.     (2150, 500),
  344. ]
  345.  
  346. trees = [
  347.     (450, 420),
  348.     (750, 470),
  349.     (1050, 400),
  350.     (1450, 450),
  351.     (1750, 430),
  352.     (2050, 470),
  353. ]
  354.  
  355. bushes = [
  356.     (350, 430),
  357.     (850, 520),
  358.     (1150, 500),
  359.     (1550, 390),
  360.     (1850, 520),
  361.     (2200, 440),
  362. ]
  363.  
  364. # =========================
  365. # DRAW ENVIRONMENT
  366. # =========================
  367.  
  368.  
  369. def draw_environment(camera_x, camera_y):
  370.     screen.fill(SKY_BLUE)
  371.  
  372.     # Ocean
  373.     pygame.draw.rect(
  374.         screen,
  375.         OCEAN_BLUE,
  376.         (-camera_x, 300 - camera_y, WORLD_WIDTH, WORLD_HEIGHT),
  377.     )
  378.  
  379.     # Ocean waves
  380.     for x in range(0, WORLD_WIDTH, 80):
  381.         screen_x = x - camera_x
  382.         pygame.draw.arc(
  383.             screen,
  384.             (180, 225, 245),
  385.             (screen_x, 320 - camera_y, 60, 20),
  386.             math.pi,
  387.             math.pi * 2,
  388.             2,
  389.         )
  390.  
  391.     # Sand
  392.     sand_rect = pygame.Rect(
  393.         SAND_CENTER_X - SAND_RADIUS_X - camera_x,
  394.         SAND_CENTER_Y - SAND_RADIUS_Y - camera_y,
  395.         SAND_RADIUS_X * 2,
  396.         SAND_RADIUS_Y * 2,
  397.     )
  398.     pygame.draw.ellipse(screen, SAND, sand_rect)
  399.  
  400.     # Grass
  401.     grass_rect = pygame.Rect(
  402.         GRASS_CENTER_X - GRASS_RADIUS_X - camera_x,
  403.         GRASS_CENTER_Y - GRASS_RADIUS_Y - camera_y,
  404.         GRASS_RADIUS_X * 2,
  405.         GRASS_RADIUS_Y * 2,
  406.     )
  407.     pygame.draw.ellipse(screen, GRASS, grass_rect)
  408.  
  409.     # Rocks
  410.     for rock_x, rock_y in rocks:
  411.         if not point_inside_island(rock_x, rock_y):
  412.             continue
  413.  
  414.         screen_x = rock_x - camera_x
  415.         screen_y = rock_y - camera_y
  416.         pygame.draw.circle(
  417.             screen,
  418.             (100, 100, 100),
  419.             (int(screen_x), int(screen_y)),
  420.             18,
  421.         )
  422.  
  423.     # Trees
  424.     for tree_x, tree_y in trees:
  425.         if not point_inside_island(tree_x, tree_y):
  426.             continue
  427.  
  428.         screen_x = tree_x - camera_x
  429.         screen_y = tree_y - camera_y
  430.         pygame.draw.rect(
  431.             screen,
  432.             (100, 70, 35),
  433.             (int(screen_x - 8), int(screen_y), 16, 45),
  434.         )
  435.         pygame.draw.circle(
  436.             screen,
  437.             (35, 120, 45),
  438.             (int(screen_x), int(screen_y - 15)),
  439.             30,
  440.         )
  441.  
  442.     # Bushes
  443.     for bush_x, bush_y in bushes:
  444.         if not point_inside_island(bush_x, bush_y):
  445.             continue
  446.  
  447.         screen_x = bush_x - camera_x
  448.         screen_y = bush_y - camera_y
  449.         pygame.draw.circle(
  450.             screen,
  451.             (40, 130, 50),
  452.             (int(screen_x - 12), int(screen_y)),
  453.             18,
  454.         )
  455.         pygame.draw.circle(
  456.             screen,
  457.             (45, 145, 55),
  458.             (int(screen_x + 8), int(screen_y - 5)),
  459.             20,
  460.         )
  461.         pygame.draw.circle(
  462.             screen,
  463.             (35, 120, 45),
  464.             (int(screen_x + 20), int(screen_y + 3)),
  465.             15,
  466.         )
  467.  
  468.  
  469. # =========================
  470. # DRAW STORMFIN
  471. # =========================
  472.  
  473.  
  474. def draw_stormfin(camera_x, camera_y):
  475.     screen_x = int(player_x - camera_x)
  476.     screen_y = int(player_y - camera_y)
  477.  
  478.     if stormfin_image is not None:
  479.         scaled_image = pygame.transform.smoothscale(
  480.             stormfin_image,
  481.             (stormfin_size, stormfin_size),
  482.         )
  483.         image_rect = scaled_image.get_rect(center=(screen_x, screen_y))
  484.         screen.blit(scaled_image, image_rect)
  485.     else:
  486.         body_color = (20, 35, 90)
  487.         fur_color = (45, 80, 180)
  488.  
  489.         pygame.draw.ellipse(
  490.             screen,
  491.             body_color,
  492.             (
  493.                 screen_x - stormfin_size // 2,
  494.                 screen_y - stormfin_size // 2,
  495.                 stormfin_size,
  496.                 stormfin_size,
  497.             ),
  498.         )
  499.  
  500.         # Ears
  501.         ear_size = max(10, stormfin_size // 6)
  502.         pygame.draw.circle(
  503.             screen,
  504.             fur_color,
  505.             (
  506.                 screen_x - stormfin_size // 4,
  507.                 screen_y - stormfin_size // 3,
  508.             ),
  509.             ear_size,
  510.         )
  511.         pygame.draw.circle(
  512.             screen,
  513.             fur_color,
  514.             (
  515.                 screen_x + stormfin_size // 4,
  516.                 screen_y - stormfin_size // 3,
  517.             ),
  518.             ear_size,
  519.         )
  520.  
  521.         # Golden eyes
  522.         eye_size = max(5, stormfin_size // 12)
  523.         pygame.draw.circle(
  524.             screen,
  525.             GOLD,
  526.             (
  527.                 screen_x - stormfin_size // 7,
  528.                 screen_y - stormfin_size // 10,
  529.             ),
  530.             eye_size,
  531.         )
  532.         pygame.draw.circle(
  533.             screen,
  534.             GOLD,
  535.             (
  536.                 screen_x + stormfin_size // 7,
  537.                 screen_y - stormfin_size // 10,
  538.             ),
  539.             eye_size,
  540.         )
  541.  
  542.  
  543. # =========================
  544. # LIGHTNING
  545. # =========================
  546.  
  547.  
  548. def draw_lightning(camera_x, camera_y):
  549.     if not attacking:
  550.         return
  551.  
  552.     start_x = player_x + facing_direction * 25
  553.     start_y = player_y - 10
  554.     end_x = start_x + facing_direction * lightning_range
  555.     end_y = start_y
  556.  
  557.     screen_start_x = int(start_x - camera_x)
  558.     screen_start_y = int(start_y - camera_y)
  559.     screen_end_x = int(end_x - camera_x)
  560.     screen_end_y = int(end_y - camera_y)
  561.  
  562.     pygame.draw.line(
  563.         screen,
  564.         ENERGY_BLUE,
  565.         (screen_start_x, screen_start_y),
  566.         (screen_end_x, screen_end_y),
  567.         8,
  568.     )
  569.     pygame.draw.line(
  570.         screen,
  571.         WHITE,
  572.         (screen_start_x, screen_start_y),
  573.         (screen_end_x, screen_end_y),
  574.         3,
  575.     )
  576.  
  577.     branch_length = lightning_range * 0.12
  578.     branch_points = [0.25, 0.50, 0.75]
  579.  
  580.     for percentage in branch_points:
  581.         branch_x = start_x + (end_x - start_x) * percentage
  582.         branch_y = start_y
  583.         branch_direction = random.choice([-1, 1])
  584.  
  585.         pygame.draw.line(
  586.             screen,
  587.             ENERGY_BLUE,
  588.             (int(branch_x - camera_x), int(branch_y - camera_y)),
  589.             (
  590.                 int(
  591.                     branch_x
  592.                     - camera_x
  593.                     + random.randint(5, int(branch_length)) * facing_direction
  594.                 ),
  595.                 int(
  596.                     branch_y
  597.                     - camera_y
  598.                     + branch_direction * random.randint(10, int(branch_length))
  599.                 ),
  600.             ),
  601.             3,
  602.         )
  603.  
  604.  
  605. # =========================
  606. # UI
  607. # =========================
  608.  
  609. font = pygame.font.SysFont(None, 28)
  610. small_font = pygame.font.SysFont(None, 22)
  611.  
  612.  
  613. def draw_ui():
  614.     # Stormfin type
  615.     type_text = font.render(f"Stormfin: {stormfin_type}", True, WHITE)
  616.     screen.blit(type_text, (20, 20))
  617.  
  618.     # Energy
  619.     energy_text = font.render(f"Energy: {energy}/100", True, WHITE)
  620.     screen.blit(energy_text, (20, 50))
  621.  
  622.     # Energy bar
  623.     pygame.draw.rect(screen, BLACK, (20, 80, 200, 20))
  624.     pygame.draw.rect(
  625.         screen,
  626.         ENERGY_BLUE,
  627.         (20, 80, int(200 * (energy / MAX_ENERGY)), 20),
  628.     )
  629.  
  630.     # Lightning range
  631.     range_text = small_font.render(
  632.         f"Lightning range: {int(lightning_range)}", True, WHITE
  633.     )
  634.     screen.blit(range_text, (20, 110))
  635.  
  636.     # Lightning cost
  637.     cost_text = small_font.render(f"Lightning cost: {lightning_cost}", True, WHITE)
  638.     screen.blit(cost_text, (20, 135))
  639.  
  640.     # Movement speed
  641.     speed_text = small_font.render(f"Speed: {player_speed}", True, WHITE)
  642.     screen.blit(speed_text, (20, 160))
  643.  
  644.     # Sprint speed
  645.     sprint_text = small_font.render(f"Sprint speed: {sprint_speed}", True, WHITE)
  646.     screen.blit(sprint_text, (20, 185))
  647.  
  648.     # Alpha pity
  649.     pity_text = small_font.render(
  650.         f"Alpha pity: {alpha_pity}/{ALPHA_PITY_LIMIT}", True, GOLD
  651.     )
  652.     screen.blit(pity_text, (20, 210))
  653.  
  654.     # Controls
  655.     controls = [
  656.         "WASD - Move",
  657.         "Shift - Sprint",
  658.         "Space - Jump",
  659.         "E - Lightning",
  660.         "1 - Save",
  661.         "2 - Load",
  662.     ]
  663.  
  664.     y = SCREEN_HEIGHT - 150
  665.     for control in controls:
  666.         text = small_font.render(control, True, WHITE)
  667.         screen.blit(text, (20, y))
  668.         y += 22
  669.  
  670.  
  671. # =========================
  672. # REROLL BUTTON
  673. # =========================
  674.  
  675. reroll_button = pygame.Rect(SCREEN_WIDTH - 150, 20, 120, 40)
  676.  
  677.  
  678. def draw_reroll_button():
  679.     pygame.draw.rect(screen, (70, 70, 70), reroll_button)
  680.     text = small_font.render("Reroll", True, WHITE)
  681.     text_rect = text.get_rect(center=reroll_button.center)
  682.     screen.blit(text, text_rect)
  683.  
  684.  
  685. # =========================
  686. # ALPHA CONFIRMATION
  687. # =========================
  688.  
  689. confirmation_active = False
  690. confirmation_box = pygame.Rect(300, 210, 400, 180)
  691. yes_button = pygame.Rect(350, 320, 120, 45)
  692. no_button = pygame.Rect(530, 320, 120, 45)
  693.  
  694.  
  695. def draw_confirmation():
  696.     # Dark overlay
  697.     overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
  698.     overlay.fill((0, 0, 0, 150))
  699.     screen.blit(overlay, (0, 0))
  700.  
  701.     # Confirmation box
  702.     pygame.draw.rect(screen, DARK_GRAY, confirmation_box)
  703.     pygame.draw.rect(screen, GOLD, confirmation_box, 3)
  704.  
  705.     # Message
  706.     message_1 = small_font.render("Are you sure you want", True, WHITE)
  707.     message_2 = small_font.render("to reroll your Alpha?", True, GOLD)
  708.  
  709.     screen.blit(
  710.         message_1,
  711.         (confirmation_box.centerx - message_1.get_width() // 2, 235),
  712.     )
  713.     screen.blit(
  714.         message_2,
  715.         (confirmation_box.centerx - message_2.get_width() // 2, 265),
  716.     )
  717.  
  718.     # Yes button
  719.     pygame.draw.rect(screen, GREEN, yes_button)
  720.     yes_text = small_font.render("Yes", True, WHITE)
  721.     screen.blit(yes_text, yes_text.get_rect(center=yes_button.center))
  722.  
  723.     # No button
  724.     pygame.draw.rect(screen, RED, no_button)
  725.     no_text = small_font.render("No", True, WHITE)
  726.     screen.blit(no_text, no_text.get_rect(center=no_button.center))
  727.  
  728.  
  729. # =========================
  730. # REROLL STORMFIN
  731. # =========================
  732.  
  733.  
  734. def reroll_stormfin():
  735.     global stormfin_type
  736.     global stormfin_size
  737.     global player_speed
  738.     global sprint_speed
  739.     global lightning_range
  740.     global lightning_cost
  741.     global player_x
  742.     global player_y
  743.     global energy
  744.     global facing_direction
  745.     global jumping
  746.     global jump_velocity
  747.     global sprint_frame_counter
  748.     global last_energy_regen
  749.  
  750.     stormfin_type = generate_stormfin()
  751.     stormfin_size = get_stormfin_size(stormfin_type)
  752.     player_speed = get_stormfin_speed(stormfin_type)
  753.     sprint_speed = player_speed * 2
  754.     lightning_range = get_lightning_range(stormfin_type)
  755.     lightning_cost = get_lightning_cost(stormfin_type)
  756.  
  757.     player_x = 1200
  758.     player_y = 475
  759.     energy = MAX_ENERGY
  760.     facing_direction = 1
  761.     jumping = False
  762.     jump_velocity = 0
  763.     sprint_frame_counter = 0
  764.     last_energy_regen = pygame.time.get_ticks()
  765.  
  766.     print(f"Rerolled: {stormfin_type}")
  767.     print(f"Alpha pity: {alpha_pity}/{ALPHA_PITY_LIMIT}")
  768.  
  769.  
  770. # =========================
  771. # MAIN LOOP
  772. # =========================
  773.  
  774. running = True
  775.  
  776. while running:
  777.     clock.tick(60)
  778.  
  779.     # =========================
  780.     # EVENTS
  781.     # =========================
  782.  
  783.     for event in pygame.event.get():
  784.         if event.type == pygame.QUIT:
  785.             running = False
  786.  
  787.         if event.type == pygame.KEYDOWN:
  788.             # Lightning
  789.             if event.key == pygame.K_e:
  790.                 if energy >= lightning_cost:
  791.                     energy -= lightning_cost
  792.                     attacking = True
  793.                     attack_start_time = pygame.time.get_ticks()
  794.  
  795.             # Jump
  796.             if event.key == pygame.K_SPACE:
  797.                 if not jumping:
  798.                     jumping = True
  799.                     jump_velocity = -jump_strength
  800.  
  801.             # Save
  802.             if event.key == pygame.K_1:
  803.                 save_game()
  804.  
  805.             # Load
  806.             if event.key == pygame.K_2:
  807.                 load_game()
  808.  
  809.         # =========================
  810.         # MOUSE
  811.         # =========================
  812.  
  813.         if event.type == pygame.MOUSEBUTTONDOWN:
  814.             if event.button == 1:
  815.                 # Confirmation is open
  816.                 if confirmation_active:
  817.                     # YES
  818.                     if yes_button.collidepoint(event.pos):
  819.                         confirmation_active = False
  820.                         reroll_stormfin()
  821.  
  822.                     # NO
  823.                     elif no_button.collidepoint(event.pos):
  824.                         confirmation_active = False
  825.  
  826.                 # Normal game
  827.                 else:
  828.                     if reroll_button.collidepoint(event.pos):
  829.                         # Alpha requires confirmation
  830.                         if stormfin_type == "Alpha":
  831.                             confirmation_active = True
  832.                         else:
  833.                             reroll_stormfin()
  834.  
  835.     # =========================
  836.     # ATTACK TIMER
  837.     # =========================
  838.  
  839.     if attacking:
  840.         current_time = pygame.time.get_ticks()
  841.  
  842.         if current_time - attack_start_time >= ATTACK_DURATION:
  843.             attacking = False
  844.  
  845.     # =========================
  846.     # MOVEMENT
  847.     # =========================
  848.  
  849.     keys = pygame.key.get_pressed()
  850.     sprinting = keys[pygame.K_LSHIFT] and energy > 0
  851.  
  852.     # =========================
  853.     # SPRINT ENERGY DRAIN
  854.     # =========================
  855.  
  856.     if sprinting:
  857.         sprint_frame_counter += 1
  858.  
  859.         if sprint_frame_counter >= SPRINT_DRAIN_FRAMES:
  860.             if energy > 0:
  861.                 energy -= SPRINT_ENERGY_COST
  862.  
  863.             sprint_frame_counter = 0
  864.     else:
  865.         sprint_frame_counter = 0
  866.  
  867.     # =========================
  868.     # ENERGY REGEN
  869.     # =========================
  870.  
  871.     current_time = pygame.time.get_ticks()
  872.  
  873.     if not sprinting:
  874.         if current_time - last_energy_regen >= ENERGY_REGEN_TIME:
  875.             if energy < MAX_ENERGY:
  876.                 energy += 1
  877.  
  878.             last_energy_regen = current_time
  879.     else:
  880.         last_energy_regen = current_time
  881.  
  882.     # =========================
  883.     # SPEED
  884.     # =========================
  885.  
  886.     if sprinting:
  887.         speed = sprint_speed
  888.     else:
  889.         speed = player_speed
  890.  
  891.     # =========================
  892.     # MOVEMENT INPUT
  893.     # =========================
  894.  
  895.     move_x = 0
  896.     move_y = 0
  897.  
  898.     if keys[pygame.K_a]:
  899.         move_x -= speed
  900.         facing_direction = -1
  901.  
  902.     if keys[pygame.K_d]:
  903.         move_x += speed
  904.         facing_direction = 1
  905.  
  906.     if keys[pygame.K_w]:
  907.         move_y -= speed
  908.  
  909.     if keys[pygame.K_s]:
  910.         move_y += speed
  911.  
  912.     # Horizontal collision
  913.     new_x = player_x + move_x
  914.  
  915.     if stormfin_inside_island(new_x, player_y):
  916.         player_x = new_x
  917.  
  918.     # Vertical movement
  919.     new_y = player_y + move_y
  920.  
  921.     if stormfin_inside_island(player_x, new_y):
  922.         player_y = new_y
  923.  
  924.     # =========================
  925.     # JUMP PHYSICS
  926.     # =========================
  927.  
  928.     if jumping:
  929.         jump_velocity += gravity
  930.         jump_y = player_y + jump_velocity
  931.  
  932.         if stormfin_inside_island(player_x, jump_y):
  933.             player_y = jump_y
  934.         else:
  935.             jumping = False
  936.             jump_velocity = 0
  937.  
  938.     # =========================
  939.     # CAMERA
  940.     # =========================
  941.  
  942.     camera_x = player_x - SCREEN_WIDTH // 2
  943.     camera_y = player_y - SCREEN_HEIGHT // 2
  944.  
  945.     camera_x = max(0, min(camera_x, WORLD_WIDTH - SCREEN_WIDTH))
  946.     camera_y = max(0, min(camera_y, WORLD_HEIGHT - SCREEN_HEIGHT))
  947.  
  948.     # =========================
  949.     # DRAW
  950.     # =========================
  951.  
  952.     draw_environment(camera_x, camera_y)
  953.     draw_stormfin(camera_x, camera_y)
  954.     draw_lightning(camera_x, camera_y)
  955.     draw_ui()
  956.     draw_reroll_button()
  957.  
  958.     # Confirmation dialog goes last
  959.     # so it appears above everything.
  960.     if confirmation_active:
  961.         draw_confirmation()
  962.  
  963.     pygame.display.flip()
  964.  
  965. pygame.quit()
  966.  
Advertisement
Add Comment
Please, Sign In to add comment