Shafiul Islam
Shafiul Islam

Reputation: 11

Draw multiple objects in Canvas

I got this game developing concept from the book "Beginning Android Games, 2nd Edition by Mario Zechner" so credit goes to him!

Now, I want to create and animate many objects in the screen like "enemies or blocks". I want to create a separate class and create an array or linked list of instances of them in this class so that I don't have to write code for each "enemy". I want to define there movement in there own classes also. I tried...

Enemy e = new Enemy(canvas);

but it does not work. I'm a beginner in Android and trying desperately to learn! I figured out movement, collision, etc, but stuck here. Please, give me some ideas.

public class MyGFXSur extends SurfaceView implements Runnable{

    SurfaceHolder holder;
    Thread thread = null;
    boolean isRunning = false;

    public MyGFXSur(Context context) {
        super(context);
        holder = getHolder();

    }

    public void pause(){
        isRunning = false;
        while (true){
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            break;
        }
        thread = null;
    }

    public void resume(){
        isRunning = true;
        thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        while(isRunning){
            if(!holder.getSurface().isValid()){
                continue;
            }
            Canvas canvas = holder.lockCanvas();
            canvas.drawRGB(02, 02, 150);
            if(x != 0 && y != 0){
                Bitmap test = BitmapFactory.decodeResource(getResources(), R.drawable.greenball);
            canvas.drawBitmap(test, x-(test.getWidth()/2), y-(test.getWidth()/2), null);
            }
            holder.unlockCanvasAndPost(canvas);
        }
    }
}

The other class...

public class GFXSur extends Activity implements View.OnTouchListener{

    MyGFXSur mygfxsur;
    float x, y;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mygfxsur = new MyGFXSur(this);
        mygfxsur.setOnTouchListener(this);
        x = 0;
        y = 0;
        setContentView(mygfxsur);


    }

    @Override
    protected void onResume() {
        super.onResume();
        mygfxsur.resume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mygfxsur.pause();
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        x = event.getX();
        y = event.getY();

        return true;
    }
} 

I tried the following, but I get this error: "cannot resolve method getResources()"

public class Enemy {
    public Enemy(Canvas canvas) {
        Bitmap test = BitmapFactory.decodeResource(getResources(), R.drawable.greenball);
        canvas.drawBitmap(test, 100, 100, null);
    }
}

Upvotes: 1

Views: 2349

Answers (2)

Patrick Wertal
Patrick Wertal

Reputation: 1

You have to handle your context from the activity to the Enemy Class, where you have the decodeBitmap methode. otherwise NULLPointer Exception

Upvotes: 0

A.S.
A.S.

Reputation: 4574

Here you go, this should give you a hint how to handle self drawing objects:

A SuperClass which defines what a DrawingObject should do

public abstract class DrawinObject{ 
    public abstract void draw(Canvas canvas);
    public abstract void updatePhysics();
}

Implementation of the Class to eg draw a Rect, but you could draw anything

public class MyRect extends DrawinObject{

    Paint paint;
    Context context;

    public MyRect(Context context){
        //do some init
        Paint paint = new Paint();
        paint.setColor(Color.BLACK);
        paint.setStrokeWidth(3);
    }

    public void updatePhysics(){

    }

    public void draw(Canvas canvas){
        //if you need some resources eg drawables just call
        //context.getResources().getDrawables(R.drawable.ic_launcher);
        canvas.drawRect(30, 30, 80, 80, paint);
    }
}

Another implementation

public class MyCircle extends DrawinObject{

    Paint paint;
    int x, y;

    public MyRect(){
        //do some init
        Paint paint = new Paint();
        paint.setColor(Color.BLACK);
        paint.setStrokeWidth(3);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.WHITE);

        x= 10;
        y = 30;
    }   

    public void updatePhysics(){
        x++;
        y++;
    }


    public void draw(Canvas canvas){
         canvas.drawCircle(x / 2, y / 2, radius, paint);
    }
}

Now, just add them to a List and loop over the list in your gameloop

//MAIN
private ArrayList<DrawinObject> myDrawingObjects;
    public MyGFXSur(Context context){
        myDrawingObjects = new ArrayList<DrawinObject>();
        myDrawingObjects.add(new MyCircle());
        myDrawingObjects.add(new MyRect(MainActivity.this)); 
    }


     @Override
    public void run() {
        while(isRunning){
            if(!holder.getSurface().isValid()){
                continue;
            }
            updatePhysics();
            Canvas canvas = holder.lockCanvas();
            drawObjects(canvas);    
            holder.unlockCanvasAndPost(canvas);
        }
    }

    private void updatePhysics(){
        for(DrawinObject drawObject : myDrawingObjects){
            drawObject.updatePhysics();
        }   
    }

    private void drawObjects(Canvas canvas){
        for(DrawinObject drawObject : myDrawingObjects){
            drawObject.draw(canvas);
        }
    }

Upvotes: 2

Related Questions