1
    package com.anu;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
public class GameView extends SurfaceView {
  public static int a,y;
private Bitmap bm ,hud;
   private SurfaceHolder holder;
   private GameLoopThread gameLoopThread;

   private long lastClick;
private Bitmap bmpBlood ;
private static boolean ab=true;
Timex n = new Timex();



private List<Sprite> sprites = new ArrayList<Sprite>();
private List<Sprite> sprites2 = new ArrayList<Sprite>();
private List<Sprite> sprites3 = new ArrayList<Sprite>();
private List<Sprite> sprites4 = new ArrayList<Sprite>();
private List<Sprite> sprites5 = new ArrayList<Sprite>();
private List<Sprite> sprites6 = new ArrayList<Sprite>();

private List<TempSprite> temps = new ArrayList<TempSprite>();

       public GameView(Context context) {
         super(context);
         gameLoopThread = new GameLoopThread(this);
         holder = getHolder();
         holder.addCallback(new Callback()
           {
                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {
                }
                @Override
                public void surfaceCreated(SurfaceHolder holder) {
                    int t2 =Timex.a;
                                      createSprites();
                                      cs2();
                                      cs3();
                                      cs4();


                                    /*  if(t2>10){
                                      cs2();}
                                      if(t2>20){
                                      cs3();}
                                      if(t2>30){
                                      cs4();}
                                      if(t2>40){
                                          cs5();
                                      }*/
                       gameLoopThread.setRunning(true);
                       gameLoopThread.start();
                       n.start();

                }
                @Override
                public void surfaceChanged(SurfaceHolder holder, int format,
                              int width, int height) {
                }
         });
         bmpBlood = BitmapFactory.decodeResource(getResources(), R.drawable.blood2);
          bm = BitmapFactory.decodeResource(getResources(), R.drawable.sky4);
          Bitmap  o = Bitmap.createScaledBitmap( bm, 800, 490, false);
          bm=o;


   }

   private void createSprites() {
       sprites.add(createSprite(R.drawable.act0));
       sprites.add(createSprite(R.drawable.act0));
       sprites.add(createSprite(R.drawable.act0));
       sprites.add(createSprite(R.drawable.act0));
       sprites.add(createSprite(R.drawable.act0));


   }

   private Sprite createSprite(int resouce) {
        Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
         return new Sprite(this, bmp);
   }
   private void cs2() {
       sprites2.add(createSprite(R.drawable.act));
       sprites2.add(createSprite(R.drawable.act));
       sprites2.add(createSprite(R.drawable.act));
       sprites2.add(createSprite(R.drawable.act));
       sprites2.add(createSprite(R.drawable.act ));
   }
   private void cs3() {
       sprites3.add(createSprite(R.drawable.act1));
       sprites3.add(createSprite(R.drawable.act1));
       sprites3.add(createSprite(R.drawable.act1));
       sprites3.add(createSprite(R.drawable.act1));
       sprites3.add(createSprite(R.drawable.act1));


   }
   private void cs4() {
       sprites4.add(createSprite(R.drawable.act2));
       sprites4.add(createSprite(R.drawable.act2));
       sprites4.add(createSprite(R.drawable.act2));
       sprites4.add(createSprite(R.drawable.act2));
       sprites4.add(createSprite(R.drawable.act2));
   }
   private void cs5() {
       sprites5.add(createSprite(R.drawable.act3));
       sprites5.add(createSprite(R.drawable.act3));
       sprites5.add(createSprite(R.drawable.act3));
       sprites5.add(createSprite(R.drawable.act3));
       sprites5.add(createSprite(R.drawable.act3));


   }
   private void cs6() {
         sprites6.add(createSprite(R.drawable.act4));
         sprites6.add(createSprite(R.drawable.act4));
         sprites6.add(createSprite(R.drawable.act4));
         sprites6.add(createSprite(R.drawable.act4));
         sprites6.add(createSprite(R.drawable.act4));
           }


