主程序代码:
package com.toby.personal.testlistview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
final private static String TAG = "Toby_Test";
final private static int MSG_WHAT = 170411;
private boolean isOver = false;
// 桌面的宽高
private int tableWidth;
private int tableHeight;
// 球拍的垂直位置
private int racketY;
// 球拍的宽高
private final int RACKET_WIDTH = 70;
private final int RACKET_HEIGHT = 20;
// 小球的大小
private final int BALL_SIZE = 12;
// 小球的纵向速度
private int ySpeed = 20;
private Random random = new Random();
// 返回一个介于 -0.5 ~ 0.5 之间的比率,用于控制小球的运行方向
private double xyRate = random.nextDouble() - 0.5;
// 小球的横向速度
private int xSpeed = (int) (ySpeed * xyRate * 2);
// 小球的坐标
private int ballX = random.nextInt(200) + 20;
private int ballY = random.nextInt(10) + 20;
// 球拍的水平位置
private int racketX = random.nextInt(200);
// 球拍上次的 x 坐标
private float racketLastX = racketX;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
final GameView gameView = new GameView(this);
setContentView(gameView);
WindowManager windowManager = getWindowManager();
Display display = windowManager.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
tableWidth = metrics.widthPixels;
tableHeight = metrics.heightPixels - 400;
racketY = tableHeight - 80;
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == MSG_WHAT) {
gameView.invalidate();
}
super.handleMessage(msg);
}
};
gameView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
float x = event.getX();
if (x < racketLastX) {
if (racketX > 0) racketX -= 10;
} else {
if (racketX < tableWidth - RACKET_WIDTH) racketX += 10;
}
racketLastX = x;
return true;
}
});
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (ballX <= 0 || ballX >= tableWidth - BALL_SIZE) {
xSpeed = -xSpeed;
}
if (ballY >= racketY - BALL_SIZE
&& (ballX < racketX || ballX > racketX + RACKET_WIDTH)) {
timer.cancel();
isOver = true;
} else if (ballY <= 0 || (ballY >= racketY - BALL_SIZE
&& ballX > racketX && ballX <= racketX + RACKET_WIDTH)) {
ySpeed = -ySpeed;
}
ballY += ySpeed;
ballX += xSpeed;
handler.sendEmptyMessage(MSG_WHAT);
}
}, 0, 100);
}
class GameView extends View {
Paint paint = new Paint();
public GameView(Context context) {
super(context);
setFocusable(true);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.GRAY);
if (isOver) {
paint.setColor(Color.RED);
paint.setTextSize(40);
canvas.drawText("Game Over!", 50, 200, paint);
} else {
paint.setColor(Color.rgb(240, 240, 80));
canvas.drawCircle(ballX, ballY, BALL_SIZE, paint);
paint.setColor(Color.rgb(80, 80, 200));
canvas.drawRect(racketX, racketY, racketX + RACKET_WIDTH, racketY + RACKET_HEIGHT,
paint);
}
}
}
}
运行效果:
显示效果
本文参考文献:《疯狂Android讲义 : 第2版 》