这个教程就让我们学习怎么用这个游戏框架开发一个简单的空战游戏吧!由于素材有限,都是用的网上的素材。这个游戏可以改造成为空战或者植物大战僵尸等的养成类型游戏或者更多,原理都差不多。    一个出类拔萃的人总是一个有耐心的人! 一个游戏的制作经常会出现小意外,一个不耐心的人往往会不知所措,我看过李华明他的书上面有介绍游戏框架,而且很详细,但是没有这个全面,现在的很多游戏书籍也很少有关于游戏框架的构建,希望大家可以多借鉴一下,多提提意见!
先上图:

第一个教程就先搭建属于我们的游戏框架:
com.mocn.framework中是框架包
com.mocn.airBottle中是游戏包

首先看框架包 中的BaseActivity类,主要用于设置横竖屏,全屏,屏幕的宽高度等等。

package com.mocn.framework;

import android.R;

import android.app.Activity;

import android.content.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) {

                super.onCreate(savedInstanceState);

                setFullScreen();// 设置全屏

                setLandscape();// 设置横屏

                Global.context = 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 com.mocn.framework;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.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 = this.getHolder();// 得到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 com.mocn.framework;

import android.content.Context;

/**

 * 得到屏幕的宽度,高度,Context对象

 *

 * @author Administrator

 *

 */

public class Global

{

        public static Context context;//得到上下文的引用

        public static int screenWidth;//屏幕的宽度

        public static int screenHeight;//屏幕的高度

}

  Layer类,所以绘制组件的基类,里面包括组件的坐标,宽高,以及绘制的方法等

package com.mocn.framework;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.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 com.mocn.framework;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.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;

                src.top = 0;

                src.right = w;

                src.bottom = h;

                dst.left = (int) x;

                dst.top = (int) y;

                dst.right = dst.left + w;

                dst.bottom = dst.top + h;

                canvas.drawBitmap(bitmap, src, dst, paint);

        }

}

  Sprite类,精灵类,用于绘制动态人物

package com.mocn.framework;

import java.util.Hashtable;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.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 = actions.get(actionName);// 从动作集合中得到该动作

        }

        /**

         * 绘制精灵的方法

         */

        @Override

        public void drawSelf(Canvas canvas, Paint paint) {

                if (currentAction != null) {

                        currentFrame = currentAction.frames[frameIdx];// 获取当前需要的帧

                }

                // 截取图片中需要的帧

                src.left = currentFrame * w;// 左端宽度:当前帧乘上帧的宽度

                src.top = 0;// 上端高度:0

                src.right = src.left + w;// 右端宽度:左端宽度加上帧的宽度

                src.bottom = h;// 下端高度为帧的高度

                // 绘制在界面上,取中心点绘制

                dst.left = (int) x - w / 2;

                dst.top = (int) y - h / 2;

                dst.right = dst.left + w;

                dst.bottom = dst.top + h;

                canvas.drawBitmap(bitmap, src, dst, paint);// 绘制当前帧

                if (currentAction != null) {

                        currentAction.nextFrame();// 绘制下一帧

                }

        }

        /**

         * 添加一个动作集合的方法

         *

         * @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类,组件管理类,用于管理组件

package com.mocn.framework;

import java.util.Vector;

import android.graphics.Canvas;

import android.graphics.Paint;

/**

 * 组件的管理类,用于存放组件,绘制所有组件,添加一个组件,删除一个组件,插入一组件

 *

 *

 * @author Administrator

 *

 */

public class LayerManager {

        public static Vector<Layer> vec = new Vector<Layer>(); // Vector对象用于存放所有组件

        /**

         * 绘制所有组件的方法

         *

         * @param canvas

         * @param paint

         */

        public static void drawLayerManager(Canvas canvas, Paint paint) {

                for (int i = 0; i < vec.size(); i++) {

                        vec.elementAt(i).drawSelf(canvas, paint);// 把存在于Vector对象中的组件绘制出来

                }

        }

        /**

         * 添加一个组件的方法

         *

         * @param layer

         */

        public static synchronized void addLayer(Layer layer) {

                vec.add(layer);// 在Vector对象中添加此组件

        }

