emulus
emulus

Reputation: 77

Defining the size of the bitmap in android app

My android game has sprites bouncing all over the place but on the right and bottom edges/walls of the screen, the sprites go off slightly before bouncing off.

I know this is something to do with the size of the bitmap and it is in the sprite class below but I can't figure out what needs amending.

Here is the sprite class:

public class Sprite extends AppCompatActivity {

private static final int BMP_ROWS = 4;
private static final int BMP_COLUMNS = 3;
//x,y position of sprite - initial position (0,50)
private int x = 0;
private int y = 0;
private int xSpeed = 5;//Horizontal increment of position (speed)
private int ySpeed = 5;// Vertical increment of position (speed)
private GameView gameView;
private Bitmap spritebmp;
private int currentFrame = 0;
//Width and Height of the Sprite image
private int bmp_width;
private int bmp_height;
// Needed for new random coordinates.
private Random random = new Random();

private SoundPool mySound;
int zapSoundId;

public Sprite(GameView gameView) {
    this.gameView = gameView;
    spritebmp = BitmapFactory.decodeResource(gameView.getResources(),
            R.drawable.bad4);
    this.bmp_width = spritebmp.getWidth() / BMP_COLUMNS;
    this.bmp_height = spritebmp.getHeight() / BMP_ROWS;
    xSpeed = random.nextInt(15) + 1;
    ySpeed = random.nextInt(15) + 1;
    x = random.nextInt(gameView.getWidth() - bmp_width);
    y = random.nextInt(gameView.getHeight() - bmp_height);


}

public Sprite(GameView gameView, Bitmap bmp) {

        spritebmp.recycle();
}

//update the position of the sprite
public void update() {
    x = x + xSpeed;
    y = y + ySpeed;
    bounce();

    //y = random.nextInt(gameView.getWidth());
    //wrapAround(); //Adjust motion of sprite.
}

private void bounce() {
    if (x <= 0 || x >= gameView.getWidth() ) {
        xSpeed = xSpeed * -1;
    }
    if (y <= 0 || y >= gameView.getHeight() ) {
        ySpeed = ySpeed * -1;
    }
    currentFrame = ++currentFrame % BMP_COLUMNS;

}

public void draw(Canvas canvas) {

    update();
    int srcX = currentFrame * bmp_width;
    int srcY;
    if (xSpeed > 0) {
        srcY = 0 * bmp_height;
    }
    else {
        srcY = 1 * bmp_height;
    }
    // Create Rect around the source image to be drawn
    Rect src = new Rect(srcX, srcY, srcX + bmp_width, srcY + bmp_height);
    // Rect for destination image
    Rect dst = new Rect(x, y, x + bmp_width, y + bmp_height);
    //
    // Draw the image frame
    canvas.drawBitmap(spritebmp, src, dst, null);

}


// Checks if the sprite was touched
public boolean wasItTouched(float ex, float ey) {
    boolean touched = false;
    if ((x <= ex) && (ex < x + bmp_width) &&
            (y <= ey) && (ey < y + bmp_height)) {
        touched = true;
    }


    return touched;

}

}

Any help greatly appreciated.

Thanks

Upvotes: 0

Views: 202

Answers (3)

emulus
emulus

Reputation: 77

I've fixed it.

I needed to add 'this.bmp_width' and 'this.bmp_height' to my bounce() method.

private void bounce() {
    if (x <= 0 || x + this.bmp_width >= gameView.getWidth() ) {
        xSpeed = xSpeed * -1;
    }
    if (y <= 0 || y + this.bmp_height >= gameView.getHeight() ) {
        ySpeed = ySpeed * -1;
    }
    currentFrame = ++currentFrame % BMP_COLUMNS;

}

Upvotes: 1

Gabe Sechan
Gabe Sechan

Reputation: 93614

It has nothing to do with size, and everything to do with your bounce detection. When update is called, you're adding speed to the x position. Then you're checking to see it it went over and changing the speed. If say the speed was 10 pixels, the wall is at position 100, and your sprite is at 99, adding 10 will move it to 109- past the edge. You need a slightly more intelligent update method- check if you move past the edge, and if so actually reverse the movement:

  if(x+speed < 0 ) {
      x= -(x+speed);
      speed = -speed;
   }
   else if(x+speed > maxPosition) {
      x = maxPosition- (x+speed - maxPosition);
      speed = -speed;
   }
   else {
      x = x+speed;
   }

This would check the boundaries, and adjust position accordingly (putting any excess movement into the negative direction).

Upvotes: 0

Zoe - Save the data dump
Zoe - Save the data dump

Reputation: 28238

Firstly, a very good suggestion is making sure your drawables are not in drawable-nodpi put it in a folder like drawable-mdpi to make it scale automatically.

But if you really want to set the size to a fixed size, you can use this method:

Bitmap resizedBitmap = Bitmap.createScaledBitmap(myBitmap, 960, 960, false);

WARNING: (If I understand correctly) this method inputs pixels. Meaning using this method sets it to a fixed size on all devices, meaning it will look bigger on low densities, and smaller on higher densities(depending on how you have set it up). Find how many DP you want to have the image to(design for 160 dpi) and convert DP to PX. I suggest you place your images in mdpi.

But as to your images bouncing off the screen, you have to get the width and height of the bitmap:

myBitmap.getWidth();
myBitmap.getHeight();

And apply that to the location-check. 0 is 0, but 0 + 50(if that is the width at 160 dpi) isn't the same position on the bitmap compared to 640 DPI if the image is put in a folder like mdpi.

As you are using a spritesheet, this is my suggestion

  • Get the amount of rows and columns
  • Get the width and height of the spritesheet and divide by the rows and columns

That way, you can place them into mdpi and automatically scale it to make sure it looks the same size on different densities. Then you get the width and height of each frame using getWidth/Height, and apply that to checking if the sprite is off the screen.

Upvotes: 0

Related Questions