Question

In my Android game, the bullets are appearing too fast and too close to each other! How can I adjust their behaviour? Here's a picture of it

class for animated objects

package game.objects.animation;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;

abstract class AnimatedObject {
    protected Bitmap bitmap;        // the animation sequence
    protected Rect sourceRect;  // the rectangle to be drawn from the animation bitmap
    private int frameNr;        // number of frames in animation
    private int currentFrame;   // the current frame
    private long frameTicker;   // the time of the last frame update
    private int framePeriod;    // milliseconds between each frame (1000/fps)

    protected int spriteWidth;  // the width of the sprite to calculate the cut out rectangle
    protected int spriteHeight; // the height of the sprite

    private int x;              // the X coordinate of the object (top left of the image)
    private int y;              // the Y coordinate of the object (top left of the image)

    public boolean exist; 

    public AnimatedObject(Bitmap bitmap, int x, int y, int width, int height, int fps, int frameCount) {

        this.bitmap = bitmap;
        this.x = x;
        this.y = y;
        currentFrame = 0;
        frameNr = frameCount;
        spriteWidth = bitmap.getWidth()/frameCount;
        spriteHeight = bitmap.getHeight();
        sourceRect = new Rect(0, 0, spriteWidth, spriteHeight);
        framePeriod = 1000/ fps;
        frameTicker = 0l;

        exist = true;
    }

    private void update(long gameTime) {

        //if (gameTime > frameTicker + framePeriod) {
            //frameTicker = gameTime;
            // increment the frame
            currentFrame++;
            if (currentFrame >= frameNr) {
                currentFrame = 0;
                }
            //}
        // define the rectangle to cut out sprite
        this.sourceRect.left = currentFrame * spriteWidth;
        this.sourceRect.right = this.sourceRect.left + spriteWidth;

    }

    public void animate(){

        if (currentFrame <= frameNr){
            update(0);
        }
    }

    public void draw(Canvas canvas) {
        // where to draw the sprite
        Rect destRect = new Rect(getX(), getY(), getX() + spriteWidth, getY() + spriteHeight);
        canvas.drawBitmap(bitmap, sourceRect, destRect, null);
    }

    public boolean checkCollisons(Rect another)
    {
        return Rect.intersects(new Rect(getX(), getY(), getX() + spriteWidth, getY() + spriteHeight), another);
    }

    public void destroy()
    {
        exist = false;
    }


    public Bitmap getBitmap() {
        return bitmap;
    }
    public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
    }
    public Rect getSourceRect() {
        return sourceRect;
    }
    public void setSourceRect(Rect sourceRect) {
        this.sourceRect = sourceRect;
    }
    public int getFrameNr() {
        return frameNr;
    }
    public void setFrameNr(int frameNr) {
        this.frameNr = frameNr;
    }
    public int getCurrentFrame() {
        return currentFrame;
    }
    public void setCurrentFrame(int currentFrame) {
        this.currentFrame = currentFrame;
    }
    public int getFramePeriod() {
        return framePeriod;
    }
    public void setFramePeriod(int framePeriod) {
        this.framePeriod = framePeriod;
    }
    public int getSpriteWidth() {
        return spriteWidth;
    }
    public void setSpriteWidth(int spriteWidth) {
        this.spriteWidth = spriteWidth;
    }
    public int getSpriteHeight() {
        return spriteHeight;
    }
    public void setSpriteHeight(int spriteHeight) {
        this.spriteHeight = spriteHeight;
    }
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }


}

class for bullet

package game.objects.animation;


import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;

public class Bullet extends AnimatedObject{

    private int mSpeedY;

    public Bullet(Bitmap bitmap, int x, int y, int width, int height, int fps,
            int frameCount) {
        super(bitmap, x, y, width, height, fps, frameCount);
        // TODO Auto-generated constructor stub
        mSpeedY = 10;
        setFramePeriod(5000/ fps);

    }

    public void draw(Canvas canvas) {
        // where to draw the sprite
        setY(getY() - mSpeedY);
        Rect destRect = new Rect(getX(), getY(), getX() + spriteWidth, getY() + spriteHeight);
        canvas.drawBitmap(bitmap, sourceRect, destRect, null);

    }

    public void animate()//анимация движения
    {
        super.animate();
        setY(getY() - mSpeedY);
       // checkBorders(rect);
    }



}

