Skip to content
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
158 changes: 158 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# IDE and Editor files
.vscode/
.idea/
*.swp
*.swo
*~

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Game specific files
*.save
*.dat
highscores.txt
game_data/
saves/

# Temporary files
*.tmp
*.temp
temp/
tmp/
102 changes: 79 additions & 23 deletions Flappy Bird.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
BIRD_SIZE = 40
PIPE_WIDTH = 60
PIPE_GAP = 200
GRAVITY = 0.5
GRAVITY = 0.8
FLAP_STRENGTH = 10
FORWARD_VELOCITY = 2 # Forward velocity of the bird
PIPE_SPEED = 3 # Speed at which pipes move towards the bird
COUNTDOWN_TIME = 3 * 1000 # 3 seconds

# Colors
Expand All @@ -35,22 +35,40 @@
bird_velocity = 0
score = 0
game_over = False
paused = False
countdown_start_time = pygame.time.get_ticks() + COUNTDOWN_TIME
PIPE_HEIGHT = random.randint(100, 400) # Initial pipe height

# Initial pipe position
pipe_x = WIDTH
PIPE_HEIGHT = random.randint(100, 400)

def reset_game():
"""Reset all game variables to initial state"""
global bird_x, bird_y, bird_velocity, score, game_over, paused, countdown_start_time, pipe_x, PIPE_HEIGHT
bird_x = WIDTH // 4
bird_y = HEIGHT // 2
bird_velocity = 0
score = 0
game_over = False
paused = False
countdown_start_time = pygame.time.get_ticks() + COUNTDOWN_TIME
pipe_x = WIDTH
PIPE_HEIGHT = random.randint(100, 400)

# Game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN and not game_over:
if event.key == pygame.K_SPACE:
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and not game_over and not paused:
bird_velocity = -FLAP_STRENGTH
elif event.key == pygame.K_p and not game_over:
paused = not paused
elif event.key == pygame.K_r and game_over:
reset_game()

if not game_over:
current_time = pygame.time.get_ticks()
Expand All @@ -62,27 +80,40 @@
font = pygame.font.Font(None, 72)
countdown_text = font.render(str(countdown), True, GREEN)
screen.blit(countdown_text, ((WIDTH - countdown_text.get_width()) // 2, (HEIGHT - countdown_text.get_height()) // 2))

# Display controls
controls_font = pygame.font.Font(None, 24)
controls_text = [
"Controls:",
"SPACE - Flap",
"P - Pause/Resume",
"R - Restart (when game over)"
]
for i, text in enumerate(controls_text):
control_surface = controls_font.render(text, True, GREEN)
screen.blit(control_surface, (10, 10 + i * 25))
else:
bird_x += FORWARD_VELOCITY # Add forward motion
bird_velocity += GRAVITY
bird_y += bird_velocity
if not paused:
# Bird only moves vertically, not horizontally
bird_velocity += GRAVITY
bird_y += bird_velocity

# Check for collisions
if bird_y < 0 or bird_y > HEIGHT - GROUND_HEIGHT:
game_over = True
# Check for collisions
if bird_y < 0 or bird_y > HEIGHT - GROUND_HEIGHT:
game_over = True

# Move pipes
pipe_x -= 5
# Move pipes towards the bird
pipe_x -= PIPE_SPEED

if pipe_x < -PIPE_WIDTH:
pipe_x = WIDTH
PIPE_HEIGHT = random.randint(100, 400)
score += 1
if pipe_x < -PIPE_WIDTH:
pipe_x = WIDTH
PIPE_HEIGHT = random.randint(100, 400)
score += 1

# Check for collisions with pipes
if bird_x < pipe_x + PIPE_WIDTH and bird_x + BIRD_SIZE > pipe_x:
if bird_y < PIPE_HEIGHT or bird_y + BIRD_SIZE > PIPE_HEIGHT + PIPE_GAP:
game_over = True
# Check for collisions with pipes
if bird_x < pipe_x + PIPE_WIDTH and bird_x + BIRD_SIZE > pipe_x:
if bird_y < PIPE_HEIGHT or bird_y + BIRD_SIZE > PIPE_HEIGHT + PIPE_GAP:
game_over = True

# Draw everything
screen.fill(WHITE)
Expand All @@ -91,16 +122,41 @@
pygame.draw.rect(screen, GREEN, (0, HEIGHT - GROUND_HEIGHT, WIDTH, GROUND_HEIGHT))
screen.blit(bird_image, (bird_x, bird_y))

# Display score
font = pygame.font.Font(None, 36)
score_text = font.render(f"Score: {score}", True, GREEN)
screen.blit(score_text, (10, 10))

# Display pause message if paused
if paused:
font = pygame.font.Font(None, 48)
pause_text = font.render("PAUSED", True, GREEN)
screen.blit(pause_text, ((WIDTH - pause_text.get_width()) // 2, (HEIGHT - pause_text.get_height()) // 2))
instruction_font = pygame.font.Font(None, 24)
instruction_text = instruction_font.render("Press P to resume", True, GREEN)
screen.blit(instruction_text, ((WIDTH - instruction_text.get_width()) // 2, (HEIGHT - instruction_text.get_height()) // 2 + 50))

pygame.display.update()
clock.tick(30)
else:
# Game over screen
screen.fill(WHITE)
font = pygame.font.Font(None, 72)
game_over_text = font.render("Game Over", True, GREEN)
screen.blit(game_over_text, ((WIDTH - game_over_text.get_width()) // 2, (HEIGHT - game_over_text.get_height()) // 2))
screen.blit(game_over_text, ((WIDTH - game_over_text.get_width()) // 2, (HEIGHT - game_over_text.get_height()) // 2 - 50))

# Display final score
score_font = pygame.font.Font(None, 36)
final_score_text = score_font.render(f"Final Score: {score}", True, GREEN)
screen.blit(final_score_text, ((WIDTH - final_score_text.get_width()) // 2, (HEIGHT - final_score_text.get_height()) // 2))

# Display restart instruction
instruction_font = pygame.font.Font(None, 24)
restart_text = instruction_font.render("Press R to restart", True, GREEN)
screen.blit(restart_text, ((WIDTH - restart_text.get_width()) // 2, (HEIGHT - restart_text.get_height()) // 2 + 50))

pygame.display.update()
pygame.time.wait(2000) # Wait for 2 seconds before closing the game
running = False
clock.tick(30)

pygame.quit()
sys.exit()
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pygame==2.6.1