import pygame
from pygame.locals import *
import random
import time


pygame.mixer.pre_init(44100, -16, 2, 2048)
pygame.init()

pygame.mixer.music.load("music.mp3")  
pygame.mixer.music.set_volume(0.5)

screenWidth = 900
screenHeight = 600
framerate = 100
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
blue = (130,130,255)
lightblue = (180,180,255)
darkblue = (50,50,255)
grey = (130,130,130)
darkgrey = (50,50,50)
lightorange = (255,190,65)
brown3 = (205,51,51)
chocolate1 = (255,127,36)
burlywood = (222,184,135)
tan1 = (255,165,79)
RoyalBlue1 = (72,118,255)
PaleTurquoise = (175,238,238)
SlateBlue3 = (105,89,205)
LightSlateGray = (119,136,153)
SeaGreen1 = (84,255,159)
DarkSeaGreen = (43,188,143)
r1 = (201, 31, 22)
r2 = (202, 35, 22)
r3 = (204, 42, 19)
r4 = (208, 56, 21)
r5 = (204, 54, 21)
r6 = (210, 61, 22)
r7 = (211, 72, 16)
r8 = (212, 75, 13)
r9 = (217, 88, 14)
r10 = (217, 91, 15)
r11 = (218, 95, 14)
r12 = (219, 100, 13)
r13 = (221, 104, 11)
r14 = (220, 110, 13)
r15 = (227, 117, 9)
r16 = (231, 134, 11)
r17 = (230, 134, 1)
r18 = (237, 158, 10)
r19 = (241, 166, 10)
r20 = (241, 173, 6)
r21 = (238, 173, 0)
r22 = (247, 189, 0)
r23 = (245, 182, 0)
r24 = (249, 198, 15)
r25 = (252, 207, 3)
r26 = (251, 213, 10)
r27 = (252, 229, 3)
r28 = (246, 230, 10)
r29 = (237, 228, 0)
r30 = (230, 226, 9)
r31 = (223, 220, 9)
r32 = (216, 219, 9)
r33 = (206, 213, 0)
r34 = (197, 211, 0)
r35 = (190, 210, 15)
r36 = (181, 204, 10)
r37 = (176, 197, 15)
r38 = (165, 197, 15)
r39 = (159, 196, 13)
r40 = (152, 193, 0)
r41 = (143, 187, 12)
r42 = (146, 192, 14)
r43 = (127, 181, 19)
r44 = (128, 184, 18)
r45 = (119, 179, 18)
r46 = (113, 179, 14)
r47 = (111, 178, 15)
r48 = (105, 172, 18)
r49 = (105, 176, 17)
r50 = (85, 164, 28)
r51 = (90, 170, 29)
r52 = (78, 164, 29)
r53 = (71, 164, 30)
r54 = (58, 155, 32)
r55 = (52, 155, 38)
r56 = (51, 156, 30)
r57 = (45, 156, 31)
r58 = (43, 155, 34)
r59 = (32, 148, 38)
r60 = (27, 147, 36)
r61 = (24, 148, 37)
r62 = (3, 147, 49)
r63 = (0, 140, 51)
r64 = (9, 141, 58)
r65 = (8, 131, 67)
r66 = (12, 140, 75)
r67 = (0, 132, 74)
r68 = (4, 141, 92)
r69 = (14, 140, 98)
r70 = (8, 141, 108)
r71 = (0, 140, 124)
r72 = (8, 147, 148)
r73 = (5, 148, 157)
r74 = (11, 141, 148)
r75 = (9, 148, 166)
r76 = (0, 157, 190)
r77 = (8, 148, 182)
r78 = (13, 155, 196)
r79 = (0, 157, 207)
r80 = (21, 155, 212)
r81 = (31, 154, 215)
r82 = (20, 141, 198)
r83 = (29, 147, 209)
r84 = (20, 124, 181)
r85 = (13, 132, 196)
r86 = (12, 123, 187)
r87 = (13, 115, 179)
r88 = (16, 108, 172)
r89 = (3, 99, 163)
r90 = (19, 90, 158)
r91 = (8, 82, 147)
r92 = (10, 83, 151)
r93 = (9, 74, 145)
r94 = (13, 66, 132)
r95 = (6, 67, 138)
r96 = (13, 57, 129)
r97 = (17, 50, 121)
r98 = (18, 49, 121)
r99 = (21, 44, 116)
r100 = (24, 42, 113)
r101 = (24, 35, 105)
r102 = (27, 26, 95)
r103 = (24, 28, 103)
r104 = (29, 26, 98)
r105 = (29, 18, 89)
r106 = (30, 16, 89)
r107 = (35, 14, 89)
r108 = (48, 13, 90)
r109 = (49, 12, 90)
r110 = (58, 11, 89)
r111 = (75, 10, 91)
r112 = (81, 9, 90)
r113 = (91, 11, 90)
r114 = (115, 8, 97)
r115 = (107, 1, 90)
r116 = (124, 3, 98)
r117 = (130, 0, 96)
r118 = (139, 10, 98)
r119 = (148, 11, 99)
r120 = (164, 5, 99)
r121 = (174, 9, 100)
r122 = (194, 15, 104)
r123 = (189, 0, 98)
r124 = (196, 0, 99)
r125 = (197, 0, 89)
r126 = (198, 0, 75)

achievement = (0,0,1)

levelSpecs = [	#bricksize, topSpace, hor.space, ver.space
				[(80,30),100,5,5],
				[(70,24),100,3,3],
				[(70,24),50,3,3],
				[(40,24),50,3,3],
				[(60,24),50,5,5],
				[(60,18),50,2,2]]
