斯坦福cs106a-突破运动型



我正试图通过在线学习cs106a课程来学习java。目前,我已经达到突破的极限,我遇到了一些错误

我还没有完全完成,但我想先解决这些问题,然后再进一步。

问题1:

当球与砖块碰撞时,它们似乎并不总是从画布上移开。有时砖块会在第二次碰撞时被移走。但有一排(黄砖(对球的碰撞根本没有反应。

问题2:

拖动鼠标可以移动我的球拍。唯一的问题是,砖块也可以像划桨一样移动。

我知道这与的这段代码有关

gobj = getElementAt(lastX, lastY);

如果我把它全部移走,砖块就不能再移动了。这很好。但我还是无论我在哪里点击和拖动,都可以移动球拍。

有人能给我一个提示,让我改正错误吗?

下面是我的代码。感谢

   /*  
 * File: Breakout.java 
 * ------------------- 
 * 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.*;
import org.omg.CORBA.PUBLIC_MEMBER;
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 = 8;
    /** 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 final int NTURNS = 3;

    private static final int DELAY = 50;
    private static final double X_START = WIDTH / 2;
    private static final double Y_START = 450;
    public void run() {
        world();
        play();
    }
    private void ball() {
        ball = new GOval(X_START, Y_START, BALL_RADIUS, BALL_RADIUS);
        ball.setFillColor(Color.BLACK);
        ball.setFilled(true);
        add(ball);
    }
    private void paddle() {
        paddle = new GRect(100, 500, PADDLE_WIDTH, PADDLE_HEIGHT);
        paddle.setColor(Color.BLACK);
        paddle.setFilled(true);
        add(paddle);
    }

    private void brick(int x, int y, Color c) {
        GRect brick = new GRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);
        brick.setColor(getBackground());
        brick.setFillColor(c);
        brick.setFilled(true);
        add(brick);
    }
    private void brickRow(int x, int y, Color c) {
        x = BRICK_SEP / 2;
        y += BRICK_Y_OFFSET;
        for (int i = 0; i < NBRICKS_PER_ROW; i++) {
            brick(x, y, c);
            x += BRICK_WIDTH + BRICK_SEP;
        }
    }

private void world() {
        //initialize x and y position for the rows of bricks
        int x = 0;
        int y = 0;
        // set starting color for first row
        Color c = Color.red;
        paddle();
        //create 2 rows of bricks and switch colors
        for (int i = 0; i < NBRICK_ROWS; i++) {
            if (i <= 1) {
                c = Color.ORANGE;
            } else if (i > 1 && i <= 3) {
                c = Color.YELLOW;
            } else if (i > 3 && i <= 5) {
                c = Color.GREEN;
            } else if (i > 5 && i <= 7) {
                c = Color.CYAN;
            }
            brickRow(x, y, c);
            y += BRICK_HEIGHT + BRICK_SEP;
        }
    }

    private void moveBall() {
        ball.move(xVel, yVel);
    }

    public void mousePressed(MouseEvent e) {
        lastX = e.getX();
        lastY = e.getY();
        gobj = getElementAt(lastX, lastY);
    }
    public void mouseDragged(MouseEvent e) {
        if (paddle != null) {
            paddle.move(e.getX() - lastX, getY());
            lastX = e.getX();
            lastY = e.getY();
        }
        //constrain paddle movement
        if (paddle.getX() < 0){
            paddle.setLocation(0, 500);
        }else if (paddle.getX()+BRICK_WIDTH > WIDTH ){
            paddle.setLocation(WIDTH-BRICK_WIDTH, 500);
        }

    }
    private void checkForCollision() {
        // ball collission with walls
        if (ball.getY() > getHeight() - BALL_RADIUS
                || ball.getY() < 0 + BALL_RADIUS) {
            yVel = -yVel;
        } else if (ball.getX() > getWidth() - BALL_RADIUS
                || ball.getX() < 1 + BALL_RADIUS) {
            xVel = -xVel;
            // ball collission with paddle
        } else if (getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
                + BALL_RADIUS) == paddle) {
            yVel = -yVel;
            // check for collision with bricks to remove them but ignore collision with paddle
        } else if (getElementAt(ball.getX(), ball.getY()) != null
                && getElementAt(ball.getX(), ball.getY()) != paddle) {
            remove(getCollidingObject(ball.getX(), ball.getY()));
            yVel = -yVel;
        } else if (getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
                + BALL_RADIUS) != null
                && getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
                        + BALL_RADIUS) != paddle) {
            remove(getCollidingObject(ball.getX() + BALL_RADIUS, ball.getY()
                    + BALL_RADIUS));
            yVel = -yVel;
        } else if (getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
                + BALL_RADIUS) != null
                && getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
                        + BALL_RADIUS) != paddle) {
            remove(getCollidingObject(ball.getX() + BALL_RADIUS, ball.getY()
                    + BALL_RADIUS));
            yVel = -yVel;
        } else if (getElementAt(ball.getX(), ball.getY() + BALL_RADIUS) != null
                && getElementAt(ball.getX(), ball.getY() + BALL_RADIUS) != paddle) {
            remove(getCollidingObject(ball.getX(), ball.getY() + BALL_RADIUS));
            yVel = -yVel;
        }
    }
    private void play() {
        addMouseListeners();
        ball();
        while (true) {
            checkForCollision();
            moveBall();
            pause(DELAY);
        }
    }

    private GObject getCollidingObject(double x, double y) {
        return getElementAt(x, y);
    }
    private double lastX;
    private double lastY;
    private double xVel = 5;
    private double yVel = 15;
    private GOval ball;
    private GRect paddle;
    private GObject gobj;
}

为什么不使用讲义19:中的建议方法

private GObject getCollidingObject()

同时使用对撞机:

GObject collider = getCollidingObject();

首先,用墙碰撞和(用砖划桨(游戏元素碰撞将你的条件分离为两种不同的方法,从而简化else if级联(分解我想你知道它的意思(。您只有两个对象——您应该担心paddlebricks,所以您只需要比较(collider == paddle)collider != null。此外,在比较中只使用半径,但应使用直径(2*radius(。玩得开心:(

你是y步,因为球的每一个移动在15时都太大了。由于每块砖的高度只有8,因此在评估该位置是否包含对象之前,有时会绕过砖。例如,假设你是最后一个剩下的评估——你是一个Y位置为20的球,而最近的砖块只有2的长度。您的下一次评估将不包括此砖块,因为您移动了15,砖块的高度为8,这意味着y值的范围为22到30。在你的下一次评估中,你将离开这块砖5分。我知道考虑到砖块的位置,这些值应该颠倒,但你明白了。。。

对于y值中较小的步长,将更定期地检查碰撞,如果您使步长足够小,则可以消除此问题。

相关内容

  • 没有找到相关文章

最新更新