        /**

         * 删除一个组件的方法

         *

         * @param layer

         */

        public static synchronized void deleteLayer(Layer layer) {

                vec.remove(layer);// 在Vector对象中删除此组件

        }

        /**

         * 在before指定的位置插入layer,原来对象以及此后的对象依次往后顺延。

         *

         * @param layer

         * @param before

         */

        public static void insert(Layer layer, Layer before) {

                for (int i = 0; i < vec.size(); i++) {// 遍历Vector对象

                        if (before == vec.elementAt(i)) {

                                vec.insertElementAt(layer, i);// 在before对象前面插入layer,该对象位于before之上

                                return;

                        }

                }

        }

}

  最后一个,Utilsl类,工具类,包含各种取得图片,碰撞事件的检测等方法

package com.mocn.framework;

import java.io.IOException;

import java.io.InputStream;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

/**

 * 工具类 获得一张图片,判断两个矩形是否相交,判断一个点是否在矩形内

 *

 * @author Administrator

 *

 */

public class Utils {

        /**

         * 获取一张图片的方法

         *

         * @param path

         * @return

         */

        public static Bitmap getBitmap(String path) {

                try {

                        InputStream is = Global.context.getAssets().open(path);

                        return BitmapFactory.decodeStream(is);

                catch (IOException e) {

                        e.printStackTrace();

                }

                return null;

        }

        /**

         * 判断两个矩形是否相交的方法

         *

         * @param x

         * @param y

         * @param w

         * @param h

         * @param x2

         * @param y2

         * @param w2

         * @param h2

         * @return

         */

        public static boolean colliseWidth(float x, float y, float w, float h,

                        float x2, float y2, float w2, float h2) {

                if (x > x2 + w2 || x2 > x + w || y > y2 + h2 || y2 > y + h) {

                        return false;

                }

                return true;

        }

        /**

         * 判断 一个点是否在矩形内的方法

         *

         * @param x

         * @param y

         * @param w

         * @param h

         * @param px

         * @param py

         * @return

         */

        public static boolean inRect(float x, float y, float w, float h, float px,

                        float py) {

                if (px > x && px < x + w && py > y && py < y + h) {

                        return true;

                }

                return false;

        }

}

  框架搭建完成,第二篇就是绘制篇了,如果大家在框架上有什么问题可以问我。

如何构建自己的游戏框架并且制作游戏(一)(附源码)相关推荐

  1. (上)Vue+Echarts构建可视化大数据平台实战项目分享(附源码)

    前言 分享之前我们先来普及一下什么是数据可视化?数据可视化可以把数据从冰冷的数字转换成图形,揭示蕴含在数据中的规律和道理.数据可视化通俗来说就是:数据的展示.处理和分析.目的是借助于图形化手段,清晰有 ...

  2. 基于嵌入式linux五子棋游戏,Android 实战项目之五子棋 附源码

    Android五子棋游戏五子连珠算法实现 1.游戏规则 五子棋是两个人之间进行的竞技活动,黑方白方规则规则相同,黑棋必须先行,五连子的方向为横.竖.斜,如黑白色任一方先五子连一线则算胜出. 2.五子连 ...

  3. 【Java游戏开发】坦克大战(附源码+课件+资料)

    本课程讲解了一个坦克大战游戏的详细编写流程,即使你是刚入门java的新手,只要你简单掌握了该游戏所需要的javase基础知识,便可以跟随教程视频完成属于你自己的坦克大战游戏!同时还可以加深和巩固你对面 ...

  4. 如何构建自己的游戏框架并且制作游戏

    这个教程就让我们学习怎么用这个游戏框架开发一个简单的空战游戏吧!由于素材有限,都是用的网上的素材.这个游戏可以改造成为空战或者植物大战僵尸等的养成类型游戏或者更多,原理都差不多.    一个出类拔萃的 ...

  5. 【unity实战】制作类元气骑士、挺进地牢——俯视角射击游戏多种射击效果(一)(附源码)

    文章目录 本期目标 前言 欣赏 开始 1. 角色移动和场景搭建 2. 绑定枪械 2.1 首先将各种枪械的素材添加给人物作为子物体 2.2 给枪械也分别添加两个子物体用作标记枪口和弹仓位置 3. 枪械动 ...