splitPartsX = 10.0
splitPartsY = 6.0
level3cols = []
level3types = []
for i in range(0,9):
	rowCol = []
	rowType = []
	for j in range (0,14):
		rowCol.append(vars()["r"+str(i*14+j+1)])
		rowType.append(1)
	level3types.append(rowType)
	level3cols.append(rowCol)
levelBrickCols=[
				[	[brown3,brown3,brown3,brown3,brown3,brown3,brown3],
					[chocolate1,chocolate1,chocolate1,chocolate1,chocolate1,chocolate1,chocolate1],
					[burlywood,burlywood,burlywood,burlywood,burlywood,burlywood,burlywood],
					[tan1,tan1,tan1,tan1,tan1,tan1,tan1],
					[lightorange,lightorange,lightorange,lightorange,lightorange,lightorange,lightorange]
				],
				[	[r80,r82,r84,r88,r90,r88,r84,r82,r80],
					[r82,None,None,None,None,None,None,None,r82],
					[r84,None,None,grey,grey,grey,None,None,r84],
					[r88,None,None,grey,red,grey,None,None,r88],
					[r84,None,None,grey,grey,grey,None,None,r84],
					[r82,None,None,None,None,None,None,None,r82],
					[r80,r82,r84,r88,r90,r88,r84,r82,r80]
				],
				[	[r34,r35,r36,r37,r38,r39,r92,r94,r96,r98,r100],
					[r36,r37,r38,r39,r40,r41,r90,r92,r94,r96,r98],
					[r38,r39,r40,r41,r42,r43,r88,r90,r92,r94,r96],
					[r40,r41,r42,r43,r44,r45,r86,r88,r90,r92,r94],
					[r42,r43,r44,r45,r46,r47,r84,r86,r88,r90,r92],
					[r44,r45,r46,r47,r48,r49,r82,r84,r86,r88,r90],
					[r46,r47,r48,r49,r50,r51,r80,r82,r84,r86,r88],
					[r48,r49,r50,r51,r52,r53,r78,r80,r82,r84,r86],
					[r50,r51,r52,r53,r54,r55,r76,r78,r80,r82,r84],
				],
				[	[r20,r20,r20,r20,r20,r20,r20,r20,r20,r20,r20],
					[r20,None,None,None,None,None,None,None,None,None,r20],
					[r20,None,r15,None,r15,None,r15,None,r15,None,r20],
					[r20,None,None,None,None,None,None,None,None,None,r20],
					[r20,None,r10,None,r10,None,r10,None,r10,None,r20],
					[r20,None,None,None,None,None,None,None,None,None,r20],
					[r20,None,r5,None,r5,None,r5,None,r5,None,r20],
					[r20,None,None,None,None,None,None,None,None,None,r20],
					[r20,r20,r20,r20,r20,r20,r20,r20,r20,r20,r20]
				],
				[	[r126,None,None,r126,r120,r118,r110,r118,r120,r126,None,None,r126],
					[r120,r126,None,None,r126,r120,r118,r120,r126,None,None,r126,r120],
					[r118,r120,r126,None,None,r126,r120,r126,None,None,r126,r120,r118],
					[r116,r118,r120,r126,None,None,r126,None,None,r126,r120,r118,r116],
					[r114,r116,r118,r120,r126,None,None,None,r126,r120,r118,r116,r114],
					[r116,r118,r120,r126,None,None,r126,None,None,r126,r120,r118,r116],
					[r118,r120,r126,None,None,r126,r120,r126,None,None,r126,r120,r118],
					[r120,r126,None,None,r126,r120,r118,r120,r126,None,None,r126,r120],
					[r126,None,None,r126,r120,r118,r110,r118,r120,r126,None,None,r126],
				],
				level3cols
]
levelBrickTypes=[
				[	[1,1,1,1,1,1,1],
					[1,1,1,1,1,1,1],
					[1,1,14,1,14,1,1],
					[1,1,1,1,1,1,1],
					[1,1,1,1,1,1,1]
				],
				[	[1,1,1,1,1,1,1,1,1],
					[1,0,0,0,0,0,0,0,1],
					[1,0,0,103,103,103,0,0,1],
					[1,0,0,103,12,103,0,0,1],
					[1,0,0,103,103,103,0,0,1],
					[1,0,0,0,0,0,0,0,1],
					[1,1,1,1,1,1,1,1,1],
				],
				[	[1,0,0,0,12,0,13,0,0,0,1],
					[1,0,1,0,0,0,0,0,1,0,1],
					[1,0,1,0,1,0,1,0,1,0,1],
					[1,0,1,0,1,0,1,0,1,0,1],
					[1,1,1,1,1,0,1,1,1,1,1],
					[1,0,1,0,1,0,1,0,1,0,1],
					[1,0,1,0,1,0,1,0,1,0,1],
					[1,0,1,0,0,0,0,0,1,0,1],
					[1,0,0,0,0,0,0,0,0,0,1],
				],
				[	[103,101,102,102,103,101,103,102,102,103,103],
					[101,0,0,0,0,0,0,0,0,0,102],
					[103,0,14,0,14,0,14,0,14,0,103],
					[102,0,0,0,0,0,0,0,0,0,101],
					[103,0,14,0,14,0,14,0,14,0,101],
					[101,0,0,0,0,0,0,0,0,0,103],
					[102,0,14,0,14,0,14,0,14,0,102],
					[101,0,0,0,0,0,0,0,0,0,103],
					[103,102,101,103,103,101,103,102,102,103,103],
				],
				[	[105,0,0,105,1,1,13,1,1,105,0,0,105],
					[1,105,0,0,105,1,1,1,105,0,0,105,1],
					[1,1,105,0,0,105,1,105,0,0,105,1,1],
					[1,1,1,105,0,0,105,0,0,105,1,1,1],
					[14,1,1,1,105,0,0,0,105,1,1,1,14],
					[1,1,1,105,0,0,105,0,0,105,1,1,1],
					[1,1,105,0,0,105,1,105,0,0,105,1,1],
					[1,105,0,0,105,1,1,1,105,0,0,105,1],
					[105,0,0,105,1,1,12,1,1,105,0,0,105]
				],
				level3types
]

