GeneRal interface for Non-3D animation
GRiNa is still under development. This document is for developers.
For most games uses Qt5 as a container of games or interface, we found that SDL is also a good Render platform who has been maintained by Software Develop Companies like Valve. And Also it is quite light compared to Qt5, which means it would be easier to SDL2 based project when transferring its code to another multi-media platform.
1. Content
2. Overview
2.1 SDL2 Pages
This part will be transferred to CSDN. website
2.2 GRiNa Overview
GRiNa is simple script-based automation 2D animation engine.
3. Basic Mechanisms
3.1 SDL_Renderer
Every time you use a device to render, you have to establish a SDL_Renderer
Object to call SDL_RenderCopy()
to render the texture you want. For instance, You have to bundle a pointer of SDL_Renderer
to each texture you defines.
3.2 SDL_Window
SDL_Window
is essential while you initializing SDL_Renderer
. Before you create a SDL_Window
, you have to take care of the render mode and also its window size. What you don’t have to take care of is the different window calls under different OSs. Thanks to SDL2.
3.3 SDL_RWOps
SDL_RWOps
is a raw binary format which can be manipulated by the SDL platform. And it contains several useful methods, so it’s native and secure. There’s a plan to expand its feature in the future. (features like crypto and checksum)
3.4 GR_ResourcePack
(TODO)
This feature is still under development. ResourcePack is designed to contain multiple directories, can manage resource according to Global Name
, which is defined externally.
struct ResourcePackHeader
{
BYTE MAGIC_DESC[2]; // File Descriptor 'MP'
BYTE PACK_NAME[16]; // Package Name within length of 16
BYTE CHECKSUM[32]; // SHA-256 checksum
BYTE REBUNDANT[64]; // For future use
BYTE NEXT_PTR[4]; // uint32 ptr
};
struct ResourcePackNode
{
BYTE NAME[16]; // File name
BYTE CRYPT[2]; // Crypto method 1 byte for method | 1 byte for crypto-bits descriptor
BYTE TYPE[2]; // Type Descriptor
BYTE RAW_PTR[4]; // Pointer to Content data
};
We use pointers to node to locate the exact offset location in a ResourcePack
file. And it provide Type Descriptor
and Crypto Descriptor
domains to mapping the binary file content to specific object in code.
3.5 Global Name
(TODO)
Global Name
is a mapping profile to manage resource. GRiNa
push the binary memory blocks to a list according to its type. Then we manipulate through their interface.
3.6 Game Routing
- adjunctions is important
GR_Playable
has name for addressing- Every
GR_Playable
shares avector<GR_Playable*>
GR_Button
has attributeGR_Button::trigger <std::string>
- This trigger is for
GR_Playable
Addressing - Game routine just like a graph traveling problem
GRiNa
is a graph management system in global scope
4. GRiNa Instances & Methods
GRiNa uses classes to divide Application and SDL Interfaces. We provide low layer object like Texture
, also we give developers a high-level interface like ParticelSys
. We prefer to creating a convinient, light interface to use.
4.1 GR_Texture
class GR_Texture
{
public:
GR_Texture(){};
GR_Texture(SDL_RWops *src, SDL_Renderer *ren, int id);
void Load(SDL_RWops *src, SDL_Renderer *ren);
void LoadFromFile(const std::string &file, SDL_Renderer *ren);
//释放SDL_GR_Texture对象
void Free();
//设定颜色模式
void SetColor(Uint8 red, Uint8 green, Uint8 blue);
//设定混合模式
void SetBlendMode(SDL_BlendMode blending);
//设定透明度alpha值
void SetAlpha(Uint8 alpha);
//简单定比渲染函数
void Render(int x, int y, SDL_Renderer *ren);
//切片渲染
void Render_clip(SDL_Rect dest, SDL_Rect clip, SDL_Renderer *ren);
void Render_clip(int dstX, int dstY, int dstW, int dstH, int srcX, int srcY, int srcW, int srcH, SDL_Renderer *ren);
//标定渲染
void Render_dst(SDL_Rect dest, SDL_Renderer *ren);
int GetWidth();
int GetHeight();
int id = 0x0;
private:
//纹理顶点位置
SDL_Rect dst;
SDL_Texture *texture;
};
- This Interface is used by all renderable objects, and is designed to adapt to different rendering platforms.
4.2 GR_Element
GR_Element contains basic features that a controllable and managable sprite must have. The whole system use name for element addressing.
class GR_Element
{
public:
void LoadTexture(SDL_RWops *src, SDL_Renderer *ren);
void Render(int Screen_w, int Screen_h, SDL_Renderer *ren);
void SetName(const std::string &s);
std::string GetName();
void Free();
protected:
GR_Texture *tex;
std::string name;
private:
Uint32 type;
SDL_Rect dst;
};
4.2.1 GR_Background
#define BG_STITCH 0x1000
#define BG_FLAT 0x1001
class GR_Background: public GR_Element
{
public:
GR_Background();
~GR_Background();
GR_Background(Uint32 type);
void Render(int Screen_w, int Screen_h, SDL_Renderer *ren);
private:
Uint32 type;
SDL_Rect dst;
};
Render(int Screen_w, int Screen_h, SDL_Renderer *ren)
(Screen_w, Screen_h) is the screen’s width and height. it need to be the same value as window’s width and height. The fill type will be defined withBackground.type
.GR_Background.type
should be defined with macro provided.
4.2.2 GR_Button
class GR_Button: public GR_Element
{
public:
GR_Button(int x, int y, int w, int h, SDL_RWops *src, SDL_Renderer *ren, Uint32 id);
~GR_Button();
void SetPos(int x, int y, int w, int h);
void LoadTexture(SDL_RWops *src, SDL_Renderer *ren);
void Render();
// 用于处理鼠标消息(0代表位置判断,1代表鼠标摁下,2代表鼠标松开)
void MouseMotionEvent(int Mouse_x, int Mouse_y);
void MouseButtonEvent(int type);
// 按钮id用于触发消息
int id;
bool is_pushed;
private:
int tex_w, tex_h;
bool flag;
SDL_Rect dst;
SDL_Renderer *ren;
//GR_Texture方法类用于处理按钮纹理
SDL_Rect clip[4];
};
GR_Button
should be defined with coordinates.GR_Button.flag
is to define whether the button is activated.GR_Button.dst
is the target position in screen.GR_Button.clip
is the clip texture of the origin image. The same mechanism as animations.GR_Button.MouseMotionEvent(int Mouse_x, int Mouse_y);
When GR_Button is activated, This function is to trigger event when the mouse hover on the button.GR_Button.MouseButtonEvent(int type);
When Button is activated, This function is to trigger event when the mouse clicked on the button.GR_Button
will have aGR_Trigger
to trigger event.
4.2.3 ParticleSys
typedef struct
{
//定义粒子位置速度加速度
Vector2D position;
Vector2D acceleration;
Vector2D speed;
int t;
int age;
int life;
}Particle;
class GR_ParticleSys: public GR_Element
{
public:
GR_ParticleSys(int num, int life, int speed_x, int speed_y);
~GR_ParticleSys();
//设定粒子生命值(生命值的设定是为了方便垃圾回收)
//注意:合适的生命值设定有利于改善游戏内存的占用量和游戏运行效率
void SetLife(int life);
//设定粒子系统边界,设定散射率,设定抽象系统重力
void SetKinematic(int _width, int _height, int _dispersion, Vector2D _gravity);
//设定颜色
void SetColor(Uint8 Red, Uint8 Green, Uint8 Blue);
//设定透明度值
void SetAlpha(Uint8 alpha);
//中心渲染过程函数,坐标为粒子系统的中心点
void Render_Central(int x, int y, SDL_Renderer *ren);
//释放对象内容(包括栈,纹理等等..)
void Free();
private:
Vector2D gravity;
Vector2D init_speed;
int ptnum, ptwidth, ptheight, ptlife, ptdispersion;
//将指定数量指定状态的粒子压入栈内
void Push(int num, int life, Vector2D speed);
//粒子系统主要结构体容器
std::vector<Particle> *particles;
//粒子系统容器使用的迭代器
std::vector<Particle>::iterator iter;
};
- This Particle System is a high-level interface. It generate particles with a random status (in a set range).
GR_ParticleSys.init_speed
2D vector speed value.GR_ParticleSys.gravity
2D vector gravity value.
4.3 GR_Playable
This Playable Object is to divide pages between different episode.(for its origin purpose).GR_Playable
is a basic unit of resource management. Different kinds of resources will be used between pages.
class GR_Playable
{
protected:
SDL_Renderer *renderer;
SDL_Event event;
// Background (we only need one)
GR_Background *background;
// Sprites Vectors
vector<GR_Button*> buttons;
vector<GR_Button*>::iterator button_iter;
vector<GR_Texture*> layer;
vector<GR_Texture*>::iterator layer_iter;
vector<GR_ParticleSys*> particles;
vector<GR_ParticleSys*>::iterator particles_iter;
// Resource Vectors
vector<SDL_RWops*> resources;
public:
int SCREEN_WIDTH; //画面分辨率
int SCREEN_HEIGHT;
bool quit = false;
int Init();
int Load();
Uint32 Loop();
int Quit();
};
This is still work in progress… Structure will change during development.
4.3.1 Intro
class Intro
{
public:
Intro(SDL_Renderer *ren, int Screen_w, int Screen_h);
~Intro();
// 载入对象
void Load();
// 渲染
void Loop();
//释放SDL_Texture对象
void Quit();
private:
// Logo
int Screen_w, Screen_h;
GR_Texture *logo;
SDL_Renderer *ren;
};
4.3.2 Menu
#define MENU_NEWGAME 0xF001
#define MENU_RESUME 0xF002
#define MENU_OPTION 0xF003
#define MENU_ABOUT 0xF004
#define MENU_QUIT 0xFFFF
#define MENU_CITY1 0xE001
#define MENU_CITY2 0xE002
#define MENU_CITY3 0xE003
#define MENU_MARGIN 60
#define MENU_BUTTON_W 160
#define MENU_BUTTON_H 50
class Menu
{
private:
SDL_Renderer *renderer;
SDL_Event event;
GR_Background *background;
list<GR_Button*> buttons;
list<GR_Button*>::iterator button_iter;
list<GR_Texture*> layer;
list<GR_Texture*>::iterator layer_iter;
vector<SDL_RWops*> resources;
public:
int SCREEN_WIDTH; //画面分辨率
int SCREEN_HEIGHT;
bool quit = false;
Menu(SDL_Renderer *renderer, int w, int h);
~Menu();
int Init();
int Load();
Uint32 Loop();
int Quit();
};
(TODO)
Macros in this file containes resource naming, engine signal naming and also object naming. It will be a messy stuff, so those macros will be moved to a seperate header file.
4.2.3 Game
#define GAME_BUTTON_START 0xF001
#define GAME_BUTTON_PAUSE 0xF002
#define GAME_BUTTON_OPTION 0xF003
#define GAME_BUTTON_SAVE 0xF004
#define GAME_BUTTON_ESCAPE 0xF005
#define GAME_BUTTON_QUIT 0xFFFF
#define GAME_START GAME_BUTTON_START
#define GAME_PAUSE GAME_BUTTON_PAUSE
#define GAME_OPTION GAME_BUTTON_OPTION
#define GAME_SAVE GAME_BUTTON_SAVE
#define GAME_ESCAPE GAME_BUTTON_ESCAPE
#define GAME_QUIT GAME_BUTTON_QUIT
class Game
{
private:
SDL_Renderer *renderer;
SDL_Window *window;
SDL_Event event;
int SCREEN_WIDTH; //画面分辨率
int SCREEN_HEIGHT;
GR_ParticleSys *particles;
GR_Background *background;
vector<GR_Button*> buttons;
vector<GR_Button*>::iterator button_iter;
public:
bool quit = 0;
Game(SDL_Renderer *ren, int w, int h);
int Load();
int Loop();
int Quit();
};
Game.buttons
is a iterative object list. In further development, this vector list will be maintained by script and the engine itself.