class of main game loop or how it calls in english(i'm not native speaker, sorry)

package game.view;

import game.main.R;
import game.objects.animation.Bullet;
import game.objects.animation.Explosion;
import game.objects.animation.ScrollingElement;
import game.objectsmain.Player;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

public class ViewManager extends Thread 
{
    private static final int FIELD_WIDTH = 480;
    private static final int FIELD_HEIGHT = 800;
    private static final int dist = 100;

    public int touchedX, touchedY;

    /** Область, на которой будем рисовать */
    private SurfaceHolder mSurfaceHolder;

    /** Состояние потока (выполняется или нет. Нужно, чтобы было удобнее прибивать поток, когда потребуется) */
    private boolean mRunning;

    /** Стили рисования */
    private Paint mPaint;

   /** The drawable to use as the background of the animation canvas */
    private Bitmap mBackgroundImage;
    private Bitmap mLinesImage;
    private Bitmap mExplosionImage;
    private Bitmap mBulletImage;
    private Drawable mPlayerImage;

    private ArrayList<ScrollingElement> mScrollEls = new ArrayList<ScrollingElement>();
    private ArrayList<Bullet> mBullets = new ArrayList<Bullet>();
    private ArrayList<Explosion> mBang = new ArrayList<Explosion>();
    private Player mHero;

    // desired fps
    private final static int    MAX_FPS = 50;
    // maximum number of frames to be skipped
    private final static int    MAX_FRAME_SKIPS = 5;
    // the frame period
    private final static int    FRAME_PERIOD = 1000 / MAX_FPS;  

    private Explosion mBoom;//объект класса взрыв

    public ViewManager(SurfaceHolder surfaceHolder, Context context)
    {
        mSurfaceHolder = surfaceHolder;
        mRunning = false;
        Resources res = context.getResources();
        mExplosionImage = BitmapFactory.decodeResource(res, R.drawable.explosion);
        mBackgroundImage = BitmapFactory.decodeResource(res, R.drawable.bckgr1);
        mLinesImage = BitmapFactory.decodeResource(res, R.drawable.lines3); 
        mPlayerImage = res.getDrawable(android.R.drawable.star_big_on);
        mBulletImage = BitmapFactory.decodeResource(res, R.drawable.bullet3);
        InitElements(res);
        mHero = new Player(mPlayerImage, 240, 400);
        mBoom = new Explosion(mExplosionImage, 200, 500, 64, 64, 7, 7);

    }


    /**
        * Задание состояния потока
        * @param running
        */
       public void setRunning(boolean running)
       {
           mRunning = running;
       }

       public void run()
       {
           while (mRunning)
           {
               Canvas canvas = null;
               try
               {
                   // подготовка Canvas-а
                   canvas = mSurfaceHolder.lockCanvas();
                   synchronized (mSurfaceHolder)
                   {

                       mHero.update();
                       // собственно рисование
                       addBullets();
                       doDraw(canvas);
                       //mImage.draw(canvas);

                       synchronized (mBullets) {
                           for (Bullet bullet: mBullets) {
                               //explosion if collides
                               if(bullet.checkCollisons(mHero.getRect()))
                               {
                                   mBang.add(new Explosion(mExplosionImage, mHero.getXCoord(), mHero.getYCoord(), 64, 64, 7, 7));
                                   mBang.get(0).draw(canvas);
                                   mBang.get(0).animate();
                               };
                               //bullet.animate();
                           }
                       }

                   }
               }
               catch (Exception e) { }
               finally
               {
                   if (canvas != null)
                   {
                       mSurfaceHolder.unlockCanvasAndPost(canvas);
                   }
               }
           }
       }

       public boolean gettouch = false;//in class with surface golder there are touchlistener works with this variable

       private void doDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        canvas.drawBitmap(mBackgroundImage, 0, 0, null);
        //отрисовка анимации
           synchronized (mScrollEls) {
               for (ScrollingElement element: mScrollEls) {
                   element.doDraw(canvas, mLinesImage);
                   element.animate(mLinesImage);
               }
           }
           mHero.draw(canvas);
           //mBoom.draw(canvas);
          /*if(gettouch == true){

              mBoom.draw(canvas);
               mBoom.getCurrentFrame();
               mBoom.animate();
        }*/

          synchronized (mBullets) {
               for (Bullet bullet: mBullets) {

                   bullet.animate();
                   bullet.draw(canvas);
                   //bullet.animate();
               }
           }

    }

    private void addBullets()//элементы для анимации заднего плана
       {
             if(gettouch)
             {
                 mBullets.add(new Bullet(mBulletImage, touchedX, touchedY, 22, 52, 3, 3));
             }
       }



    public boolean touched(boolean x)
    {
        return x;
    }
}
Was it helpful?

Solution

You're adding bullets every frame. Instead, only add every few frames or at an interval. For example, if you wanted to do it at a time interval, before you add a bullet check if the current time is the same as the last time you added a bullet plus the interval.

// fire every 500 ms
private static long INTERVAL = 500;
private long mLastFiredTime;
private void addBullets()//элементы для анимации заднего плана
{
    if(gettouch)
    {
         long now = System.currentTimeMillis();
         if (now > mLastFiredTime + INTERVAL) {
             mBullets.add(new Bullet(mBulletImage, touchedX, touchedY, 22, 52, 3, 3));
             mLastFiredTime = now;
         }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top