boardSize = (60,10)
boardSpeed = 0.0
maxBoardSpeed = 500.0
ballXPos = 0
ySpeed = 300.0
xSpeed = 300.0
border = 5
bottomBorder = 10
hover = 5
topBorder = 20
score = 0
ballRadius = 7.0
ballColor = lightblue
ballComing = False
splash = False
splashTime = 0
waterTime = 0
waterSpeed = 0.03
lives = 3
gameOver = False
levelComplete = False
keysUsed = False
lastMousePos = (0,0)
columns = 0
rows = 0
brickNumber = rows*columns
horizontalBrickSpace = 0
verticalBrickSpace = 0
demo = False
randomDemoPos = round(random.random(),1)
fontSpace = 10
font = pygame.font.Font(None, 20)
fontL = pygame.font.Font(None, 40)
fontU = pygame.font.Font(None, 20)
fontU.set_underline(True)
helpTextOffset = 5
demoTextOffset = 45
pauseTextOffset = 90
soundTextOffset = 140
musicTextOffset = 200
helpActive = False
helpScreenWidth = 450
helpScreenHeight = 245
paused = False
level = 0
breakSound1 = pygame.mixer.Sound("break1.wav")
breakSound2 = pygame.mixer.Sound("break2.wav")
breakSound3 = pygame.mixer.Sound("break3.wav")
breakSound4 = pygame.mixer.Sound("break4.wav")
breakSound5 = pygame.mixer.Sound("break5.wav")
breakSound6 = pygame.mixer.Sound("break6.wav")
breakSound7 = pygame.mixer.Sound("break7.wav")
breakSound8 = pygame.mixer.Sound("break8.wav")
breakSound9 = pygame.mixer.Sound("break9.wav")
breakSound10 = pygame.mixer.Sound("break10.wav")
breakSound11 = pygame.mixer.Sound("break11.wav")
breakSound12 = pygame.mixer.Sound("break12.wav")
breakSound13 = pygame.mixer.Sound("break13.wav")
breakSound14 = pygame.mixer.Sound("break14.wav")
breakSound15 = pygame.mixer.Sound("break15.wav")
boardSound = pygame.mixer.Sound("board.wav")
splashSound = pygame.mixer.Sound("splash.wav")
catchSound = pygame.mixer.Sound("catch.wav")
crumbleSound1 = pygame.mixer.Sound("crumble1.wav")
crumbleSound2 = pygame.mixer.Sound("crumble2.wav")
crumbleSound3 = pygame.mixer.Sound("crumble3.wav")
crumbleSound4 = pygame.mixer.Sound("crumble4.wav")
crumbleSound5 = pygame.mixer.Sound("crumble5.wav")
soundActive = True
musicActive = False
prizeSize = (30,16)
prizeColor = white
prizeSpeed = 1.0
dirChange = False

class Board(pygame.sprite.Sprite):
	def __init__(self):
		pygame.sprite.Sprite.__init__(self)
		self.image = pygame.Surface(boardSize)
		self.image.fill(white)
		self.rightSide = pygame.Surface((boardSize[0]/2, boardSize[1]))
		self.leftSide = pygame.Surface((boardSize[0]/2, boardSize[1]))
		self.triangle1 = pygame.Surface((10,10))
		self.triangle1.fill(white)
		pygame.draw.polygon(self.triangle1, black, [(0,1),(0,9),(6,5)])
		self.triangle2 = pygame.Surface((10,10))
		self.triangle2.fill(white)
		pygame.draw.polygon(self.triangle2, black, [(9,1),(9,9),(3,5)])
		self.rect = self.image.get_rect()
		self.xPos = (screenWidth-boardSize[0])/2.0
		self.rect.topleft = (self.xPos, screenHeight - boardSize[1] - bottomBorder-hover)
		self.offset = 0
		self.oldOffset = 0
	def update(self, time_passed):
		if keysUsed:
			self.xPos = min(self.xPos + boardSpeed* (time_passed/1000.0),float(screenWidth-boardSize[0]-border))
			self.xPos = max(self.xPos, float(border))
		self.rect.left = round(self.xPos,0)
		self.offset = (self.offset+1) % 100
		if not self.offset/10 == self.oldOffset/10: 
			a = 0
			self.leftSide.fill(white)
			self.rightSide.fill(white)
			while a < boardSize[0]/2+10:
				self.leftSide.blit(self.triangle2,(boardSize[0]/2-a-self.offset/10,0))
				self.rightSide.blit(self.triangle1,(-10+a+self.offset/10,0))
				a += 10
			self.image.blit(self.leftSide,(0,0))
			self.image.blit(self.rightSide,(boardSize[0]/2,0))
		self.oldOffset = self.offset
		
