From 9872d564f3a52bbbbae6b1ea9ec51b6da65a087a Mon Sep 17 00:00:00 2001 From: Pratyush Kumar Date: Thu, 16 Nov 2023 16:14:13 +0530 Subject: [PATCH] Added collision convert --- README.md | 11 ++++++++++- globals.py | 9 ++++++++- main.py | 38 +++++++++++++++++++++++++++++++----- notes.py | 54 ++++++++++++++++++++++++++-------------------------- obstacles.py | 13 +++++++++++-- 5 files changed, 89 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 513b444..7fa9b42 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,13 @@ Game submission entry for GitHub Game-OFF 2023 -Music based runner game with power-ups, milestones and retro aesthetic +Music themed runner game with power-ups, milestones and retro aesthetic +You are in control of a note, escape the hordes of musical notes coming at you and earn exciting powerups on the way. + +## Features + +- [ ] Basic gameplay +- [x] Conversion of player to enemy when encountered +- [ ] Powerups +- [ ] Text stats +- [ ] Splash screen diff --git a/globals.py b/globals.py index 4c8de84..f276e85 100644 --- a/globals.py +++ b/globals.py @@ -1,10 +1,11 @@ # This file contains all the constant quantities used in the program import pygame import sys +from enum import Enum from pygame.locals import * -WIDTH = 800 +WIDTH = 1000 HEIGHT = 450 STAFFPOS = (75, 150, 225, 300, 375) FPS = 60 @@ -22,4 +23,10 @@ TOTAL_STAFFS = len(STAFFSOUNDS) TOTAL_NOTES = 6 + +class Direction(Enum): + UP = -1 + DOWN = 1 + + obstacles_group = pygame.sprite.Group() diff --git a/main.py b/main.py index 711c87b..d428e2b 100644 --- a/main.py +++ b/main.py @@ -19,22 +19,50 @@ game_obstacles = obstacles.ObstacleList() player1 = notes.Player() + +def check_collision(): + hits = pygame.sprite.spritecollide( + player1, globals.obstacles_group, False, collided=pygame.sprite.collide_mask + ) + if hits: + print("Collision detected:") + if player1.hit_count < 3: + # Increase hit count and display it + player1.hit_count += 1 + print("Hit count: " + str(player1.hit_count)) + + # Remove the obstacles from the list + for obj in hits: + game_obstacles.remove_obstacle(obj) + obj.hide_obstacle(DISPLAYSURF) + + # Convert the player sprite to that of the obstacle + player1.convert_to_obstacle(DISPLAYSURF, hits[0]) + else: + print("Game over") + pygame.quit() + sys.exit() + + while True: # main game loop for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: - if event.key == pygame.K_UP: - player1.staff_up(DISPLAYSURF) - elif event.key == pygame.K_DOWN: - player1.staff_down(DISPLAYSURF) + dir = ( + globals.Direction.UP + if event.key == pygame.K_UP + else globals.Direction.DOWN + ) + player1.staff_movement(DISPLAYSURF, dir) # Display the player player1.draw(DISPLAYSURF) # Check for collisions - player1.check_collision() + # player1.check_collision() + check_collision() # Display and move the obstacles if random.randint(0, 1000) < 10: diff --git a/notes.py b/notes.py index dc0adfd..459e104 100644 --- a/notes.py +++ b/notes.py @@ -33,6 +33,7 @@ def __init__(self, image, x, y, offset_x=0, offset_y=0): self.offset_y = offset_y self.rect = self.image.get_rect(center=(x + offset_x, y + offset_y)) self.mask = pygame.mask.from_surface(self.image.convert_alpha()) + self.orig_image = self.image.copy() def draw(self, surface): """ @@ -44,8 +45,6 @@ def draw(self, surface): surface.blit(self.image, self.rect) -# [x]: Add a class for the player character which is inherited from Note class -# TODO: Add player character convert feature class Player(Note): """ Player Class as a type of Note (attributes inherited) @@ -69,44 +68,45 @@ def __init__( """Set default position of the player class at third staff line in the beginning""" self.staff_loc = staff_loc super().__init__(image, x, globals.STAFFPOS[staff_loc], offset_x, offset_y) - colorImage = pygame.Surface(self.image.get_size()).convert_alpha() + self.color_player() + self.hit_count = 0 + + def color_player(self): + colorImage = pygame.Surface(self.orig_image.get_size()).convert_alpha() colorImage.fill((134, 217, 119, 255)) - self.image.blit(colorImage, (0, 0), special_flags=pygame.BLEND_RGBA_MULT) + final_image = self.orig_image.copy() + final_image.blit(colorImage, (0, 0), special_flags=pygame.BLEND_RGBA_MULT) + self.image = final_image - # FIXME: Player chracter goes directly to last lines and then reports index out of range error - def staff_up(self, surface): + def convert_to_obstacle(self, surface, obstacle: Note): """ - Move to the staff line above + Convert the player sprite to that of the obstacle """ - if self.staff_loc == 0: - return pygame.draw.rect(surface, (0, 0, 0), self.rect) - prev_y = globals.STAFFPOS[self.staff_loc] - self.staff_loc -= 1 - new_y = globals.STAFFPOS[self.staff_loc] - self.rect.move_ip(0, new_y - prev_y) - pygame.mixer.Sound.play(globals.STAFFSOUNDS[4 - self.staff_loc]) + self.image = obstacle.orig_image + self.orig_image = self.image + self.offset_x = obstacle.offset_x + self.offset_y = obstacle.offset_y + self.rect = self.image.get_rect( + center=(self.x + self.offset_x, self.y + self.offset_y) + ) + self.mask = pygame.mask.from_surface(self.image.convert_alpha()) + self.color_player() self.draw(surface) - def staff_down(self, surface): + def staff_movement(self, surface, dir: globals.Direction): """ - Move to the staff line below + Move to the staff line above """ - if self.staff_loc == 4: + if self.staff_loc == 0 and dir == globals.Direction.UP: + return + elif self.staff_loc == 4 and dir == globals.Direction.DOWN: return pygame.draw.rect(surface, (0, 0, 0), self.rect) prev_y = globals.STAFFPOS[self.staff_loc] - self.staff_loc += 1 + self.staff_loc += dir.value new_y = globals.STAFFPOS[self.staff_loc] + self.y = new_y self.rect.move_ip(0, new_y - prev_y) pygame.mixer.Sound.play(globals.STAFFSOUNDS[4 - self.staff_loc]) self.draw(surface) - - def check_collision(self): - hits = pygame.sprite.spritecollide( - self, globals.obstacles_group, False, collided=pygame.sprite.collide_mask - ) - if hits: - print("Collision detected: " + str(hits[0])) - pygame.quit() - sys.exit() diff --git a/obstacles.py b/obstacles.py index f3b67b2..d01c0e0 100644 --- a/obstacles.py +++ b/obstacles.py @@ -28,6 +28,7 @@ def __init__( """ self.note_type = note_type self.staff_loc = staff_loc + # FIXME: Change the offset x values so that all the notes align up properly on the left edge image = "assets/images/" if note_type == 0: image += "whole-note.png" @@ -40,12 +41,14 @@ def __init__( image += "eight-note.png" elif note_type == 4: image += "eight-line.png" + offset_x = 15 elif note_type == 5: image += "sixteenth-notes.png" + offset_x = 35 image = pygame.image.load(image) super().__init__(image, x, globals.STAFFPOS[staff_loc], offset_x, offset_y) - colorImage = pygame.Surface(self.image.get_size()).convert_alpha() + colorImage = pygame.Surface(self.orig_image.get_size()).convert_alpha() colorImage.fill((245, 123, 86, 255)) self.image.blit(colorImage, (0, 0), special_flags=pygame.BLEND_RGBA_MULT) @@ -61,6 +64,12 @@ def move_left(self, surface): # draw the obstacle at its new position self.draw(surface) + def hide_obstacle(self, surface): + """ + Hide the obstacle + """ + pygame.draw.rect(surface, (0, 0, 0), self.rect) + class ObstacleList: """ @@ -123,7 +132,7 @@ def move_obstacles(self, surface): for obstacle in self.obstacles: obstacle.move_left(surface) w = obstacle.rect.width - if obstacle.x + w / 2 < 0: + if obstacle.x + obstacle.offset_x + w / 2 < 0: self.remove_obstacle(obstacle) for i in range(0, 5):