0

hope someone helps witch flickering. I'm been trying to wrote game based on youtube tutorial by RetroChicken but run into a problem with animation of my player object and background. Only coding 4 days in java, first year studying IT so i'm newbie af. I think its someting with double buffering (as i was reading in other topic but still dont know how to applay it to my code). I'm writing in android studio. Here is my animation class and animatorMenager

public class AnimationManager {

private Animations[] animationses;
private int animationIndex = 0;

public AnimationManager(Animations[] animationses){
    this.animationses = animationses;
}

public void playAnim(int index){
    for(int i = 0; i < animationses.length; i++){
        if(i == index)
            if(!animationses[index].isPlaying())
            animationses[i].play();
        else
            animationses[i].stop();
    }
    animationIndex = index;
}
public void draw(Canvas canvas, Rect rect){

    if(animationses[animationIndex].isPlaying())
        animationses[animationIndex].draw(canvas,rect);
}
public void update(){
    if(animationses[animationIndex].isPlaying())
        animationses[animationIndex].update();
}
}

And Animation

public class Animations {

private Bitmap[] frames;
private int frameIndex;

public static boolean isPlaying = false;
public boolean isPlaying(){
    return isPlaying;
}
public void play(){
    isPlaying = true;
    frameIndex = 0;
    lastFrame = System.currentTimeMillis();
}
public void stop(){
    isPlaying = false;
}

private float frameTime;
private long lastFrame;

public Animations(Bitmap[] frames, float animTime){
    this.frames = frames;
    frameIndex = 0;
    frameTime = animTime/frames.length;
    lastFrame = System.currentTimeMillis();
}
public void draw(Canvas canvas, Rect destination){
    if(!isPlaying){
        return;
    }
    //scaleRect(destination);
    canvas.drawBitmap(frames[frameIndex], null, destination, new Paint());
}
/*
private void  scaleRect(Rect rect){
    float whRatio = (float)(frames[frameIndex].getWidth()/frames[frameIndex].getHeight());
    if(rect.width() > rect.height()){
        rect.left = rect.right - (int)(rect.height() * whRatio);
    }else{
        rect.top = rect.bottom - (int)(rect.height() * (1/whRatio));
    }
}
*/

public void update(){
    if(!isPlaying){
        return;
    }
    if(System.currentTimeMillis() - lastFrame > frameTime*1000){
        frameIndex++;
        frameIndex = frameIndex >= frames.length ? 0 : frameIndex;
        lastFrame = System.currentTimeMillis();
    }
}
}

And maybe Player class will help

public class PlayerCar implements GameObject {

private Rect car;
int color;

private Animations idle;
private Animations driveLeft;
private Animations driveRight;
private  AnimationManager animManager;
private int state;


public PlayerCar(Rect car, int color){
    this.car = car;
    this.color = color;

    BitmapFactory bf = new BitmapFactory();
    Bitmap idleImg = bf.decodeResource(Constant.CURRENT_CONTEXT.getResources(), R.drawable.car1_spr);
    Bitmap left = bf.decodeResource(Constant.CURRENT_CONTEXT.getResources(), R.drawable.car1_spr);
    Bitmap right = bf.decodeResource(Constant.CURRENT_CONTEXT.getResources(), R.drawable.car1_spr);

    idle = new Animations(new Bitmap[]{idleImg}, 2);

    Matrix m = new Matrix();
    m.postRotate(-5);
    left = Bitmap.createBitmap(left, 0, 0, left.getWidth(), left.getHeight(),m,false);
    driveLeft = new Animations(new Bitmap[]{left}, 2);
    m.postRotate(10);
    right = Bitmap.createBitmap(right, 0, 0, right.getWidth(), right.getHeight(),m,false);
    driveRight = new Animations(new Bitmap[]{right}, 2);

    animManager = new AnimationManager(new Animations[]{idle, driveRight,driveLeft});

}
public void decrementY(float y){
    car.top -= y;
    car.bottom -= y;
}

public Rect getRectangle() {
    return car;
}

@Override
public void draw(Canvas canvas) {
    //Paint paint = new Paint();
    //paint.setColor(color);
    //canvas.drawRect(car, paint);
    animManager.draw(canvas,car);
}

@Override
public void update() {
    animManager.update();
}

public void update(Point point){

    //left,top,right,bottom
    car.set(point.x - car.width() / 2, point.y - car.height() / 2, point.x + car.width() / 2, point.y + car.height() / 2);

    if(GameplayScene.carGravity <= -5)
        state = 1;
    else if(GameplayScene.carGravity >= 5)
        state = 2;
    else if (GameplayScene.carGravity == 0)
        state = 0;

    animManager.playAnim(state);
    animManager.update();
}


}