class Brick(pygame.sprite.Sprite):
	def __init__(self,position,size,color, type):
		pygame.sprite.Sprite.__init__(self)
		self.image = pygame.Surface(size)
		self.image.fill(color)
		# if type > 10 and type < 20: #prize
			# if type == 14:
				# sIn = 8
			# else:
				# sIn = 4
			# sOut = 8
			# pygame.draw.polygon(self.image, (color[0]+(255-color[0])/2,color[1]+(255-color[1])/2,color[2]+(255-color[2])/2),
				# [(size[0]/2,size[1]/2-sOut),(size[0]/2+sIn,size[1]/2-sIn),
				# (size[0]/2+sOut,size[1]/2),(size[0]/2+sIn,size[1]/2+sIn),
				# (size[0]/2,size[1]/2+sOut),(size[0]/2-sIn,size[1]/2+sIn),
				# (size[0]/2-sOut,size[1]/2),(size[0]/2-sIn,size[1]/2-sIn)],1
			# )
		self.size = size
		self.color = color
		self.type = type
		self.rect = self.image.get_rect()
		self.rect.topleft = position
		self.left = position[0]
		self.up = position[1]
		self.right = position[0]+self.size[0]
		self.down = position[1]+self.size[1]
		self.hit = False
		if type > 100:
			self.resistance = type-100
			self.maxResistance = type-100
		else:
			self.resistance = 0
	def update(self, time_passed):
		if self.hit and self.resistance == 0:
			global score, scoreText, brickNumber, levelComplete, ballComing, boardSpeed
			if soundActive:
				(globals()["breakSound"+str(random.randint(1,15))]).play()
			for i in range(int(splitPartsY)):
				for j in range(int(splitPartsX)):
					rand = round(random.random(),2)/2.0
					rand2 = random.randint(0,1)
					if rand2 == 0:
						randCol = (self.color[0]+(255-self.color[0])*rand,self.color[1]+(255-self.color[1])*rand,self.color[2]+(255-self.color[2])*rand)
					else:
						randCol = (self.color[0]-self.color[0]*rand,self.color[1]-self.color[1]*rand,self.color[2]-self.color[2]*rand)
					sprites.add(ExplosionPart((self.left+j*self.size[0]/splitPartsX,self.up+i*self.size[1]/splitPartsY),
												(random.randint(1,self.size[0]/splitPartsX),random.randint(1,self.size[1]/splitPartsY)),randCol,j-splitPartsX/2,i-splitPartsY/2))
			if not demo:
				score +=1
				scoreText = font.render("score: "+str(score), True, white, darkgrey)
			brickNumber -= 1
			if brickNumber == 0:
				levelComplete = True
				ball.onBoard = False
				ballComing = True
				boardSpeed = 0.0
				ball.xVek = (board.xPos+boardSize[0]/2.0-ballRadius-ball.xPos)/3.0
				ball.yVek = (screenHeight-bottomBorder-hover-boardSize[1]-2*ballRadius-ball.yPos)/3.0
				ball.started = True
			if self.type > 10 and self.type < 20:
				sprites.add(Prize((self.left+self.size[0]/2,self.up+self.size[1]/2),self.type-10))
			sprites.remove(self)
		elif self.hit: #crumble
			if soundActive:
				(globals()["crumbleSound"+str(random.randint(1,5))]).play()
			self.resistance -= 1
			self.hit = False
			self.damage()
	def damage(self):
		col = (float(self.resistance)/float(self.maxResistance))
		for i in range(0, random.randint(1,5)):
			posX = random.randint(0,splitPartsX-1)*(self.size[0]/splitPartsX)
			posY = random.randint(0,splitPartsY-1)*(self.size[1]/splitPartsY)
			pygame.draw.rect(self.image, (self.color[0]*col, self.color[1]*col, self.color[2]*col), 
			(posX,posY,(self.size[0]/splitPartsX),(self.size[1]/splitPartsY)), 0)

class Prize(pygame.sprite.Sprite):
	def __init__(self,position,type):
		pygame.sprite.Sprite.__init__(self)
		self.size = prizeSize
		self.type = type
		self.image = pygame.Surface(prizeSize)
		self.image.fill(prizeColor)
		pygame.draw.rect(self.image, black, (1,1,self.size[0]-2, self.size[1]-2))
		if type == 2: #extra ball
			pygame.draw.circle(self.image, ballColor, (int(ballRadius-2)+3, self.size[1]/2), int(ballRadius-2))
			pygame.draw.rect(self.image, white, (9,4,2,2))
			pygame.draw.rect(self.image, white, (18,5,1,6))
			pygame.draw.rect(self.image, white, (16,7,5,2))
			pygame.draw.rect(self.image, white, (26,4,1,8))
			pygame.draw.line(self.image, white, (26,4), (24,6))
		if type == 3: #expand boardwidth
			pygame.draw.polygon(self.image, white, [(10,5),(10,11),(5,8)])
			pygame.draw.polygon(self.image, white, [(19,5),(19,11),(24,8)])
		if type == 4: #extra score
			self.image.blit(font.render("+10", True, white),(3,1))
		self.position = (float(position[0]-prizeSize[0]/2),float(position[1]-prizeSize[1]/2))
		self.xPos = self.position[0]
		self.yPos = self.position[1]
		self.rect = self.image.get_rect()
		self.rect.topleft = self.position
	def update(self, time_passed):
		global balls, lives, boardSize, board, score, scoreText
		self.yPos += prizeSpeed
		self.rect.top = round(self.yPos)
		if self.yPos > screenHeight-bottomBorder-self.size[1]/2:
			sprites.remove(self)
			if soundActive:
				splashSound.play()
			for i in range(0,200):
				randCol = round(random.random(),2)
				sprites.add(ExplosionPart((self.xPos+random.randint(0,int(ballRadius/2)),screenHeight),
											(random.randint(1,4),random.randint(1,4)),
											(randCol*255,randCol*255,255),
											(round(random.random(),2)-0.5)*4.0,
											(round(random.random(),2)*-3.0)))
		if pygame.sprite.collide_rect(self,board):
			sprites.remove(self)
			if soundActive:
				catchSound.play()
			if self.type == 2: #extra ball
				extraBall = Ball(ballRadius, (screenWidth-220-lives*20,(topBorder-2*ballRadius)/2.0))
				balls.insert(0,extraBall)
				sprites.add(extraBall)
				lives += 1
			if self.type == 3: #expand boardwidth
				boardSize = (boardSize[0]+10, boardSize[1])
				x = board.xPos
				sprites.remove(board)
				board = Board()
				board.xPos = x
				board.rect.left = x
				sprites.add(board)
			if self.type == 4: #extra score
				score += 10
				scoreText = font.render("score: "+str(score), True, white, darkgrey)