  6. Python制作经典游戏案例-水果忍者(附源码等文件)

    目录 前言 代码展示 总结 前言 大家好,我是辣条哥,今天给大家分享一款我以前特爱玩的游戏,水果大战,今天我就教大家使用python把这款游戏制作出来.我们先来看效果 点击跳转文末 相关的一些音乐文件 ...

  7. 【Unity实战】制作类元气骑士、挺进地牢——俯视角射击游戏多种射击效果(二)(附源码)

    文章目录 前言 一.火箭筒 1. 编写火箭筒脚本 2. 创建火箭弹和新爆炸特效的预制体 3. 编写火箭弹脚本 4. 设置好火箭弹和火箭筒的脚本和参数 5. 运行效果 二.激光枪 1. 编写激光枪脚本 ...

  8. 大家都在发圣诞树,我偏偏要发一个圣诞小游戏给大家玩【内附源码】

    ​大家好,我是辣条. 前言 圣诞节快来了,热榜都被一堆圣诞树攻占了,这样的流量密码我怎么会错过,大家都发圣诞树,我就不发啦,直接分享一个圣诞小游戏给大家玩,代码太长一定要先赞和收藏. 领取福利 300 ...

  9. 毕业设计-基于Unity的餐厅经营游戏的设计与开发(附源码、开题报告、论文、答辩PPT、演示视频,带数据库)

    基于Unity的餐厅经营游戏的设计与开发 下载链接: 点我下载资源 一.登陆(Unity2020.3.3f1c1版本) 开始界面 进入游戏后,在开始界面右下角是一个登陆按钮,当玩家点击开始按钮后,会进 ...

  10. ASP.NET MVC+EF框架+EasyUI实现权限管理(附源码)

    前言目录 前言:时间很快,已经快到春节的时间了,这段时间由于生病,博客基本没更新,所以今天写一下我们做的一个项目吧,是对权限的基本操作的操作,代码也就不怎么说了,直接上传源码和图片展示,下面我们直接进 ...

最新文章

  1. MySQL如何选择数据类型
  2. 从CES 2017看今年智能汽车发展趋势之一:车联网有望率先实现
  3. navicat 添加外键1215错误
  4. 干得最多最累,工资还不如新人
  5. java支付宝第三方支付详解
  6. python搭配什么数据库_教你如何优雅地用Python连接MySQL数据库
  7. flutter html 加载_Flutter开发:项目加载本地html文件的步骤
  8. linux ftp win nt,Java中apache包中FTPClient读取win NT上的FTP服务器文件失败
  9. php存省市,PHP格式化全国省市区列表
  10. SOME/IP与DDS对比及DDS测试策略和方案探讨
  11. WebGL varying变量和颜色插值
  12. JAVA北京时间转换为世界协调时
  13. oracle检查表的级联关系,有条件的两个表关联查询为什么会出现 MERGE JOIN CARTESIAN操作...
  14. 生活,令人满意的生活,丰富的生活包括了起起落落,包括了痛苦和再次振作,包括了失败和再次奋
  15. 靠谱的动漫培训班怎么选
  16. Spring 夺命 35 问!
  17. hive执行报错:Both left and right aliases encountered in JOIN
  18. Mixamo:在线3D动漫角色生成平台
  19. python3 爬煎蛋ooxx妹子图
  20. 3D 渲染软件市场增长迅速的原因

热门文章

  1. 学以致用深入浅出数字信号处理 pdf_数字阵列雷达:零中频接收机的优缺点
  2. 按键精灵打怪学习-多窗口多线程后台技能
  3. 夯实Java基础系列8:深入理解Java内部类及其实现原理
  4. Windows下让Tomcat6定时重启服务的方法
  5. STM32 JLINK接口定义 JTAG/SWD
  6. html登陆滑动验证,JavaScript实现登录滑块验证
  7. 2.4 数值分析: Doolittle直接三角分解法
  8. Sigmoid函数求导
  9. 浅学transcad(与表格链接以及创建矩阵OD并显示期望线)
  10. 使用Gps获取经纬度