Skip to content

Added Brick Breaker #431

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

Merged
merged 2 commits into from
Oct 15, 2022
Merged
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
4 changes: 4 additions & 0 deletions scripts/Brick-Breaker-Python/README.md
Original file line number Diff line number Diff line change
@@ -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 changes: 229 additions & 0 deletions scripts/Brick-Breaker-Python/main.py
Original file line number Diff line number Diff line change
@@ -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()