**************************UPDATE*******************************

as my reserch go on i found out that in fact i'am using doublebuffer by using bitmap and bitmapfactor in my Player class, so it isn't fault, of not doublebuffering, in fact i think its something witch updating my position in game panel class so i'm adding this class too

package com.example.szatan_bies.myapplication;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.MotionEvent;

import static android.graphics.Typeface.DEFAULT_BOLD;
import static com.example.szatan_bies.myapplication.Constant.SCREEN_HEIGHT;
import static com.example.szatan_bies.myapplication.Constant.SCREEN_WIDTH;
import static com.example.szatan_bies.myapplication.Difficulty.DENSITY;
import static 
com.example.szatan_bies.myapplication.Difficulty.HORIZONTAL_SPEED;
import static 
com.example.szatan_bies.myapplication.Difficulty.VERTICAL_SPEED;

/**
 * Created by Szatan - Bies on 08.08.2017.
 */

public class GameplayScene implements Scene {


private PlayerCar player;
private Point playerPoint;
public static double carGravity = 0;
private int isTouch = 1;
private ObstacleManagerCars obstacleManagerCars;
private ObstacleManagerLantern obstacleManagerLantern;
private ObstacleManagerPeople obstacleManagerPeople;
private ManagerBackground background;
public static int score = 0;
public boolean gameOver = false;
private long gameOverTime;

public GameplayScene(){

    player = new PlayerCar(new Rect(100,100,200,300), Color.rgb(255,0,0));
    playerPoint = new Point(SCREEN_WIDTH/2,SCREEN_HEIGHT - 300);
    player.update(playerPoint);
    obstacleManagerCars = new ObstacleManagerCars(2000 + (DENSITY),250,Color.BLACK); //(ObstacleGap,,)
    obstacleManagerLantern = new ObstacleManagerLantern(SCREEN_HEIGHT/2 ,100,Color.BLACK); //(ObstacleGap,,)
    obstacleManagerPeople = new ObstacleManagerPeople(0,15,Color.BLUE);
    background = new ManagerBackground(SCREEN_HEIGHT,Color.GRAY);

}

public void reset(){
    playerPoint = new Point(SCREEN_WIDTH/2,SCREEN_HEIGHT - 300);
    player.update(playerPoint);
    obstacleManagerCars = new ObstacleManagerCars(2000 + (DENSITY),250,Color.BLACK); //(ObstacleGap,,)
    obstacleManagerLantern = new ObstacleManagerLantern(SCREEN_HEIGHT/2 ,100,Color.BLACK); //(ObstacleGap,,)
    obstacleManagerPeople = new ObstacleManagerPeople(0,15,Color.BLUE);
    background = new ManagerBackground(SCREEN_HEIGHT,Color.GRAY);
    carGravity = 0;
    isTouch = 1;
}

@Override
public void terminate() {
    SceneManager.ACTIVE_SCENE = 0;
}

@Override
public void draw(Canvas canvas) {

    background.draw(canvas);
    player.draw(canvas);
    obstacleManagerCars.draw(canvas);
    obstacleManagerLantern.draw(canvas);
    obstacleManagerPeople.draw(canvas);

    Paint paint = new Paint();
    paint.setColor(Color.BLACK);
    paint.setTypeface(DEFAULT_BOLD);
    paint.setTextSize(60);
    canvas.drawText(""+score, 60, 60, paint);
}
@Override
public void update() {

    if(!gameOver) {
        if (playerPoint.x >= 250 && playerPoint.x <= (SCREEN_WIDTH - 250)) {
            player.update(playerPoint = new Point((int) (playerPoint.x - (carGravity)), playerPoint.y));
        } else if (playerPoint.x <= 250) {
            if (isTouch == 3) {
                carGravity = 0;
            }else if(isTouch == 2) {carGravity = -5 - VERTICAL_SPEED; player.update(playerPoint = new Point(251, playerPoint.y));}
        } else if (playerPoint.x >= SCREEN_WIDTH - 250) {
            if (isTouch == 2) {
                carGravity = 0;
            } else if(isTouch == 3){carGravity = 5 + VERTICAL_SPEED;player.update(playerPoint = new Point(SCREEN_WIDTH - 251, playerPoint.y));}
        }
        score += 13;
        background.update();
        obstacleManagerCars.update();
        obstacleManagerLantern.update();
        obstacleManagerPeople.update();


        // COLLISIONS //////////////////////////////////////////////////////////////////////////
        if(obstacleManagerCars.playerCollideCars(player) == 1){
            gameOver = true;
            gameOverTime = System.currentTimeMillis();
            score = 0;
        }
        if(obstacleManagerPeople.playerCollidePeople(player) == 0 || obstacleManagerPeople.playerCollidePeople(player) == 1){
        }


        if(isTouch == 2){
            carGravity = -5 - VERTICAL_SPEED;
        }else if(isTouch == 3){
            carGravity = 5 + VERTICAL_SPEED;
        }

        if(obstacleManagerCars.playerCollideCars(player) == 2 && isTouch == 3){carGravity = 5 + VERTICAL_SPEED;}
        else if(obstacleManagerCars.playerCollideCars(player) == 3 && isTouch == 2){carGravity = -5 - VERTICAL_SPEED;}
        else if (obstacleManagerCars.playerCollideCars(player) == 2 || obstacleManagerCars.playerCollideCars(player) == 3){
            player.update(playerPoint = new Point(playerPoint.x, playerPoint.y));
            carGravity = 0;
        }

        if(obstacleManagerLantern.playerCollideLantern(player)){
            player.update(playerPoint = new Point(playerPoint.x , playerPoint.y + 15));
        }
        // DIFFICULTY AND SCORE ////////////////////////////////////////////////////////////////
        if(score < 0 || player.getRectangle().top >= SCREEN_HEIGHT) {
            gameOver = true;
            gameOverTime = System.currentTimeMillis();
            score = 0;
        }
        if(score < 5000) {
            VERTICAL_SPEED = 0;
            HORIZONTAL_SPEED = 0;
            DENSITY = 0;
        }else if(score > 5000 && score < 10000){
            VERTICAL_SPEED = 0;
            HORIZONTAL_SPEED = -3000.0f;
            DENSITY = -1000;
        }else if(score > 10000 && score < 50000){
            VERTICAL_SPEED = 1;
            HORIZONTAL_SPEED = -5000.0f;
            DENSITY = -3000;
        }else if(score > 50000 && score < 70000){
            VERTICAL_SPEED = 2;
            HORIZONTAL_SPEED = -7000.0f;
            DENSITY = -3500;
        }else if(score > 80000){
            VERTICAL_SPEED = 2;
            HORIZONTAL_SPEED = -8500.0f;
            DENSITY = -4000;
        }
        ////////////////////////////////////////////////////////////////////////////////////////
    }

}

@Override
public void reciveTouch(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN){
        if(gameOver && System.currentTimeMillis() - gameOverTime >= 2000){
            gameOver = false;
            gameOverTime = System.currentTimeMillis();
            reset();
        }
    }
    if (event.getAction() == MotionEvent.ACTION_MOVE) {
        isTouch = 2;
    } else {
        isTouch = 3;
    }
}
}

1 Answers1

0

Here's how to double buffer. You must draw to a separate buffered image first. You must change animManager.draw so it accepts a BufferedImage rather than a Canvas

@Override
public void draw(Canvas canvas) {
    BufferedImage img = new BufferedImage(canvas.getWidth(), canvas.getHeight(), BufferedImage.TYPE_INT_ARGB)
    animManager.draw(img, car);
    Graphics g = canvas.getGraphics();
    g.drawImage(0, 0, null);
}
Derek Kaplan
  • 138
  • 9
  • but there is problem with that because BuferredImage and graphics is not included in AndroidSDK witch i'm using, sorry I should mention it earlier – Kacper Lechowicz Aug 12 '17 at 15:07