突破游戏:我无法移动球拍,它一直给我NULLPOINTEXCEPTION ERROR

时间:2016-06-04 10:06:43

标签: java

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

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


public class Breakout1 extends GraphicsProgram {


public static final int APPLICATION_WIDTH = 400;
public static final int APPLICATION_HEIGHT = 600;


private static final int WIDTH = APPLICATION_WIDTH;
private static final int HEIGHT = APPLICATION_HEIGHT;


private static final int PADDLE_WIDTH = 60;
private static final int PADDLE_HEIGHT = 10;


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 final int NTURNS = 3;



/* Method: init() */

/**
 * Sets up the Breakout program.
 */
public void init() {
    add (new GImage("C:\\Users\\Home\\Desktop\\beach.jpg"));
    drawCanvas();
    drawBrickWall();
    drawPaddle();
    drawBall();
    addMouseListeners();
}


/* Method: run() */

/**
 * Runs the Breakout program.
 */
public void run() {


    }


private GRect brick;
private GOval ball;
private GRect paddle;

private void drawBrickWall() {
    for (int i = 0; i < NBRICK_ROWS; i++)
        for (int j = 0; j < NBRICKS_PER_ROW; j++)
            drawBrick(i, j);
}

private void drawBrick(int row, int col) {
    double x, y; // brick location
    GRect brick = new GRect(BRICK_WIDTH, BRICK_HEIGHT);
    x = computeXOffset() + col * (BRICK_WIDTH + BRICK_SEP);
    y = BRICK_Y_OFFSET + row * (BRICK_HEIGHT + BRICK_SEP);
    brick = new GRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);
    brick.setFilled(true);
    add(brick, x, y);


    if (row < 2) {
        brick.setColor(Color.RED);
    } else if (row == 2 || row == 3) {
        brick.setColor(Color.ORANGE);
    } else if (row == 4 || row == 5) {
        brick.setColor(Color.YELLOW);
    } else if (row == 6 || row == 7) {
        brick.setColor(Color.GREEN);
    } else if (row == 8 || row == 9) {
        brick.setColor(Color.CYAN);
    }
}


private double computeXOffset() {
    return 0.5 * (WIDTH - (NBRICKS_PER_ROW - 1) * BRICK_SEP - BRICK_WIDTH * NBRICKS_PER_ROW);
}

private void drawPaddle() {
    GRect paddle = new GRect(PADDLE_WIDTH, PADDLE_HEIGHT);
    paddle.setFilled(true);
    add(paddle, 0.5 * (WIDTH - PADDLE_WIDTH), HEIGHT - PADDLE_Y_OFFSET - PADDLE_HEIGHT);
    addMouseListeners();
}

private boolean isMouseXInsideWindow(int x) {
    return ((x > PADDLE_WIDTH / 2) && (x < (WIDTH - PADDLE_WIDTH / 2)));
}


public void mouseMoved(MouseEvent e) {

    if (isMouseXInsideWindow(e.getX())) {
        paddle.setLocation(paddle.getX() - PADDLE_WIDTH / 2, paddle.getY());

    }

}

    private void drawBall(){
    GOval ball = new GOval(2*BALL_RADIUS, 2*BALL_RADIUS);
    ball.setFilled(true);
    add(ball, 0.5*WIDTH - BALL_RADIUS , 0.5*HEIGHT - BALL_RADIUS );
}

    private void drawCanvas(){
        GLabel myLabel= new GLabel ("Welcome to my Breakout Game!");
        myLabel.setFont("Serif-bold-24");
        myLabel.setColor(Color.CYAN);
        add(myLabel,getXCenter(myLabel), getYCenter(myLabel));


    }
    private double getXCenter (GObject g){

        return (getWidth()-g.getWidth())/2;
    }
    private double getYCenter (GObject g){

        return (getHeight()-g.getHeight())/2;
    }
}

它在我运行程序时一直给我错误NULLPOINTEXCEPTION,有人可以尝试检查mouseMoved(MouseEvent e)的错误,paddle不会移动并继续给我错误。但其余代码正在运行。

1 个答案:

答案 0 :(得分:0)

您称为数据成员的Paddle似乎并未实例化。您确实创建了Paddle,但它尚未分配给成员变量,这是您在其余代码中使用的变量。

因此,在您的代码中drawPaddle()内,您可以像这样创建Paddle

GRect paddle = new GRect(...)

但是,从未将其分配给类局部变量paddle;因此,一旦调用drawPaddle(),您对分配的变量的引用基本上就会丢失。当您来电话isMouseXInsideWindow(int)时,您会尝试使用paddle.x;但是这指的是属于类本身的成员变量paddle,它已经未初始化。

所以,当你最初分配一个paddle时,需要将它分配给类&#39;成员变量而不是成为局部变量。这是一个非常简单的解决方案;在drawPaddle()内,只需使用paddle = new GRect(...)代替GRect paddle = new GRect(...);这确保我们分配对成员变量paddle的引用,而不是创建一个本地的引用,我们在调用该方法后会忽略它。

为了避免将来出现这些问题,您应该尝试设计方法调用,以便将GRect传递给它们。这使您可以更加具体地了解方法的工作方式,并强制您在管理引用时要小心。此外,如果将来你想添加第二个paddle,或者第三个或第四个......,你会发现它会帮助你一大堆...

作为旁注,每当您与NullPointerExceptions挣扎时,有助于缩小错误的确切来源。您已经知道问题必须放在mouseMoved(...)方法的某个位置,因此您可以尝试将您使用的各种变量打印到控制台,以查看它们是否打印出有效的内容,打印null或“不要”。甚至可以打印(这表示应用程序在您放置打印语句的位置之前的某个位置终止)。