   @Override
   protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.rgb(21, 181, 195));
        canvas.drawBitmap(bm, 0, 0, null);

             for (int i = temps.size() - 1; i >= 0; i--) {
             temps.get(i).onDraw(canvas);
       } 
         int tt = Timex.a;
             if(tt>0){
             for (Sprite wave2 : sprites) {
              wave2.onDraw(canvas);

              }
             if(tt>10){

             for (Sprite wave2 : sprites2) {
              wave2.onDraw(canvas);
              }
             if(tt>20){
                for (Sprite wave2 : sprites3) {
                      wave2.onDraw(canvas);
                      }
            }
             if(tt>30){
                for (Sprite wave2 : sprites4) {
                      wave2.onDraw(canvas);

                      }
                 if(tt>40){
                     for (Sprite wave2 : sprites5) {
                      wave2.onDraw(canvas);
                      }
                 }

               }

         }



        canvas.drawBitmap(hud, 0, 0, null);

         }
          }
             @Override
            public boolean onTouchEvent(MotionEvent event) {
           int kt=Timex.a;
           if (System.currentTimeMillis() - lastClick > 500) {
                  lastClick = System.currentTimeMillis();
             synchronized (getHolder()) {
             float x = event.getX();
                float y =event.getY();
                if(kt>0){
                   for (int i = sprites.size() - 1; i >= 0; i--) {
                        Sprite sprite = sprites.get(i);
                        if (sprite.isCollition(x, y)) {
                              sprites.remove(sprite);

                            temps.add(new TempSprite(temps, this, x, y, bmpBlood));
                              break;
                        }
                    }}
                if(kt>10){
                   for (int i = sprites2.size() - 1; i >= 0; i--) {
                       Sprite sprite = sprites2.get(i);
                       if (sprite.isCollition(x, y)) {
                             sprites2.remove(sprite);

                        temps.add(new TempSprite(temps, this, x, y, bmpBlood));
                             break;
                       }}
                   }
                if(kt>20){
                   for (int i = sprites3.size() - 1; i >= 0; i--) {
                       Sprite sprite = sprites3.get(i);
                       if (sprite.isCollition(x, y)) {
                             sprites3.remove(sprite);

                        temps.add(new TempSprite(temps, this, x, y, bmpBlood));
                             break;
                       }
                   }}
                if(kt>30)
                   for (int i = sprites4.size() - 1; i >= 0; i--) {
                       Sprite sprite = sprites4.get(i);
                       if (sprite.isCollition(x, y)) {
                             sprites4.remove(sprite);

                        temps.add(new TempSprite(temps, this, x, y, bmpBlood));
                             break;
                       }
                   }
                if(kt>40)
                       for (int i = sprites5.size() - 1; i >= 0; i--) {
                           Sprite sprite = sprites5.get(i);
                           if (sprite.isCollition(x, y)) {
                                 sprites5.remove(sprite);

                            temps.add(new TempSprite(temps, this, x, y, bmpBlood));
                                 break;
                           }
                       }
                if(kt>50)
                       for (int i = sprites6.size() - 1; i >= 0; i--) {
                           Sprite sprite = sprites6.get(i);
                           if (sprite.isCollition(x, y)) {
                                 sprites6.remove(sprite);

                            temps.add(new TempSprite(temps, this, x, y, bmpBlood));
                                 break;
                           }
                       }
                }
         }
         return true;
   }
  }

This is my game code . where i get multiple sprite in list and use them to display in canvas with On draw method they game runs fine till cs4(); in my code runs ..when i call cs5(); i get error saying bitmap vm budget out of memory . i thought when i destroy sprites while playing game i could reduce the budget but i keep getting the same error . i want to usecs2();,cs3(),cs4(),cs5() again and again in my game without exceeding the vm budget . how to get this running by clearing the previous bitmap cleared in memory and create new image from the method and use them again .. i thought scaling would help but my bitmaps are very small so if i scale them they become very small to see so i want to use the same image with same size and display again and again in canvas Thank you all !

UPDATE my sprite class

  package com.anu;

  import java.util.Random;

  import android.graphics.Bitmap;

  import android.graphics.Canvas;

 import android.graphics.Rect;

 public class Sprite {
  // direction = 0 up, 1 left, 2 down, 3 right,
   // animation = 3 back, 1 left, 0 front, 2 right
   int[] DIRECTION_TO_ANIMATION_MAP = { 3, 1, 0, 2 };
   private static final int BMP_ROWS = 4;
   private static final int BMP_COLUMNS = 3;
 //  private static final int MAX_SPEED = 9;
   private GameView gameView;
   private Bitmap bmp;
   private int x = 0;
   private int y = 0;
   private int xSpeed =15;
   private int ySpeed=15;
   private int currentFrame = 0;
   private int width;
   private int height;

   public Sprite(GameView gameView, Bitmap bmp) {
         this.width = bmp.getWidth() / BMP_COLUMNS;
         this.height = bmp.getHeight() / BMP_ROWS;
         this.gameView = gameView;
         this.bmp = bmp;
         Random rnd = new Random();
         x = rnd.nextInt(gameView.getWidth() - width);
         y = rnd.nextInt(gameView.getHeight() - height);
    //     xSpeed = rnd.nextInt(MAX_SPEED * 2) - MAX_SPEED;
      //   ySpeed = rnd.nextInt(MAX_SPEED * 2) - MAX_SPEED;
  }
   private void update() {
         if (x >= gameView.getWidth() - width - xSpeed || x + xSpeed <= 0) {
                xSpeed = -xSpeed;
         }
         x = x + xSpeed;
         if (y >= gameView.getHeight() - height - ySpeed || y + ySpeed <= 0) {
                ySpeed = -ySpeed;
         }
         y = y + ySpeed;
         currentFrame = ++currentFrame % BMP_COLUMNS;
  }

   public void onDraw(Canvas canvas) {
         update();
         int srcX = currentFrame * width;
         int srcY = getAnimationRow() * height;
         Rect src = new Rect(srcX, srcY, srcX + width, srcY + height);
         Rect dst = new Rect(x, y, x + width, y + height);
         canvas.drawBitmap(bmp, src, dst, null);
   }

   private int getAnimationRow() {
         double dirDouble = (Math.atan2(xSpeed, ySpeed) / (Math.PI / 2) + 2);
         int direction = (int) Math.round(dirDouble) % BMP_ROWS;
         return DIRECTION_TO_ANIMATION_MAP[direction];
   }

   public boolean isCollition(float x2, float y2) {
         return x2 > x && x2 < x + width && y2 > y && y2 < y + height;
   }
   }
