接下来将慢慢涉入游戏的开发,作为第一篇介绍一个模拟平抛运动的小DEMO。主要核心是两个线程类:BallThread负责改变小球的状态和坐标位置,会用到一些常用的物理公式,相信大家并不陌生。DrawThread负责绘制界面图片,包括背景,木板,小球。这两个线程相结合,就实现了模拟小球的平抛运动并将其绘制在界面上。BallThread就相当于一个物理引擎,对小球的运动进行分阶段处理,包括开始运动到滑至木板边缘、小球下落、小球反弹、小球达到最高点再下落、循环直至运动停止。每个阶段的开始都对小球位置和状态进行初始操作。保证小球坐标的准确性。
MainActivity:
package com.home.simulationthrow;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import android.app.Activity;
public class MainActivity extends Activity {
BallView bv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 设置为全屏模式
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
bv = new BallView(this);
setContentView(bv);
}
}
BallView:
package com.home.simulationthrow;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class BallView extends SurfaceView implements SurfaceHolder.Callback {
public static final int V_MAX = 45; // 小球水平速度的最大值
public static final int V_MIN = 20; // 小球竖直速度的最大值
private Bitmap[] bitmapArray = new Bitmap[6];// 6个小球图片
private Bitmap bmpBack; // 背景图片对象
private Bitmap bmpWood; // 木板图片对象
private int ballNumber = 6; // 小球数目
public static final int WOOD_EDGE = 60; // 木板的右边沿的x坐标
public static final int GROUND_LING = 600;// 游戏中代表地面y坐标,小球下落到此会弹起
public static final int UP_ZERO = 30; // 小球在上升过程中,如果速度大小小于该值就算为0
public static final int DOWN_ZERO = 60; // 小球在撞击地面后,如果速度大小小于该值就算为0
List
movables = new ArrayList
(); private DrawThread dt; // 后台屏幕绘制线程 String fps = "FPS:N/A"; // 用于显示帧速率的字符串,调试使用 public BallView(Context context) { super(context); getHolder().addCallback(this); initBitmaps(getResources()); initMovables(); dt = new DrawThread(this, getHolder()); } /** * 初始化图片 * * @param resources */ private void initBitmaps(Resources r) { bitmapArray[0] = BitmapFactory.decodeResource(r, R.drawable.ball_red_small); // 红色较小球 bitmapArray[1] = BitmapFactory.decodeResource(r, R.drawable.ball_purple_small); // 紫色较小球 bitmapArray[2] = BitmapFactory.decodeResource(r, R.drawable.ball_green_small); // 绿色较小球 bitmapArray[3] = BitmapFactory.decodeResource(r, R.drawable.ball_red); // 红色较大球 bitmapArray[4] = BitmapFactory .decodeResource(r, R.drawable.ball_purple); // 紫色较大球 bitmapArray[5] = BitmapFactory.decodeResource(r, R.drawable.ball_green); // 绿色较大球 bmpBack = BitmapFactory.decodeResource(r, R.drawable.back); // 背景砖墙 bmpWood = BitmapFactory.decodeResource(r, R.drawable.wood); } /** * 初始化小球集合 */ private void initMovables() { Random r = new Random(); for (int i = 0; i < ballNumber; i++) { int index = r.nextInt(32); // 产生随机数 Bitmap tempBitmap = null; if (i < ballNumber / 2) { tempBitmap = bitmapArray[3 + index % 3];// 如果是初始化前一半球,就从大球中随机找一个 } else { tempBitmap = bitmapArray[index % 3];// 如果是初始化后一半球,就从小球中随机找一个 } Movable m = new Movable(0, 70 - tempBitmap.getHeight(), tempBitmap.getWidth() / 2, tempBitmap); // 创建Movable对象 movables.add(m); // 将新建的Movable对象添加到ArrayList列表中 } } /** * 绘制程序中所需要的图片等信息 * * @param canvas */ public void doDraw(Canvas canvas) { canvas.drawBitmap(bmpBack, 0, 0, null); // 绘制背景图片 canvas.drawBitmap(bmpWood, 0, 60, null);// 绘制木板图片 for (Movable m : movables) { // 遍历Movable列表,绘制每个Movable对象 m.drawSelf(canvas); } Paint p = new Paint(); p.setColor(Color.BLUE); p.setTextSize(18); p.setAntiAlias(true); // 设置抗锯齿 canvas.drawText(fps, 30, 30, p); // 画出帧速率字符串 } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { } @Override public void surfaceCreated(SurfaceHolder arg0) { if (dt != null && !dt.isAlive()) { // 如果DrawThread没有启动,就启动这个线程 dt.start(); } } @Override public void surfaceDestroyed(SurfaceHolder arg0) { if (dt != null) { dt.flag = false;// 停止线程的执行 dt = null; // 将dt指向的对象声明为垃圾 } } }
Movable实体类:
package com.home.simulationthrow;
import android.graphics.Bitmap;
import android.graphics.Canvas;
/**
* 小球实体类
*
* @author Administrator
*
*/
public class Movable {
int startX = 0; // 初始X坐标
int startY = 0; // 初始Y坐标
int x; // 实时X坐标
int y; // 实时Y坐标
float startVX = 0f; // 初始水平方