我正在制作一个应用程序,其中球从屏幕顶部落到屏幕底部,用户必须触摸某个区域才能使球消失。但是,当球落下时,它们会随着屏幕下降而断断续续。以下是该项目的完整代码:
public class GameActivity extends Activity implements View.OnTouchListener {
MyBringBack ourSurfaceView;
Paint p;
float x, y, secondX, secondY;
int firstRun;
Bitmap green, red, blue, purple, white;
int currentColor;
ArrayList<Ball> balls = new ArrayList<>();
Paint buttonPaint;
Boolean thingFirstRun;
int score;
Model model;
int cHeight, cWidth;
int nextBallSpeed;
int totalBalls;
int countBalls;
int buttonState = 0;
public final static int BUTTON_NONE = 0;
public final static int BUTTON_LEFT = 1;
public final static int BUTTON_RIGHT = 2;
public final static int BUTTON_BOTH = 3;
class Ball {
public Ball(int x, int y, int s, int color, Bitmap b) {
xCord = x;
yCord = y;
speed = s;
this.color = color;
passedLineYet = false;
bitmap = b;
}
public int xCord;
public int yCord;
public int speed;
public int color;
public boolean passedLineYet;
public Bitmap bitmap;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
red = BitmapFactory.decodeResource(getResources(), R.drawable.redcircle);
blue = BitmapFactory.decodeResource(getResources(), R.drawable.bluecircle);
green = BitmapFactory.decodeResource(getResources(), R.drawable.greencircle);
purple = BitmapFactory.decodeResource(getResources(), R.drawable.purplecircle);
white = BitmapFactory.decodeResource(getResources(), R.drawable.white);
secondX = secondY = -1;
cHeight = 0;
cWidth = 0;
countBalls = 0;
nextBallSpeed = 60;
p = new Paint();
p.setColor(Color.WHITE);
p.setTextSize(200);
ourSurfaceView = new MyBringBack(this);
ourSurfaceView.setOnTouchListener(this);
setContentView(ourSurfaceView);
model = new Model();
score = 0;
(new Thread(model)).start();
thingFirstRun = false;
currentColor = Color.GREEN;
buttonPaint = new Paint();
buttonPaint.setColor(currentColor);
buttonPaint.setStrokeWidth(10);
buttonPaint.setStyle(Paint.Style.FILL);
firstRun = 0;
}
public boolean correctColor(Ball b) {
if (currentColor == b.color) {
return true;
}
return false;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
return true;
}
@Override
protected void onPause() {
super.onPause();
ourSurfaceView.pause();
}
@Override
protected void onResume() {
super.onResume();
ourSurfaceView.resume();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
try {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
float xEvent = event.getX(event.getPointerId(event.getActionIndex()));
float yEvent = event.getY(event.getPointerId(event.getActionIndex()));
if (yEvent > cHeight / 4 * 3) {
if (xEvent < cWidth / 2) {
buttonState |= BUTTON_LEFT;
}
if (xEvent > cWidth / 2) {
buttonState |= BUTTON_RIGHT;
}
}
break;
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_UP:
try {
xEvent = event.getX(event.getPointerId(event.getActionIndex()));
yEvent = event.getY(event.getPointerId(event.getActionIndex()));
} catch (Exception e) {
xEvent = event.getX();
yEvent = event.getY();
}
if (yEvent > cHeight / 4 * 3) {
if (xEvent < cWidth / 2) {
buttonState &= ~BUTTON_LEFT;
}
if (xEvent > cWidth / 2) {
buttonState &= ~BUTTON_RIGHT;
}
}
break;
}
switch (buttonState) {
case BUTTON_LEFT:
currentColor = Color.RED;
break;
case BUTTON_RIGHT:
currentColor = Color.BLUE;
break;
case BUTTON_BOTH:
currentColor = Color.MAGENTA;
break;
case BUTTON_NONE:
currentColor = Color.GREEN;
break;
}
buttonPaint.setColor(currentColor);
Log.v("BUTTON STATE", buttonState + "");
Log.v("BUTTON COLOR", currentColor + "");
return true;
} catch (Exception e) {
}
return true;
}
public class Model extends Thread implements Runnable {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000 / 240);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (countBalls % nextBallSpeed == 0) {
int temp = (int) (Math.random() * 4);
if (temp == 0) {
balls.add(new Ball((int) (Math.random() * (cWidth - red.getWidth())), 0 - red.getHeight(), cHeight / 800, Color.RED, red));
} else if (temp == 1) {
balls.add(new Ball((int) (Math.random() * (cWidth - red.getWidth())), 0 - green.getHeight(), cHeight / 800, Color.GREEN, green));
} else if (temp == 2) {
balls.add(new Ball((int) (Math.random() * (cWidth - blue.getWidth())), 0 - blue.getHeight(), cHeight / 800, Color.BLUE, blue));
} else if (temp == 3) {
balls.add(new Ball((int) (Math.random() * (cWidth - purple.getWidth())), 0 - purple.getHeight(), cHeight / 800, Color.MAGENTA, purple));
}
totalBalls++;
}
if (totalBalls < 10) {
nextBallSpeed = 30;
} else if (totalBalls < 30) {
nextBallSpeed = 25;
} else if (totalBalls < 50) {
nextBallSpeed = 20;
} else if (totalBalls < 80) {
nextBallSpeed = 15;
} else if (totalBalls < 150) {
nextBallSpeed = 10;
} else {
nextBallSpeed = 5;
}
for (int i = 0; i < balls.size(); i++) {
int h = cHeight;
balls.get(i).yCord += balls.get(i).speed;
}
for (int i = 0; i < balls.size(); i++) {
try {
if (balls.get(i).yCord + green.getHeight() > ((double) cHeight * .75) && !balls.get(i).passedLineYet) {
balls.get(i).passedLineYet = true;
boolean b = correctColor(balls.get(i));
if (b) {
balls.remove(i);
score++;
}
if (!b) {
}
} else if (balls.get(i).yCord > cHeight) {
balls.remove(i);
score -= 5;
}
} catch (Exception ignored) {
}
}
countBalls++;
}
}
public boolean correctColor(Ball b) {
if (currentColor == b.color) {
return true;
}
return false;
}
}
public class MyBringBack extends SurfaceView implements Runnable {
SurfaceHolder ourHolder;
Thread ourThread = null;
boolean isRunning = false;
public MyBringBack(Context context) {
super(context);
ourHolder = getHolder();
}
public void pause() {
isRunning = false;
while (true) {
try {
ourThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
ourThread = null;
}
public void resume() {
isRunning = true;
ourThread = new Thread(this);
ourThread.start();
}
@Override
public void run() {
while (isRunning) {
try {
Thread.sleep(1000 / 240);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!ourHolder.getSurface().isValid()) {
continue;
}
//NE
Bitmap tempCanvasBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas tempCanvas = new Canvas();
tempCanvas.setBitmap(tempCanvasBitmap);
//NEND
//Canvas canvas = ourHolder.lockCanvas();
tempCanvas.drawColor(Color.BLACK);
if (firstRun == 0) {
cHeight = tempCanvas.getHeight();
cWidth = tempCanvas.getWidth();
red = getResizedBitmap(red, tempCanvas.getWidth() / 12, tempCanvas.getWidth() / 12);
green = getResizedBitmap(green, tempCanvas.getWidth() / 12, tempCanvas.getWidth() / 12);
blue = getResizedBitmap(blue, tempCanvas.getWidth() / 12, tempCanvas.getWidth() / 12);
purple = getResizedBitmap(purple, tempCanvas.getWidth() / 12, tempCanvas.getWidth() / 12);
white = getResizedBitmap(white, cHeight / 4 * 3, cWidth / 20);
firstRun = 1;
totalBalls = 0;
}
//canvas.drawBitmap(white, );
tempCanvas.drawRect(0, tempCanvas.getHeight() * 3 / 4, tempCanvas.getWidth(), tempCanvas.getHeight(), buttonPaint);
for (int i = 0; i < balls.size(); i++) {
try {
tempCanvas.drawBitmap(balls.get(i).bitmap, balls.get(i).xCord, balls.get(i).yCord, null);
} catch (Exception ignored) {
}
}
Rect r = new Rect();
p.getTextBounds(score + "", 0, (score + "").length(), r);
tempCanvas.drawText(score + "", cWidth - r.width() - 20, r.height() + 20, p);
Canvas canvas = ourHolder.lockCanvas();
canvas.drawBitmap(tempCanvasBitmap, 0, 0, p);
ourHolder.unlockCanvasAndPost(canvas);
}
}
}
public static Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
}
我以前创建过动画,但没有使用Runnable(onDraw()方法中的所有代码)。也许问题就在于此。
有谁知道为什么会出现这种口吃?
答案 0 :(得分:1)
使用此: 添加类成员字段,替换run(),并添加primeCanvas()方法。
boolean isPrimed = false;
Canvas canvas;
@Override
public void run() {
while(isRunning) {
if (!ourHolder.getSurface().isValid())
continue;
canvas = ourHolder.lockCanvas();
if(!isPrimed)
primeCanvas();
canvas.drawColor(Color.BLACK);
canvas.drawRect(0, canvas.getHeight() * 3 / 4, canvas.getWidth(), canvas.getHeight(), buttonPaint);
for(int i = 0; i < balls.size(); i ++)
canvas.drawBitmap(balls.get(i).bitmap, balls.get(i).xCord, balls.get(i).yCord, null);
Rect r = new Rect();
p.getTextBounds(score + "", 0, (score + "").length(), r);
canvas.drawText(score + "", cWidth - r.width() - 20, r.height() + 20, p);
ourHolder.unlockCanvasAndPost(canvas);
}
}
private void primeCanvas() {
cHeight = canvas.getHeight();
cWidth = canvas.getWidth();
red = getResizedBitmap(red, canvas.getWidth()/12, canvas.getWidth()/12);
green = getResizedBitmap(green, canvas.getWidth()/12, canvas.getWidth()/12);
blue = getResizedBitmap(blue, canvas.getWidth()/12, canvas.getWidth()/12);
purple = getResizedBitmap(purple, canvas.getWidth()/12, canvas.getWidth()/12);
white = getResizedBitmap(white, cHeight / 4 * 3, cWidth / 20);
firstRun = 1;
totalBalls = 0;
}