开始的时候打算将 Simple2D 做成一个库的,但现在没有那个功夫了。

  要渲染顶点数据,就必须将渲染函数放置到 glClear( ) 函数和 SwapBuffers( ) 函数之间,但又不希望开发时涉及 Simple2D 的内部。使用回调函数进行刷新回调和渲染回调,需要时添加相应的回调函数即可。

  假设使用 Simple2D 开发一个游戏,更新操作和渲染操作都在自定义的类 GameApplication (类名是自定义的,这里使用的是 GameApplication)中完成。GameApplication 有两个函数,分别是 Update( ) 函数和 Draw( ) 函数,更新的操作在 Update( ) 函数中实现,渲染的操作在 Draw( ) 函数中实现。

  那么 Simple2D 需要实例化一个不知类名的类,并调用该类的方法。这里通过类模板和多态的方法实现。Application 是一个抽象类,提供 Update( ) 和 Draw( ) 的虚方法。GameApplication 继承 Application 并实现 Update( ) 和 Draw( ) 方法,这样 Simple2D 可以通过基类来调用子类的方法:

    class Application
{
public:
Application() {}
virtual ~Application() {} virtual void Update(float dt) = ;
virtual void Draw(GraphicsContext* gc) = ;
};
  class GameApplication : public Application
  {
  public:
  void Update(float dt) {}
  void Draw(GraphicsContext* gc) {}
  };
    Application app = new GameApplication;
app->Update();
app->Draw(nullptr);

  ApplicationInstance 是一个模板类,用来实例化自定义类

    //-------------------------------------------------------------------
// ApplicationPrivate
//-------------------------------------------------------------------
class ApplicationInstancePrivate
{
public:
ApplicationInstancePrivate();
virtual ~ApplicationInstancePrivate(); virtual std::unique_ptr<Application> Create() = ;
}; //-------------------------------------------------------------------
// ApplicationInstance
//-------------------------------------------------------------------
template<class ApplicationClass>
class ApplicationInstance : public ApplicationInstancePrivate
{
public:
std::unique_ptr<Application> Create()
{
return std::unique_ptr<Application>(new ApplicationClass());
}
};

  当 Simple2D 调用 ApplicationInstance 的 Create( ) 方法时实例化自定义类并返回该类的对象指针,ApplicationInstance 需要在外部实例化,模板参数为自定义类名:

ApplicationInstance<GameApplication> app;

  当 ApplicationInstance  实例化时需要将实例的对象指针传递给 Simple2D 使用:

namespace Simple2D
{
static ApplicationInstancePrivate* app_instance = nullptr; ApplicationInstancePrivate::ApplicationInstancePrivate()
{
app_instance = this;
} ApplicationInstancePrivate::~ApplicationInstancePrivate()
{
}
}

  这里说明了为什么 ApplicationInstance 需要继承 ApplicationInstancePrivate 抽象类,因为 ApplicationInstance 是一个模板类,要保存模板类实例的对象指针需要使用这种方法。当 Simple2D 有了 ApplicationInstance 的对象指针,就可以通过该对象的 Create( ) 函数实例化 GameApplication 并调用该类的方法进行更新和渲染操作了:

std::unique_ptr<Application> app = app_instance->Create();

  Simple2D 还提供 Engine 对象来进行内部状态的设置,例如帧率、窗口标题、窗口大小、背景擦除颜色以及 ImGui 的中文支持的开关。这是一个单例类,可以在任意地方调用。

  最后是一个 Simple2D.h 的头文件,引出 Simple2D 内部的文件:

#pragma once

