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

     打了***号的都是老师要求明天早上默写的  编程语言的作用(程序员使用的编程语言达到命令电脑工作的目的)及与操作系统和硬件的关系(编程 语言用来开发软件,软件基于操作系统之上,操作系统又基于硬件之上 ...

  2. ABP+AdminLTE+Bootstrap Table权限管理系统第二节--在ABP的基础做数据库脚本处理

    返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期 第一点,上一篇文章中我们讲到codefirst中一些问题包括如图,codefirst在每次执行命令的时候会生成新的 ...

  3. java 面试,如何提升自己的实力,摘自 java web轻量级开发面试教程

    本内容摘自 java web轻量级开发面试教程 其中有一段讲述到了实习经验对找工作的帮助 1.2.2大学阶段的实习经验能帮到你 一般公司在筛选简历时,一个非常重要考察的要点是相关经验的工作年限,说一个 ...

  4. STL空间配置器

    1.什么是空间配置器? 空间配置器负责空间配置与管理.配置器是一个实现了动态空间配置.空间管理.空间释放的class template.以内存池方式实现小块内存管理分配.关于内存池概念可以点击:内存池 ...

  5. 转:每天一个linux命令(1):ls命令

    ls命令是linux下最常用的命令.ls命令就是list的缩写缺省下ls用来打印出当前目录的清单如果ls指定其他目录那么就会显示指定目录里的文件及文件夹清单. 通过ls 命令不仅可以查看linu ...

  6. latex 生成pdf

    我个人还是比较推崇传统的方法:先生成dvi,在生成pdf. 直接在winEdt中点击最下方的Windows Command Prompt, 否则从cmd进入命令行的话,还要进入tex文件夹,好麻烦. ...

  7. 线性代数-矩阵-【4】点乘 C和C++的实现

    点击这里可以跳转至 [1]矩阵汇总:http://www.cnblogs.com/HongYi-Liang/p/7287369.html [2]矩阵生成:http://www.cnblogs.com/ ...

  8. CSS边框外的小三角形+阴影效果的实现。

    ...虽然是一个很小的问题,但其实还是挺实用的. 实现一个边框外的角. 用纯CSS来写. 一开始实现的效果是这个样子的. 但是这个效果没有办法给他附带阴影,所以换了一种写法.实现成了这个样子 想要实现 ...

  9. jQuery实现鼠标滑过导航栏呈现不同的样式

    素材图片 源码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...

  10. 九九乘法表实现---基于python

    # coding:utf-8"""九九乘法表"""for k in range(1,10):    for i in range(1,k+1 ...