Skip to content
This repository was archived by the owner on Aug 24, 2018. It is now read-only.
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
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"python.pythonPath": "C:\\Users\\Me\\.virtualenvs\\Sprint-Challenge--Graphs-zXtD9vvw\\Scripts\\python.exe"
}
33 changes: 28 additions & 5 deletions src/ball.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import math
import math

from pygame.math import Vector2
from pygame import Rect

from block import KineticBlock
from block import KineticBlock, UnbreakableBlock, GhostBlock

class Ball:
"""
base class for bouncing objects
"""
#This class is the "template" for the various types of balls that are playable in the game
def __init__(self, bounds, position, velocity, color, radius):
self.position = position
self.velocity = velocity
self.bounds = bounds
self.color = color
self.radius = radius
self.collision_rectangle = self.update_rectangle()
self.game_over = False
self.points = 0

def update_rectangle(self):
return Rect(self.position.x - self.radius,
Expand All @@ -29,13 +32,21 @@ def update(self, **kwargs):
if self.position.x >= self.bounds[0] - self.radius:
self.position.x = self.bounds[0] - self.radius - 1
self.velocity.x *= -1

#The ball has reached the top of the screen and a point is awarded
if self.position.y <= 0 + self.radius: # screen height
self.position.y = self.radius + 1
self.velocity.y *= -1
self.points += 1
print("Score: ", self.points)

#The ball has hit the bottom of the screen, GAME OVER :(
if self.position.y >= self.bounds[1] - self.radius:
self.position.y = self.bounds[1] - self.radius - 1
self.velocity.y *= -1

self.velocity.y = 0
self.velocity.x = 0
self.game_over = True

self.position += self.velocity
self.collision_rectangle = self.update_rectangle()

Expand Down Expand Up @@ -118,6 +129,7 @@ def collide_with_rectangle(self, object):

if test == 1:
object.touched_by_ball = True
object.check_collision()
# the ball has collided with an edge
# TODO: # fix sticky edges
if left or right:
Expand Down Expand Up @@ -163,7 +175,18 @@ def check_collision(self):
index = self.object_list.index(self)
for object in self.object_list[index+1:]: # TODO: Check effeciency
# Balls colliding with blocks
if issubclass(type(object), KineticBlock) and object != self:
kinetic = issubclass(type(object), KineticBlock)
paddle = issubclass(type(object), Paddle)
unbreakable = issubclass(type(object), UnbreakableBlock)
ghost = issubclass(type(object), GhostBlock)


if (kinetic and paddle or unbreakable) and object != self:
# Do a first round pass for collision (we know object is a KineticBlock)
if self.collision_rectangle.colliderect(object.rectangle):
self.collide_with_rectangle(object)
if ghost:
if self.collision_rectangle.colliderect(object.rectangle):
print("GHOSTBUSTER")
object.touched_by_ball = True
object.check_collision()
82 changes: 79 additions & 3 deletions src/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,84 @@ def draw(self, screen, pygame):
pygame.draw.rect(screen, self.color, self.rectangle)

class KineticBlock(Block):
# No custom code needed here, just want to be able to differentiate
# KineticBall will handle the collison
pass
def __init__(self, position, width, height, color, hits):
super().__init__(position, width, height, color)
self.hits_to_break = hits
self.broken = False
self.colors = [[255, 0, 0], [255,140,0], [0, 255, 0]]
self.color = self.colors[-hits]

def check_collision(self):
if self.touched_by_ball:
self.hits_to_break -= 1
self.color = self.colors[-self.hits_to_break]
if self.hits_to_break == 0:
self.broken = True

class UnbreakableBlock(Block):
#This a block that is bounceable but not breakable

def __init__(self, position, width, height, color):
super().__init__(position, width, height, color)
self.color = [75, 75, 75]

class GhostBlock(Block):
#The block is destroyed when hit but the ball can't bounce off of it
def __init__(self, position, width, height, color):
super().__init__(position, width, height, color)
self.color = [200, 200, 200]
self.broken = False

def check_collision(self):
if self.touched_by_ball:
self.broken = True

class Paddle(KineticBlock):
#this is the paddle that the player controls at the bottom of the screen

def update(self, **kwargs):
distance = 2
for k, v in kwargs.items():
if k == "left" and v == True:
self.rectangle = self.rectangle.move(-distance, 0)
self.position.x -= distance
if k == "right" and v == True:
self.rectangle = self.rectangle.move(distance, 0)
self.position.x += distance


if self.left:
self.position.x -= self.SPEED

if self.right:
self.position.x += self.SPEED

self.rectangle = pygame.Rect(
self.position.x - (self.rectangle.width/2),
self.position.y - (self.rectangle.height/2),
self.rectangle.width,
self.rectangle.height
)
super().update()

class EasyBlock(KineticBlock):
def update(self, **kwargs):
if self.touched_by_ball:
kwargs['object_list'].pop(kwargs['object_list'].index(self))


class HardBlock(EasyBlock):
def __init__(self, life, position, width, height, color):
self.life = life
super().__init__(position, width, height, color)

rand_color = [random.randint(0, 255), random.randint(0, 255), random.randint(0,255)]

def update(self, **kwargs):
if self.touched_by_ball:
self.life -= 1
self.color = self.random_color
if self.life <= 0:
super().update(object_list = kwargs['object_list'])
else:
self.touched_by_ball = False
83 changes: 71 additions & 12 deletions src/draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,65 @@
from ball import *
from block import *

SCREEN_SIZE = [640, 480]
SCREEN_SIZE = [400, 800]
BACKGROUND_COLOR = [255, 255, 255]

def debug_create_objects(object_list):
kinetic = GameBall(1, object_list, SCREEN_SIZE,
Vector2(random.randint(20, SCREEN_SIZE[0] - 20), random.randint(20, SCREEN_SIZE[1] - 20)),
Vector2(4*random.random() - 2, 4*random.random() - 2),
Vector2(random.randint(20, SCREEN_SIZE[0] - 20), random.randint(20, SCREEN_SIZE[1] - 350)),
Vector2(4*random.random() - 2, 4),
[255, 10, 0], 20)
object_list.append(kinetic)

block = KineticBlock(Vector2(200,200), 100, 100, [0, 0, 255])
object_list.append(block)

block1_size = random.randint(40, 100)
block1_hits = 1
block1_color = [0, 0, 255]
block1 = KineticBlock(
Vector2(random.randint(block1_size, SCREEN_SIZE[0]-block1_size),
random.randint(block1_size, SCREEN_SIZE[1]-300)),
block1_size, block1_size, block1_color, block1_hits)
object_list.append(block1)

block2_size = random.randint(40, 100)
block2_hits = 3
block2_color = [0, 125, 0]
block2 = KineticBlock(
Vector2(random.randint(block2_size, SCREEN_SIZE[0]-block2_size),
random.randit(block2_size, SCREEN_SIZE[1]-300)),
block2_size, block2_size, block2_color, block2_hits)
object_list.append(block2)

block3_size = random.randint(40, 100)
block3_hits = 2
block3_color = [125, 0, 125]
block3 = KineticBlock(
Vector2(random.randint(int(block3_size/2), SCREEN_SIZE[0]-int(block3_size/2)),
random.randint(block3_size, SCREEN_SIZE[1]-300)),
block3_size, block3_size, block3_color, block3_hits)
object_list.append(block3)
unbreakable_size = random.randint(40, 100)
unbreakable = UnbreakableBlock(
Vector2(random.randint(int(unbreakable_size/2), SCREEN_SIZE[0]-int(unbreakable_size/2)),
random.randint(unbreakable_size, SCREEN_SIZE[1]-300)),
unbreakable_size, unbreakable_size, [0, 0, 0])
object_list.append(unbreakable)

ghost_size = random.randint(40, 100)
ghost = GhostBlock(
Vector2(random.randint(int(ghost_size/2), SCREEN_SIZE[0]-int(ghost_size/2)),
random.randint(ghost_size, SCREEN_SIZE[1]-300)),
ghost_size, ghost_size, [0, 0, 0])
object_list.append(ghost)
paddle = Paddle(Vector2(SCREEN_SIZE[0]/2, SCREEN_SIZE[1]-15), 100, 30, [0, 0, 0])
object_list.append(paddle)

def continue_playing(obj_list):
for obj in obj_list:
if isinstance(obj, KineticBlock):
return True
print("YOU WIN!")
return False

def main():
pygame.init()
screen = pygame.display.set_mode(SCREEN_SIZE)
Expand All @@ -29,23 +75,36 @@ def main():
object_list = [] # list of objects of all types in the toy

debug_create_objects(object_list)

playing = True

while True: # TODO: Create more elegant condition for loop
while playing:
left = False
right = False

playing = continue_playing(object_list)

for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()

#TODO: Feed input variables into update for objects that need it.
if event.type == pygame.QUIT:
playing = False
break

keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
left = True
if keys[pygame.K_RIGHT]:
right = True
for object in object_list:
object.update()
if hasattr(object, 'defeated'):
if object.defeated == True:
object_list.remove(object)
object.update(left=left, right=right)
object.check_collision()

if hasattr(object, 'game_over'):
if object.game_over == True:
print('GAME OVER')
playing = False

# Draw Updates
screen.fill(BACKGROUND_COLOR)
Expand All @@ -59,4 +118,4 @@ def main():
pygame.quit()

if __name__ == "__main__":
main()
main()