mirror of
https://github.com/metafy-social/python-scripts.git
synced 2024-11-23 20:11:10 +00:00
commit
f330631c2f
4
scripts/Brick-Breaker-Python/README.md
Normal file
4
scripts/Brick-Breaker-Python/README.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Brick-Breaker-Python
|
||||
Brick breaker game in which there is a ball that bounces of a platform to break a brick wall and the player has to keep the ball going by making sure the paddle is always there to bounce off the ball back.
|
||||
|
||||
The game will have three layers of bricks, and each layer of brick will have a different hit capacity, which means some bricks will break in a single hit, some will require a double hit and some will require three hits.
|
229
scripts/Brick-Breaker-Python/main.py
Normal file
229
scripts/Brick-Breaker-Python/main.py
Normal file
|
@ -0,0 +1,229 @@
|
|||
import pygame
|
||||
import math
|
||||
|
||||
pygame.init()
|
||||
|
||||
WIDTH, HEIGHT = 800, 600
|
||||
win = pygame.display.set_mode((WIDTH, HEIGHT))
|
||||
pygame.display.set_caption("Brick Breaker")
|
||||
|
||||
FPS = 60
|
||||
PADDLE_WIDTH = 100
|
||||
PADDLE_HEIGHT = 15
|
||||
BALL_RADIUS = 10
|
||||
|
||||
LIVES_FONT = pygame.font.SysFont("comicsans", 40)
|
||||
|
||||
|
||||
class Paddle:
|
||||
VEL = 5
|
||||
|
||||
def __init__(self, x, y, width, height, color):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.color = color
|
||||
|
||||
def draw(self, win):
|
||||
pygame.draw.rect(
|
||||
win, self.color, (self.x, self.y, self.width, self.height))
|
||||
|
||||
def move(self, direction=1):
|
||||
self.x = self.x + self.VEL * direction
|
||||
|
||||
|
||||
class Ball:
|
||||
VEL = 5
|
||||
|
||||
def __init__(self, x, y, radius, color):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.radius = radius
|
||||
self.color = color
|
||||
self.x_vel = 0
|
||||
self.y_vel = -self.VEL
|
||||
|
||||
def move(self):
|
||||
self.x += self.x_vel
|
||||
self.y += self.y_vel
|
||||
|
||||
def set_vel(self, x_vel, y_vel):
|
||||
self.x_vel = x_vel
|
||||
self.y_vel = y_vel
|
||||
|
||||
def draw(self, win):
|
||||
pygame.draw.circle(win, self.color, (self.x, self.y), self.radius)
|
||||
|
||||
|
||||
class Brick:
|
||||
def __init__(self, x, y, width, height, health, colors):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.health = health
|
||||
self.max_health = health
|
||||
self.colors = colors
|
||||
self.color = colors[0]
|
||||
|
||||
def draw(self, win):
|
||||
pygame.draw.rect(
|
||||
win, self.color, (self.x, self.y, self.width, self.height))
|
||||
|
||||
def collide(self, ball):
|
||||
if not (ball.x <= self.x + self.width and ball.x >= self.x):
|
||||
return False
|
||||
if not (ball.y - ball.radius <= self.y + self.height):
|
||||
return False
|
||||
|
||||
self.hit()
|
||||
ball.set_vel(ball.x_vel, ball.y_vel * -1)
|
||||
return True
|
||||
|
||||
def hit(self):
|
||||
self.health -= 1
|
||||
self.color = self.interpolate(
|
||||
*self.colors, self.health/self.max_health)
|
||||
|
||||
@staticmethod
|
||||
def interpolate(color_a, color_b, t):
|
||||
# 'color_a' and 'color_b' are RGB tuples
|
||||
# 't' is a value between 0.0 and 1.0
|
||||
# this is a naive interpolation
|
||||
return tuple(int(a + (b - a) * t) for a, b in zip(color_a, color_b))
|
||||
|
||||
|
||||
def draw(win, paddle, ball, bricks, lives):
|
||||
win.fill("white")
|
||||
paddle.draw(win)
|
||||
ball.draw(win)
|
||||
|
||||
for brick in bricks:
|
||||
brick.draw(win)
|
||||
|
||||
lives_text = LIVES_FONT.render(f"Lives: {lives}", 1, "black")
|
||||
win.blit(lives_text, (10, HEIGHT - lives_text.get_height() - 10))
|
||||
|
||||
pygame.display.update()
|
||||
|
||||
|
||||
def ball_collision(ball):
|
||||
if ball.x - BALL_RADIUS <= 0 or ball.x + BALL_RADIUS >= WIDTH:
|
||||
ball.set_vel(ball.x_vel * -1, ball.y_vel)
|
||||
if ball.y + BALL_RADIUS >= HEIGHT or ball.y - BALL_RADIUS <= 0:
|
||||
ball.set_vel(ball.x_vel, ball.y_vel * -1)
|
||||
|
||||
|
||||
def ball_paddle_collision(ball, paddle):
|
||||
if not (ball.x <= paddle.x + paddle.width and ball.x >= paddle.x):
|
||||
return
|
||||
if not (ball.y + ball.radius >= paddle.y):
|
||||
return
|
||||
|
||||
paddle_center = paddle.x + paddle.width/2
|
||||
distance_to_center = ball.x - paddle_center
|
||||
|
||||
percent_width = distance_to_center / paddle.width
|
||||
angle = percent_width * 90
|
||||
angle_radians = math.radians(angle)
|
||||
|
||||
x_vel = math.sin(angle_radians) * ball.VEL
|
||||
y_vel = math.cos(angle_radians) * ball.VEL * -1
|
||||
|
||||
ball.set_vel(x_vel, y_vel)
|
||||
|
||||
|
||||
def generate_bricks(rows, cols):
|
||||
gap = 2
|
||||
brick_width = WIDTH // cols - gap
|
||||
brick_height = 20
|
||||
|
||||
bricks = []
|
||||
for row in range(rows):
|
||||
for col in range(cols):
|
||||
brick = Brick(col * brick_width + gap * col, row * brick_height +
|
||||
gap * row, brick_width, brick_height, 2, [(0, 255, 0), (255, 0, 0)])
|
||||
bricks.append(brick)
|
||||
|
||||
return bricks
|
||||
|
||||
|
||||
def main():
|
||||
clock = pygame.time.Clock()
|
||||
|
||||
paddle_x = WIDTH/2 - PADDLE_WIDTH/2
|
||||
paddle_y = HEIGHT - PADDLE_HEIGHT - 5
|
||||
paddle = Paddle(paddle_x, paddle_y, PADDLE_WIDTH, PADDLE_HEIGHT, "black")
|
||||
ball = Ball(WIDTH/2, paddle_y - BALL_RADIUS, BALL_RADIUS, "black")
|
||||
|
||||
bricks = generate_bricks(3, 10)
|
||||
lives = 3
|
||||
|
||||
def reset():
|
||||
paddle.x = paddle_x
|
||||
paddle.y = paddle_y
|
||||
ball.x = WIDTH/2
|
||||
ball.y = paddle_y - BALL_RADIUS
|
||||
|
||||
|
||||
def display_text(text):
|
||||
text_render = LIVES_FONT.render(text, 1, "red")
|
||||
win.blit(text_render, (WIDTH/2 - text_render.get_width() /
|
||||
2, HEIGHT/2 - text_render.get_height()/2))
|
||||
pygame.display.update()
|
||||
pygame.time.delay(3000)
|
||||
|
||||
run = True
|
||||
while run:
|
||||
clock.tick(FPS)
|
||||
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
run = False
|
||||
break
|
||||
|
||||
keys = pygame.key.get_pressed()
|
||||
|
||||
if keys[pygame.K_LEFT] and paddle.x - paddle.VEL >= 0:
|
||||
paddle.move(-1)
|
||||
if keys[pygame.K_RIGHT] and paddle.x + paddle.width + paddle.VEL <= WIDTH:
|
||||
paddle.move(1)
|
||||
|
||||
ball.move()
|
||||
ball_collision(ball)
|
||||
ball_paddle_collision(ball, paddle)
|
||||
|
||||
for brick in bricks[:]:
|
||||
brick.collide(ball)
|
||||
|
||||
if brick.health <= 0:
|
||||
bricks.remove(brick)
|
||||
|
||||
# lives check
|
||||
if ball.y + ball.radius >= HEIGHT:
|
||||
lives -= 1
|
||||
ball.x = paddle.x + paddle.width/2
|
||||
ball.y = paddle.y - BALL_RADIUS
|
||||
ball.set_vel(0, ball.VEL * -1)
|
||||
|
||||
if lives <= 0:
|
||||
bricks = generate_bricks(3, 10)
|
||||
lives = 3
|
||||
reset()
|
||||
display_text("You Lost!")
|
||||
|
||||
if len(bricks) == 0:
|
||||
bricks = generate_bricks(3, 10)
|
||||
lives = 3
|
||||
reset()
|
||||
display_text("You Won!")
|
||||
|
||||
draw(win, paddle, ball, bricks, lives)
|
||||
|
||||
pygame.quit()
|
||||
quit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue
Block a user