#include <Core\Log.h>
#include <Core\Math.h>
#include <Core\Event.h>
#include <Core\Engine.h>
#include <Core\Common.h>
#include <Core\Random.h>
#include <Core\Program.h>
#include <Core\Painter.h>
#include <Core\Renderer.h>
#include <Core\PathHelper.h>
#include <Core\TextRender.h>
#include <Core\TexturePool.h>
#include <Core\RenderWindow.h>
#include <Core\EventDispatcher.h>
#include <Core\GraphicsContext.h>
#include <Core\StandardProgram.h> #include <Framework\Tween.h>
#include <Framework\Signal.h>
#include <Framework\Sprite.h>
#include <Framework\Variant.h>
#include <Framework\TimeLine.h>
#include <Framework\Action.h>
#include <Framework\Noise.h>
#include <Framework\Gui.h> #include <Particle\ParticleEffect.h>
#include <Particle\ParticleSystem.h>
#include <Particle\ParticleEmitter.h> #include <External\ImGui\imgui.h>
#include <External\ImGui\Dialog.h>
#include <External\Tinyxml\tinyxml2.h>

  所以使用 Simple2D 只需要引入两个头文件 Application.h 和 Simple2D.h 即可。

  结束语

  cocos2d-x 是我第一个学习的游戏引擎,Simple2D 的粒子系统和动作系统的灵感来自 cocos2d-x。之后,产生了自己实现一个游戏引擎的想法。hge 是一个开源的 2D 游戏引擎,使用的是 directx9 进行渲染,通过学习 hge 源码学会了 diectx9。但是,发现 directx9 已经过时了。后来找到 ClanLib 这个游戏引擎,于是花了一两个月的时间学习 ClanLib 的源码,几乎把 ClanLib 的源码敲了一半,最后因为太难就放弃了。不过也有收获,那就是 directx11,第一次接触可编程渲染流水线。

  虽然以前也想学 OpenGL,但是找不到好的教程,就放弃了。但是前一段时间,无意中发现了一个网站 LearnOpenGL CN,这是一个很好的学习 OpenGL 的网站。在学习 OpenGL 之后,就迫不及待的使用 OpenGL 来做一个项目,那就是 Simple2D。

  Simple2D 是在 4 月份开始的一个项目,为此写了一系列的文章,来记录开发 Simple2D 的点点滴滴。开始有很大的热情,全身心都投入到 Simple2D 中。但最终敌不过时间,随着时间的推移,刚开始的热情都没有了,后来对 Simple2D 感到烦躁,虽然想中途放弃的,但还是坚持了下来。前后使用了 4 个月的时间,总算完成了。虽然 Simple2D 是一个比较简单的项目,但也是我第一个有头有尾的的项目。最后,使用 Simple2D 开发了 2048 这个游戏,来证明 Simple2D 也是可以用的。

  关于游戏 2048 的实现就不打算写文章了,感兴趣的可以看 Game2048 的源码实现。如果对 OpenGL 或开发小游戏感兴趣,但又不知道怎么做,Simple2D 这系列的文章获取可以帮到你。从 OpenGL 环境的搭建、简单渲染系统的实现、简单游戏开发框架以及 2048 游戏的实现都有比较详细的介绍。按照开始的设想,会在 Simple2D 添加上物理引擎 Box2D,除了 OpenGL 渲染方式还支持 DX11 的方式,但没有那个热情了。

  源码下载:Simple2D-20.rar

