Прямоугольник не двигается при умножении на время дельты
Я пытаюсь использовать дельту, чтобы переместить прямоугольник. Однако, когда я умножаю его на скорость и добавляю в положение прямоугольника x, прямоугольник не перемещается. Я думал, что проблема может заключаться в игровом цикле, но я не думаю, что это так. Вот код:
package Main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.JPanel;
//do double buffering
public class Game extends Canvas {
int x, y;
private static final long serialVersionUID = 1L;
public static final int height = 400;
public static final int width = height * 16 / 9;
JPanel p;
Game game;
Image buffer;
KeyListener kl;
MouseListener ml;
public boolean running = true;
public Game(){
kl = new KeyListener(){
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
};
ml = new MouseListener(){
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
};
}
public void update(double delta){
x += 10/1000 * delta;
}
public void render(){
BufferStrategy bs = getBufferStrategy();
if(bs==null){
createBufferStrategy(2);
return;
}
Graphics g = bs.getDrawGraphics();
g.clearRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
g.fillRect(x, y, 100, 100);
g.dispose();
bs.show();
}
public void run(){
//initialize time loop variables
long lastLoopTime = System.nanoTime();
final int TARGET_FPS = 60;
final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;
double lastFpsTime = 0;
//Main game loop
while(running)
{
//Calculate since last update
long now = System.nanoTime();
long updateLength = now - lastLoopTime;
lastLoopTime = now;
double delta = updateLength / ((double)OPTIMAL_TIME);
//update frame counter
lastFpsTime += updateLength;
//update FPS counter
if(lastFpsTime >= 1000000000)
{
lastFpsTime = 0;
}
//game updates
game.update(delta);
//graphics (gameState)
game.render();
try{
Thread.sleep((Math.abs(lastLoopTime - System.nanoTime() + OPTIMAL_TIME)/1000000));
}catch(Exception e){
System.out.println("Error in sleep");
}
}
}
public void start(){
JFrame frame = new JFrame("Game");
game = new Game();
frame.add(game);
frame.pack();
frame.setSize(width, height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.addKeyListener(kl);
frame.addMouseListener(ml);
frame.setVisible(true);
run();
}
public static void main(String[] args){
new Game().start();
}
}
3 ответа
Вам нужно изменить переменные x и y на float или double.
double x, y;
И если вы хотите увидеть движение, вам нужно изменить что-то вроде этого...
x += 100d / 1000d * delta;
То, что вы делали раньше, делило целое число 10 на целое число 1000 и в результате получало 0.
Вам также нужно будет привести результаты в целые числа при рисовании прямоугольника...
g.fillRect((int)x, (int)y, 100, 100);
x
а также y
целые числа и 10/1000 * delta
в большинстве случаев меньше 1. Инкремент x
с таким значением не изменится x
совсем.
Чтобы это исправить, попробуйте изменить тип x
в float
или же double
и просто использовать Math.floor()
или просто брось это int
при рисовании:
g.fillRect((int) x, (int) y, 100, 100);
Чтобы продолжить предыдущий ответ: 10/1000 даст вам ноль, а 10./1000 даст вам реальное число, которое он представляет. Таким образом, вы должны изменить свое заявление на
x += (int)(10./1000 * delta);
и, надеюсь, дельта будет некоторым числом больше 1000/10, чтобы поднять это целое число больше 0.