如何绘制无限量的精灵?

时间:2015-06-09 08:55:34

标签: java arraylist android-studio sprite

我是一名初学程序员,我正在android studio中制作一款飞鸟类游戏。我坚持让屏幕右侧的导弹进入。如何解决这个问题的任何提示,技巧和窍门?我认为自己制作精灵列表并尝试将这个列表循环无限时间,但我不知道如何。

基斯

public Missles(GamePanel game, Bitmap bmp) {
    this.game = game;
    this.sprite = bmp;
    this.width = bmp.getWidth() / Sprite_Columns;
    this.height = bmp.getHeight() / Sprite_Rows;
    this.xposition = 1100;
}
private void update() {
    //Here we check whether the bitmap touches the bound or not.
    //if (xposition > game.getWidth() - width - xspeed) {
    //    xspeed = -5;
    //}
    //if (xposition + xspeed < 0) {
    //    xspeed = 5;
    // }
    xposition = xposition + xspeed;
    currentframe = (currentframe + 1) % Sprite_Columns;
}
public void onDraw(Canvas canvas) {
    update();
    // Here we cut our bitmap, such that we get the frames from left to right in the columns
    int smallrectX = currentframe * width;

    //choosing the second row of our sprite sheet, quite confusing y-axis though
    int smallrectY = height;

    // Making two rectangles, the frame of the spritesheet and
    // the position to put it in!
    Rect smallrect = new Rect(smallrectX, smallrectY, smallrectX + width, smallrectY + height);
    Rect position = new Rect(xposition, yposition, xposition + width, yposition + height);

    // making a drawing
    canvas.drawBitmap(sprite, smallrect, position, null);
}

}

和我的游戏面板:

public class GamePanel extends SurfaceView implements SurfaceHolder.Callback {
private Sprite sprite;
private Missles missles;
private SurfaceHolder holder;
private GamePanelThread thread;
private Bitmap bmp;
private Bitmap missle;
private List<Sprite> spriteslist = new ArrayList<Sprite>();
private Bitmap background;
private Bitmap scaledbmp;
private int xposition = 0;
private int xspeed = 1;

public GamePanel(Context context,int resource) {
    super(context);
    //TODO Auto generated constructor stub
    // unpacking sprites and missles
    bmp = BitmapFactory.decodeResource(getResources(), resource);
    missle = BitmapFactory.decodeResource(getResources(), R.mipmap.angle_sprite);

    sprite = new Sprite(this,bmp);
    missles = new Missles(this,missle);

    // Making the surfaceholder and the thread for the gameloop
    holder = getHolder();
    holder.addCallback(this);
    thread = new GamePanelThread(holder, this);

    // This statement improves the performance
    setFocusable(true);
}


@Override
public void surfaceCreated(SurfaceHolder holder) {

    //Here i just creat the scaled background
    background = BitmapFactory.decodeResource(getResources(), R.mipmap.cool_background);
    float scale = (float)background.getHeight()/(float)getHeight();
    int newWidth = Math.round(background.getWidth()/scale);
    int newHeight = Math.round(background.getHeight()/scale);
    scaledbmp = Bitmap.createScaledBitmap(background, newWidth, newHeight, true);
    createSprites();

    // starting the thread
    thread.setRunning(true);
    thread.start();
}

private Sprite createSprite(int resouce) {
    Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
    return new Sprite(this, bmp);
}

private void createSprites() {
    spriteslist.add(createSprite(R.mipmap.angle_sprite));
    spriteslist.add(createSprite(R.mipmap.monster_girl_sprite));
    spriteslist.add(createSprite(R.mipmap.flyingwoman_sprite));
}

@Override
protected void onDraw(Canvas canvas) {
    //Drawing the background and sprites as it is a blackboard.
    canvas.drawBitmap(scaledbmp,0,0,null);
    sprite.onDraw(canvas);
    for (Sprite sprite : spriteslist) {
        missles.onDraw(canvas);
    }
    missles.onDraw(canvas);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format,
                           int width, int height) {
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    // the purpose here is to tell the thread to shut down.
    boolean retry = false;
    while (retry) {
        try {
            thread.join();
            retry = false;
        } catch (InterruptedException e) {

        }
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if(event.getAction() == MotionEvent.ACTION_DOWN){
        sprite.up = true;
        return true;
    }
    if(event.getAction() == MotionEvent.ACTION_UP){
        sprite.up = false;
        return true;
    }


    return super.onTouchEvent(event);
}

}

和游戏循环:

public class GamePanelThread extends Thread {

private int FPS = 10;
private boolean running;
private SurfaceHolder surfaceholder;
private GamePanel game;

public GamePanelThread(SurfaceHolder surfaceholder, GamePanel game){

    super();
    this.surfaceholder = surfaceholder;
    this.game = game;

}
public void setRunning(boolean running) {
    this.running = running;
}

@Override
public void run(){
    long startTime;
    long sleepTime;
    //tijd van gameloop
    long ticksPS = 1000 / FPS;
    while(running){
        startTime = System.nanoTime();
        Canvas canvas = null;
    try {
        canvas = surfaceholder.lockCanvas();
        synchronized (surfaceholder)
        {
            game.onDraw(canvas);
        }
    } finally {
        if (canvas != null) {
            surfaceholder.unlockCanvasAndPost(canvas);
        }
    sleepTime = ticksPS - (System.nanoTime()- startTime);//laatste deel is hoeveel seconden om 1 loop om te gaan;
    try{
        if(sleepTime>0) {
            this.sleep(sleepTime);
        } else {
            sleep(10);
        }
        } catch (Exception e) {}
    }
}


}

}

1 个答案:

答案 0 :(得分:2)

要跟踪无限数量的精灵,需要无限量的内存,并且需要无限的时间来绘制。 IE它不会工作。

你想要的是创建一些物体,在屏幕上绘制它并在它离开屏幕后静静地回收它。

您需要查找的主题是&#34;对象池&#34;。

我可能会有5到10枚导弹。他们每个人都有一个位图,一个位置和一个位置。布尔&#39; isAlive&#39;旗。当我想要制造导弹时,我会寻找一个alive == false的导弹并激活它。我只需要更新,绘制&amp;检查isAlive对象的冲突。一旦他们离开屏幕,设置isAlive = false并且可以再次重复使用它们。

这可能会用于无限赛跑游戏中的很多东西。