- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
请看一下我的 pong 游戏的以下结构。
gameLoop();方法
//Only run this in another Thread!
private void gameLoop()
{
//This value would probably be stored elsewhere.
final double GAME_HERTZ = 30.0;
//Calculate how many ns each frame should take for our target game hertz.
final double TIME_BETWEEN_UPDATES = 1000000000 / GAME_HERTZ;
//At the very most we will update the game this many times before a new render.
//If you're worried about visual hitches more than perfect timing, set this to 1.
final int MAX_UPDATES_BEFORE_RENDER = 5;
//We will need the last update time.
double lastUpdateTime = System.nanoTime();
//Store the last time we rendered.
double lastRenderTime = System.nanoTime();
//If we are able to get as high as this FPS, don't render again.
final double TARGET_FPS = 60;
final double TARGET_TIME_BETWEEN_RENDERS = 1000000000 / TARGET_FPS;
//Simple way of finding FPS.
int lastSecondTime = (int) (lastUpdateTime / 1000000000);
while (running)
{
double now = System.nanoTime();
int updateCount = 0;
if (!paused)
{
//Do as many game updates as we need to, potentially playing catchup.
while( now - lastUpdateTime > TIME_BETWEEN_UPDATES && updateCount < MAX_UPDATES_BEFORE_RENDER )
{
updateGame();
lastUpdateTime += TIME_BETWEEN_UPDATES;
updateCount++;
}
//If for some reason an update takes forever, we don't want to do an insane number of catchups.
//If you were doing some sort of game that needed to keep EXACT time, you would get rid of this.
if ( now - lastUpdateTime > TIME_BETWEEN_UPDATES)
{
lastUpdateTime = now - TIME_BETWEEN_UPDATES;
}
//Render. To do so, we need to calculate interpolation for a smooth render.
float interpolation = Math.min(1.0f, (float) ((now - lastUpdateTime) / TIME_BETWEEN_UPDATES) );
//float interpolation = 1.0f;
drawGame(interpolation);
lastRenderTime = now;
//Yield until it has been at least the target time between renders. This saves the CPU from hogging.
while ( now - lastRenderTime < TARGET_TIME_BETWEEN_RENDERS && now - lastUpdateTime < TIME_BETWEEN_UPDATES)
{
Thread.yield();
//This stops the app from consuming all your CPU. It makes this slightly less accurate, but is worth it.
//You can remove this line and it will still work (better), your CPU just climbs on certain OSes.
//FYI on some OS's this can cause pretty bad stuttering. Scroll down and have a look at different peoples' solutions to this.
try {Thread.sleep(1);} catch(Exception e) {}
now = System.nanoTime();
}
}
}
}
updateGame();方法
if(p1_up){
if(player.equals("p1")){
p1.moveUp();
}
else
{
p2.moveUp();
}
}
else if(p1_down){
if(player.equals("p1")){
p1.moveDown();
}
else
{
p2.moveDown();
}
}
向上移动();向下移动();桨法
public void moveUp(){
last_y = y;
last_x = x;
y -= 50.0;
}
public void moveDown(){
last_y = y;
last_x = x;
y += 50.0;
}
drawGame(插值);方法
public void paintComponent(Graphics g)
{
super.paintComponent(g);
for(int i=0;i<balls.size();i++){
paintBall(g, balls.get(i));
}
drawPaddle(g, p1);
drawPaddle(g, p2);
}
public void drawPaddle(Graphics g, Paddle p){
paddle_drawX = (int)((p.x - p.last_x)*interpolation + p.last_x);
paddle_drawY = (int)((p.y - p.last_y)*interpolation + p.last_y);
g.drawRect(paddle_drawX, paddle_drawY, 10, 50);
}
我是游戏编程的初学者,所以我对游戏循环不太了解。我在互联网上找到了上述固定时间步长的游戏循环,并将其用作我的游戏的游戏循环。环使球平稳移动,但 Racket 在移动时不会停留在一处。当我按下一个按键来移动桨时,桨会不断晃动不在一处停留。桨的 y 坐标不断变化,就像
33、45、20、59、34、59、34、59、33、59、34、58
我知道问题出在插值上,因为它不断变化的值会改变渲染中桨的 y 坐标。我已经思考这个问题有一段时间了,但我不知道如何使游戏循环适用于任何 Action ,所以我来这里寻求帮助。我感谢任何建议/帮助!
这是我完整的桨类(class)。
public class Paddle
{
float x;
float y;
float last_y;
float last_x;
public Paddle(int x, int y)
{
this.x = x;
this.y = y;
this.last_x = x;
this.last_y = y;
}
public void setNewX(int d){
last_y = y;
last_x = x;
x = d;
}
public void setNewY(int d){
last_y = y;
last_x = x;
y = d;
}
public void moveUp(){
last_y = y;
last_x = x;
y -= 50.0;
}
public void moveDown(){
last_y = y;
last_x = x;
y += 50.0;
}
}
我通过全局变量在主类中启动桨位置。
public Paddle p1 = new Paddle(10, 10);
public Paddle p2 = new Paddle(950, 10);
我有以下事件监听器来处理击键。
Action handle_up_action = new AbstractAction(){
public void actionPerformed(ActionEvent e){
p1_up = true;
}
};
Action handle_up_action_released = new AbstractAction(){
public void actionPerformed(ActionEvent e){
p1_up = false;
}
};
Action handle_down_action = new AbstractAction(){
public void actionPerformed(ActionEvent e){
p1_down = true;
}
};
Action handle_down_action_released = new AbstractAction(){
public void actionPerformed(ActionEvent e){
p1_down = false;
}
};
最佳答案
您想通过 interpolation
实现什么目标?根据我的理解,它代表上一个和下一个“更新时间”之间耗时百分比。因此它应该每 33.3 毫秒从 0 连续进展到 1。
不知道你怎么用这个interpolation
paintBall
中的变量方法,但对于桨,它会将你的桨绘制在 p.x;p.y
之间的“伪随机位置”和p.last_x;p.last_y
(取决于两者之间的时间updateGame()
)。
为了纠正这个问题,从循环逻辑中,您应该了解每个游戏实体(球、桨等)必须有两种状态(位置):- 逻辑状态,仅在每次 TIME_BETWEEN_UPDATES
时更新- 视觉状态,可以在每次渲染时随时更新。
这就像您有一组点(代表逻辑状态)并且您想要在这些点(代表视觉状态)之间的任意位置进行插值。你的代码就像 this .
第一个解决方案
纠正桨抖动的最简单方法是避免插值和使用:
public void drawPaddle(Graphics g, Paddle p){
paddle_drawX = (int)p.x;
paddle_drawY = (int)p.y;
g.drawRect(paddle_drawX, paddle_drawY, 10, 50);
}
但是你的 Action 看起来像 this (视觉位置只会改变每个 TIME_BETWEEN_UPDATES
)
第二种解决方案
您想要p.x;p.y
作为逻辑位置,但视觉位置应插入 p.last_x;p.last_y
之间以及逻辑位置(如果渲染是在输入处理和下一个 updateGame() 之间完成的):您必须重置 p.last_x;p.last_y
当updateGame()
叫做。要实现此目的,请在 updateGame()
内调用桨的 updateMovement() 方法.
public void updateMovement(){
last_y = y;
last_x = x;
}
您可以有其他解决方案,例如使用速度变量或移动函数,以获得平滑的移动、加速度等。它主要是第二种解决方案的推广。它需要更大的改变,但更灵活、更强大。为了实现这一点,您可能需要在桨中存储最后的“更新位置”以及所有与运动相关的变量,例如运动开始日期。添加一个方法来检索可以使用两次更新之间的任何日期调用的“视觉位置”,以及一个更新“逻辑位置”的方法,调用每个 updateGame()
.
关于java - 乒乓 Racket 不停地晃动,不停留在一个位置上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20365539/
这是我的代码 />100 1000 它不按要求工作.. 当提交表单时(并且在任何错误情况下)它返回到默认选中的单选按钮,即值 = 1000 用户必须再次单击值 = 100,而目标是,如果用户选择了 1
假设我有一个透明的红色 HTML 元素。当我悬停该元素时,它应该变成纯红色。当我停止悬停该元素时,它应该动画回到第一个状态,但仅在 X 秒后。 到目前为止一切顺利,请参阅代码片段。 我的问题是当我停止
我遇到了 cookie 情况,我的 cookie 会存储一个颜色名称或根本不存储任何内容。所以让我们这样解释吧。我的 cookie 与我网站的外观有关,我的网站有 3 种外观: 正常(完全没有 coo
这是我的问题。我有一张包含三个 div 的 Bootstrap v4 卡。 A 是最重要的一个,我希望它保持在左上角。 当页面较宽时,我希望 B 和 C 在 A 的右侧。 当页面变窄时,卡片缩小,C
示例表: uid time_stp traf 1 2016-01-13 00:00:00 6 1 2016-01-13 05:00:00 8 1
我是一名优秀的程序员,十分优秀!