class ExplosionPart(pygame.sprite.Sprite):
	def __init__(self,position,size,color,xDir,yDir):
		pygame.sprite.Sprite.__init__(self)
		self.image = pygame.Surface(size)
		self.image.fill(color)
		(r,g,b) = color
		self.r = r
		self.g = g
		self.b = b
		self.xPos = float(position[0])
		self.yPos = float(position[1])
		self.xDir = xDir
		self.yDir = yDir
		self.rect = self.image.get_rect()
		self.rect.topleft = position
		self.count = 0
		self.speed = round(random.random()+1.0,2)
	def update(self, time_passed):
		self.image.fill((
			int(self.r-self.count*self.r/10.0),
			int(self.g-self.count*self.g/10.0),
			int(self.b-self.count*self.b/10.0)))
		self.count += 0.1
		self.xPos += self.xDir*self.speed
		self.yPos += self.yDir*self.speed
		self.yDir += 0.05
		self.rect.left = int(self.xPos)
		self.rect.top = int(self.yPos)
		if self.count >= 10 or (self.xDir == 0 and self.yDir == 0):
			sprites.remove(self)
			del self
		
class Ball(pygame.sprite.Sprite):
	def __init__(self, radius, initial_position):
		pygame.sprite.Sprite.__init__(self)
		self.image = pygame.Surface((radius*2, radius*2),  pygame.SRCALPHA, 32)
		pygame.draw.circle(self.image, ballColor, (int(radius), int(radius)), int(radius))
		pygame.draw.rect(self.image, white, (9,2,2,2))
		self.rect = self.image.get_rect()
		self.rect.topleft = initial_position
		self.xPos = float(initial_position[0])
		self.yPos = float(initial_position[1])
		self.xVek  = 0.0
		self.yVek = 0.0
		self.size = radius
		self.color = ballColor
		self.onBoard = False
		self.down = False
		self.started = False
	def update(self, time_passed):
		self.rect.left = round(self.xPos,0)
		self.rect.top = round(self.yPos,0)
		global lives,ball,ballComing,gameOver,splash,splashTime,boardSpeed,randomDemoPos,levelComplete,paused,dirChange
		if self.started:
			moved_distanceX = (time_passed * self.xVek) / 1000.0
			moved_distanceY = (time_passed * self.yVek) / 1000.0
			if moved_distanceX < 0:
				moved_distanceX = max(moved_distanceX, -ballRadius)
			else:
				moved_distanceX = min(moved_distanceX, ballRadius)
			if moved_distanceY < 0:
				moved_distanceY = max(moved_distanceY, -ballRadius)
			else:
				moved_distanceY = min(moved_distanceY, ballRadius)
			self.xPos += moved_distanceX
			self.yPos += moved_distanceY
			if not ballComing:
				if self.xPos < border:
					self.xPos = border
					self.xVek *= -1.0
				if self.xPos > screenWidth-2*self.size-border:
					self.xPos = float(screenWidth-2*self.size-border)
					self.xVek *= -1.0
				if self.yPos < topBorder:
					self.yPos = topBorder
					self.yVek *= -1.0
				if self.yPos > screenHeight-2*self.size-bottomBorder:
					self.yPos = float(screenHeight-2*self.size-bottomBorder)
					self.yVek = 0.0
					self.xVek = 0.0
					self.down = True
					if not splash and not gameOver:
						if soundActive:
							splashSound.play()
						splash = True
						for i in range(0,500):
							randCol = round(random.random(),2)
							sprites.add(ExplosionPart((self.xPos+random.randint(0,int(ballRadius/2)),screenHeight),
														(random.randint(1,5),random.randint(1,5)),
														(randCol*255,randCol*255,255),
														(round(random.random(),2)-0.5)*4.0,
														(round(random.random(),2)*-3.0)))
						for sprite in sprites:
							if type(sprite) == Prize:
								sprites.remove(sprite)
								for i in range(0,20):
									randCol = int(random.random()*255)
									sprites.add(ExplosionPart((sprite.xPos,sprite.yPos),
													(3,3),
													(randCol,randCol,randCol),
													(round(random.random(),2)-0.5)*4.0,
													(round(random.random(),2)*-3.0)))
						splashTime = time.time()
			dirChange = False
			for sprite in sprites:
				if type(sprite) == Board:
					if pygame.sprite.collide_rect(self,sprite):
						if not ballComing and soundActive:
							boardSound.play()
						if not self.onBoard:
							self.onBoard = True
							if (not demo) or levelComplete:
								self.xVek = 0.0
								self.yVek = 0.0
								self.started = False
							ballComing = False
							self.color = ballColor
							pygame.draw.circle(self.image, self.color, (int(ballRadius), int(ballRadius)), int(ballRadius))
							pygame.draw.rect(self.image, white, (9,2,2,2))
						self.yVek *= -1.0
						self.yPos = screenHeight-bottomBorder-boardSize[1]-hover-2*ballRadius
						if self.xPos < sprite.xPos+boardSize[0]/2.0-ballRadius:
							self.xVek = -xSpeed*(sprite.xPos+boardSize[0]/2.0-ballRadius-self.xPos)/(boardSize[0]/2.0)
						else:
							self.xVek = -xSpeed*(sprite.xPos+boardSize[0]/2.0-ballRadius-self.xPos)/(boardSize[0]/2)
						randomDemoPos = round(random.random(),1)
				elif type(sprite) == Brick and not ballComing:
					if pygame.sprite.collide_rect(self,sprite):
						sprite.hit = True
						if not dirChange:
							if self.xPos+ballRadius > sprite.right and self.xVek < 0:
								self.xPos = sprite.right+1
								self.xVek *= -1.0
								dirChange = True
							elif self.xPos+ballRadius < sprite.left and self.xVek > 0:
								self.xPos = sprite.left-2*ballRadius-1
								self.xVek *= -1.0
								dirChange = True
							elif self.yPos+ballRadius > sprite.down and self.yVek < 0:
								self.yPos = sprite.down+1
								self.yVek *= -1.0
								dirChange = True
							elif self.yPos+ballRadius < sprite.up and self.yVek > 0:
								self.yPos = sprite.up-2*ballRadius-1
								self.yVek *= -1.0
								dirChange = True
							if not dirChange:
								if abs(self.xPos-sprite.left) < abs(self.xPos-sprite.right):
									self.xPos = sprite.left-2*ballRadius-1
									self.xVek = -abs(self.xVek)
								else:
									self.xPos = sprite.right+1
									self.xVek = abs(self.xVek)
								if abs(self.yPos-sprite.up) < abs(self.yPos-sprite.down):
									self.yPos = sprite.up-2*ballRadius-1
									self.yVek = -abs(self.yVek)
								else:
									self.yPos = sprite.down+1
									self.yVek = abs(self.yVek)

			if self.down:
				self.yPos = screenHeight
			if self.down and not splash and lives > 0:
				ball = balls[0]
				del balls[0]
				boardSpeed = 0.0
				ball.xVek = (board.xPos+boardSize[0]/2.0-ballRadius-ball.xPos)/3.0
				ball.yVek = (screenHeight-bottomBorder-hover-boardSize[1]-2*ballRadius-ball.yPos)/3.0
				pygame.draw.circle(ball.image, (ballColor[0],ballColor[1],ballColor[2],130), (int(ballRadius), int(ballRadius)), int(ballRadius))
				pygame.draw.rect(self.image, (255,255,255,130), (9,2,2,2))
				ball.started = True
				lives -= 1
				sprites.remove(self)
				del self
			elif splash:
				if time.time()-splashTime > 1:
					splash = False
					if lives > 0:
						ballComing = True
					else:
						gameOver = True
					splashTime = 0

		
