我正在尝试在this site
上实施最后一个游戏循环以下是该网站的代码:
const int TICKS_PER_SECOND = 25;
const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
const int MAX_FRAMESKIP = 5;
DWORD next_game_tick = GetTickCount();
int loops;
float interpolation;
bool game_is_running = true;
while( game_is_running ) {
loops = 0;
while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) {
update_game();
next_game_tick += SKIP_TICKS;
loops++;
}
interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick )
/ float( SKIP_TICKS );
display_game( interpolation );
}
// GetTickCount() returns the current number of milliseconds
// that have elapsed since the system was started
我使用System.currentTimeMillis()代替GetTickCount()希望它可以做到这一点。
但是我的代码让我的结果变得非常奇怪: 有谁知道如何在java中实现这个游戏循环?
这是我的非工作示例:(我不断为插值获取大数字)
private final int TICKS_PER_SECOND = 25;
private final int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
private final int MAX_FRAMESKIP = 5;
private double nextGameTick = System.currentTimeMillis() ;
private int loops;
private float interpolation;
private boolean isGameRunning = true;
public GameLoop(){
while( isGameRunning ) {
loops = 0;
while( System.currentTimeMillis() > nextGameTick && loops < MAX_FRAMESKIP) {
// update_game();
nextGameTick += SKIP_TICKS;
loops++;
}
interpolation = (float)( System.currentTimeMillis() + SKIP_TICKS - nextGameTick )/ (float)( SKIP_TICKS );
//display_game( interpolation );
view.display(interpolation);
}
}
我使用网站上的公式在该位置画一个球,但球只是来回徘徊
view_position = position +(speed * interpolation)
我添加了其余的代码,因此不那么混乱: (虽然我甚至在我点击这段代码之前就遇到了问题,因为当我运行调试器并且它应该是一小部分时插值数量很大) 这是我绘制球的视图类:
public class View extends JPanel
{
private static final long serialVersionUID = -2744215808270823059L;
Ball myBall = new Ball();
public void paintComponent(Graphics g){
super.paintComponent(g);
paintBall(g);
g.drawString(String.valueOf(interpolation), 20, 20);
g.drawString(String.valueOf(myBall.getLocation()), 20, 50);
}
private void paintBall(Graphics g){
g.drawOval(myBall.getLocation().x, myBall.getLocation().y, myBall.getDiameter(), myBall.getDiameter() );
}
private float interpolation;
public void display(float interpolation){
Point location = new Point();
this.interpolation = interpolation;
location.x = myBall.getLocation().x + (int)(myBall.getSpeedX() * interpolation);
location.y = myBall.getLocation().y + (int)(myBall.getSpeedY() * interpolation);
myBall.setLocation(location);
repaint();
}
}
我的球类:
public class Ball {
private Point location = new Point();
private int diameter;
private double speed;
private double speedX;
private double speedY;
private double angle;
Ball(){
this(new Point(0, 10));
}
Ball(Point location){
this(10, 3, 60, location);
}
Ball(int diameter, double speed, double angleDeg, Point location ){
this.speed = speed;
setAngleDeg(angleDeg);
setDiameter(diameter);
setLocation(location);
}
//Getters and Setters
public double getAngleRad() {
return angle;
}
public void setAngleRad(double angle) {
this.angle = angle;
speedX = Math.cos(angle)*speed;
speedY = Math.sin(angle)*speed;
}
public double getAngleDeg() {
return angle*180/Math.PI;
}
public void setAngleDeg(double angle) {
this.angle = angle * Math.PI/180;
speedX = Math.cos(angle)*speed;
speedY = Math.sin(angle)*speed;
}
public double getSpeedX() {
return speedX;
}
public void setSpeedX(double speedX) {
this.speedX = speedX;
}
public double getSpeedY() {
return speedY;
}
public void setSpeedY(double speedY) {
this.speedY = speedY;
}
public Point getLocation() {
return location;
}
public void setLocation(Point location) {
this.location = location;
}
public int getDiameter() {
return diameter;
}
public void setDiameter(int diameter) {
this.diameter = diameter;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
speedX = Math.cos(angle)*speed;
speedY = Math.sin(angle)*speed;
}
}
答案 0 :(得分:0)
在游戏循环中使用繁忙等待是不好的做法,我建议使用不同的策略,例如等待显示刷新以渲染下一帧。大多数游戏框架都包含他们自己的游戏循环逻辑,我强烈建议您查看其中一个。
问题看起来就像是将时差输入view_position而不是将其添加到获取实际时间的时间。所以球的位置是基于帧时间之间的抖动而不是时间本身。
在你想到用自己的车轮重新发明车轮之前,请尝试一下游戏框架;在游戏逻辑上工作更有趣,而不是调试低级别的东西。当你更有经验,并且如果你需要它来表现时,请回到这里。