作业 弹球

/*
 * File: Breakout.java
 * -------------------
 * Name:
 * Section Leader:
 * 
 * This file will eventually implement the game of Breakout.
 */

import acm.graphics.*;
import acm.program.*;
import acm.util.*;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Breakout extends GraphicsProgram {

/** Width and height of application window in pixels */
    public static final int APPLICATION_WIDTH = 400;
    public static final int APPLICATION_HEIGHT = 600;

/** Dimensions of game board (usually the same) */
    private static final int WIDTH = APPLICATION_WIDTH;
    private static final int HEIGHT = APPLICATION_HEIGHT;

/** Dimensions of the paddle */
    private static final int PADDLE_WIDTH = 60;
    private static final int PADDLE_HEIGHT = 10;

/** Offset of the paddle up from the bottom */
    private static final int PADDLE_Y_OFFSET = 30;

/** Number of bricks per row */
    private static final int NBRICKS_PER_ROW = 10;

/** Number of rows of bricks */
    private static final int NBRICK_ROWS = 10;

/** Separation between bricks */
    private static final int BRICK_SEP = 4;

/** Width of a brick */
    private static final int BRICK_WIDTH =
      (WIDTH - (NBRICKS_PER_ROW - 1) * BRICK_SEP) / NBRICKS_PER_ROW;

/** Height of a brick */
    private static final int BRICK_HEIGHT = 8;

/** Radius of the ball in pixels */
    private static final int BALL_RADIUS = 10;

/** Offset of the top brick row from the top */
    private static final int BRICK_Y_OFFSET = 70;

/** Number of turns */
    private static int NTURNS = 3;

/* Method: run() */
/** Runs the Breakout program. */
    public void run() {
        /* You fill this in, along with any subsidiary methods */
        addMouseListeners();
        initGame();
        
    }

    private void initGame() {
//        this.setSize(APPLICATION_WIDTH, APPLICATION_HEIGHT);
        for (int i = 0; i < NBRICK_ROWS; i++) {
            for (int j = 0; j < NBRICKS_PER_ROW; j++) {
                GRect gr = new GRect(0 + j*(BRICK_WIDTH+BRICK_SEP), BRICK_Y_OFFSET + i*(BRICK_HEIGHT+BRICK_SEP), BRICK_WIDTH, BRICK_HEIGHT);
                gr.setFilled(true);
                switch(i) {
                    case 0:
                    case 1:
                        gr.setFillColor(Color.red);
                        break;
                    case 2:
                    case 3:
                        gr.setFillColor(Color.ORANGE);
                        break;
                    case 4:
                    case 5:
                        gr.setFillColor(Color.YELLOW);
                        break;
                    case 6:
                    case 7:
                        gr.setFillColor(Color.GREEN);
                        break;
                    case 8:
                    case 9:
                        gr.setFillColor(Color.CYAN);
                        break;
                    default:
                        gr.setFillColor(Color.black);
                }
                add(gr);
                brickCount++;
            }
        }
        paddle = new GRect((WIDTH - PADDLE_WIDTH)/2, HEIGHT - PADDLE_HEIGHT - PADDLE_Y_OFFSET, PADDLE_WIDTH, PADDLE_HEIGHT);
        paddle.setFilled(true);
        paddle.setFillColor(Color.black);
        add(paddle);
        oval = new GOval(paddle.getX() + (paddle.getWidth() - BALL_RADIUS)/2, paddle.getY() - BALL_RADIUS, BALL_RADIUS, BALL_RADIUS);
        oval.setFilled(true);
        oval.setColor(Color.black);
        add(oval);
        printGameInfo();
        startGame();
    }
    
    public void mouseMoved(MouseEvent e) {
        if (e.getX() <= getWidth() - paddle.getWidth()) {
            paddle.setLocation(e.getX(), paddle.getY());
        }
    }
    
    private void startGame() {
        vx = rgen.nextDouble(3.0, 5.0);
        vy = -(rgen.nextDouble(3.0, 5.0));
        if (rgen.nextBoolean(0.5)) vx = -vx;
        while (isAlived() == true && NTURNS > 0 && brickCount > 0) {
            oval.move(vx, vy);
            paddle.setLocation(oval.getX(), paddle.getY());
            pause(PAUSE_TIME);
            if (isCollisionLeft() == true) {
                vx = -vx;
            }
            if (isCollisionRight() == true) {
                vx = -vx;
            }
            if (isCollisionTop() == true) {
                vy = -vy;
            }
            gobj = collisionObject();
            if (gobj != null) {
                if (gobj == paddle) {
                    vy = -vy;
                } else {
                    vy = -vy;
                    destoryBrick(gobj);
                }
            }    
        }
        if (isAlived() == false) {
            destoryBall();
            if (NTURNS > 0 && brickCount > 0) {
                pause(2000);
                restartGame();
            } else {
                println("^^^ Gameover ^^^");
            }
        } else if (brickCount == 0) {
            println("=== You Win! ===");
        } else {
            println("^^^ &&&&&& ^^^");
        }
        
    }
    
    private void restartGame() {
        oval = new GOval(paddle.getX() + (paddle.getWidth() - BALL_RADIUS)/2, paddle.getY() - BALL_RADIUS, BALL_RADIUS, BALL_RADIUS);
        oval.setFilled(true);
        oval.setColor(Color.black);
        add(oval);
        startGame();
    }
    
    private boolean isAlived() {
        if (oval != null) {
            if (oval.getY() > paddle.getY() + paddle.getHeight() + BALL_RADIUS) {
                return false;
            }
        }    
        return true;
    }
    
    private void destoryBall() {
        remove(oval);
        NTURNS--;
        printGameInfo();
    }
    
    private void printGameInfo() {
        println("live: " + NTURNS);
        println("bricks: " + brickCount);
        println("----------------------");
    }
    
    private boolean isCollisionLeft() {
        if (oval.getX() <= 0) {
            return true;
        }
        return false;
    }
    
    private boolean isCollisionRight() {
        if (oval.getX() + 2*BALL_RADIUS >= getWidth()) {
            return true;
        }
        return false;    
    }
    
    private boolean isCollisionTop() {
        if (oval.getY() <= 0) {
            return true;
        }
        return false;    
    }
    
    private GObject collisionObject() {
        GObject collider1 = getElementAt(oval.getX(), oval.getY());
        GObject collider2 = getElementAt(oval.getX()+BALL_RADIUS, oval.getY());
        GObject collider3 = getElementAt(oval.getX(), oval.getY()+BALL_RADIUS);
        GObject collider4 = getElementAt(oval.getX()+BALL_RADIUS, oval.getY()+BALL_RADIUS);
        if (vy > 0) {
            if (collider3 != null) return collider3;
            if (collider4 != null) return collider4;
        } else {
            if (collider1 != null) return collider1;
            if (collider2 != null) return collider2;
        }
        return null;
    }
        
    private void destoryBrick(GObject gobj) {
        if (gobj != null) {
            if (gobj != paddle) {
                remove(gobj);
                brickCount--;
            }
        }
    }
    
/* private instance variable from myself */
    private GOval oval;
    private GRect paddle;
    private RandomGenerator rgen = RandomGenerator.getInstance();
    private int brickCount = 0;
    private double vx, vy;
    private GObject gobj;
    private static final int PAUSE_TIME = 10;
    
}

运行结果:

 

posted @ 2020-02-12 10:03  神之一招  阅读(198)  评论(0编辑  收藏  举报