所需的基本知识:
使用SurfaceView类创建游戏场景,游戏场景实现Runnable接口,并使用线程刷新游戏画布
如何解决不同物体的刷新频率?
由于画布是统一刷新的(暂时不知道如何实现局部刷新画布),例如A要0.1秒刷新一次画布,而B要1秒刷新一次画布,那么就在场景中引入计时器timer,每次刷新线程计时器递增,让线程休眠100毫秒,通过对计时器求模运算(如timer%20就是2秒刷新频率)
核心代码:
package com.example.testgame;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.security.KeyStoreParameter.Builder;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
public class gameView extends SurfaceView implements Callback, Runnable {
private SurfaceHolder sfh;
private Thread thread;
private boolean flag;
private int[][] grid = {
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 }
};
private int ROWS, COLS;
int BLK_WIDTH, BLK_HEIGHT;
private int mouseX, mouseY;
private int getX, getY;
private boolean touched;
private int timer = 1;
private int score = 0;
private SoundPool clickSound, startSound;
private int soundId, startSoundId;
private Bitmap[] bmpBtn = new Bitmap[2];
private Bitmap bmpBg, bmpScoreBoard, map;
private boolean pressed = false;
private boolean startGame = false;
private MediaPlayer mp, end;
private Bitmap mouse;
private int count_down;
public gameView(Context context) {
super(context);
// TODO 自动生成的构造函数存根
sfh = this.getHolder();
sfh.addCallback(this);
flag = true;
BLK_WIDTH = 100;
BLK_HEIGHT = 100;
ROWS = 7;
COLS = 5;
touched = false;
clickSound = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
startSound = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
soundId = clickSound.load(getContext(), R.raw.click, 1);
startSoundId = startSound.load(getContext(), R.raw.start_sound, 100);
bmpBtn[0] = BitmapFactory.decodeResource(getResources(), R.raw.btn_1);
bmpBtn[1] = BitmapFactory.decodeResource(getResources(), R.raw.btn_2);
bmpBg = BitmapFactory.decodeResource(getResources(), R.raw.bg);
mouse = BitmapFactory.decodeResource(getResources(), R.raw.mouse);
map = BitmapFactory.decodeResource(getResources(), R.raw.map);
bmpScoreBoard = BitmapFactory.decodeResource(getResources(), R.raw.score_board);
mp = MediaPlayer.create(getContext(), R.raw.bg_music);
end = MediaPlayer.create(getContext(), R.raw.end);
mp.setLooping(true);
count_down = 60;
}
@Override
public void run() {
// TODO 自动生成的方法存根
while (flag) {
timer++;
gameDraw();
if (timer % 15 == 0) {
logic();
}
if (timer % 10 == 0) {
count_down--;
}
if (count_down < 0) {
// System.out.println("GAME OVER");
flag = false;
mp.stop();
scoreBoard();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO 自动生成的方法存根
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO 自动生成的方法存根
gameInit();
// thread = new Thread(this);
// thread.start();
}
public boolean containsPoint(int x, int y, Bitmap bitmap, Point point) {
if (point.x > x && point.x < x + bitmap.getWidth() && point.y > y & point.y < y + bitmap.getHeight()) {
return true;
} else {
return false;
}
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO 自动生成的方法存根
flag = false;
}
public void logic() {
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
grid[i][j] = 0;
}
}
int jump_count = (int) (Math.random() * 4 + 2);
// System.out.println(jump_count);
long start = System.currentTimeMillis();
for (int i = 0; i < jump_count; i++) {
int x = (int) (Math.random() * ROWS);
int y = (int) (Math.random() * COLS);
grid[x][y] = 1;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO 自动生成的方法存根
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mouseX = (int) event.getX();
mouseY = (int) event.getY();
pressed = true;
if (mouseX <= BLK_WIDTH * COLS && mouseY < BLK_HEIGHT * ROWS) {
getX = mouseX / BLK_WIDTH;
getY = mouseY / BLK_HEIGHT;
// System.out.println(grid[getY][getX] + "");
// System.out.println(getX + ", " + getY);
if (grid[getY][getX] == 1) {
// System.out.println("CAUGHTED...");
score++;
grid[getY][getX] = 0;
clickSound.play(soundId, 1, 1, 0, 0, 1);
}
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
// gameInit();
pressed = false;
}
if (!startGame) {
gameInit();
}
return true;
}
public void gameDraw() {
Canvas canvas = sfh.lockCanvas();
Paint paint = new Paint();
canvas.drawColor(Color.GREEN);
canvas.drawBitmap(map, 0, 0, null);
// 边框
// paint.setColor(Color.GRAY);
// paint.setStyle(Paint.Style.STROKE);
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
paint.setStyle(Paint.Style.FILL);
if (grid[i][j] == 0) {
// 填充
// paint.setColor(Color.WHITE);
} else if (grid[i][j] == 1) {
// 填充
// paint.setColor(Color.BLACK);
canvas.drawBitmap(mouse, j * BLK_WIDTH, i * BLK_HEIGHT, null);
}
// paint.setColor(Color.BLACK);
// canvas.drawRect(j * BLK_WIDTH, i * BLK_HEIGHT, (j + 1) *
// BLK_WIDTH, (i + 1) * BLK_HEIGHT, paint);
// 边框
// paint.setColor(Color.GRAY);
// paint.setStyle(Paint.Style.STROKE);
// canvas.drawRect(j * BLK_WIDTH, i * BLK_HEIGHT, (j + 1) *
// BLK_WIDTH, (i + 1) * BLK_HEIGHT, paint);
}
}
Paint scorePaint = new Paint();
scorePaint.setColor(Color.RED);
scorePaint.setTextSize(80);
Paint countdownPaint = new Paint();
countdownPaint.setColor(Color.WHITE);
countdownPaint.setTextSize(40);
if (score != 0) {
canvas.drawText(score + "", this.getWidth() / 2 - 40, BLK_HEIGHT * ROWS + 100, scorePaint);
}
canvas.drawText(count_down + "", this.getWidth() - 60, 40, countdownPaint);
sfh.unlockCanvasAndPost(canvas);
}
public void gameInit() {
Paint paintBlue = new Paint();
paintBlue.setColor(Color.BLUE);
Paint paintWhite = new Paint();
paintWhite.setColor(Color.WHITE);
Canvas canvas = sfh.lockCanvas();
// canvas.drawColor(Color.WHITE);
canvas.drawBitmap(bmpBg, 0, 0, null);
// // canvas.drawRect(100, 100, 200, 200, paintBlue);
int x = this.getWidth() / 2 - bmpBtn[0].getWidth() / 2;
int y = this.getHeight() / 2 - bmpBtn[0].getHeight() / 2;
if (containsPoint(x, y, bmpBtn[0], new Point(mouseX, mouseY)) && pressed) {
canvas.drawBitmap(bmpBtn[1], x, y, null);
startGame = true;
startSound.play(startSoundId, 1, 1, 0, 0, 1);
} else {
canvas.drawBitmap(bmpBtn[0], x, y, null);
}
if (startGame) {
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// // TODO 自动生成的 catch 块
// e.printStackTrace();
// }
if (flag) {
thread = new Thread(this);
thread.start();
mp.start();
}
}
paintWhite.setTextSize(20);
canvas.drawText("Start Game", x + bmpBtn[0].getWidth() / 2 - 50, y + bmpBtn[0].getHeight() / 2 + 4, paintWhite);
sfh.unlockCanvasAndPost(canvas);
}
public void scoreBoard() {
Canvas canvas = sfh.lockCanvas();
Paint scorePaint = new Paint();
scorePaint.setColor(Color.RED);
scorePaint.setTextSize(100);
canvas.save();
canvas.scale((float) this.getWidth() / (float) bmpScoreBoard.getWidth(), (float) this.getHeight() / (float) bmpScoreBoard.getHeight());
canvas.drawBitmap(bmpScoreBoard, 0, 0, null);
canvas.restore();
canvas.drawText(score + "", 70, 260, scorePaint);
sfh.unlockCanvasAndPost(canvas);
end.start();
}
public void startGame() {
flag = true;
}
}
源文件下载: