Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feedback #1

Open
wants to merge 8 commits into
base: feedback
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 121 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
[![Open in Visual Studio Code](https://classroom.github.com/assets/open-in-vscode-718a45dd9cf7e7f842a935f5ebbe5719a5e09af4491e668f4dbf3b35d5cca122.svg)](https://classroom.github.com/online_ide?assignment_repo_id=14592674&assignment_repo_type=AssignmentRepo)

:warning: Everything between << >> needs to be replaced (remove << >> after replacing)

# << Project Title >>
## CS110 Final Project << Semester, Year >>
# Block Jump (doodle jump knock off)
## CS110 Final Project Spring , 2024

## Team Members
1 Team Member

<< List team member names >>
Team member names: Selina

***

## Project Description

<< Give an overview of your project >>
My project aims to replicate but simplify the already poipular game Doodle Jump. The player will be a square jumping on rectangles.

***

Expand All @@ -26,24 +27,127 @@

![final gui](assets/finalgui.jpg)

## Program Design
## Program Design > Classes

class Player:
"""
Represents the player-controlled character in the game.
"""

def __init__(self, x, y, img_file):
"""
Initializes the player object.
Args:
- x : int - starting x coordinate
- y : int - starting y coordinate
- img_file : str - path to img file
"""

class Platform:
"""
Represents the platforms in the game that the player must hop on to survive.
"""

def __init__(self, x, y, img_file):
"""
Initializes the obstacle object.
Args:
- x : int - starting x coordinate
- y : int - starting y coordinate
- img_file : str - path to img file
"""

def update_position(self, x, y):
"""
Updates the position of the obstacle.
Args:
- x : int - new x coordinate
- y : int - new y coordinate
Returns:
None
"""

def detect_collision(self):
"""
Detects collision with the pigeon.
Args:
None
Returns:
None
"""

### Features

1. << Feature 1 >>
2. << Feature 2 >>
3. << Feature 3 >>
4. << Feature 4 >>
5. << Feature 5 >>
1. Click to start tab
2. Moveable character
3. Obsticle collison
4. Moving background
5. Game over screen

### Classes

- << You should have a list of each of your classes with a description >>
1. Player class: Represents the player character in the game.
2. Platform class: Represents the platforms that the player can jump on in the game.

## ATP

| Step |Procedure |Expected Results |
|----------------------|:--------------------:|----------------------------------:|
| 1 | Run Counter Program |GUI window appears with count = 0 |
| 2 | click count button | display changes to count = 1 |
etc...
Test Case 1: Player Movement

Test Description: Confirm that the player track the user's mouse and move from side to side.

Test Steps:
1. Start the game.
2. Observe the character's inital position and the movement of the platoform.
3. Move the mouse to the right.
4. Verify that the player moves to the right.
5. Move the mouse to the leeft.
6. Verify that the player moves to the left.
Expected Outcome: The character successfully tracks the mouse and moves right if the mouse moves right and moves left if the mouse moves left.

Test Case 2: Score Increment

Test Description: Ensure that the player's score increases correctly upon successful jump.

Test Steps:
1. Start the game.
2. Observe the inital score, which should start at 0.
3. Successful jump on the platform.
4. Verify that the score increases by 1.
5. Repeat the process of jumping on platforms multiple times.
Expected Outcome: The score increases by 1 with each successful jump.

Test Case 3: Game Over Detection

Test Description: Verify that the game correctly detects when the player fails to jump in time and falls off the screen.

Test Steps:
1. Start the game.
2. Observe the character movement.
3. Fail to jump in time and falls of the screen.
4. Verify that the game displays a "Game Over" message.
Expected Outcome: When the character falls off the scsreen, a game over message is displayed.

Test Case 4: Collison Detection

Test Description: Ensure that collisions between the player and the platform are detected correctly.

Test Steps:
1. Start the game.
2. Continue playing the game.
3. Verify as the player aquires more points increase the sped of the taxis.
Expected Outcome: As the game progresses, the taxis would move faster. This requires the player to have quicker reflexes to avoid collisions.

Test Case 5: Menu Navigation

Test Description: Test the navigation through the game over page.

Test Steps:
1. Start the game
2. Fall off the screen to display the game over message
3. Verify that each option (Play again, quit) is selectable and leads to the expected actions.
Press "Play Again"
4. Takes you back to the initial screen to play the game again.
5. Fall off the screen
6. Press quit
7. The game will exit
Expected Outcome: The menu should allow the player to navigate through options and select them. If the player chooses to play again, they will be taken back to the starting screen. If the player chooses to quit, the screen wil close.
5 changes: 3 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pygame
#import your controller
from src.controller import Controller

def main():
pygame.init()
Expand All @@ -10,4 +10,5 @@ def main():

# https://codefather.tech/blog/if-name-main-python/
if __name__ == '__main__':
main()
controller = Controller()
controller.run()
Binary file added src/__pycache__/controller.cpython-310.pyc
Binary file not shown.
190 changes: 190 additions & 0 deletions src/controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import pygame
import random

"""Initializes pygame"""
pygame.init()

"""Screen dimensions"""
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 800

"""Colors"""
"""background"""
WHITE = (255, 255, 255)
"""platforms"""
BLACK = (0, 0, 0)
"""player"""
RED = (255, 0, 0)

"""Platform dimensions (black boxes)"""
PLATFORM_WIDTH = 80
PLATFORM_HEIGHT = 20

"""Player dimensions (red box)"""
PLAYER_WIDTH = 50
PLAYER_HEIGHT = 50

"""Gravity"""
GRAVITY = 0.5

"""Jump height"""
JUMP_HEIGHT = 12

"""Platform speed"""
PLATFORM_SPEED = 5

"""Font settings"""
FONT_SIZE = 24
FONT_COLOR = BLACK
FONT_POS_JUMP = (SCREEN_WIDTH // 2, 50)
FONT_POS_GAME_OVER = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 3)

"""Button stuff"""
BUTTON_WIDTH = 140
BUTTON_HEIGHT = 40
BUTTON_COLOR = (100, 100, 255)
BUTTON_TEXT_COLOR = WHITE
BUTTON_TEXT_SIZE = 20

"""Sets up the screen"""
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Rectangle Jump")

font = pygame.font.Font(None, FONT_SIZE)

"""Defines the Player class"""
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((PLAYER_WIDTH, PLAYER_HEIGHT))
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.centerx = SCREEN_WIDTH // 2
self.rect.bottom = SCREEN_HEIGHT
self.velocity = 0
self.jump_count = 0

def update(self):
"""Track mouse movement (horizonally from side to side)"""
mouse_x, _ = pygame.mouse.get_pos()
self.rect.centerx = mouse_x

self.velocity += GRAVITY
self.rect.y += self.velocity

"""Checks if player falls below the screen"""
if self.rect.top > SCREEN_HEIGHT:
game_over()

"""Checks for collision with platforms"""
hits = pygame.sprite.spritecollide(self, platforms, False)
if hits:
self.rect.bottom = hits[0].rect.top
self.velocity = -JUMP_HEIGHT
self.jump_count += 1

"""Defines the Platform class"""
class Platform(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((PLATFORM_WIDTH, PLATFORM_HEIGHT))
self.image.fill(BLACK)
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)

def update(self):
self.rect.y += PLATFORM_SPEED
if self.rect.top > SCREEN_HEIGHT:
self.rect.bottom = 0
self.rect.left = random.randint(0, SCREEN_WIDTH - PLATFORM_WIDTH)

"""initializes the game"""
def initialize_game():

"""Create groups for sprites"""
global all_sprites, platforms, player
all_sprites = pygame.sprite.Group()
platforms = pygame.sprite.Group()

"""Adds platforms"""
for _ in range(10):
platform = Platform(random.randint(0, SCREEN_WIDTH - PLATFORM_WIDTH), random.randint(0, SCREEN_HEIGHT))
platforms.add(platform)
all_sprites.add(platform)

"""Creates the player"""
player = Player()
all_sprites.add(player)

"""Display game over screen"""
def game_over():
while True:
screen.fill(WHITE)
game_over_text = font.render("Game Over", True, FONT_COLOR)
screen.blit(game_over_text, (FONT_POS_GAME_OVER[0] - game_over_text.get_width() // 2, FONT_POS_GAME_OVER[1] - 2 * game_over_text.get_height()))

"""Display's the player's score"""
score_text = font.render(f"Your score: {player.jump_count}", True, FONT_COLOR)
screen.blit(score_text, (FONT_POS_GAME_OVER[0] - score_text.get_width() // 2, FONT_POS_GAME_OVER[1] + score_text.get_height() // 2))

play_again_rect = pygame.Rect((SCREEN_WIDTH - BUTTON_WIDTH) // 2, SCREEN_HEIGHT // 2, BUTTON_WIDTH, BUTTON_HEIGHT)
quit_rect = pygame.Rect((SCREEN_WIDTH - BUTTON_WIDTH) // 2, SCREEN_HEIGHT // 2 + BUTTON_HEIGHT + 10, BUTTON_WIDTH, BUTTON_HEIGHT)
pygame.draw.rect(screen, BUTTON_COLOR, play_again_rect)
pygame.draw.rect(screen, BUTTON_COLOR, quit_rect)

play_again_text = font.render("Play Again", True, BUTTON_TEXT_COLOR)
quit_text = font.render("Quit", True, BUTTON_TEXT_COLOR)
screen.blit(play_again_text, (play_again_rect.centerx - play_again_text.get_width() // 2, play_again_rect.centery - play_again_text.get_height() // 2))
screen.blit(quit_text, (quit_rect.centerx - quit_text.get_width() // 2, quit_rect.centery - quit_text.get_height() // 2))

pygame.display.flip()

for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_x, mouse_y = pygame.mouse.get_pos()
if play_again_rect.collidepoint(mouse_x, mouse_y):
"""restarts the game"""
initialize_game()
return
elif quit_rect.collidepoint(mouse_x, mouse_y):
pygame.quit()
quit()

""""Initialize the game"""
initialize_game()

"""Main loop"""
running = True
game_started = False

while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
game_started = True

if game_started:
all_sprites.update()

screen.fill(WHITE)

"""Click to start"""
if not game_started:
click_to_start_text = font.render("Click to start", True, FONT_COLOR)
screen.blit(click_to_start_text, (SCREEN_WIDTH // 2 - click_to_start_text.get_width() // 2, SCREEN_HEIGHT // 2))

all_sprites.draw(screen)

"""Display jump count"""
jump_text = font.render(f"Jumps: {player.jump_count}", True, FONT_COLOR)
screen.blit(jump_text, (FONT_POS_JUMP[0] - jump_text.get_width() // 2, FONT_POS_JUMP[1]))

pygame.display.flip()

pygame.time.Clock().tick(60)

pygame.quit()