Симуляция движения в 2D игре, Android canvas

232
26 ноября 2016, 19:19

Пишу простенький раннер, движение объекта (того, кто бежит) симулирую сдвигом на определенное расстояние картинки на бэкграунде (фона).

Но почему-то прорисовка очень медлительна, нет плавности, такое ощущение, что игра выдает 5-10 фпс.

В чем может быть проблема? Вот кусок кода класса, отвечающего за прорисовку :

public class GameView extends View {
    public GameView(Context context) {
        MyTimerTask myTimerTask = new MyTimerTask();
        Timer timer = new Timer();
        timer.schedule(myTimerTask,0, 17);
    }

    class MyTimerTask extends java.util.TimerTask {
        @Override
        public void run() {
            long ticksPS = 60;
            long startTime;
            long sleepTime;
            while (playing) {
                startTime = System.currentTimeMillis();
                try {
                    draw();
                    player.move();
                    STEP_COUNTER += 1;
                    sleepTime = ticksPS - (System.currentTimeMillis() - startTime);
                    try {
                        if (sleepTime > 0)
                            Thread.sleep(sleepTime);
                        else
                            Thread.sleep(10);
                    } catch (Exception e) {
                    }
                } catch (Exception e) {}
            }
        }
    }

    ...
    private void draw() {
        BitmapConstants bitmapConstants = new BitmapConstants(getContext());
        if (surfaceHolder.getSurface().isValid()) {
            canvas = surfaceHolder.lockCanvas();

            if (STEP_COUNTER % 4 == 3)
                currentStep = bitmapConstants.firstStepAnimationBitmap;
            if (STEP_COUNTER % 4 == 2)
                currentStep = bitmapConstants.secondStepAnimationBitmap;
            if (STEP_COUNTER % 4 == 1)
                currentStep = bitmapConstants.thirdStepAnimationBitmap;
            if (STEP_COUNTER % 4 == 0)
                currentStep = bitmapConstants.forthStepAnimationBitmap;
            canvas.drawBitmap(bitmapConstants.background, player.backgroundLayer, 0, paint);
            canvas.drawBitmap(
                    currentStep,
                    player.getX(),
                    player.getY(),
                    paint);
            surfaceHolder.unlockCanvasAndPost(canvas);
        }
    }

}

BitmapConstants.java:

public class BitmapConstants {
    private CompressedImageBitmap compressedImageBitmap;
    public final  Bitmap firstStepAnimationBitmap;
    public final  Bitmap secondStepAnimationBitmap;
    public final  Bitmap thirdStepAnimationBitmap;
    public final  Bitmap forthStepAnimationBitmap;
    public final  Bitmap background;
    private Context context;
    public BitmapConstants(Context context) {
        this.context = context;
        compressedImageBitmap = new CompressedImageBitmap(context);
        background = compressedImageBitmap.getBackground();
        firstStepAnimationBitmap = compressedImageBitmap.getFirstStepAnimationBitmap();
        secondStepAnimationBitmap = compressedImageBitmap.getSecondStepAnimationBitmap();
        thirdStepAnimationBitmap = compressedImageBitmap.getThirdStepAnimationBitmap();
        forthStepAnimationBitmap = compressedImageBitmap.getForthStepAnimationBitmap();
    }
}

CompressedImageBitmap.java:

public class CompressedImageBitmap {
    private Bitmap firstAnimationBitmap;
    private Bitmap secondAnimationBitmap;
    private Bitmap thirdAnimationBitmap;
    private Bitmap forthAnimationBitmap;
    private Context context;
    private final int COMPRESS_HEIGHT = 360;
    private final int COMPRESS_WIDTH = 360;

    public CompressedImageBitmap(Context context) {
        this.context = context;
    }
    public Bitmap getBackground() {
        return BitmapFactory.decodeResource(context.getResources(),
                R.drawable.background);
    }
    public Bitmap getFirstStepAnimationBitmap() {
        return compressFirstStepAnimationBitmap();
    }
    public Bitmap getSecondStepAnimationBitmap() {
        return compressSecondStepAnimationBitmap();
    }
    public Bitmap getThirdStepAnimationBitmap() {
        return compressThirdStepAnimationBitmap();
    }
    public Bitmap getForthStepAnimationBitmap() {
        return compressForthStepAnimationBitmap();
    }
    private Bitmap compressFirstStepAnimationBitmap() {
            Bitmap original = BitmapFactory.decodeResource(context.getResources(), R.drawable.char_anim_1);
            firstAnimationBitmap = compress(original);
        return firstAnimationBitmap;
    }
    private Bitmap compressSecondStepAnimationBitmap() {
            Bitmap original = BitmapFactory.decodeResource(context.getResources(), R.drawable.char_anim_2);
            secondAnimationBitmap = compress(original);
        return secondAnimationBitmap;
    }
    private Bitmap compressThirdStepAnimationBitmap() {
            Bitmap original = BitmapFactory.decodeResource(context.getResources(), R.drawable.char_anim_3);
            thirdAnimationBitmap = compress(original);
        return thirdAnimationBitmap;
    }
    private Bitmap compressForthStepAnimationBitmap() {
            Bitmap original = BitmapFactory.decodeResource(context.getResources(), R.drawable.char_anim_4);
            forthAnimationBitmap = compress(original);
        return forthAnimationBitmap;
    }
    private Bitmap compress(Bitmap original) {
        return Bitmap.createScaledBitmap(original, COMPRESS_WIDTH, COMPRESS_HEIGHT, false);
    }
}

Player.java:

public class Player {
    private Bitmap bitmap;
    private int maxY;
    private int minY;
    private int x;
    private int y;
    private int speed = 40;
    int dv = 4;
    int s = 0;
    public int backgroundLayer = 0;
    public Player(Context context, int screenX, int screenY) {
        x = 75;
        y = screenY / 2;
        speed = 1;
        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.char_anim_1);
        maxY = screenY - bitmap.getHeight();
        minY = 0;
    }
    public void update(){
        x++;
    }

    public Bitmap getBitmap() {
        return bitmap;
    }
    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
    public int getSpeed() {
        return speed;
    }
    public void move() {
        speed += dv;
        backgroundLayer -= speed/60;
    }
}
Answer 1

Проблема решена. Оказывается, из-за того, что я в методе draw() каждый раз создаю новый экземпляр класса BitmapConstants, canvas перерисовывает bitmap, на что уходит очень много ресурсов.

READ ALSO
Движение по лабиринту.

Движение по лабиринту.

Делаю лабиринтДвижение осуществляется по фрейму, в зависимости от значения в массиве map, где 1 - можно двигаться, 2 - стена

323
Неверная кодировка MySQL

Неверная кодировка MySQL

Выводит непонятные символы, не могу понять где и как нужно менять кодировку

222
SSH подключение к Android девайсу

SSH подключение к Android девайсу

Здравствуйте, возможно ли разработать приложение для Android которое бы создавало сессию ssh и к которой можно было подключиться по средствам...

311