这个教程就让我们学习怎么用这个游戏框架开发一个简单的空战游戏吧!由于素材有限,都是用的网上的素材。这个游戏可以改造成为空战或者植物大战僵尸等的养成类型游戏或者更多,原理都差不多。 一个出类拔萃的人总是一个有耐心的人! 一个游戏的制作经常会出现小意外,一个不耐心的人往往会不知所措,我看过李华明他的书上面有介绍游戏框架,而且很详细,但是没有这个全面,现在的很多游戏书籍也很少有关于游戏框架的构建,希望大家可以多借鉴一下,多提提意见!
先上图:
先上图:
第一个教程就先搭建属于我们的游戏框架:
framework中是框架包
airBottle中是游戏包
framework中是框架包
airBottle中是游戏包
首先看框架包 中的BaseActivity类,主要用于设置横竖屏,全屏,屏幕的宽高度等等。
?
package framework; biao.qqlove789 import android.R; import android.app.Activity; import t.pm.ActivityInfo; import android.os.Bundle; import android.util.DisplayMetrics; import android.view.Window; import android.view.WindowManager; /** * Activity的基类,本类中只要设置屏幕为竖屏,全屏,得到屏幕的高度和宽度 * * @author Administrator * */ public class BaseActivity extends Activity { /** * Activity创建时执行的方法 */ @Override protected void onCreate(Bundle savedInstanceState) { Create(savedInstanceState); setFullScreen();// 设置全屏 setLandscape();// 设置横屏 t = this;// 获取上下文事件 // 获取屏幕的宽高 DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); Global.screenWidth = dm.widthPixels;// 建筑环境与能源应用工程获取屏幕的宽度 Global.screenHeight = dm.heightPixels;// 获取屏幕的高度 } /** * 设置为全屏的方法 */ public void setFullScreen() { requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); } /** * 设置为竖屏的方法 */ public void setPortrait() { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } /** * 设置为横屏的方法 */ public void setLandscape() { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } } |
BaseView,主要用于设置线程的开关,游戏界面的绘制
?
package framework; dudu.qqq23 import t.Context; import aphics.Canvas; import aphics.Paint; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; /** * 游戏界面的基类 SurfaceHolder,线程的开启和关闭,添加組件drawSurfaceView * * @author Administrator * */ public abstract class BaseView extends SurfaceView implements Callback, Runnable { private SurfaceHolder holder;// SurfaceHolder的引用 private Thread currentThread;// Thread的引用 public int sleepTime = 20;// 设置睡眠时间 public BaseView(Context context) { super(context); holder = Holder();// 得到holder对象 holder.addCallback(this);// 得到调函数对象 } /** * 开启线程的方法 */ public void startThread() { currentThread = new Thread(this);// 得到线程的对象 currentThread.start();// 开启线程 } /** * 关闭线程的方法 */ public void stopThread() { currentThread = null;// 设置线程为空 } /** * 当界面改变时执行的方法 */ @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } /** * 当界面创建时执行的方法 */ @Override public void surfaceCreated(SurfaceHolder holder) { startThread();// 开启游戏线程 } /** * 当游戏被摧毁时执行的方法 */ @Override public void surfaceDestroyed(SurfaceHolder holder) { stopThread();// 关闭游戏线程 } /** * 绘制界面的方法 * * @param canvas * @param paint */ public void drawSurfaceView(Canvas canvas, Paint paint) { LayerManager.drawLayerManager(canvas, paint);// 绘制组件 } /** * 线程的控制方法 */ @Override public void run() { Canvas canvas; Paint paint = new Paint(); while (currentThread != null) { canvas = holder.lockCanvas(); drawSurfaceView(canvas, paint); holder.unlockCanvasAndPost(canvas); try { Thread.sleep(sleepTime); } catch (InterruptedException e) { e.printStackTrace(); } } } } |
Global类,用于设置一些常量
?
package framework; import t.Context; /** * 得到屏幕的宽度,高度,Context对象 * * @author Administrator * */ public class Global { public static Context context;//得到上下文的引用 public static int screenWidth;//屏幕的宽度 public static int screenHeight;//屏幕的高度 } |
西方世界的劫难 |
Layer类,所以绘制组件的基类,里面包括组件的坐标,宽高,以及绘制的方法等
?
package framework; import aphics.Bitmap; import aphics.Canvas; import aphics.Paint; import aphics.Rect; /** * 层类,组件的父类,添加组件,设置组件位置,绘制自己, 是所有人物和背景的基类 * * @author Administrator * */ public abstract class Layer { public float x;// 商住两用房 上海层的x坐标 public float y;// 层的y坐标 public int w;// 层的宽度 public int h;// 层的高度 public Rect src, dst;// 引用Rect类 public Bitmap bitmap;// 引用Bitmap类 protected Layer(Bitmap bitmap, int w, int h, boolean autoAdd) { this.bitmap = bitmap; this.w = w; this.h = h; src = new Rect(); dst = new Rect(); if (autoAdd) { LayerManager.addLayer(this);// 在LayerManager类中添加本组件 } } /** * 设置组件位置的方法 * * @param x * @param y */ public void setPosition(float x, float y) { this.x = x; this.y = y; } /** * 绘制自己的抽象接口 * * @param canvas * @param paint */ public abstract void drawSelf(Canvas canvas, Paint paint); } |
BackGroundLayer类,主要用于背景的绘制,可以用做静态的绘制
?
package framework; import aphics.Bitmap; import aphics.Canvas; import aphics.Paint; 秋的词语 /** * 游戏背景组件,在LayerManager中添加游戏背景组件,绘制自己 * * @author Administrator * */ public class BackGroundLayer extends Layer { public BackGroundLayer(Bitmap bitmap, int w, int h) { super(bitmap, w, h, true); } 上海知名装修公司排行 @Override public void drawSelf(Canvas canvas, Paint paint) { src.left = 0; p = 0; src.right = w; src.bottom = h; dst.left = (int) x; p = (int) y; dst.right = dst.left + w; dst.bottom = p + h; canvas.drawBitmap(bitmap, src, dst, paint); } } |
Sprite类,精灵类,用于绘制动态人物
?
package framework; import java.util.Hashtable; import aphics.Bitmap; import aphics.Canvas; import aphics.Paint; /** * 精灵组件类,添加精灵组件,设置动作,绘制精灵,添加一个动作序列,精灵动作类 * * @author Administrator * */ public class Sprite extends Layer { public int frameIdx;// 当前帧下标 public int currentFrame = 0;// 当前帧 public Hashtable<String, SpriteAction> actions;// 动作集合 public SpriteAction currentAction;// 当前动作 public Sprite(Bitmap bitmap, int w, int h, boolean autoAdd) { super(bitmap, w, h, autoAdd); actions = new Hashtable<String, Sprite.SpriteAction>();// 用Hashtable保存动作集合 } /** * 设置动作的方法 * * @param actionName */ public void setAction(String actionName) { currentAction = (actionName);// 从动作集合中得到该动作 } /** * 绘制精灵的方法 */ @Override public void drawSelf(Canvas canvas, Paint paint) { if (currentAction != null) { currentFrame = currentAction.frames[frameIdx];// 获取当前需要的帧 } // 截取图片中需要的帧 src.left = currentFrame * w;// 左端宽度:当前帧乘上帧的宽度 p = 0;// 上端高度:0 src.right = src.left + w;// 右端宽度:左端宽度加上帧的宽度 src.bottom = h;// 下端高度为帧的高度 // 绘制在界面上,取中心点绘制 dst.left = (int) x - w / 2; p = (int) y - h / 2; dst.right = dst.left + w; dst.bottom = p + h; canvas.drawBitmap(bitmap, src, dst, paint);// 绘制当前帧 if (currentAction != null) { Frame();// 绘制下一帧 } } /** * 添加一个动作集合的方法 * * @param name * @param frames * @param frameTime */ public void addAction(String name, int[] frames, int[] frameTime) { SpriteAction sp = new SpriteAction();// 创建SpiteAction的对象 sp.frames = frames;// 当前帧的数量,用下标表示 sp.frameTime = frameTime;// 每一帧切换的时间 actions.put(name, sp);// 将名字为"name"的动作集合,值为sp的动作集合放进acitons中 } /** * 精灵的移动方法 * * @param dx * @param dy */ public void move(int dx, int dy) { this.x += dx; this.y += dy; } // 精灵动作类 class SpriteAction { public int[] frames;// 该动作的帧序列 public int[] frameTime;// 帧序列中每一帧切换对应的时间 private long updateTime;// 记录上次失效时间 /** * 切换到下一帧的方法姜至鹏出轨 */ public void nextFrame() { if (System.currentTimeMillis() > updateTime) { frameIdx++;// 帧下标增加 frameIdx %= frames.length; updateTime = System.currentTimeMillis() + frameTime[frameIdx];// 切换下一帧所需要的时间 } } } } |
LayerManager类,组件管理类,用于管理组件
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论