2D游戏中Java swing渲染现象

标签 java swing rendering 2d-games

我目前正在制作我的第一个“跳跃与奔跑”游戏。初始部分已经工作得很好,但当我的“列”移动时,我仍然遇到一个“错误”。仅当“MOVE_SPEED”为 1< 时才会发生这种情况。我也用计时器尝试过,同样的事情。

它是这样的:

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);

   }
}

任何提示都值得赞赏!

(抱歉英语不好)

最佳答案

我通过更改以下内容修复了该问题:

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);
    }

关于2D游戏中Java swing渲染现象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36727540/

相关文章:

java - 多次尝试后,R无法解析为变量

java - Opencv java - 将图像加载到 GUI

java - 如何使带有匿名内部类 Action 监听器的 JButton 在单击时自行删除?

c - Vulkan - 同步对单个缓冲区的访问

css - Roboto Condensed google 字体在所有浏览器中都会回落

google-chrome - Blink 内存缓存存储什么?

java - 如何将 JSON (org.jooq.JSON) 转换为 Java 对象 (POJO)

java - 将多个文本节点转换为单个文本节点的 XPath 函数

java - 访问组合中的字段方法

java - 如何让 java swing 组合框显示数组中的列而不是它正在显示的内容?