Simple2D-26 Simple2D 最后的工作,开发结束的更多相关文章

  1. 2019.05.26 周日--《阿里巴巴 Java 开发手册》精华摘要

    一.写在开头 Java作为一个编程界最流行的语言之一,有着很强的生命力.代码的编写规范也是不容忽视的,今天,我就把自己阅读的国内的互联网巨头阿里巴巴的<阿里巴巴 Java 开发手册>一些精 ...

  2. Objective-C编码规范:26个方面解决iOS开发问题

    介绍 我们制定Objective-C编码规范的原因是我们能够在我们的书,教程和初学者工具包的代码保持优雅和一致.即使我们有很多不同的作者来完成不同的书籍. 这里编码规范有可能与你看到的其他Object ...

  3. android 开发 - 结束所有activity

    每一个activity都有自己的生命周期,被打开了最终就要被关闭. 四种结束当前的activity方法 //关闭当前activity方法一 finish(); //关闭当前界面方法二 android. ...

  4. Objective-C编码规范:26个方面解决iOS开发问题(转)

    链接

  5. 介绍几个工作开发中封装的好用的android自定义控件

    首先看效果图, 看下这两个界面,第一个中用到了一个自定义的FlowRadioGroup,支持复合子控件,自定义布局: 第二个界面中看到了输入的数字 自动4位分割了吧:也用到了自定义的DivisionE ...

  6. [工作总结]jQuery在工作开发中常用代码片段集锦(1-10)

    1.jQuery,JS实现tab切换 原生JS实现 HTML代码如下: <div class="wrap"> <ul id="tag"> ...

  7. iOS开发之聊天模块--内容保存逻辑实现

    需求详解: 在实际开发中,有可能是在后期优化的时候,会有这么需要优化的需求:聊天输入框保存之前输入的文本,提高用户的良好体验. 在聊天模块中,用户可能会在输入框输入若干字符,但是没有点击发送就点击退出 ...

  8. iOS:iOS开发非常全的三方库、插件等等

    iOS开发非常全的三方库.插件等等 github排名:https://github.com/trending, github搜索:https://github.com/search. 此文章转自git ...

  9. iOS开发之资料收集

    github排名:https://github.com/trending, github搜索:https://github.com/search. 此文章转自github:https://github ...

随机推荐

  1. pipelinedb 滑动窗口

    滑动窗口可以方便的让我们进行一段时间的数据分析 几个主要函数 clock_timestamp 内置的函数,总是返回当前的时间戳 arrival_timestamp 事件达到的时间 单滑动窗口 参考 C ...

  2. 协程、gevent实现异步io、进程、线程、协程对比

    异步io的说白了就是遇到io操作的时候,就停下来去做别的事情.io分网络io和磁盘io,网络io比如说打开一个网站获取数据,下载一首歌等等,磁盘io就是把数据存到一个文件里面,写到磁盘上. 从网站上获 ...

  3. 函数对象(functional)

    来自STL中的概念:如果f是一个function object,则可以将operator()作用于f身上. 调用函数对象时构造函数和operator()执行顺序 首先执行构造函数,构造出一个匿名对象 ...

  4. hadoop之 参数调优

    一. hdfs-site.xml 配置文件 1. dfs.blocksize 参数:hadoop文件块大小描述:新文件的默认块大小,以字节为单位,默认 134217728 字节.可以使用以下后缀(大小 ...

  5. Linux C程序操作Mysql 调用PHP采集淘宝商品 (转)

    还是继续这个项目. 在上一篇Linux下利用Shell使PHP并发采集淘宝产品中,采用shell将对PHP的调用推到后台执行,模拟多线程. 此方法有一致命缺点,只能人工预判每个程序执行时间.如果判断时 ...

  6. Microsoft Dynamics CRM 2011 如何导入组织

    一.首先备份数据库,还原数据库(前面SQL server 2008数据库的备份与还原(转)已经说明),这里就不说明了. 二.怎么删除组织? 先要在组织管理器里禁用组织,然后删除组织,再从数据库里删除. ...

  7. 利用x-requested-with判断请求是否是Ajax请求

    在服务器端判断request来自Ajax请求(异步)还是传统请求(同步):         两种请求在请求的Header不同,Ajax 异步请求比传统的同步请求多了一个头参数 1.传统同步请求参数 a ...

  8. [转]链接中 href='#' 和 href='###' 的区别以及优缺点

    本文来自:http://c.jinhusns.com/bar/t-829 链接中 href='#' 和 href='###' 的区别以及优缺点 上一篇 下一篇近乎_问阳 发表于:2013-09-09 ...

  9. java 泛型中 T 和 问号(通配符)的区别

    类型本来有:简单类型和复杂类型,引入泛型后把复杂类型分的更细了: 现在List<Object>, List<String>是两种不同的类型;且无继承关系: 泛型的好处如: 开始 ...

  10. 触屏设备上的多点触碰检测C++代码实现

    转自:http://aigo.iteye.com/blog/2272698 代码还是参考自Epic官方的塔防项目:StrategyGame 看了下C++的API,现成的API中貌似只支持单点触碰检测, ...