def generateWater():
	global waterSpeed, waterTime, list1, list2
	if waterTime > 1.0/waterSpeed:
		waterTime = 0
	if waterTime == 0:
		list1 = [(0,screenHeight)]
		for i in range(0,100):
			list1.append((i*screenWidth/100.0,screenHeight-random.random()*bottomBorder))
		list1.append((screenWidth,screenHeight))
	if waterTime == int((1.0/waterSpeed)/2.0):
		list2 = [(0,screenHeight)]
		for i in range(0,100):
			list2.append((i*screenWidth/100.0,screenHeight-random.random()*bottomBorder))
		list2.append((screenWidth,screenHeight))
	waterTime += 1

def useKeys():
	global keysUsed, lastMousePos
	keysUsed = True
	pygame.mouse.set_visible(False)
	lastMousePos = pygame.mouse.get_pos()
	
def isInRect((a,b), (x,y,w,h)):
	return a > x and b > y and a < x+w and b < y+h
	
def underlineFirstLetter(str, fontCol, bgCol):
	T = fontU.render(str[0], True, fontCol, bgCol)
	ext = font.render(str[1:], True, fontCol, bgCol)
	Text = pygame.Surface((T.get_width()+ext.get_width(), T.get_height()))
	Text.blit(T, (0,0))
	Text.blit(ext, (T.get_width(),0))
	return Text
	
def setDemo():
	global demo, score, scoreText, boardSpeed
	if demo == False:
		score = 0
		scoreText = font.render("score: "+str(score), True, grey, darkgrey)
		demo = True
		useKeys()
		if not ball.started and not levelComplete:
			ball.started = True
			ball.xVek = random.randint(int(-xSpeed),int(xSpeed))
			ball.yVek = -ySpeed
	else:
		demo = False
		keysUsed = False
		boardSpeed = 0.0
		scoreText = font.render("score: "+str(score), True, white, darkgrey)
		
def setHelp():
	global helpActive
	if helpActive == False:
		helpActive = True
	else:
		helpActive = False
		
def setSound():
	global soundActive
	if soundActive:
		soundActive = False
		pygame.mixer.pause()
	else:
		soundActive = True
		pygame.mixer.unpause()
		
def setMusic():
	global musicActive
	if musicActive:
		musicActive = False
		pygame.mixer.music.stop()
	else:
		musicActive = True
		pygame.mixer.music.play(-1)
		
def newLevel():
	global boardSpeed, brickNumber, levelComplete, level, levelText, rows, columns, demo
	global horizontalBrickSpace, verticalBrickSpace
	boardSpeed = 0.0
	levelComplete = False
	level += 1
	levelText = font.render("Level: "+str(level), True, white, darkgrey)
	brickNumber = 0
	if len(levelBrickCols) < level:
		generateRandomLevel()
	else:
		rows = len(levelBrickCols[level-1])
		columns = len(levelBrickCols[level-1][0])
		brickSize = levelSpecs[level-1][0]
		topSpace = levelSpecs[level-1][1]
		horizontalBrickSpace = levelSpecs[level-1][2]
		verticalBrickSpace = levelSpecs[level-1][3]
		leftSpace = (screenWidth-columns*brickSize[0]-((columns-1)*horizontalBrickSpace))/2.0
		for j in range (0,columns):
			for i in range (0,rows):
				if not levelBrickTypes[level-1][i][j] == 0 and not levelBrickCols[level-1][i][j] == None:
					brickNumber += 1
					sprites.add(Brick((leftSpace+j*(brickSize[0]+horizontalBrickSpace),topSpace+i*(brickSize[1]+verticalBrickSpace)),brickSize,levelBrickCols[level-1][i][j],levelBrickTypes[level-1][i][j]))
	if demo:
		ball.started = True
		ball.xVek = random.randint(-xSpeed,xSpeed)
		ball.yVek = -ySpeed
		
