Blockwars Game
This commit is contained in:
1 parent
7216a7db56
commit
affdf0391a
6 files changed
+321
No files matched your search
@@ -0,0 +1,321 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# Description: blockwars - A simple game written in Python.
|
||||||
|
# Usage: python3 blockwars.py
|
||||||
|
# Author: Justin Oros
|
||||||
|
# Source: https://github.com/JustinOros
|
||||||
|
|
||||||
|
import pygame
|
||||||
|
import random
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Initialize pygame
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
# Set up full-screen mode
|
||||||
|
SCREEN_WIDTH = pygame.display.Info().current_w
|
||||||
|
SCREEN_HEIGHT = pygame.display.Info().current_h
|
||||||
|
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.FULLSCREEN)
|
||||||
|
pygame.display.set_caption("Block Wars")
|
||||||
|
|
||||||
|
# Define colors
|
||||||
|
WHITE = (255, 255, 255)
|
||||||
|
BLUE = (0, 0, 255)
|
||||||
|
RED = (255, 0, 0)
|
||||||
|
DARK_GRAY = (50, 50, 50)
|
||||||
|
|
||||||
|
# Function to load sound safely
|
||||||
|
def load_sound(filename):
|
||||||
|
if os.path.exists(filename):
|
||||||
|
return pygame.mixer.Sound(filename)
|
||||||
|
else:
|
||||||
|
print(f"Warning: {filename} not found. Sound will be disabled.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Load sounds
|
||||||
|
GO_SOUND = load_sound("go_sound.wav")
|
||||||
|
FIRE_SOUND = load_sound("player_fire_sound.wav")
|
||||||
|
DIE_SOUND = load_sound("player_death_sound.wav")
|
||||||
|
LEVEL_UP_SOUND = load_sound("level_up_sound.wav")
|
||||||
|
ENEMY_DEATH_SOUND = load_sound("enemy_death_sound.wav")
|
||||||
|
EXPLOSION_SOUND = load_sound("explosion_sound.wav")
|
||||||
|
|
||||||
|
# Set font for score
|
||||||
|
font = pygame.font.SysFont(None, 30)
|
||||||
|
|
||||||
|
# Initialize the joystick (controller)
|
||||||
|
pygame.joystick.init()
|
||||||
|
controller = None
|
||||||
|
if pygame.joystick.get_count() > 0:
|
||||||
|
controller = pygame.joystick.Joystick(0)
|
||||||
|
controller.init()
|
||||||
|
|
||||||
|
# Player class
|
||||||
|
class Player:
|
||||||
|
def __init__(self):
|
||||||
|
self.x = SCREEN_WIDTH // 2
|
||||||
|
self.y = SCREEN_HEIGHT // 2
|
||||||
|
self.size = 20
|
||||||
|
self.color = BLUE
|
||||||
|
self.speed = 5
|
||||||
|
self.direction = None
|
||||||
|
|
||||||
|
def move(self, keys, joystick_axes):
|
||||||
|
if joystick_axes[1] < -0.5:
|
||||||
|
self.y -= self.speed
|
||||||
|
self.direction = 'up'
|
||||||
|
elif joystick_axes[1] > 0.5:
|
||||||
|
self.y += self.speed
|
||||||
|
self.direction = 'down'
|
||||||
|
if joystick_axes[0] < -0.5:
|
||||||
|
self.x -= self.speed
|
||||||
|
self.direction = 'left'
|
||||||
|
elif joystick_axes[0] > 0.5:
|
||||||
|
self.x += self.speed
|
||||||
|
self.direction = 'right'
|
||||||
|
|
||||||
|
if keys[pygame.K_w]:
|
||||||
|
self.y -= self.speed
|
||||||
|
self.direction = 'up'
|
||||||
|
if keys[pygame.K_s]:
|
||||||
|
self.y += self.speed
|
||||||
|
self.direction = 'down'
|
||||||
|
if keys[pygame.K_a]:
|
||||||
|
self.x -= self.speed
|
||||||
|
self.direction = 'left'
|
||||||
|
if keys[pygame.K_d]:
|
||||||
|
self.x += self.speed
|
||||||
|
self.direction = 'right'
|
||||||
|
|
||||||
|
if self.x < 0:
|
||||||
|
self.x = SCREEN_WIDTH - self.size
|
||||||
|
elif self.x > SCREEN_WIDTH - self.size:
|
||||||
|
self.x = 0
|
||||||
|
if self.y < 0:
|
||||||
|
self.y = SCREEN_HEIGHT - self.size
|
||||||
|
elif self.y > SCREEN_HEIGHT - self.size:
|
||||||
|
self.y = 0
|
||||||
|
|
||||||
|
def draw(self):
|
||||||
|
pygame.draw.rect(screen, self.color, (self.x, self.y, self.size, self.size))
|
||||||
|
|
||||||
|
# Projectile class
|
||||||
|
class Projectile:
|
||||||
|
def __init__(self, x, y, direction):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.size = 5
|
||||||
|
self.color = WHITE
|
||||||
|
self.speed = 15
|
||||||
|
self.direction = direction
|
||||||
|
|
||||||
|
def move(self):
|
||||||
|
if self.direction == 'up':
|
||||||
|
self.y -= self.speed
|
||||||
|
elif self.direction == 'down':
|
||||||
|
self.y += self.speed
|
||||||
|
elif self.direction == 'left':
|
||||||
|
self.x -= self.speed
|
||||||
|
elif self.direction == 'right':
|
||||||
|
self.x += self.speed
|
||||||
|
|
||||||
|
def draw(self):
|
||||||
|
pygame.draw.rect(screen, self.color, (self.x, self.y, self.size, self.size))
|
||||||
|
|
||||||
|
# Explosion class
|
||||||
|
class Explosion:
|
||||||
|
def __init__(self, x, y):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.size = 50
|
||||||
|
self.lifetime = 10
|
||||||
|
|
||||||
|
def draw(self):
|
||||||
|
pygame.draw.circle(screen, (255, 165, 0), (self.x, self.y), self.size)
|
||||||
|
self.lifetime -= 1
|
||||||
|
|
||||||
|
def is_alive(self):
|
||||||
|
return self.lifetime > 0
|
||||||
|
|
||||||
|
# Enemy class
|
||||||
|
class Enemy:
|
||||||
|
def __init__(self, speed):
|
||||||
|
edge = random.choice(["top", "bottom", "left", "right"])
|
||||||
|
if edge == "top":
|
||||||
|
self.x = random.randint(0, SCREEN_WIDTH - 20)
|
||||||
|
self.y = 0
|
||||||
|
elif edge == "bottom":
|
||||||
|
self.x = random.randint(0, SCREEN_WIDTH - 20)
|
||||||
|
self.y = SCREEN_HEIGHT - 20
|
||||||
|
elif edge == "left":
|
||||||
|
self.x = 0
|
||||||
|
self.y = random.randint(0, SCREEN_HEIGHT - 20)
|
||||||
|
else:
|
||||||
|
self.x = SCREEN_WIDTH - 20
|
||||||
|
self.y = random.randint(0, SCREEN_HEIGHT - 20)
|
||||||
|
|
||||||
|
self.size = 20
|
||||||
|
self.color = RED
|
||||||
|
self.speed = speed
|
||||||
|
|
||||||
|
def move(self, player_x, player_y):
|
||||||
|
if self.x < player_x:
|
||||||
|
self.x += self.speed
|
||||||
|
elif self.x > player_x:
|
||||||
|
self.x -= self.speed
|
||||||
|
if self.y < player_y:
|
||||||
|
self.y += self.speed
|
||||||
|
elif self.y > player_y:
|
||||||
|
self.y -= self.speed
|
||||||
|
|
||||||
|
def draw(self):
|
||||||
|
pygame.draw.rect(screen, self.color, (self.x, self.y, self.size, self.size))
|
||||||
|
|
||||||
|
# Draw pause screen
|
||||||
|
def draw_pause_screen():
|
||||||
|
overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
|
||||||
|
overlay.set_alpha(180)
|
||||||
|
overlay.fill((0, 0, 0))
|
||||||
|
screen.blit(overlay, (0, 0))
|
||||||
|
|
||||||
|
pause_font = pygame.font.SysFont(None, 100)
|
||||||
|
instruction_font = pygame.font.SysFont(None, 40)
|
||||||
|
pause_text = pause_font.render("PAUSED", True, WHITE)
|
||||||
|
instruction_text = instruction_font.render("Press ESC to resume or Q to Quit.", True, WHITE)
|
||||||
|
|
||||||
|
screen.blit(pause_text, (
|
||||||
|
SCREEN_WIDTH // 2 - pause_text.get_width() // 2,
|
||||||
|
SCREEN_HEIGHT // 2 - pause_text.get_height() // 2 - 30
|
||||||
|
))
|
||||||
|
screen.blit(instruction_text, (
|
||||||
|
SCREEN_WIDTH // 2 - instruction_text.get_width() // 2,
|
||||||
|
SCREEN_HEIGHT // 2 + 30
|
||||||
|
))
|
||||||
|
|
||||||
|
# Main game loop
|
||||||
|
def game():
|
||||||
|
clock = pygame.time.Clock()
|
||||||
|
player = Player()
|
||||||
|
projectiles = []
|
||||||
|
explosions = []
|
||||||
|
level = 1
|
||||||
|
score = 0
|
||||||
|
enemies = [Enemy(2)]
|
||||||
|
running = True
|
||||||
|
paused = False
|
||||||
|
player_dead = False
|
||||||
|
|
||||||
|
if GO_SOUND:
|
||||||
|
GO_SOUND.play()
|
||||||
|
|
||||||
|
while running:
|
||||||
|
screen.fill(DARK_GRAY)
|
||||||
|
|
||||||
|
keys = pygame.key.get_pressed()
|
||||||
|
joystick_axes = [controller.get_axis(0), controller.get_axis(1)] if controller else [0, 0]
|
||||||
|
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
running = False
|
||||||
|
if event.type == pygame.KEYDOWN:
|
||||||
|
if event.key == pygame.K_ESCAPE:
|
||||||
|
paused = not paused
|
||||||
|
elif paused and event.key == pygame.K_q:
|
||||||
|
running = False
|
||||||
|
elif not paused and event.key == pygame.K_SPACE:
|
||||||
|
if player.direction:
|
||||||
|
projectiles.append(Projectile(player.x + player.size // 2, player.y + player.size // 2, player.direction))
|
||||||
|
if FIRE_SOUND:
|
||||||
|
FIRE_SOUND.play()
|
||||||
|
if event.type == pygame.JOYBUTTONDOWN:
|
||||||
|
if event.button == 7 or event.button == 6: # Start or Select
|
||||||
|
paused = not paused
|
||||||
|
elif paused and event.button == 2: # X button
|
||||||
|
running = False
|
||||||
|
elif not paused and event.button == 0: # A button
|
||||||
|
if player.direction:
|
||||||
|
projectiles.append(Projectile(player.x + player.size // 2, player.y + player.size // 2, player.direction))
|
||||||
|
if FIRE_SOUND:
|
||||||
|
FIRE_SOUND.play()
|
||||||
|
if event.type == pygame.MOUSEBUTTONDOWN:
|
||||||
|
if not paused and event.button == 1:
|
||||||
|
if player.direction:
|
||||||
|
projectiles.append(Projectile(player.x + player.size // 2, player.y + player.size // 2, player.direction))
|
||||||
|
if FIRE_SOUND:
|
||||||
|
FIRE_SOUND.play()
|
||||||
|
|
||||||
|
if paused:
|
||||||
|
draw_pause_screen()
|
||||||
|
pygame.display.flip()
|
||||||
|
clock.tick(60)
|
||||||
|
continue
|
||||||
|
|
||||||
|
player.move(keys, joystick_axes)
|
||||||
|
|
||||||
|
for projectile in projectiles[:]:
|
||||||
|
projectile.move()
|
||||||
|
projectile.draw()
|
||||||
|
if projectile.x < 0 or projectile.x > SCREEN_WIDTH or projectile.y < 0 or projectile.y > SCREEN_HEIGHT:
|
||||||
|
projectiles.remove(projectile)
|
||||||
|
|
||||||
|
for enemy in enemies[:]:
|
||||||
|
enemy.move(player.x, player.y)
|
||||||
|
enemy.draw()
|
||||||
|
|
||||||
|
if pygame.Rect(player.x, player.y, player.size, player.size).colliderect(
|
||||||
|
pygame.Rect(enemy.x, enemy.y, enemy.size, enemy.size)):
|
||||||
|
if not player_dead:
|
||||||
|
if DIE_SOUND:
|
||||||
|
DIE_SOUND.play()
|
||||||
|
player_dead = True
|
||||||
|
show_final_score(score)
|
||||||
|
running = False
|
||||||
|
|
||||||
|
for projectile in projectiles[:]:
|
||||||
|
if pygame.Rect(enemy.x, enemy.y, enemy.size, enemy.size).colliderect(
|
||||||
|
pygame.Rect(projectile.x, projectile.y, projectile.size, projectile.size)):
|
||||||
|
explosions.append(Explosion(enemy.x + enemy.size // 2, enemy.y + enemy.size // 2))
|
||||||
|
if ENEMY_DEATH_SOUND:
|
||||||
|
ENEMY_DEATH_SOUND.play()
|
||||||
|
enemies.remove(enemy)
|
||||||
|
projectiles.remove(projectile)
|
||||||
|
score += 100
|
||||||
|
break
|
||||||
|
|
||||||
|
for explosion in explosions[:]:
|
||||||
|
explosion.draw()
|
||||||
|
if not explosion.is_alive():
|
||||||
|
explosions.remove(explosion)
|
||||||
|
|
||||||
|
if not enemies:
|
||||||
|
level += 1
|
||||||
|
if LEVEL_UP_SOUND:
|
||||||
|
LEVEL_UP_SOUND.play()
|
||||||
|
enemy_speed = 2 + (level // 3)
|
||||||
|
enemies = [Enemy(enemy_speed) for _ in range(level)]
|
||||||
|
|
||||||
|
player.draw()
|
||||||
|
|
||||||
|
score_text = font.render(f"Score: {score}", True, WHITE)
|
||||||
|
level_text = font.render(f"Level: {level}", True, WHITE)
|
||||||
|
screen.blit(score_text, (10, 10))
|
||||||
|
screen.blit(level_text, (SCREEN_WIDTH - level_text.get_width() - 10, 10))
|
||||||
|
|
||||||
|
pygame.display.flip()
|
||||||
|
clock.tick(60)
|
||||||
|
|
||||||
|
# Function to display the final score on death
|
||||||
|
def show_final_score(score):
|
||||||
|
font_large = pygame.font.SysFont(None, 80)
|
||||||
|
final_score_text = font_large.render(f"Final Score: {score}", True, WHITE)
|
||||||
|
screen.fill(DARK_GRAY)
|
||||||
|
screen.blit(final_score_text, (SCREEN_WIDTH // 2 - final_score_text.get_width() // 2, SCREEN_HEIGHT // 2 - final_score_text.get_height() // 2))
|
||||||
|
pygame.display.flip()
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
# Run the game
|
||||||
|
if __name__ == "__main__":
|
||||||
|
game()
|
||||||
|
|
||||||
|
pygame.quit()
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in new issue
Block a user