我试图在SurfaceView类中使用画布在screeen上绘制一些气球,我成功地能够在画布上绘制多个气球并通过交换不同的图像为其设置动画。问题是当我尝试触摸Oneballoon时,我需要将其从屏幕上删除。

码:
主要活动:

package com.pradhul.game.touchball;
import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new GameView(this));
    /*TODO Hide the bottom navigation bar */
}


}

GameView.java

package com.pradhul.game.touchball;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class GameView extends SurfaceView implements    SurfaceHolder.Callback, View.OnTouchListener {
private static final int NUM_OF_BALLOONS = 5; //TODO for more than one  balloons animations dont work(?)
/*use SurfaceView because we want complete control over the screen.
    * unlike extending View class the oDraw() Method will not be called automatically
    * from the method onSurfaceCreated() we have to call it Manually and pass a canvas object into it
    * */
private final SurfaceHolder holder;
private GameLoopThread gameLoopThread;
private List<Balloon> balloons =  new ArrayList<>();

public GameView(Context context) {
    super(context);
    gameLoopThread = new GameLoopThread(this);
    holder = getHolder();
    holder.addCallback(this);
    createBalloons(NUM_OF_BALLOONS);
    this.setOnTouchListener(this);
}

private void createBalloons(int count) {
    for(int i=0 ; i< count ;i++){
        balloons.add(createBalloon());
    }
}

@Override
protected void onDraw(Canvas canvas) {
    if(canvas != null) {
        canvas.drawColor(Color.WHITE);
        for(Balloon balloon : balloons){
            try {
                gameLoopThread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            balloon.onDraw(canvas);
        }
    }
}

@SuppressLint("WrongCall")
@Override
public void surfaceCreated(SurfaceHolder holder) {
    /*this is called when the view is created*/
    gameLoopThread.setRunning(true);
    gameLoopThread.start();
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    /*pausing game Thread*/
    gameLoopThread.setRunning(false);
    while (true){
        try {
            gameLoopThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
private  Balloon createBalloon(){
    return new Balloon(this);
}


@Override
public synchronized boolean onTouch(View v, MotionEvent event) {
    Log.d("OnTouch real -", "x: " + event.getX() + ", Y: " + event.getY());
 /*   for (int i = balloons.size()-1; i >= 0; i--) {
        Balloon balloon = balloons.get(i);
        Log.d("OnTouch collision -", !balloon.isCollision(event.getX(), event.getY())+"");
        if (!balloon.isCollision(event.getX(), event.getY())) {
            balloons.remove(0);
            break;
        }
    }*/
    Iterator<Balloon>  balloonIterator = balloons.iterator();
    while(balloonIterator.hasNext()){
        Balloon balloon = balloonIterator.next();
        balloons.remove(0);
    }
    return true;
}
}


GameLoopThread.java

package com.pradhul.game.touchball;
import android.annotation.SuppressLint;
import android.graphics.Canvas;

public class GameLoopThread extends Thread {

private GameView view;
private boolean running = false;

public GameLoopThread(GameView view){
    this.view = view;
}
public void setRunning(boolean run){
    running = run;
}

@SuppressLint("WrongCall")
public void run(){
    while (running){
        Canvas canvas = null;
        try{
            canvas = view.getHolder().lockCanvas();
            synchronized (view.getHolder()){
                view.onDraw(canvas);
            }
        }finally{
            if(canvas != null) {
                view.getHolder().unlockCanvasAndPost(canvas);
            }
        }
    }

}
}


Balloon.java

package com.pradhul.game.touchball;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.Log;
import java.util.Random;

public class Balloon {
private static final int BALLOON_SPEED = 10;
private int y = 0;
private int x = 0;
private int speed = 1;
private GameView gameView;
private Bitmap balloon;
public Bitmap[] normalBalloons;
private int balloonIndex = 0;

private int normalImages[] = {R.drawable.normal_01,R.drawable.normal_02,R.drawable.normal_03,
        R.drawable.normal_04,R.drawable.normal_05,R.drawable.normal_06,R.drawable.normal_07,
        R.drawable.normal_08,
};
private int crackingImages[] = {R.drawable.crack_01,R.drawable.crack_02,R.drawable.crack_03,
        R.drawable.crack_04, R.drawable.crack_05,R.drawable.crack_04,R.drawable.crack_03,
        R.drawable.crack_02
};
private boolean reverseSwap = false;


public Balloon(GameView gameView){
    this.gameView = gameView;
    normalBalloons = new Bitmap[8];
    setUpImages();
}

public  void onDraw(Canvas canvas){
    /*draws the balloon in canvas */
    animateBalloon();
    update(canvas.getWidth());
    canvas.drawBitmap(balloon, x, y, null);
}

public boolean isCollision(float x2, float y2) {
    return x2 > x && x2 < x + balloon.getWidth() && y2 > y && y2 < y + balloon.getHeight();
}

private int getRandomX(int maxVal) {
    Random rand = new Random();
    return rand.nextInt(maxVal);
}

private void animateBalloon() {
    /*Animates the balloon by swapping resource image at each call*/
    this.balloon = getBalloons();
    Log.d("Balloon",balloonIndex % normalBalloons.length + "");
}

private void update(int canvasWidth) {
    /*updates the y position for moving the balloon*/
    if (y <= 0){
        /*so that the balloon starts from bottom
        * gameView will return a height only after the View is ready
        * getting 0 in constructor of this class*/
        y = gameView.getHeight();
        /*x is assigned a random between the width od the canvas
        * so that the balloons will appear random positions from below*/
        x = getRandomX(canvasWidth - balloon.getWidth());
    }
    if (y > gameView.getHeight() - balloon.getHeight() - speed) {
        speed = -BALLOON_SPEED;
    }
    y = y + speed;
    Log.d("Balloon","Positions:"+x+","+y);
}

private Bitmap getBalloons() {
    if(balloonIndex == normalBalloons.length-1) {
        reverseSwap = true;
    }
    if(balloonIndex == 0){
        reverseSwap = false;
    }
    balloonIndex = reverseSwap?balloonIndex-1:balloonIndex+1;
    return normalBalloons[balloonIndex];
}

private void setUpImages() {
    /*setting up resources array*/
    for(int count =0; count < normalImages.length; count++){
        Bitmap balloon =   BitmapFactory.decodeResource(gameView.getResources(), normalImages[count]);
        normalBalloons[count] = balloon;
    }


}
}


我很困惑为什么它会导致这样的错误,任何人都可以看看它并建议我一个解决方案,这是去除错误的正确方法吗?

请分享任何建议

谢谢

最佳答案

这是错误的删除方式。

如果要遍历Collection / List,并且要删除当前元素,则必须使用Iterator.remove()方法。

就您而言,只需调用balloonIterator.remove()而不是balloons.remove(0)

甚至更简单,因为您要从列表中删除所有元素-您只需调用balloons.clear()并完全删除循环。

09-10 01:14
查看更多