Управление анимацией спрайтов с использованием потоков - PullRequest
0 голосов
/ 28 апреля 2011

Я в процессе создания собственной двумерной игры. Каждый объект в игровом мире имеет объект Sprite, и когда рисуется экран, спрайт объекта рисуется в местоположении объекта.

Класс спрайта может быть отдельным изображением или серией изображений, используемых для создания спрайта с анимацией.

import java.awt.image.BufferedImage;
import java.awt.Graphics2D;
public class Sprite implements Runnable{
    private int currentImage;   
    private BufferedImage[] sprites;
    private int delayMS;
    private Thread animation;

    public Sprite(BufferedImage sprite){
        sprites = new BufferedImage[1];
        sprites[0] = sprite;
    }

    public Sprite(BufferedImage[] spriteAnimation,int delay){
        this.sprites = spriteAnimation;
        currentImage = 0;
        delayMS = delay;
        //start a thread to time animation
        animation = new Thread(this);
        animation.start();
    }

    private void next(){
        if(currentImage < sprites.length - 1)
            currentImage++;
        else
            currentImage = 0;
    }

    public void run() {
        while (Thread.currentThread() == animation) {
            //delay the animation for delayMS
            try {
                Thread.sleep(delayMS);
            } catch (InterruptedException e) {
                break;
            }
            //next image
            next();
        }
    }

    public void draw(Graphics2D g,int x,int y){
        g.drawImage(sprites[currentImage],null,x,y);
    }
}

Я не смог найти достоверной информации о том, как использовать потоки для запуска многих анимаций, и мне было интересно, был ли это лучший подход. Все прекрасно работает, пока я не выброшу в мир 200 одинаковых предметов. FPS начинает снижаться, и некоторые анимированные спрайты начинают менять кадры в разное время. Это имело бы смысл, так как потоки начнут задерживаться при создании экземпляра.

У меня вопрос: есть ли более эффективный способ справиться с этим, позволяющий мне использовать больше объектов без значительной потери FPS и синхронизировать поток / потоки, чтобы анимации переключали кадры вместе.

Ответы [ 3 ]

1 голос
/ 28 апреля 2011

Обычный способ сделать это - создать игровой цикл, который знает все спрайты и вызывает для них метод рисования (или, предпочтительно, только те, которые необходимо перерисовать) для каждого кадра.Таким образом, всякий раз, когда спрайт решает, что хочет анимировать, он не будет делать этого до следующего кадра.Просто выполните анимацию метода рисования, например, следующую () часть.И, конечно же, в игровой цикл вы кладете задержку, которая будет определять fps.

Чтобы получить независимую от частоты кадров анимацию, вы делаете то же самое, но добавляете аргумент к методу draw, который говорит, сколько времени прошлоначиная с последнего розыгрыша, затем рассчитайте количество анимации на основе этого.

0 голосов
/ 28 апреля 2011

если вы используете больше потоков для спрайтов (т. Е. Один поток для одного спрайта), тогда он съест ваш процессор и повесит лучший способ реализовать анимацию в играх - для каждого цикла выполнения потока изменить последовательности анимации (как следующее изображение или предыдущий после нажатия клавиш) и нарисуйте спрайты в конце.Здесь, если больше спрайтов и рисование займет больше времени, FPS упадет в то время как максимум два или три потока с синхронизацией

0 голосов
/ 28 апреля 2011

Вместо того, чтобы запускать каждый спрайт в своем собственном потоке, вы можете поместить спрайты в контейнер, а в потоке рендеринга перебрать все видимые спрайты и нарисовать их (вы даже можете реализовать приоритеты спрайтов, рендерить фоновые слои перед спрайтами,...).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...