def setup(): size(900, 450) global b # Make rectangle location be its center position rectMode(CENTER) # Instantiate the state of the game board b = Breakout() def draw(): global b b.update() b.draw() class Breakout: # "Constructor" for new Breakout object def __init__(self): # various screen boundaries self.ytop = 0.0 self.ybot = height self.xleft = 0.0 self.xright = width # ball's size, position, velocity self.rball = 7.0 self.xball = 0.5*width self.yball = 0.5*height self.speed = 3.0 self.vxball = self.speed/sqrt(2) self.vyball = self.speed/sqrt(2) # paddle's location and x,y thickness self.xpaddle = 0.5*width self.ypaddle = 0.95*height self.dxpaddle = 0.1*width self.dypaddle = 0.02*height self.previousMouseX = mouseX # make list of bricks self.bricks = [] ncol = 10 for irow in range(5): for jcol in range(ncol): dxbrick = 1.0*width/ncol dybrick = 0.05*height xbrick = (jcol+0.5)*dxbrick if (irow % 2) != 0: xbrick += 0.2*dxbrick ybrick = 0.1*height + (irow+0.5)*dybrick self.bricks.append(Brick(x=xbrick, y=ybrick, dx=dxbrick, dy=dybrick)) def update(self): dt = 1.0 # use ball velocity to update ball position self.xball += self.vxball*dt self.yball += self.vyball*dt # update ball velocity if it hits the game boundary if ((self.xball >= self.xright) or (self.xball <= self.xleft)): self.vxball *= -1.0 if ((self.yball >= self.ybot) or (self.yball <= self.ytop)): self.vyball *= -1.0 # check for collisions with bricks for i in range(len(self.bricks)): b = self.bricks[i] if b.checkCollision(self.xball, self.yball): # collision! reverse the ball's velocity self.vxball *= -1.0 self.vyball *= -1.0 # delete the struck brick from the list! self.bricks.pop(i) # don't check any more bricks this frame, # as we modified the list of bricks break # estimate the horizontal velocity of the paddle vxpaddle = (mouseX - self.previousMouseX)/dt self.previousMouseX = mouseX # make the paddle follow the horizontal mouse position self.xpaddle = mouseX # check for ball bouncing off of the paddle if (abs(self.yball - self.ypaddle) < self.dypaddle/2 and abs(self.xball - self.xpaddle) < self.dxpaddle/2 and self.vyball > 0): self.vyball *= -1.0 # allow paddle velocity to affect horizontal # ball velocity, since otherwise we can get # stuck with bricks that cannot be reached self.vxball += vxpaddle # don't let ball velocity become too horizontal minvh = 0.5*self.speed if abs(self.vyball) < minvh: self.vyball = -minvh # but keep the overall ball speed constant temp_speed = sqrt(self.vxball**2 + self.vyball**2) self.vxball *= self.speed/temp_speed self.vyball *= self.speed/temp_speed def draw(self): # clear the screen background(200) # draw the bricks for b in self.bricks: b.draw() # draw the paddle (white) fill(color(255, 255, 255)) rect(self.xpaddle, self.ypaddle, self.dxpaddle, self.dypaddle) # draw the ball (black) fill(color(0, 0, 0)) ellipse(self.xball, self.yball, 2*self.rball, 2*self.rball) class Brick: def __init__(self, x, y, dx, dy): self.x = x self.y = y self.dx = dx self.dy = dy self.rcolor = random(0, 255) self.gcolor = random(0, 255) self.bcolor = random(0, 255) def checkCollision(self, x, y): if abs(x-self.x) > 0.5*self.dx: return False if abs(y-self.y) > 0.5*self.dy: return False return True def draw(self): fill(color(self.rcolor, self.gcolor, self.bcolor)) rect(self.x, self.y, self.dx, self.dy)