Answer the question
In order to leave comments, you need to log in
What is the reason for small lags in the game?
I decided in my spare time to try to write my own project - a small game on flash.
As a method for displaying images, I decided to use BitmapData, which acts as a camera. On it, every update using the draw method, all game objects that fall into the camera's field of view are drawn. However, in the process of implementation, one problem arose, with which I have been fighting for the 3rd day.
When moving the camera, there is a "jumping" of the game background. The problem is that this is only a visual effect. In fact, one update takes <1 ms, so it's not a matter of performance at all.
Actually a question. What is the reason for these "jumps"?
Program architecture:
1) A timer is created that is responsible for updating game elements.
_timer = new Timer(1000 / FPS);//FPS == 60;
_timer.addEventListener(TimerEvent.TIMER, gameLoop);
_timer.start();
2) Main game loop
private function gameLoop(e:Event):void
{
//Считаем время, которое прошло с момента последнего апдейта
_date = new Date();
var deltaTime:Number = (isNaN(_lastUpdate))?0:(_date.getTime() - _lastUpdate) / 1000;
//НАЧАЛО ОБРАБОТКИ ИГРОВОГО ЦИКЛА
//Обновляем команды полученные от игрока.
_playerController.update();
//Обновляем игровую модель.
_gameController.update(deltaTime);
//Обновляем позицию камеры.
updateCameraPosition();
//Обновляем отображение игры.
_gameView.update();
//КОНЕЦ ОБРАБОТКИ ИГРОВОГО ЦИКЛА
//Засекаем время, на котором закончился апдейт.
_lastUpdate = _date.getTime();
}
private function updateCameraPosition():void
{
var levelWidth:int = _gameLevel.maxWidth / 2 - 1;
var leveHeight:int = _gameLevel.maxHeight / 2 - 1;
if ((levelWidth + 1) * LevelView.CELL_WIDTH > _gameController.player.x + GAME_WIDTH / 2
&& ( -levelWidth - 1) * LevelView.CELL_WIDTH < _gameController.player.x - GAME_WIDTH / 2)
{
_gameView.camX = _gameController.player.x;
}
if ((leveHeight + 1) * LevelView.CELL_HEIGHT > _gameController.player.y + GAME_HEIGHT / 2
&& ( -leveHeight - 1) * LevelView.CELL_HEIGHT < _gameController.player.y - GAME_HEIGHT / 2)
{
_gameView.camY = _gameController.player.y;
}
}
public function update():void
{
camera.lock();
camera.fillRect(new Rectangle(0, 0, _camWidth, _camHeight), 0);
drawLevelAndStuff();
drawUnits();
camera.unlock();
}
private function drawLevelAndStuff():void
{
var minColumn:int = (camX - _camWidth / 2) / LevelView.CELL_WIDTH - 1;
var minRow:int = (camY - _camHeight / 2) / LevelView.CELL_HEIGHT - 1;
var maxColumn:int = minColumn + _camWidth / LevelView.CELL_WIDTH + 1;
var maxRow:int = minRow + _camHeight / LevelView.CELL_HEIGHT + 1;
var matrix:Matrix = new Matrix();
for (var i:int = minRow; i <= maxRow; i++)
{
for (var j:int = minColumn; j <= maxColumn; j++)
{
//Отрисовываем покрытие клетки
matrix.translate(getLocalX(j * LevelView.CELL_WIDTH), getLocalY(i * LevelView.CELL_HEIGHT));
camera.draw(_level.getCell(i, j), matrix);
//Отрисовываем статические объекты
var stuff:IBitmapDrawable = _level.getStuff(i, j);
if (stuff)
{
camera.draw(stuff,matrix);
}
matrix.identity();
}
}
}
Answer the question
In order to leave comments, you need to log in
This is the so-called Screen tearing, the effect occurs, as mentioned above, due to the fact that the monitor refresh rate is not a multiple of the flash render rate. When scrolling, the redraw area is large, so artifacts are more noticeable. For clarity, you can file a test, where you just fill each frame in turn by filling the bitmap, then in white, then in black. Due to the nature of single-buffer software flash rendering, this cannot be fixed with CPU rendering in general. Only the 11th player + stage3d solve this problem.
maybe you shouldn't update the screen so often ... choose an acceptable fps for yourself and work with it.
Maybe the reason is that you have a debug version of the flash player. I have a regular one, there are no lags.
Are you sure that the timer does not round the interval up to a multiple of some number of ms? Also, does flush guarantee that the timer will be called exactly 60 times and at regular intervals?
Also, is the flash image redrawing synchronized with the monitor scan?
Try getting the clock at the beginning of each frame and see if your code is called evenly. I suspect it's uneven. Also, why are you using a timer and not a frame entry event? Maybe the flash does not redraw objects immediately, but when the next frame starts?
And in general, is it necessary to move and redraw all objects every frame? Especially the ones that are invisible? Maybe you can make them classic objects, bind to a rectangle and move only it, this rectangle? Are you sure you're a flasher?
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question