Java Android画布动画出现口吃(不平滑)
我正在制作一个应用程序,其中球从屏幕顶部落到屏幕底部,用户必须触摸某个区域才能使球消失。然而,当球落下时,当球从屏幕上落下时,它们似乎会结巴。以下是该项目的完整代码:Java Android画布动画出现口吃(不平滑),java,android,animation,canvas,Java,Android,Animation,Canvas,我正在制作一个应用程序,其中球从屏幕顶部落到屏幕底部,用户必须触摸某个区域才能使球消失。然而,当球落下时,当球从屏幕上落下时,它们似乎会结巴。以下是该项目的完整代码: public class GameActivity extends Activity implements View.OnTouchListener { MyBringBack ourSurfaceView; Paint p; float x, y, secondX, secondY; int f
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;
}
}
公共类GameActivity扩展活动实现View.OnTouchListener{
MyBringBack我们的表面视图;
油漆p;
浮动x,y,secondX,secondY;
int firstRun;
位图绿色、红色、蓝色、紫色、白色;
int-currentColor;
ArrayList balls=新的ArrayList();
油漆按钮油漆;
布尔thingFirstRun;
智力得分;
模型;
中华人民共和国切特,;
int nextBallSpeed;
积分球;
int计数球;
int buttonState=0;
公共最终静态int按钮\u NONE=0;
公共最终静态int按钮_左=1;
公共最终静态int按钮_RIGHT=2;
公共最终静态int按钮_均=3;
班级舞会{
公共球(整数x、整数y、整数s、整数颜色、位图b){
xCord=x;
yCord=y;
速度=s;
这个颜色=颜色;
passedLineYet=false;
位图=b;
}
公共int xCord;
公共信息中心;
公共交通速度;
公共int颜色;
公共布尔passedLineYet;
公共位图;
}
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
红色=BitmapFactory.decodeResource(getResources(),R.drawable.redcircle);
blue=BitmapFactory.decodeResource(getResources(),R.drawable.bluecircle);
绿色=BitmapFactory.decodeResource(getResources(),R.drawable.greencircle);
紫色=BitmapFactory.decodeResource(getResources(),R.drawable.purplecircle);
white=BitmapFactory.decodeResource(getResources(),R.drawable.white);
secondX=secondY=-1;
切特=0;
cWidth=0;
countBalls=0;
nextBallSpeed=60;
p=新油漆();
p、 setColor(Color.WHITE);
p、 setTextSize(200);
ourSurfaceView=新的MyBringBack(本);
我们的surfaceview.setOnTouchListener(这个);
setContentView(我们的SurfaceView);
模型=新模型();
得分=0;
(新线程(模型)).start();
thingFirstRun=false;
currentColor=Color.GREEN;
ButtonPoint=新油漆();
ButtonPoint.setColor(当前颜色);
按钮点设置行程宽度(10);
ButtonPoint.setStyle(Paint.Style.FILL);
firstRun=0;
}
公共颜色(球b){
如果(currentColor==b.color){
返回true;
}
返回false;
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
//为菜单充气;这会将项目添加到操作栏(如果存在)。
返回true;
}
@凌驾
受保护的void onPause(){
super.onPause();
我们的surfaceview.pause();
}
@凌驾
受保护的void onResume(){
super.onResume();
我们的surfaceview.resume();
}
@凌驾
公共布尔onTouch(视图v,运动事件){
试一试{
开关(event.getAction()&MotionEvent.ACTION\u掩码){
case MotionEvent.ACTION\u DOWN:
case MotionEvent.ACTION\u指针\u向下:
float xEvent=event.getX(event.getPointerId(event.getActionIndex());
float-yEvent=event.getY(event.getPointerId(event.getActionIndex());
如果(YeEvent>cHeight/4*3){
如果(xEventcWidth/2){
按钮状态|=按钮右;
}
}
打破
case MotionEvent.ACTION\u指针\u向上:
case MotionEvent.ACTION\u UP:
试一试{
xEvent=event.getX(event.getPointerId(event.getActionIndex());
yEvent=event.getY(event.getPointerId(event.getActionIndex());
}捕获(例外e){
xEvent=event.getX();
yEvent=event.getY();
}
如果(YeEvent>cHeight/4*3){
如果(xEventcWidth/2){
按钮状态&=~按钮右;
}
}
打破
}
开关(按钮状态){
案例按钮(左):
currentColor=Color.RED;
打破
案例按钮(右):
currentColor=Color.BLUE;
打破
案例按钮\u两个:
currentColor=Color.品红色;
打破
案例按钮\u无:
currentColor=Color.GREEN;
打破
}
ButtonPoint.setColor(当前颜色);
Log.v(“按钮状态”,按钮状态+”);
Log.v(“按钮颜色”,currentColor+”);
返回true;
}捕获(例外e){
}
返回true;
}
公共类模型扩展线程实现可运行{
@凌驾
公开募捐{
while(true){
试一试{
睡眠(1000/240);
}捕捉(中断异常e){
e、 printStackTrace();
}
如果(countBalls%nextBallSpeed==0){
int temp=(int)(Math.random)
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;
}