# controller.py # YOUR NAME(S) AND NETID(S) HERE # DATE COMPLETED HERE """Controller module for Breakout This module contains a class and global constants for the game Breakout. Unlike the other files in this assignment, you are 100% free to change anything in this file. You can change any of the constants in this file (so long as they are still named constants), and add or remove classes.""" import colormodel import random from graphics import * # CONSTANTS # Width of the game display (all coordinates are in pixels) GAME_WIDTH = 480 # Height of the game display GAME_HEIGHT = 620 # Width of the paddle PADDLE_WIDTH = 58 # Height of the paddle PADDLE_HEIGHT = 11 # Distance of the (bottom of the) paddle up from the bottom PADDLE_OFFSET = 30 # Horizontal separation between bricks BRICK_SEP_H = 5 # Vertical separation between bricks BRICK_SEP_V = 4 # Height of a brick BRICK_HEIGHT = 8 # Offset of the top brick row from the top BRICK_Y_OFFSET = 70 # Number of bricks per row BRICKS_IN_ROW = 10 # Number of rows of bricks, in range 1..10. BRICK_ROWS = 10 # Width of a brick BRICK_WIDTH = GAME_WIDTH / BRICKS_IN_ROW - BRICK_SEP_H # Diameter of the ball in pixels BALL_DIAMETER = 18 # Number of attempts in a game NUMBER_TURNS = 3 # Basic game states # Game has not started yet STATE_INACTIVE = 0 # Game is active, but waiting for next ball STATE_PAUSED = 1 # Ball is in play and being animated STATE_ACTIVE = 2 # Game is over, deactivate all actions STATE_COMPLETE = 3 # ADD MORE CONSTANTS (PROPERLY COMMENTED) AS NECESSARY # CLASSES class Breakout(GameController): """Instance is the primary controller for Breakout. This class extends GameController and implements the various methods necessary for running the game. Method initialize starts up the game. Method update animates the ball and provides the physics. The on_touch methods handle mouse (or finger) input. The class also has fields that provide state to this controller. The fields can all be hidden; you do not need properties. However, you should clearly state the field invariants, as the various methods will rely on them to determine game state.""" # FIELDS. # Current play state of the game; needed by the on_touch methods # Invariant: One of STATE_INACTIVE, STATE_PAUSED, STATE_ACTIVE _state = STATE_INACTIVE # List of currently active "bricks" in the game. #Invariant: A list of objects that are instances of GRectangle (or a #subclass) If list is empty, then state is STATE_INACTIVE (game over) _bricks = [] # The player paddle # Invariant: An object that is an instance of GRectangle (or a subclass) # Also can be None; if None, then state is STATE_INACTIVE (game over) _paddle = None # The ball to bounce about the game board # Invariant: An object that is an instance of GEllipse (or a subclass) # Also can be None; if None, then state is STATE_INACTIVE (game over) or # STATE_PAUSED (waiting for next ball) _ball = None # ADD MORE FIELDS (AND THEIR INVARIANTS) AS NECESSARY # METHODS def initialize(self): """Initialize the game state. Initialize any state fields as necessary to statisfy invariants. When done, set the state to STATE_INACTIVE, and display a message saying that the user should press to play a game.""" # IMPLEMENT ME pass def update(self, dt): """Animate a single frame in the game. This is the method that does most of the work. It moves the ball, and looks for any collisions. If there is a collision, it changes the velocity of the ball and removes any bricks if necessary. This method may need to change the state of the game. If the ball goes off the screen, change the state to either STATE_PAUSED (if the player still has some tries left) or STATE_COMPLETE (the player has lost the game). If the last brick is removed, it needs to change to STATE_COMPLETE (game over; the player has won). Precondition: dt is the time since last update (a float). This parameter can be safely ignored.""" # IMPLEMENT ME pass def on_touch_down(self,view,touch): """Respond to the mouse (or finger) being pressed (but not released) If state is STATE_ACTIVE or STATE_PAUSED, then this method should check if the user clicked inside the paddle and begin movement of the paddle. Otherwise, if it is one of the other states, it moves to the next state as appropriate. Precondition: view is just the view attribute (unused because we have access to the view attribute). touch is a MotionEvent (see documentation) with the touch information.""" # IMPLEMENT ME pass def on_touch_move(self,view,touch): """Respond to the mouse (or finger) being moved. If state is STATE_ACTIVE or STATE_PAUSED, then this method should move the paddle. The distance moved should be the distance between the previous touch event and the current touch event. For all other states, this method is ignored. Precondition: view is just the view attribute (unused because we have access to the view attribute). touch is a MotionEvent (see documentation) with the touch information.""" # IMPLEMENT ME pass def on_touch_up(self,view,touch): """Respond to the mouse (or finger) being released. If state is STATE_ACTIVE, then this method should stop moving the paddle. For all other states, it is ignored. Precondition: view is just the view attribute (unused because we have access to the view attribute). touch is a MotionEvent (see documentation) with the touch information.""" # IMPLEMENT ME pass # ADD MORE HELPER METHODS (PROPERLY SPECIFIED) AS NECESSARY class Ball(GEllipse): """Instance is a game ball. We extends GEllipse because a ball does not just have a position; it also has a velocity. You should add a constructor to initialize the ball, as well as one to move it. Note: The ball does not have to be a GEllipse. It could be an instance of GImage (why?). This change is allowed, but you must modify the class header up above.""" # FIELDS. You may wish to add properties for them, but that is optional. # Velocity in x direction. A number (int or float) _vx = 0.0 # Velocity in y direction. A number (int or float) _vy = 0.0 # ADD MORE FIELDS (INCLUDE INVARIANTS) AS NECESSARY # ADD MORE METHODS (PROPERLY SPECIFIED) AS NECESSARY # ADD MORE CLASSES AS NECESSARY