В моей игре «SpcaeShip» у меня есть петлевая игра, которая обновляет и рисует все мои объекты. Теперь я хочу добавить в игру список астероидов и нарисовать их, но проблема в том, что если я рисую массив астероидов в игре с петлями, игра будет очень медленной. Мое решение состояло в том, чтобы нарисовать астероиды по таймеру, и скорость игры идеальна. Единственная проблема, с которой я сталкиваюсь, это то, что мои астрооиды постоянно мерцают. Мне нужно использовать bufferStrategy или что-то подобное?Мерцающее изображение, которое работает на потоке
Это мой метод рисования в цикле игр (в этом цикле я называю в игре государственного метод Draw):
private void tick()
{
//update all objects
}
private void render()
{
//how many buffers(hold the same data as our screen) the canvas would use
bs = display.getCanvas().getBufferStrategy();
if(bs == null)
{
display.getCanvas().createBufferStrategy(3);
return;
}
g = bs.getDrawGraphics();
g.clearRect(0, 0, width, height);
if(State.getState() != null)
{
State.getState().render(g);
}
bs.show();
g.dispose();
}
public void run()
{
init();
int fps = 60;
double timePerTick = 1000000000/ fps;
double delta = 0;
long now;
long lastTime =System.nanoTime();
long timer = 0;
//game loop
while(running)
{
now = System.nanoTime();
delta += (now - lastTime)/timePerTick;
timer += now - lastTime;
lastTime = now;
if(delta >= 1)
{
tick();
render();
}
}
stop();
}
Это моя игра государственных методы:
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.Timer;
public class GameState extends State
{
private SpaceShip spaceShip;
private BgHandler bgHandler;
private ArrayList<Meteor> meteors;
public GameState(Handler handler)
{
super(handler);
bgHandler = new BgHandler(handler.getWidth(), handler.getHeight());
spaceShip = new SpaceShip(handler, handler.getWidth()/2 - Things.DEFAULT_OBJECT_WIDTH/2,
handler.getHeight() - Things.DEFAULT_OBJECT_HEIGHT - 100);
meteors = new ArrayList<Meteor>();
for(int i = 0; i < 5; i++)
{
Meteor m = new Meteor(handler,(int) (Math.random() * (handler.getWidth() - Things.DEFAULT_OBJECT_WIDTH))
, -Things.DEFAULT_OBJECT_WIDTH,
Things.DEFAULT_OBJECT_WIDTH,
Things.DEFAULT_OBJECT_HEIGHT);
meteors.add(m);
}
timer.start();
}
Timer timer = new Timer (50, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
tickMeteor();
renderMeteor();
}
});
public void tickMeteor()
{
for(int i = 0; i < meteors.size(); i++)
{
Meteor m = meteors.get(i);
if(m.getVisible())
{
m.tick();
}
else
{
meteors.remove(i);
}
}
}
public void renderMeteor()
{
for(Meteor m: meteors)
{
Meteor m1 = (Meteor) m;
if(m1.getVisible())
{
m1.render(handler.getGame().getGraphics());
}
}
}
@Override
public void tick()
{
spaceShip.tick();
for(int i = 0; i < meteors.size(); i++)
{
Meteor m = meteors.get(i);
if(m.getVisible())
{
m.tick();
}
else
{
meteors.remove(i);
}
}
}
}
@Override
public void render(Graphics g)
{
bgHandler.render(g);
spaceShip.render(g);
}
}
Проверьте, как часто 'если (State.getState()! = NULL)' генерирует пустой кадр – MadProgrammer
Если вы используете BufferStategy, то вам не нужно использовать Swing-таймер, вы можете использовать ваша собственная тема, поскольку вам больше не нужно беспокоиться о синхронизации процесса рисования с EDT, поскольку они являются отдельным процессом. – MadProgrammer
Итак, все должно быть обновлено и окрашено в одну и ту же нить и должно выполняться в одном и том же проходе вместе – MadProgrammer