def generateRandomLevel():
	global boardSpeed, brickNumber, levelComplete, level, levelText, rows, columns, demo
	global horizontalBrickSpace, verticalBrickSpace
	rows = random.randint(3,15)
	columns = random.randint(5,14)
	brickSize = (60,18)
	horizontalBrickSpace = 2
	verticalBrickSpace = 2
	none = 0.2
	resistant = 0.1
	extraScore = 0.08
	extraBall = 0.01
	topSpace = random.randint(topBorder+10,100)
	leftSpace = (screenWidth-columns*brickSize[0]-((columns-1)*horizontalBrickSpace))/2.0
	color = (random.randint(30,255),random.randint(30,255),random.randint(30,255))
	for j in range (0,columns):
		r = min(color[0]+(random.random()-0.5)*70,255)
		r = max(r,30)
		g = min(color[1]+(random.random()-0.5)*70,255)
		g = max(g,30)
		b = min(color[2]+(random.random()-0.5)*70,255)
		b = max(b,30)
		color = (r,g,b)
		for i in range (0,rows):
			rand = random.random()
			if (rand < none): #None
				pass 
			elif (rand < none+resistant): #resistant
				brickNumber += 1
				sprites.add(Brick((leftSpace+j*(brickSize[0]+horizontalBrickSpace),topSpace+i*(brickSize[1]+verticalBrickSpace)),brickSize,color,random.randint(102,108)))
			elif (rand < none+resistant+extraScore): #extraScore
				brickNumber += 1
				sprites.add(Brick((leftSpace+j*(brickSize[0]+horizontalBrickSpace),topSpace+i*(brickSize[1]+verticalBrickSpace)),brickSize,color,14))
			elif (rand < none+resistant+extraScore+extraBall): #extraBall
				brickNumber += 1
				sprites.add(Brick((leftSpace+j*(brickSize[0]+horizontalBrickSpace),topSpace+i*(brickSize[1]+verticalBrickSpace)),brickSize,color,12))
			else: #Normal
				brickNumber += 1
				sprites.add(Brick((leftSpace+j*(brickSize[0]+horizontalBrickSpace),topSpace+i*(brickSize[1]+verticalBrickSpace)),brickSize,color,1))
			
screen = pygame.display.set_mode((screenWidth, screenHeight), 0, 32)
pygame.display.set_caption("Breakout")
sprites = pygame.sprite.Group()
board = Board()
sprites.add(board)

clock = pygame.time.Clock()


scoreText = font.render("score: "+str(score), True, white, darkgrey)
demoTextGrey = underlineFirstLetter("Demo",grey,darkgrey)
helpTextGrey = underlineFirstLetter("Help",grey,darkgrey)
pauseTextGrey = underlineFirstLetter("Pause",grey,darkgrey)
soundTextGrey = underlineFirstLetter("Sounds",grey,darkgrey)
musicTextGrey = underlineFirstLetter("Music",grey,darkgrey)
demoTextWhite = underlineFirstLetter("Demo",white,darkgrey)
helpTextWhite = underlineFirstLetter("Help",white,darkgrey)
pauseTextWhite = underlineFirstLetter("Pause",white,darkgrey)
soundTextWhite = underlineFirstLetter("Sounds",white,darkgrey)
musicTextWhite = underlineFirstLetter("Music",white,darkgrey)
levelText = font.render("Level: 1", True, white, darkgrey)
helpTitle = fontU.render("HELP", True, white, darkgrey)
helpHelp = underlineFirstLetter("Help -> show/hide this help.",white,darkgrey)
helpDemo = underlineFirstLetter("Demo -> enable/disable demo mode.",white,darkgrey)
helpQuit = underlineFirstLetter("Quit -> quit game.",white,darkgrey)
helpPause = underlineFirstLetter("Pause -> pause/continue game.",white,darkgrey)
helpSound = underlineFirstLetter("Sounds -> enable/disable sounds.",white,darkgrey)
helpMusic = underlineFirstLetter("Music -> enable/disable music.",white,darkgrey)
helpControl1 = font.render("Controls:", True, white, darkgrey)
helpControl2 = font.render("Use mouse or arrow keys to move the board to the left/right.", True, white, darkgrey)
helpControl3 = font.render("Click left mouse button or space bar to launch the ball.", True, white, darkgrey)
gameOverText = fontL.render("Game Over!", True, white, darkgrey)
gameOverScreen = pygame.Surface((170, 35))
gameOverScreen.fill(darkgrey)
gameOverScreen.blit(gameOverText,(5,5))
levelCompleteText = fontL.render("Level Complete!", True, white, darkgrey)
continueText = underlineFirstLetter("Continue",white,darkgrey)
levelCompleteScreen = pygame.Surface((225, 55))
levelCompleteScreen.fill(darkgrey)
levelCompleteScreen.blit(levelCompleteText,(5,5))
levelCompleteScreen.blit(continueText,(80,35))
helpScreen = pygame.Surface((helpScreenWidth, helpScreenHeight))
helpScreen.fill(darkgrey)
helpScreen.blit(helpTitle,((helpScreenWidth-helpTitle.get_width())/2.0,5))
helpScreen.blit(helpControl1,(10,40))
helpScreen.blit(helpControl2,(10,60))
helpScreen.blit(helpControl3,(10,80))
helpScreen.blit(helpHelp,(10,120))
helpScreen.blit(helpDemo,(10,140))
helpScreen.blit(helpPause,(10,160))
helpScreen.blit(helpSound,(10,180))
helpScreen.blit(helpMusic,(10,200))
helpScreen.blit(helpQuit,(10,220))



