这两天,没事想学习游戏开发,看了一些资料之后准备开始。为了将来编码方便,先写了一个简单的游戏框架方便自己以后做练习用。
如果以后没有什么特殊的需求--比如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;
}
}
}

希望大家多多指正。因为本来有好多线程同步的东西,有问题是难免的。

[android游戏开发初学]简单的游戏框架的更多相关文章

  1. 【读书笔记《Android游戏编程之从零开始》】10.游戏开发基础(View 游戏框架)

    对于玩家来说,游戏是动态的:对于游戏开发人员来说,游戏是静态的,只是不停地播放不通的画面,让玩家看到了动态的效果. 进入Android之前,首先要熟悉三个重要的类:View(视图).Canvas(画布 ...

  2. Cocos2d-x-Lua 开发一个简单的游戏(记数字步进白色块状)

    Cocos2d-x-Lua 开发一个简单的游戏(记数字步进白色块状) 本篇博客来给大家介绍怎样使用Lua这门语言来开发一个简单的小游戏-记数字踩白块. 游戏的流程是这种:在界面上生成5个数1~5字并显 ...

  3. 【HTML5游戏开发】简单的《找不同汉字版》,来考考你的眼力吧

    一,准备工作 本次游戏开发需要用到lufylegend.js开源游戏引擎,版本我用的是1.5.2(现在最新的版本是1.6.0). 引擎下载的位置:http://lufylegend.googlecod ...

  4. Unity 2D游戏开发教程之为游戏场景添加多个地面

    Unity 2D游戏开发教程之为游戏场景添加多个地面 为游戏场景添加多个地面 显然,只有一个地面的游戏场景太小了,根本不够精灵四处活动的.那么,本节就来介绍一种简单的方法,可以为游戏场景添加多个地面. ...

  5. Libgdx游戏开发(2)——接水滴游戏实现

    原文:Libgdx游戏开发(2)--接水滴游戏实现 - Stars-One的杂货小窝 本文使用Kotlin语言开发 通过本文的学习可以初步了解以下基础知识的使用: Basic file access ...

  6. C#游戏开发中快速的游戏循环

    C#游戏开发中快速的游戏循环的实现.参考<精通C#游戏编程>一书. using System; using System.Collections.Generic; using System ...

  7. Unity 2D游戏开发教程之2D游戏的运行效果

    Unity 2D游戏开发教程之2D游戏的运行效果 2D游戏的运行效果 本章前前后后使用了很多节的篇幅,到底实现了怎样的一个游戏运行效果呢?或者说,游戏中的精灵会不会如我们所想的那样运行呢?关于这些疑问 ...

  8. 【读书笔记《Android游戏编程之从零开始》】11.游戏开发基础(SurfaceView 游戏框架、View 和 SurfaceView 的区别)

    1. SurfaceView 游戏框架实例 实例效果:就是屏幕上的文本跟着点击的地方移动,效果图如下: 步骤: 新建项目“GameSurfaceView”,首先自定义一个类"MySurfac ...

  9. 《MFC游戏开发》笔记九 游戏中的碰撞判定初步&怪物运动简单AI

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9374935 作者:七十一雾央 新浪微博:http:// ...

随机推荐

  1. Django 学习笔记(四)模板变量

    关于Django模板变量官方网址:https://docs.djangoproject.com/en/1.11/ref/templates/builtins/ 1.传入普通变量 在hello/Hell ...

  2. 【.net 深呼吸】实时获取计算结果

    上次老周介绍了在 UWP 应用中通过 x:Bind 标记来绑定到方法,以实现实时获取计算结果.今天,咱们来耍耍WPF上面的实现方法. 虽然,WPF 没有 x:Bind 标记(暂时没有,以后不好说),但 ...

  3. Spring Security学习笔记

    Spring Web Security是Java web开发领域的一个认证(Authentication)/授权(Authorisation)框架,基于Servlet技术,更确切的说是基于Servle ...

  4. [WPF]如何调试Data Binding

    前言 在WPF开发中,将ViewModel中对象绑定到UI上时,会出现明明已经将数据对象Binding到UI,但是UI上就是不显示等等的问题.这篇博客将介绍WPF Data Binding相关的内容, ...

  5. 学生管理系统开发代码分析笔记:jsp+java bean+servlet技术

    1 序言 学习java web的时候很渴望有一份完整的项目给我阅读,而网上的大部分项目拿过来都无法直接用,好不容易找到了一个学生管理系统也是漏洞百出.在此,我将边修改边学习这份代码,并且加上完全的注释 ...

  6. MySQL问题总结(持续更新)

    CHAR和VARCHAR的区别 存储方式和检索方式不同: 1.CHAR固定长度字符类型.CHAR存储定长数据,CHAR字段上的索引效率高,比如定义char(10),那么不论你存储的数据是否达到了10个 ...

  7. 初学者入门web前端:C#基础知识:函数

    入行前端对函数的掌握程度有可能直接影响以后工作的效率,使用函数可以高效的编写编码,节省时间,所以我整理了C#中最基础的函数知识点,虽然我在学习中 遇到很多问题,但是只要能够解决这些问题,都是好的. 一 ...

  8. 【Java数据结构学习笔记之二】Java数据结构与算法之栈(Stack)实现

      本篇是java数据结构与算法的第2篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型   栈是 ...

  9. JUnit 3.8.1 源码学习

    JUnit 3.8.1 源码学习 环境搭建(源码加载配置) 由于IDE自身含有JUint插件,因此通过正常途径是没有源码加载入口的,因此需通过手动加载扩展JAR,然后再添加对应源码JAR,如图:项目右 ...

  10. css编写注意事项(不定时更新)

    CSS的编写是需要积累的,而一个好的css编写习惯对我们将来的成长是非常有利的,我会把我平时看到的或者遇到的会不定时的更新到这里,不时翻一下,但求有所进步. 如果各位看官也有看法和建议,评论下,我也会 ...