General cleanup and organization.
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 111 KiB |
+351
-257
@@ -7,335 +7,429 @@ pygame.init()
|
|||||||
pygame.mixer.init()
|
pygame.mixer.init()
|
||||||
pygame.joystick.init()
|
pygame.joystick.init()
|
||||||
|
|
||||||
pygame.mixer.music.load("audio_music.mp3")
|
# Constants
|
||||||
pygame.mixer.music.set_volume(0.5)
|
WIDTH, HEIGHT = pygame.display.Info().current_w, pygame.display.Info().current_h
|
||||||
pygame.mixer.music.play(-1)
|
SCREEN_SIZE = (WIDTH, HEIGHT)
|
||||||
|
CAT_INITIAL_SIZE = [160, 160]
|
||||||
screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
|
CAT_MAX_SIZE = [320, 320]
|
||||||
pygame.mouse.set_visible(False)
|
|
||||||
info = pygame.display.Info()
|
|
||||||
WIDTH, HEIGHT = info.current_w, info.current_h
|
|
||||||
|
|
||||||
pygame.display.set_caption("Maguro!")
|
|
||||||
clock = pygame.time.Clock()
|
|
||||||
|
|
||||||
wallpaper = pygame.image.load("wallpaper.jpg").convert()
|
|
||||||
wallpaper = pygame.transform.scale(wallpaper, (WIDTH, HEIGHT))
|
|
||||||
|
|
||||||
CAT_SIZE = [160, 160]
|
|
||||||
SUSHI_SIZE = (50, 50)
|
SUSHI_SIZE = (50, 50)
|
||||||
CLOUD_SIZE = (200, 120)
|
CLOUD_SIZE = (200, 120)
|
||||||
PETAL_SIZE = (30, 30)
|
PETAL_SIZE = (30, 30)
|
||||||
|
GAME_OVER_DELAY = 3000 # ms
|
||||||
|
WASABI_CHANCE = 0.1
|
||||||
|
|
||||||
cat_left_base = pygame.image.load("cat-left.png").convert_alpha()
|
# Helper Functions
|
||||||
cat_right_base = pygame.image.load("cat-right.png").convert_alpha()
|
def quit_game():
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
cat_left = pygame.transform.smoothscale(cat_left_base, CAT_SIZE)
|
|
||||||
cat_right = pygame.transform.smoothscale(cat_right_base, CAT_SIZE)
|
|
||||||
|
|
||||||
sushi_imgs = []
|
class Cat:
|
||||||
for i in [1, 2, 4, 5]:
|
def __init__(self, cat_right_img, pos, speed):
|
||||||
|
self.cat_right_base = cat_right_img # Only right-facing base image
|
||||||
|
self.size = CAT_INITIAL_SIZE.copy()
|
||||||
|
self.speed = speed
|
||||||
|
self.facing = "right"
|
||||||
|
# Prepare the right-facing scaled image
|
||||||
|
self.image_right = pygame.transform.smoothscale(self.cat_right_base, self.size)
|
||||||
|
# Prepare flipped left-facing image
|
||||||
|
self.image_left = pygame.transform.flip(self.image_right, True, False)
|
||||||
|
self.image = self.image_right
|
||||||
|
self.rect = self.image.get_rect()
|
||||||
|
self.rect.centerx, self.rect.bottom = pos
|
||||||
|
self.grow_step = 1
|
||||||
|
|
||||||
|
def update_image(self):
|
||||||
|
if self.facing == "left":
|
||||||
|
# Flip the right image horizontally to face left
|
||||||
|
self.image = pygame.transform.flip(self.image_right, True, False)
|
||||||
|
else:
|
||||||
|
self.image = self.image_right
|
||||||
|
|
||||||
|
def move(self, dx):
|
||||||
|
self.rect.x += dx * self.speed
|
||||||
|
self.rect.x = max(0, min(WIDTH - self.rect.width, self.rect.x))
|
||||||
|
self.rect.bottom = HEIGHT
|
||||||
|
|
||||||
|
def grow(self):
|
||||||
|
# Increase size but clamp
|
||||||
|
self.size[0] = min(self.size[0] + self.grow_step, CAT_MAX_SIZE[0])
|
||||||
|
self.size[1] = min(self.size[1] + self.grow_step, CAT_MAX_SIZE[1])
|
||||||
|
self.image_right = pygame.transform.smoothscale(self.cat_right_base, self.size)
|
||||||
|
self.update_image()
|
||||||
|
# Reset rect to bottom center
|
||||||
|
mid_x = self.rect.centerx
|
||||||
|
self.rect = self.image.get_rect()
|
||||||
|
self.rect.centerx = mid_x
|
||||||
|
self.rect.bottom = HEIGHT
|
||||||
|
|
||||||
|
def draw(self, surface):
|
||||||
|
surface.blit(self.image, self.rect)
|
||||||
|
|
||||||
|
|
||||||
|
class Sushi:
|
||||||
|
def __init__(self, image, pos, wasabi=False, speed=5):
|
||||||
|
self.image = image
|
||||||
|
self.rect = self.image.get_rect(midtop=pos)
|
||||||
|
self.wasabi = wasabi
|
||||||
|
self.speed = speed
|
||||||
|
|
||||||
|
def update(self, dt):
|
||||||
|
self.rect.y += self.speed * dt / 16.67
|
||||||
|
|
||||||
|
def draw(self, surface):
|
||||||
|
surface.blit(self.image, self.rect)
|
||||||
|
|
||||||
|
def off_screen(self):
|
||||||
|
return self.rect.top > HEIGHT
|
||||||
|
|
||||||
|
|
||||||
|
class Cloud:
|
||||||
|
def __init__(self, image, speed_multiplier=1.0):
|
||||||
|
self.image = image
|
||||||
|
self.speed_multiplier = speed_multiplier
|
||||||
|
self.size = self.image.get_size()
|
||||||
|
self.y = 50
|
||||||
|
self.phase = random.uniform(0, 2 * math.pi)
|
||||||
|
self.speed = random.choice([-1.5, 1.5]) * speed_multiplier
|
||||||
|
if self.speed > 0:
|
||||||
|
self.rect = self.image.get_rect(topleft=(-self.size[0], self.y))
|
||||||
|
else:
|
||||||
|
self.rect = self.image.get_rect(topleft=(WIDTH + self.size[0], self.y))
|
||||||
|
self.base_y = self.y
|
||||||
|
|
||||||
|
def update(self, dt, now):
|
||||||
|
self.rect.x += self.speed * dt / 16.67
|
||||||
|
vertical_offset = 10 * math.sin(2 * math.pi * now / 1000 + self.phase)
|
||||||
|
self.rect.y = self.base_y + vertical_offset
|
||||||
|
|
||||||
|
def off_screen(self):
|
||||||
|
if self.speed > 0:
|
||||||
|
return self.rect.left > WIDTH
|
||||||
|
else:
|
||||||
|
return self.rect.right < 0
|
||||||
|
|
||||||
|
def draw(self, surface):
|
||||||
|
surface.blit(self.image, self.rect)
|
||||||
|
|
||||||
|
|
||||||
|
class Petal:
|
||||||
|
def __init__(self, image, pos, petal_toggle, speed_multiplier=1.0):
|
||||||
|
self.image = image
|
||||||
|
self.rect = self.image.get_rect(topleft=pos)
|
||||||
|
self.speed_multiplier = speed_multiplier
|
||||||
|
self.drift = random.uniform(-0.5, 0.5)
|
||||||
|
self.phase = random.uniform(0, 2 * math.pi)
|
||||||
|
self.base_x = pos[0]
|
||||||
|
self.spawn_time = pygame.time.get_ticks()
|
||||||
|
self.petal_toggle = petal_toggle
|
||||||
|
|
||||||
|
def update(self, dt, now):
|
||||||
|
self.rect.y += 3 * self.speed_multiplier * dt / 16.67
|
||||||
|
sway = 15 * math.sin(0.5 * now / 1000 + self.phase)
|
||||||
|
time_since_spawn = (now - self.spawn_time) / 1000
|
||||||
|
drift_speed = 0.5 * self.speed_multiplier
|
||||||
|
self.rect.x = self.base_x + sway + self.drift * self.speed_multiplier + drift_speed * time_since_spawn * 60
|
||||||
|
|
||||||
|
def off_screen(self):
|
||||||
|
return self.rect.top > HEIGHT
|
||||||
|
|
||||||
|
def draw(self, surface):
|
||||||
|
surface.blit(self.image, self.rect)
|
||||||
|
|
||||||
|
|
||||||
|
class Spawner:
|
||||||
|
def __init__(self, spawn_interval_ms):
|
||||||
|
self.spawn_interval = spawn_interval_ms
|
||||||
|
self.last_spawn = 0
|
||||||
|
|
||||||
|
def can_spawn(self, now):
|
||||||
|
return now - self.last_spawn > self.spawn_interval
|
||||||
|
|
||||||
|
def update_spawn_time(self, now):
|
||||||
|
self.last_spawn = now
|
||||||
|
|
||||||
|
|
||||||
|
class Game:
|
||||||
|
def __init__(self):
|
||||||
|
self.screen = pygame.display.set_mode(SCREEN_SIZE, pygame.FULLSCREEN)
|
||||||
|
pygame.mouse.set_visible(False)
|
||||||
|
pygame.display.set_caption("Maguro!")
|
||||||
|
|
||||||
|
# Load assets
|
||||||
|
self.wallpaper = pygame.image.load("wallpaper.jpg").convert()
|
||||||
|
self.wallpaper = pygame.transform.scale(self.wallpaper, SCREEN_SIZE)
|
||||||
|
|
||||||
|
# Only load the right-facing cat image
|
||||||
|
self.cat_right_base = pygame.image.load("cat.png").convert_alpha()
|
||||||
|
|
||||||
|
self.sushi_images = []
|
||||||
|
for i in [1, 2, 4, 5]:
|
||||||
img = pygame.image.load(f"sushi{i}.png").convert_alpha()
|
img = pygame.image.load(f"sushi{i}.png").convert_alpha()
|
||||||
img = pygame.transform.smoothscale(img, SUSHI_SIZE)
|
img = pygame.transform.smoothscale(img, SUSHI_SIZE)
|
||||||
sushi_imgs.append(img)
|
self.sushi_images.append(img)
|
||||||
|
self.wasabi_img = pygame.image.load("sushi3.png").convert_alpha()
|
||||||
|
self.wasabi_img = pygame.transform.smoothscale(self.wasabi_img, SUSHI_SIZE)
|
||||||
|
|
||||||
wasabi_img = pygame.image.load("sushi3.png").convert_alpha()
|
self.cloud_base = pygame.image.load("cloud.png").convert_alpha()
|
||||||
wasabi_img = pygame.transform.smoothscale(wasabi_img, SUSHI_SIZE)
|
self.cloud_img = pygame.transform.smoothscale(self.cloud_base, CLOUD_SIZE)
|
||||||
|
|
||||||
cloud_base = pygame.image.load("cloud.png").convert_alpha()
|
self.petal_base = pygame.image.load("petal.png").convert_alpha()
|
||||||
cloud_img = pygame.transform.smoothscale(cloud_base, CLOUD_SIZE)
|
self.petal_img = pygame.transform.smoothscale(self.petal_base, PETAL_SIZE)
|
||||||
|
self.petal_img_flipped = pygame.transform.flip(self.petal_img, True, False)
|
||||||
|
|
||||||
petal_base = pygame.image.load("petal.png").convert_alpha()
|
# Sounds
|
||||||
petal_img = pygame.transform.smoothscale(petal_base, PETAL_SIZE)
|
pygame.mixer.music.load("audio_music.mp3")
|
||||||
petal_img_flipped = pygame.transform.flip(petal_img, True, False)
|
pygame.mixer.music.set_volume(0.5)
|
||||||
petal_toggle = False
|
pygame.mixer.music.play(-1)
|
||||||
|
self.chomp_sound = pygame.mixer.Sound("audio_chomp.mp3")
|
||||||
|
self.meow_sound = pygame.mixer.Sound("audio_meow.mp3")
|
||||||
|
|
||||||
chomp_sound = pygame.mixer.Sound("audio_chomp.mp3")
|
# Joystick
|
||||||
meow_sound = pygame.mixer.Sound("audio_meow.mp3")
|
self.joystick = None
|
||||||
|
if pygame.joystick.get_count() > 0:
|
||||||
|
self.joystick = pygame.joystick.Joystick(0)
|
||||||
|
self.joystick.init()
|
||||||
|
|
||||||
joystick = None
|
# Game entities
|
||||||
if pygame.joystick.get_count() > 0:
|
self.cat = Cat(self.cat_right_base, (WIDTH // 2, HEIGHT), 14)
|
||||||
joystick = pygame.joystick.Joystick(0)
|
self.sushis = []
|
||||||
joystick.init()
|
self.clouds = []
|
||||||
|
self.petals = []
|
||||||
|
self.petal_toggle = False
|
||||||
|
|
||||||
font = pygame.font.SysFont(None, 48)
|
# Spawners
|
||||||
|
self.sushi_spawner = Spawner(125)
|
||||||
|
self.cloud_spawner = Spawner(4000)
|
||||||
|
self.petal_spawner = Spawner(200)
|
||||||
|
|
||||||
cat_img = cat_right
|
self.score = 0
|
||||||
cat_facing = "right"
|
self.game_over = False
|
||||||
cat_rect = cat_img.get_rect()
|
self.game_over_time = None
|
||||||
cat_rect.centerx = WIDTH // 2
|
self.paused = False
|
||||||
cat_rect.bottom = HEIGHT
|
self.pause_by_controller = False
|
||||||
|
|
||||||
cat_speed = 14
|
self.sushi_fall_speed = 5
|
||||||
score = 0
|
self.cloud_speed_multiplier = 1.0
|
||||||
game_over = False
|
self.petal_speed_multiplier = 1.0
|
||||||
game_over_time = None
|
|
||||||
paused = False
|
|
||||||
pause_by_controller = False
|
|
||||||
sushi_fall_speed = 5
|
|
||||||
sushi_interval = 125
|
|
||||||
objects = []
|
|
||||||
|
|
||||||
clouds = []
|
self.font = pygame.font.SysFont(None, 48)
|
||||||
cloud_spawn_interval = 4000
|
self.small_font = pygame.font.SysFont(None, 32)
|
||||||
last_cloud_spawn = 0
|
|
||||||
cloud_speed_multiplier = 1.0
|
|
||||||
|
|
||||||
petals = []
|
self.clock = pygame.time.Clock()
|
||||||
petal_spawn_interval = 200
|
self.speed_increase_time = pygame.time.get_ticks()
|
||||||
last_petal_spawn = 0
|
|
||||||
petal_fall_speed = 3
|
|
||||||
petal_speed_multiplier = 1.0
|
|
||||||
|
|
||||||
start_time = pygame.time.get_ticks()
|
def draw_text(self, text, pos, color=(255, 255, 255)):
|
||||||
speed_increase_time = start_time
|
surf = self.font.render(text, True, color)
|
||||||
|
self.screen.blit(surf, pos)
|
||||||
|
|
||||||
def draw_text(text, pos, color=(255, 255, 255)):
|
def draw_centered_text(self, text, color=(255, 255, 255)):
|
||||||
surf = font.render(text, True, color)
|
surf = self.font.render(text, True, color)
|
||||||
screen.blit(surf, pos)
|
rect = surf.get_rect(center=(WIDTH // 2, HEIGHT // 2))
|
||||||
|
self.screen.blit(surf, rect)
|
||||||
|
|
||||||
def draw_centered_text(text, color=(255, 255, 255)):
|
def draw_centered_multiline_text(self, lines, color=(255, 255, 255), line_spacing=10):
|
||||||
surf = font.render(text, True, color)
|
|
||||||
rect = surf.get_rect(center=(WIDTH//2, HEIGHT//2))
|
|
||||||
screen.blit(surf, rect)
|
|
||||||
|
|
||||||
def draw_centered_multiline_text(lines, color=(255,255,255), line_spacing=10):
|
|
||||||
total_height = 0
|
total_height = 0
|
||||||
rendered_lines = []
|
rendered_lines = []
|
||||||
for line in lines:
|
for line in lines:
|
||||||
surf = font.render(line, True, color)
|
surf = self.font.render(line, True, color)
|
||||||
rendered_lines.append(surf)
|
rendered_lines.append(surf)
|
||||||
total_height += surf.get_height() + line_spacing
|
total_height += surf.get_height() + line_spacing
|
||||||
total_height -= line_spacing
|
total_height -= line_spacing
|
||||||
y = (HEIGHT - total_height) // 2
|
y = (HEIGHT - total_height) // 2
|
||||||
for surf in rendered_lines:
|
for surf in rendered_lines:
|
||||||
rect = surf.get_rect(center=(WIDTH // 2, y + surf.get_height() // 2))
|
rect = surf.get_rect(center=(WIDTH // 2, y + surf.get_height() // 2))
|
||||||
screen.blit(surf, rect)
|
self.screen.blit(surf, rect)
|
||||||
y += surf.get_height() + line_spacing
|
y += surf.get_height() + line_spacing
|
||||||
|
|
||||||
def reset_game():
|
def spawn_sushi(self):
|
||||||
global score, objects, game_over, cat_rect, cat_img, cat_facing, game_over_time, paused, pause_by_controller
|
|
||||||
global start_time, speed_increase_time, sushi_fall_speed, CAT_SIZE, cat_left, cat_right
|
|
||||||
global clouds, last_cloud_spawn, cloud_speed_multiplier
|
|
||||||
global petals, last_petal_spawn, petal_fall_speed, petal_speed_multiplier, petal_toggle
|
|
||||||
score = 0
|
|
||||||
objects = []
|
|
||||||
game_over = False
|
|
||||||
game_over_time = None
|
|
||||||
paused = False
|
|
||||||
pause_by_controller = False
|
|
||||||
CAT_SIZE = [160, 160]
|
|
||||||
cat_left = pygame.transform.smoothscale(cat_left_base, CAT_SIZE)
|
|
||||||
cat_right = pygame.transform.smoothscale(cat_right_base, CAT_SIZE)
|
|
||||||
cat_facing = "right"
|
|
||||||
cat_img = cat_right
|
|
||||||
cat_rect = cat_img.get_rect()
|
|
||||||
cat_rect.centerx = WIDTH // 2
|
|
||||||
cat_rect.bottom = HEIGHT
|
|
||||||
sushi_fall_speed = 5
|
|
||||||
clouds.clear()
|
|
||||||
last_cloud_spawn = pygame.time.get_ticks() - 4000
|
|
||||||
cloud_speed_multiplier = 1.0
|
|
||||||
petals.clear()
|
|
||||||
last_petal_spawn = pygame.time.get_ticks() - petal_spawn_interval
|
|
||||||
petal_fall_speed = 3
|
|
||||||
petal_speed_multiplier = 1.0
|
|
||||||
petal_toggle = False
|
|
||||||
start_time = pygame.time.get_ticks()
|
|
||||||
speed_increase_time = start_time
|
|
||||||
|
|
||||||
def spawn_sushi():
|
|
||||||
x = random.randint(50, WIDTH - 50)
|
x = random.randint(50, WIDTH - 50)
|
||||||
is_wasabi = random.random() < 0.1
|
is_wasabi = random.random() < WASABI_CHANCE
|
||||||
img = wasabi_img if is_wasabi else random.choice(sushi_imgs)
|
img = self.wasabi_img if is_wasabi else random.choice(self.sushi_images)
|
||||||
rect = img.get_rect(midtop=(x, -40))
|
sushi = Sushi(img, (x, -40), wasabi=is_wasabi, speed=self.sushi_fall_speed)
|
||||||
objects.append({'img': img, 'rect': rect, 'wasabi': is_wasabi})
|
self.sushis.append(sushi)
|
||||||
|
|
||||||
def spawn_cloud():
|
def spawn_cloud(self):
|
||||||
y = 50
|
cloud = Cloud(self.cloud_img, self.cloud_speed_multiplier)
|
||||||
direction = random.choice(["left_to_right", "right_to_left"])
|
self.clouds.append(cloud)
|
||||||
if direction == "left_to_right":
|
|
||||||
x = -CLOUD_SIZE[0]
|
|
||||||
speed = 1.5
|
|
||||||
else:
|
|
||||||
x = WIDTH + CLOUD_SIZE[0]
|
|
||||||
speed = -1.5
|
|
||||||
rect = cloud_img.get_rect(topleft=(x, y))
|
|
||||||
phase = random.uniform(0, 2 * math.pi)
|
|
||||||
clouds.append({'rect': rect, 'speed': speed, 'base_y': y, 'phase': phase})
|
|
||||||
|
|
||||||
def spawn_petal():
|
def spawn_petal(self):
|
||||||
global petal_toggle
|
|
||||||
x = random.randint(0, WIDTH)
|
x = random.randint(0, WIDTH)
|
||||||
y = -PETAL_SIZE[1]
|
image = self.petal_img_flipped if self.petal_toggle else self.petal_img
|
||||||
image = petal_img_flipped if petal_toggle else petal_img
|
self.petal_toggle = not self.petal_toggle
|
||||||
petal_toggle = not petal_toggle
|
petal = Petal(image, (x, -PETAL_SIZE[1]), self.petal_toggle, self.petal_speed_multiplier)
|
||||||
rect = image.get_rect(topleft=(x, y))
|
self.petals.append(petal)
|
||||||
horizontal_drift = random.uniform(-0.5, 0.5)
|
|
||||||
phase = random.uniform(0, 2 * math.pi)
|
|
||||||
spawn_time = pygame.time.get_ticks()
|
|
||||||
petals.append({'rect': rect, 'drift': horizontal_drift, 'base_x': x, 'phase': phase, 'img': image, 'spawn_time': spawn_time})
|
|
||||||
|
|
||||||
reset_game()
|
def reset_game(self):
|
||||||
last_spawn = pygame.time.get_ticks()
|
self.score = 0
|
||||||
|
self.sushis.clear()
|
||||||
|
self.clouds.clear()
|
||||||
|
self.petals.clear()
|
||||||
|
self.petal_toggle = False
|
||||||
|
self.game_over = False
|
||||||
|
self.game_over_time = None
|
||||||
|
self.paused = False
|
||||||
|
self.pause_by_controller = False
|
||||||
|
self.sushi_fall_speed = 5
|
||||||
|
self.cloud_speed_multiplier = 1.0
|
||||||
|
self.petal_speed_multiplier = 1.0
|
||||||
|
self.cat = Cat(self.cat_right_base, (WIDTH // 2, HEIGHT), 14)
|
||||||
|
now = pygame.time.get_ticks()
|
||||||
|
self.sushi_spawner.last_spawn = now
|
||||||
|
self.cloud_spawner.last_spawn = now - self.cloud_spawner.spawn_interval
|
||||||
|
self.petal_spawner.last_spawn = now - self.petal_spawner.spawn_interval
|
||||||
|
self.speed_increase_time = now
|
||||||
|
|
||||||
while True:
|
pygame.mixer.music.play(-1)
|
||||||
dt = clock.tick(60)
|
|
||||||
screen.blit(wallpaper, (0, 0))
|
|
||||||
|
|
||||||
|
def pause(self, by_controller=False):
|
||||||
|
self.paused = True
|
||||||
|
self.pause_by_controller = by_controller
|
||||||
|
pygame.mixer.music.pause()
|
||||||
|
|
||||||
|
def unpause(self):
|
||||||
|
self.paused = False
|
||||||
|
pygame.mixer.music.unpause()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while True:
|
||||||
|
dt = self.clock.tick(60)
|
||||||
|
now = pygame.time.get_ticks()
|
||||||
|
self.screen.blit(self.wallpaper, (0, 0))
|
||||||
keys = pygame.key.get_pressed()
|
keys = pygame.key.get_pressed()
|
||||||
move = 0
|
move = 0
|
||||||
|
|
||||||
for event in pygame.event.get():
|
for event in pygame.event.get():
|
||||||
if event.type == pygame.QUIT:
|
if event.type == pygame.QUIT:
|
||||||
pygame.quit()
|
quit_game()
|
||||||
sys.exit()
|
|
||||||
if event.type == pygame.KEYDOWN:
|
if event.type == pygame.KEYDOWN:
|
||||||
if event.key == pygame.K_ESCAPE:
|
if event.key == pygame.K_ESCAPE:
|
||||||
if not game_over:
|
if not self.game_over:
|
||||||
paused = not paused
|
if self.paused:
|
||||||
pause_by_controller = False
|
self.unpause()
|
||||||
if paused:
|
|
||||||
pygame.mixer.music.pause()
|
|
||||||
else:
|
else:
|
||||||
pygame.mixer.music.unpause()
|
self.pause(by_controller=False)
|
||||||
elif event.key == pygame.K_q:
|
elif event.key == pygame.K_q:
|
||||||
pygame.quit()
|
quit_game()
|
||||||
sys.exit()
|
elif self.game_over and not self.paused:
|
||||||
elif game_over and not paused:
|
self.reset_game()
|
||||||
reset_game()
|
if self.joystick and event.type == pygame.JOYBUTTONDOWN:
|
||||||
if joystick and event.type == pygame.JOYBUTTONDOWN:
|
|
||||||
if event.button == 7 or event.button == 6:
|
if event.button == 7 or event.button == 6:
|
||||||
if not game_over:
|
if not self.game_over:
|
||||||
paused = not paused
|
if self.paused:
|
||||||
pause_by_controller = True
|
self.unpause()
|
||||||
if paused:
|
|
||||||
pygame.mixer.music.pause()
|
|
||||||
else:
|
else:
|
||||||
pygame.mixer.music.unpause()
|
self.pause(by_controller=True)
|
||||||
elif paused and event.button == 2:
|
elif self.paused and event.button == 2:
|
||||||
pygame.quit()
|
quit_game()
|
||||||
sys.exit()
|
elif self.game_over and not self.paused:
|
||||||
elif game_over and not paused:
|
self.reset_game()
|
||||||
reset_game()
|
|
||||||
|
|
||||||
if paused:
|
if self.paused:
|
||||||
draw_centered_text("PAUSED", (255, 255, 255))
|
self.draw_centered_text("PAUSED", (255, 255, 255))
|
||||||
small_font = pygame.font.SysFont(None, 32)
|
if self.pause_by_controller:
|
||||||
if pause_by_controller:
|
instruction = self.small_font.render("Press START to resume or X to quit.", True, (255, 255, 255))
|
||||||
instruction = small_font.render("Press START to resume or X to quit.", True, (255, 255, 255))
|
|
||||||
else:
|
else:
|
||||||
instruction = small_font.render("Press ESC to resume or Q to quit.", True, (255, 255, 255))
|
instruction = self.small_font.render("Press ESC to resume or Q to quit.", True, (255, 255, 255))
|
||||||
instr_rect = instruction.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 40))
|
instr_rect = instruction.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 40))
|
||||||
screen.blit(instruction, instr_rect)
|
self.screen.blit(instruction, instr_rect)
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
continue
|
continue
|
||||||
|
|
||||||
now = pygame.time.get_ticks()
|
# Difficulty increase every 30 seconds
|
||||||
|
if now - self.speed_increase_time > 30000:
|
||||||
|
self.sushi_fall_speed += 1
|
||||||
|
self.cloud_speed_multiplier += 0.1
|
||||||
|
self.petal_speed_multiplier += 0.1
|
||||||
|
self.speed_increase_time = now
|
||||||
|
|
||||||
if now - speed_increase_time > 30000:
|
# Spawn clouds, petals, sushi
|
||||||
sushi_fall_speed += 1
|
if self.cloud_spawner.can_spawn(now):
|
||||||
cloud_speed_multiplier += 0.1
|
self.spawn_cloud()
|
||||||
petal_speed_multiplier += 0.1
|
self.cloud_spawner.update_spawn_time(now)
|
||||||
speed_increase_time = now
|
if self.petal_spawner.can_spawn(now):
|
||||||
|
self.spawn_petal()
|
||||||
|
self.petal_spawner.update_spawn_time(now)
|
||||||
|
if not self.game_over and self.sushi_spawner.can_spawn(now):
|
||||||
|
self.spawn_sushi()
|
||||||
|
self.sushi_spawner.update_spawn_time(now)
|
||||||
|
|
||||||
if now - last_cloud_spawn > cloud_spawn_interval:
|
# Update clouds
|
||||||
spawn_cloud()
|
for cloud in self.clouds[:]:
|
||||||
last_cloud_spawn = now
|
cloud.update(dt, now)
|
||||||
|
if cloud.off_screen():
|
||||||
|
self.clouds.remove(cloud)
|
||||||
|
|
||||||
if now - last_petal_spawn > petal_spawn_interval:
|
# Update petals
|
||||||
spawn_petal()
|
for petal in self.petals[:]:
|
||||||
last_petal_spawn = now
|
petal.update(dt, now)
|
||||||
|
if petal.off_screen():
|
||||||
|
self.petals.remove(petal)
|
||||||
|
|
||||||
for cloud in clouds[:]:
|
if not self.game_over:
|
||||||
cloud['rect'].x += cloud['speed'] * cloud_speed_multiplier
|
# Handle input
|
||||||
time_seconds = now / 1000
|
|
||||||
vertical_offset = 10 * math.sin(2 * math.pi * time_seconds + cloud['phase'])
|
|
||||||
cloud['rect'].y = cloud['base_y'] + vertical_offset
|
|
||||||
if cloud['speed'] > 0 and cloud['rect'].left > WIDTH:
|
|
||||||
clouds.remove(cloud)
|
|
||||||
elif cloud['speed'] < 0 and cloud['rect'].right < 0:
|
|
||||||
clouds.remove(cloud)
|
|
||||||
|
|
||||||
for petal in petals[:]:
|
|
||||||
petal['rect'].y += petal_fall_speed * petal_speed_multiplier
|
|
||||||
sway = 15 * math.sin(0.5 * now / 1000 + petal['phase'])
|
|
||||||
time_since_spawn = (now - petal['spawn_time']) / 1000
|
|
||||||
drift_speed = 0.5 * petal_speed_multiplier
|
|
||||||
petal['rect'].x = petal['base_x'] + sway + petal['drift'] * petal_speed_multiplier + drift_speed * time_since_spawn * 60
|
|
||||||
if petal['rect'].top > HEIGHT:
|
|
||||||
petals.remove(petal)
|
|
||||||
|
|
||||||
if not game_over:
|
|
||||||
if keys[pygame.K_a]:
|
if keys[pygame.K_a]:
|
||||||
move = -cat_speed
|
move = -1
|
||||||
cat_facing = "left"
|
self.cat.facing = "left"
|
||||||
elif keys[pygame.K_d]:
|
elif keys[pygame.K_d]:
|
||||||
move = cat_speed
|
move = 1
|
||||||
cat_facing = "right"
|
self.cat.facing = "right"
|
||||||
|
|
||||||
if joystick:
|
if self.joystick:
|
||||||
axis = joystick.get_axis(0)
|
axis = self.joystick.get_axis(0)
|
||||||
if abs(axis) > 0.2:
|
if abs(axis) > 0.2:
|
||||||
move = int(axis * cat_speed)
|
move = int(axis / abs(axis)) # normalize to -1 or 1
|
||||||
cat_facing = "left" if axis < 0 else "right"
|
self.cat.facing = "left" if axis < 0 else "right"
|
||||||
|
|
||||||
cat_img = cat_left if cat_facing == "left" else cat_right
|
self.cat.update_image()
|
||||||
|
self.cat.move(move)
|
||||||
|
|
||||||
cat_rect.x += move
|
tuna_mid_y = self.cat.rect.top + self.cat.rect.height // 2
|
||||||
cat_rect.x = max(0, min(WIDTH - cat_rect.width, cat_rect.x))
|
|
||||||
cat_rect.bottom = HEIGHT
|
|
||||||
|
|
||||||
if now - last_spawn > sushi_interval:
|
# Update sushi positions and collisions
|
||||||
spawn_sushi()
|
for sushi in self.sushis[:]:
|
||||||
last_spawn = now
|
sushi.speed = self.sushi_fall_speed
|
||||||
|
sushi.update(dt)
|
||||||
|
|
||||||
tuna_mid_y = cat_rect.top + cat_rect.height // 2
|
horizontal_overlap = sushi.rect.right > self.cat.rect.left and sushi.rect.left < self.cat.rect.right
|
||||||
|
if horizontal_overlap and sushi.rect.bottom >= tuna_mid_y:
|
||||||
for obj in objects[:]:
|
if sushi.wasabi:
|
||||||
obj['rect'].y += sushi_fall_speed
|
self.meow_sound.play()
|
||||||
horizontal_overlap = obj['rect'].right > cat_rect.left and obj['rect'].left < cat_rect.right
|
self.game_over = True
|
||||||
if horizontal_overlap and obj['rect'].bottom >= tuna_mid_y:
|
self.game_over_time = None
|
||||||
if obj['wasabi']:
|
|
||||||
meow_sound.play()
|
|
||||||
game_over = True
|
|
||||||
game_over_time = None
|
|
||||||
else:
|
else:
|
||||||
score += 1
|
self.score += 1
|
||||||
chomp_sound.play()
|
self.chomp_sound.play()
|
||||||
mid_x = cat_rect.centerx
|
self.cat.grow()
|
||||||
CAT_SIZE[0] += 1
|
self.sushis.remove(sushi)
|
||||||
CAT_SIZE[1] += 1
|
elif sushi.off_screen():
|
||||||
cat_left = pygame.transform.smoothscale(cat_left_base, CAT_SIZE)
|
self.sushis.remove(sushi)
|
||||||
cat_right = pygame.transform.smoothscale(cat_right_base, CAT_SIZE)
|
|
||||||
cat_img = cat_left if cat_facing == "left" else cat_right
|
|
||||||
cat_rect = cat_img.get_rect()
|
|
||||||
cat_rect.centerx = mid_x
|
|
||||||
cat_rect.bottom = HEIGHT
|
|
||||||
objects.remove(obj)
|
|
||||||
elif obj['rect'].top > HEIGHT:
|
|
||||||
objects.remove(obj)
|
|
||||||
else:
|
else:
|
||||||
if game_over_time is None:
|
if self.game_over_time is None:
|
||||||
game_over_time = now
|
self.game_over_time = now
|
||||||
elif now - game_over_time >= 3000:
|
elif now - self.game_over_time >= GAME_OVER_DELAY:
|
||||||
pygame.quit()
|
quit_game()
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
for cloud in clouds:
|
# Draw everything
|
||||||
screen.blit(cloud_img, cloud['rect'])
|
for cloud in self.clouds:
|
||||||
|
cloud.draw(self.screen)
|
||||||
|
for petal in self.petals:
|
||||||
|
petal.draw(self.screen)
|
||||||
|
self.cat.draw(self.screen)
|
||||||
|
for sushi in self.sushis:
|
||||||
|
sushi.draw(self.screen)
|
||||||
|
|
||||||
for petal in petals:
|
self.draw_text(f"Score: {self.score}", (10, 10))
|
||||||
screen.blit(petal['img'], petal['rect'])
|
|
||||||
|
|
||||||
screen.blit(cat_img, cat_rect)
|
if self.game_over:
|
||||||
|
self.draw_centered_multiline_text([f"Final Score: {self.score}", "Game Over!"], color=(255, 0, 0))
|
||||||
for obj in objects:
|
|
||||||
screen.blit(obj['img'], obj['rect'])
|
|
||||||
|
|
||||||
draw_text(f"Score: {score}", (10, 10))
|
|
||||||
|
|
||||||
if game_over:
|
|
||||||
draw_centered_multiline_text([f"Final Score: {score}", "Game Over!"], color=(255, 0, 0))
|
|
||||||
|
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
game = Game()
|
||||||
|
game.reset_game()
|
||||||
|
game.run()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user