ball = Ball(ballRadius, (board.xPos+(boardSize[0]/2.0)-ballRadius,screenHeight-bottomBorder-hover-boardSize[1]-2*ballRadius))
ball.onBoard = True
balls = [
	Ball(ballRadius, (screenWidth-260,(topBorder-2*ballRadius)/2.0)),
	Ball(ballRadius, (screenWidth-240,(topBorder-2*ballRadius)/2.0)),
	Ball(ballRadius, (screenWidth-220,(topBorder-2*ballRadius)/2.0)),
]
for extraBall in balls:
	sprites.add(extraBall)

newLevel()

sprites.add(ball)

list2 = [(0,screenHeight)]
for i in range(0,100):
	list2.append((i*screenWidth/100.0,screenHeight-random.choice([bottomBorder,bottomBorder+hover/2,hover/10.0])))
list2.append((screenWidth,screenHeight))

while True:
	for event in pygame.event.get():
		if event.type == QUIT:
			exit()
		if event.type == MOUSEBUTTONDOWN:
			if isInRect(event.pos,(helpTextOffset,0,demoTextOffset-helpTextOffset-3,topBorder)):
				setHelp()
			elif isInRect(event.pos,(demoTextOffset,0,pauseTextOffset-demoTextOffset-3,topBorder)):
				setDemo()
			elif isInRect(event.pos,(pauseTextOffset,0,soundTextOffset-pauseTextOffset-3,topBorder)):
				if paused == False:
					paused = True
				else:
					paused = False
			elif isInRect(event.pos,(soundTextOffset,0,musicTextOffset-soundTextOffset-3,topBorder)):
				setSound()
			elif isInRect(event.pos,(musicTextOffset,0,60,topBorder)):
				setMusic()
			elif levelComplete and isInRect(event.pos,((screenWidth-levelCompleteScreen.get_width())/2.0,280,225,55)):
				newLevel()
			elif not ball.started and not levelComplete:
				ball.started = True
				ball.xVek = random.randint(-xSpeed,xSpeed)
				ball.yVek = -ySpeed
		if event.type == KEYDOWN:
			if event.key == K_SPACE and not ball.started and not levelComplete:
				ball.started = True
				ball.xVek = random.randint(int(-xSpeed),int(xSpeed))
				ball.yVek = -ySpeed
			if event.key == K_q:
				exit()
			if event.key == K_d:
				setDemo()
			if event.key == K_s:
				setSound()
			if event.key == K_m:
				setMusic()
			if event.key == K_p:
				if paused == False:
					paused = True
				else:
					paused = False
			if event.key == K_h:
				setHelp()
			if event.key == K_c:
				if levelComplete:
					newLevel()
			if event.key == K_l:
				for sprite in sprites:
					if type(sprite) == Brick:
						sprites.remove(sprite)
				newLevel()
			if event.key == K_LEFT and not ballComing and not demo:
				if keysUsed == False:
					useKeys()
				boardSpeed = -maxBoardSpeed
			if event.key == K_RIGHT and not ballComing and not demo:
				if keysUsed == False:
					useKeys()
				boardSpeed = maxBoardSpeed
		if event.type == KEYUP:
			if event.key == K_LEFT or event.key == K_RIGHT:
				boardSpeed = 0.0
					
	if not ballComing:
		if not keysUsed and not demo:
			board.xPos = max(border,pygame.mouse.get_pos()[0]-boardSize[0]/2)
			board.xPos = min(screenWidth-border-boardSize[0],board.xPos)
		elif demo:
			boardSpeed = (ball.xPos + ballRadius - (board.xPos + boardSize[0]/2))*8
			#perfect mode:
			#board.xPos = ball.xPos+ballRadius-boardSize[0]/2+(random.random()-0.5)*ballRadius*4
		if not pygame.mouse.get_pos() == lastMousePos:
			if not demo:
				keysUsed = False
			pygame.mouse.set_visible(True)
	if (not ball.started) and ball.onBoard:
		ball.xPos = board.xPos+boardSize[0]/2.0-ballRadius

	screen.fill(darkgrey)
	pygame.draw.rect(screen, black, (border,topBorder,screenWidth-2*border,screenHeight-topBorder), 0)
	time_passed = clock.tick(framerate)
	if not (paused or helpActive):
		generateWater()
		sprites.update(time_passed)
	pygame.draw.polygon(screen, darkblue, list1, 0)
	pygame.draw.polygon(screen, lightblue, list2, 0)
	sprites.draw(screen)
	screen.blit(scoreText, (screenWidth-90,3))
	screen.blit(levelText, (screenWidth-170,3))
	if levelComplete:
		screen.blit(levelCompleteScreen, ((screenWidth-levelCompleteScreen.get_width())/2.0,280))
	elif gameOver:
		screen.blit(gameOverScreen, ((screenWidth-gameOverScreen.get_width())/2.0,280))
	if helpActive:
		screen.blit(helpTextWhite, (border+helpTextOffset,3))
		screen.blit(helpScreen, ((screenWidth-helpScreenWidth)/2.0,30))
	else:
		screen.blit(helpTextGrey, (border+helpTextOffset,3))
	if demo:
		screen.blit(demoTextWhite, (border+demoTextOffset,3))
	else:
		screen.blit(demoTextGrey, (border+demoTextOffset,3))
	if paused:
		screen.blit(pauseTextWhite, (border+pauseTextOffset,3))
	else:
		screen.blit(pauseTextGrey, (border+pauseTextOffset,3))
	if soundActive:
		screen.blit(soundTextWhite, (border+soundTextOffset,3))
	else:
		screen.blit(soundTextGrey, (border+soundTextOffset,3))
	if musicActive:
		screen.blit(musicTextWhite, (border+musicTextOffset,3))
	else:
		screen.blit(musicTextGrey, (border+musicTextOffset,3))
	pygame.display.update()