Anu
  • 31
  • 8
  • check this out http://stackoverflow.com/questions/15254272/bitmapfactory-decodestream-out-of-memory-despite-using-reduced-sample-size – Goofy Oct 24 '13 at 10:08
  • Sorry but why are you adding the same sprite based on the same drawable multiple times? What a waste of memory! – WarrenFaith Oct 24 '13 at 10:10
  • i want to create 5 enemies each time i call the function later on i send enemies in different combos – Anu Oct 24 '13 at 10:13

1 Answers1

1

The following code is just wrong becuase you create in each of your cs2, cs3 etc 5 times the same bitmap/sprite. This is just wrong and the reason why you have the OOM. There is no reason why you should add the same bitmap 5 times to a list...

private Sprite createSprite(int resouce) {
    Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
     return new Sprite(this, bmp);
}
private void cs2() {
   sprites2.add(createSprite(R.drawable.act));
   sprites2.add(createSprite(R.drawable.act));
   sprites2.add(createSprite(R.drawable.act));
   sprites2.add(createSprite(R.drawable.act));
   sprites2.add(createSprite(R.drawable.act ));
}
private void cs3() {
   sprites3.add(createSprite(R.drawable.act1));
   sprites3.add(createSprite(R.drawable.act1));
   sprites3.add(createSprite(R.drawable.act1));
   sprites3.add(createSprite(R.drawable.act1));
   sprites3.add(createSprite(R.drawable.act1));
}
private void cs4() {
   sprites4.add(createSprite(R.drawable.act2));
   sprites4.add(createSprite(R.drawable.act2));
   sprites4.add(createSprite(R.drawable.act2));
   sprites4.add(createSprite(R.drawable.act2));
   sprites4.add(createSprite(R.drawable.act2));
}
private void cs5() {
   sprites5.add(createSprite(R.drawable.act3));
   sprites5.add(createSprite(R.drawable.act3));
   sprites5.add(createSprite(R.drawable.act3));
   sprites5.add(createSprite(R.drawable.act3));
   sprites5.add(createSprite(R.drawable.act3));
}
private void cs6() {
     sprites6.add(createSprite(R.drawable.act4));
     sprites6.add(createSprite(R.drawable.act4));
     sprites6.add(createSprite(R.drawable.act4));
     sprites6.add(createSprite(R.drawable.act4));
     sprites6.add(createSprite(R.drawable.act4));
}

Update

i want to create 5 enemies each time i call the function later on i send enemies in different combos

So you should reuse one(!!) drawable for each of your enemies. That means: Create an enemy class which will use the same drawable. That would reduce the uses images to 1 per enemy type.

WarrenFaith
  • 57,492
  • 25
  • 134
  • 150
  • i want to create 5 enemies each time i call the function later on i send enemies in different combos – Anu Oct 24 '13 at 10:15
  • could u please give me an example code for my enemy class and how to use in my Above coding ? thank u – Anu Oct 24 '13 at 10:20
  • 1
    If you have done the above code, you can do it yourself easily. Just do it step by step. Start by replacing the list of sprites with a list of "Enemy" classes/objects and continue from there... – WarrenFaith Oct 24 '13 at 10:22
  • NO i am learning from a tutorial and introducing my own code to get a better game from the tutorial game but i am trying what u said . if i fail to do it .i will let u know :) then help me please – Anu Oct 24 '13 at 10:34
  • 1
    You could try this: http://web.archive.org/web/20120922191120/http://www.droidnova.com/2d-tutorial-series-part-v,848.html (an old already offline blog from me where I introduced an "Element" class which moves randomly on the screen). This special part does not yet use the same image for all elements but to achieve that you just need some kind of a cache class where you just create a sprite for your drawable once and return it with a simple getter for everybody who wants to use it. – WarrenFaith Oct 24 '13 at 10:43
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/39899/discussion-between-anu-and-warrenfaith) – Anu Oct 24 '13 at 10:48
  • i added my sprite class which is same like your element class from the example u gave in the tutorial slightly different – Anu Oct 24 '13 at 13:23
  • 1
    i try ed my best i got null pointer exception error i try ed many ways but i still got the error can u please give me a enemy class i up loaded my sprite class can u change it to enemy1 class and give me please i like to learn more .. – Anu Oct 27 '13 at 13:17