2D游戏中的Java摆动渲染现象

时间:2016-04-19 19:20:08

标签: java swing rendering 2d-games

我目前正在开始我的第一次跳跃游戏。最初的部分已经正常工作,但我仍然得到一个&#34; bug&#34;当我的&#34; colums&#34;正在移动。这只发生在&#34; MOVE_SPEED&#34;是1 <。我也尝试使用Timer,同样的事情。

这就是它的样子:

enter image description here

请查看代码:

...
public class Board implements Runnable, KeyListener {

JFrame frame;
ArrayList<Column> cList;
Player p;
private boolean ingame = false;
public final static int INIT_WIDTH = 600;
public final static int INIT_HEIGHT = 400;
public static int WIDTH;
public static int HEIGHT;

private final int MOVE_SPEED = 10;
//When this is 1 the problem doesnt appear!

private final int GRAVITY = -3;
private int cPlayerStayingOn;
private double playerBottom;
private double floorTop;
private boolean mR = false;
private boolean mL = false;
private boolean jump = false;
long lastLoopTime = System.nanoTime();
final int TARGET_FPS = 100;
final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;
private int fps;
private int lastFpsTime;
public static double delta = 1;

public Board() {

    initBoard();
    initPlayer();
    initColumns();

}

private void initBoard() {

    frame = new JFrame("Jump'nRun");
    frame.setSize(INIT_WIDTH, INIT_HEIGHT);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(null);
    frame.addKeyListener(this);

    cList = new ArrayList<Column>();

    frame.setVisible(true);

    Board.WIDTH = frame.getContentPane().getWidth();
    Board.HEIGHT = frame.getContentPane().getHeight();

}

private void initColumns() {

    for (int i = 0; i < 8; i++) {

        cList.add(new Column(i + 1, true));
        frame.add(cList.get(i));
    }
}

private void initPlayer() {

    p = new Player();
    frame.add(p);
}

private void moveColums() {

    for (Column col : cList) {

        col.setLocation((int) (col.getLocation().getX() - MOVE_SPEED), 0);
    }
}

private int playerStanding(double pX) {

    for (int i = 0; i < 8; i++) {

        if (cList.get(i).getX() <= pX
                && (cList.get(i).getX() + cList.get(i).getWidth()) >= pX) {

            return i;
        }
    }
    return -1;

}

private void movePlayer() {

    // gravity
    if (playerBottom < floorTop) {
        p.setLocation((int) p.getLocation().getX(), (int) p.getLocation()
                .getY() - GRAVITY);
    }

    if (mR) {
        p.moveRight();
    }

    if (mL) {
        p.moveLeft();
    }

    if (jump) {
        p.jump();
        jump = false;
    }

}

private void collectData() {

    this.cPlayerStayingOn = playerStanding(p.getBounds().getX()
            + p.getBounds().getWidth());

    this.playerBottom = p.getBounds().getMaxY();
    this.floorTop = cList.get(cPlayerStayingOn).floor.getY();
}

private void recycleColums() {

    if (cList.get(0).getX() + cList.get(0).getWidth() <= 0) {

        cList.remove(0);
        cList.add(7, new Column(7 + 1, false));

        frame.add(cList.get(7));

    }
}

@Override
public void keyTyped(KeyEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void keyPressed(KeyEvent e) {

    if (e.getKeyCode() == KeyEvent.VK_SPACE
            || e.getKeyCode() == KeyEvent.VK_W
            || e.getKeyCode() == KeyEvent.VK_UP) {

        if (playerBottom >= floorTop) {
            jump = true;

        }
    }

    if (e.getKeyCode() == KeyEvent.VK_D
            || e.getKeyCode() == KeyEvent.VK_RIGHT) {

        mR = true;
    }

    if (e.getKeyCode() == KeyEvent.VK_A
            || e.getKeyCode() == KeyEvent.VK_LEFT) {

        mL = true;
    }

}

@Override
public void keyReleased(KeyEvent e) {

    if (e.getKeyCode() == KeyEvent.VK_D
            || e.getKeyCode() == KeyEvent.VK_RIGHT) {

        mR = false;
    }

    if (e.getKeyCode() == KeyEvent.VK_A
            || e.getKeyCode() == KeyEvent.VK_LEFT) {

        mL = false;
    }

}

private int getFps() {

    return fps;
}

private void setFps(int fps) {

    this.fps = fps;
}

@Override
public void run() {

    while (true) {

        if (!ingame) {

            ingame = true;

        } else {

            long now = System.nanoTime();
            long updateLength = now - lastLoopTime;
            lastLoopTime = now;
            delta = updateLength / ((double) OPTIMAL_TIME);
            lastFpsTime += updateLength;
            setFps(getFps() + 1);

            if (lastFpsTime >= 1000000000) {
                lastFpsTime = 0;
                setFps(0);
            }

            recycleColums();

            collectData();
            moveColums();
            movePlayer();

            try {
                Thread.sleep((lastLoopTime - System.nanoTime() + OPTIMAL_TIME) / 1000000);
            } catch (Exception e) {

            }
        }
    }
}

}

和列类:

...
public class Column extends JPanel {

JPanel floor;
JPanel grass;

Random rand = new Random();

private static final long serialVersionUID = 1L;

public final static int WIDTH = Board.WIDTH / 6;
public final int HEIGHT = Board.HEIGHT;

private int position;

public final static int FLOOR_H = WIDTH;

public Column(int pos, boolean init) {

    this.position = pos;

    setBounds((WIDTH * position) - WIDTH, 0, WIDTH, HEIGHT);
    setLayout(null);
    setBackground(Color.WHITE);

    floor = new JPanel();
    floor.setLayout(null);
    floor.setBackground(Color.BLACK);

    if (init) {

        floor.setBounds(0, HEIGHT - FLOOR_H, WIDTH, FLOOR_H);

    } else {

        floor.setBounds(0,
                (HEIGHT - (FLOOR_H + (FLOOR_H * rand.nextInt(2) / 2))),
                WIDTH, FLOOR_H * 2);
    }

    grass = new JPanel();
    grass.setBounds(0, 0, WIDTH, 10);
    grass.setBackground(Color.GREEN);

    floor.add(grass);
    add(floor);

   }
}

任何提示都很有意义!

(抱歉英语不好)

1 个答案:

答案 0 :(得分:1)

我通过更改以下内容来修复它:

private void recycleColums() {

if (cList.get(0).getX() + cList.get(0).getWidth() <= 0) {

    cList.remove(0);
    cList.add(7, new Column(7 + 1, false, cList.get(6).getX()));

    frame.add(cList.get(7));

  }
}

...

public Column(int pos, boolean init, int lastX) {

    this.position = pos;


    setLayout(null);
    setBackground(Color.WHITE);

    floor = new JPanel();
    floor.setLayout(null);
    floor.setBackground(Color.BLACK);

    if (init) {

        setBounds((WIDTH * position) - WIDTH, 0, WIDTH, HEIGHT);
        floor.setBounds(0, HEIGHT - FLOOR_H, WIDTH, FLOOR_H);

    } else {

        setBounds(lastX + WIDTH, 0, WIDTH, HEIGHT);
        floor.setBounds(0,
                (HEIGHT - (FLOOR_H + (FLOOR_H * rand.nextInt(2) / 2))),
                WIDTH, FLOOR_H * 2);
    }