这两天,没事想学习游戏开发,看了一些资料之后准备开始。为了将来编码方便,先写了一个简单的游戏框架方便自己以后做练习用。
如果以后没有什么特殊的需求--比如opengl什么的,会尽量用这个简单框架来实现。有优化的地方会在这个里边一直更新,也希望有问题的地方希望大家帮忙提一些意见
我的刷新线程基础类
/**
* 我的刷新线程
*/
abstract class LoopThread extends Thread{
private boolean DEBUG = true;
private Object lock = new Object(); public static final int RUNNING = 1;
public static final int PAUSE = 2;
public static final int STOP = 0;
public int runState = STOP;
private WeakReference<CustomSurfaceViewCallBack> callbackRef ;
public LoopThread(CustomSurfaceViewCallBack view){
super();
callbackRef = new WeakReference<CustomSurfaceViewCallBack>(view);
}
@Override
public void run() {
try {
loop();
} catch (InterruptedException e) {
this.interrupt();
}finally{
this.runState = STOP;
tRelase();
if(DEBUG){
System.out.println(this.getName()+" exit, lock="+lock);
}
}
}
private void loop() throws InterruptedException {
while(runState!=STOP){
synchronized (lock) {
while (runState == RUNNING) { CustomSurfaceViewCallBack callBack = callbackRef.get();
if (callBack == null) {
runState = STOP;
break;
}
onLoop(callBack);
if (runState == RUNNING) {
lock.wait(500);
} else {
break;
}
}
if(runState==PAUSE){
lock.wait();
}else if(runState==STOP){
lock.notifyAll();
return;
}
}
}
}
public abstract void onLoop(CustomSurfaceViewCallBack callBack); public void tRelase(){
callbackRef = null;
}
public void tResume(){
synchronized (lock) {
this.runState = LoopThread.RUNNING;
lock.notifyAll();
}
}
public void tPause(){
synchronized (lock) {
this.runState = LoopThread.PAUSE;
lock.notifyAll();
}
}
public boolean tStop(){
synchronized (lock) {
this.tRelase();
this.runState = LoopThread.STOP;
lock.notifyAll();
}
while(true){
try {
this.join();
return true;
} catch (InterruptedException e) {
this.interrupt();
}
}
}
}
刷新接口
public interface CustomSurfaceViewCallBack { public abstract boolean processing(); public abstract void doDraw(Canvas canvas); public SurfaceHolder getSurfaceHolder();
}
游戏的显示界面的基础类
abstract class CustomSurfaceView extends SurfaceView implements Callback,CustomSurfaceViewCallBack{
private LoopThread dt;
private ProcessThread pt;
private SurfaceHolder sHolder;
public CustomSurfaceView(Context context) {
super(context);
sHolder = getHolder();
sHolder.addCallback(this);
}
private boolean singleThread = false;
/**
* 设置是否用单线程来刷新界面和处理数据。
* 一般来说,为了保证流畅性游戏开发刷新界面的线程和数据处理线程是分开的。如果数据处理耗时,最好分开。如果数据处理耗时较少,可以使用单线程
* @param single
*/
public void setSingleThread(boolean single){
if(dt!=null){
throw new UnsupportedOperationException("must invoke setSingleThread before surfaceCreated");
}
this.singleThread = single;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
start();
} @Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
stop();
}
/**
* 进行界面绘制操作
* @param canvas
*/
public abstract void doDraw(Canvas canvas);
/**
* 处理数据 并判断是否进行界面重绘
* @return
*/
public abstract boolean processing();
@Override
public SurfaceHolder getSurfaceHolder(){
return getHolder();
}
public void start(){
if(singleThread){// 如果是单线程的话,初始化一个整合了数据处理和界面刷新一起处理的线程
stop();
dt= new SingleThread(this);
dt.runState = LoopThread.RUNNING;
dt.start();
return;
}
if(stop(dt)){
dt = new DrawThread(this);
dt.runState = LoopThread.RUNNING;
dt.start();
}
if(stop(pt)){
pt = new ProcessThread(this);
pt.runState = LoopThread.RUNNING;
pt.start();
}
}
/**
* 停止一个LoopThread 停止成功返回false
* @param t
* @return
*/
private boolean stop(LoopThread t){
if(t==null){
return true;
}
return t.tStop();
}
/**
* 游戏停止
*/
public void stop(){
stop(dt);
stop(pt);
}
/**
* 游戏暂停
*/
public void pause(){
if(dt!=null){
dt.tPause();
}
if(pt!=null){
pt.tPause();
}
}
/**
* 只可以从游戏暂停状态让游戏开始
*/
public void resume(){
if(dt!=null){
dt.tResume();
}
if(pt!=null){
pt.tPause();
}
}
/**
* 界面绘制线程
* @author cs
*/
private static class DrawThread extends LoopThread{
public DrawThread(CustomSurfaceView view) {
super(view);
this.setName("DrawThread--"+this.getId());
} @Override
public void onLoop(CustomSurfaceViewCallBack callBack) {
drawByCallback(callBack);
} }
/**
* 如果是单线程刷新的话,用到的线程类
* @author cs
*/
private static class SingleThread extends LoopThread{
public SingleThread(CustomSurfaceView view) {
super(view);
this.setName("SingleThread--"+this.getId());
}
@Override
public void onLoop(CustomSurfaceViewCallBack callBack) {
callBack.processing();
drawByCallback(callBack);
}
}
/**
* 数据处理以及逻辑判断线程
* @author cs
*/
private static class ProcessThread extends LoopThread{
public ProcessThread(CustomSurfaceViewCallBack callBack) {
super(callBack);
this.setName("ProcessThread--"+this.getId());
}
@Override
public void onLoop(CustomSurfaceViewCallBack callBack) {
if(callBack!=null){
callBack.processing();
}
} }
private static void drawByCallback(CustomSurfaceViewCallBack callBack) {
Canvas canvas = null;
try {
canvas = callBack.getSurfaceHolder().lockCanvas();
if (canvas != null) {
callBack.doDraw(canvas);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null)
callBack.getSurfaceHolder().unlockCanvasAndPost(canvas);
}
}
}
显示的实现还是上篇中要显示的贝塞尔曲线。当然,实现起来比原来代码简单多了
public class PathActivity extends Activity {
private CustomSurfaceView pathView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pathView = new PathView(this);
pathView.setSingleThread(false);
this.setContentView(pathView);
}
private static class PathView extends CustomSurfaceView{
private int vWidth;
private int vHeight;
private Paint pPaint;
private Path mPath;
private float endX;
private float endY;
private Random random; public PathView(Context context) {
super(context);
pPaint = new Paint();
pPaint.setAntiAlias(true);
pPaint.setColor(0xaf22aa22);
pPaint.setStyle(Paint.Style.STROKE);
mPath = new Path();
random = new Random();
} private void init(){
vWidth = getWidth();
vHeight = getHeight();
endX = 0.8f*vWidth;
endY = 0.8f*vHeight;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
super.surfaceCreated(holder);
init();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
super.surfaceChanged(holder, format, width, height);
init();
}
@Override
public void doDraw(Canvas canvas){
canvas.drawColor(Color.BLACK);
canvas.drawPath(mPath, pPaint);
}
@Override
public boolean processing(){
//这里构建贝塞尔曲线
mPath.reset();
mPath.moveTo(50, 50);
mPath.quadTo(random.nextInt(vWidth), random.nextInt(vHeight), endX/2, random.nextInt(vHeight));
mPath.quadTo(random.nextInt(vWidth), random.nextInt(vHeight), endX, endY);
return true;
}
}
}
希望大家多多指正。因为本来有好多线程同步的东西,有问题是难免的。