|
Posted on 2010-01-13 22:34 剑孤寒 阅读(1550) 评论(10) 编辑 收藏 引用 所属分类: Galaxy2D 游戏引擎教程
前面两个教程只是简单的在屏幕上画了个方块,这一节里我们将学习一些有趣的东西:精灵和动画。 打开上一个教程的工程,将main.cpp修改为以下内容:
#include "ggefw/ggefw.h"
#include "ggebase.h"
#include "ggesprite.h"
#include "ggeanimation.h"
#include "ggetexture.h"
using namespace gge;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
class CGameMain:public ggeApplication
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
public:
CGameMain()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
m_curTex = 0;
m_curSpr = 0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
m_aniTex = 0;
m_downAni = 0;
m_upAni = 0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
m_dir = 0;
m_scale = 1.0f;
m_scaleDt = 0.4f;
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//系统设置
void OnConfig()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
System_SetState(GGE_TITLE, "Galaxy2D Game Engine - 精灵和动画");
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//刷新
void OnUpdate(float dt)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
//刷新动画
m_downAni->Update(dt);
m_upAni->Update(dt);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
m_dir += dt;
if (m_scale > 1.5f)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
m_scale = 1.5f;
m_scaleDt = -m_scaleDt;
}
else if (m_scale < 0.5f)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
m_scale = 0.5f;
m_scaleDt = -m_scaleDt;
};
m_scale += m_scaleDt * dt;
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//渲染
void OnRender()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
//清屏
Graph_Clear();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//绘制精灵
m_picSpr->Render(0, 0);
m_picSpr->RenderStretch(64, 0, 150, 96);
m_picSpr->Render4V(180, 0, 220, 32, 180, 64, 220, 96);
m_picSpr->SetHotSpot(24, 48);
m_picSpr->RenderEx(64, 200, m_dir, m_scale);
m_picSpr->SetHotSpot(0, 0);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//播放动画
m_downAni->Render(0, 320);
m_downAni->SetHotSpot(24, 48);
m_downAni->RenderEx(160, 340, m_dir, m_scale);
m_downAni->SetHotSpot(0, 0);
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//初始化
bool OnInitiate()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
//设置光标
m_curTex = Texture_Load("cursor.png");
if (!m_curTex) return false;
m_curSpr = Sprite_Create(m_curTex);
if (!m_curSpr) return false;
SetCursor(m_curSpr);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
m_aniTex = Texture_Load("ani.png");
if (!m_aniTex) return false;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//创建精灵
m_picSpr = Sprite_Create(m_aniTex, 0, 0, 48, 96);
if (!m_picSpr) return false;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//创建动画
m_downAni = Animation_Create(m_aniTex, 4, 4, 48, 96);
if (!m_downAni) return false;
m_upAni = Animation_Create(m_aniTex, 4, 4, 48, 96, 0, 192);
if (!m_upAni) return false;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//可以把一个动画的内部精灵指针设为光标以实现动画光标
//SetCursor(m_downAni->GetSprite());
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//开始播放动画
m_downAni->Play();
m_upAni->Play();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return true;
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//释放资源
void OnRelease()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
SAFE_RELEASE(m_curSpr);
SAFE_RELEASE(m_curTex);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
SAFE_RELEASE(m_aniTex);
SAFE_RELEASE(m_downAni);
SAFE_RELEASE(m_upAni);
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
private:
ggeTexture *m_curTex;
ggeSprite *m_curSpr;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
ggeSprite *m_picSpr;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
ggeTexture *m_aniTex;
ggeAnimation *m_downAni;
ggeAnimation *m_upAni;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
float m_dir;
float m_scale;
float m_scaleDt;
};
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
CGameMain GameMain;
GameMain.Start();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 0;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
这里新增了两个函数:OnInitiate()/OnRelease()。OnInitiate()用于游戏启动时做一些初始化的工作,比如载入贴图、创建精灵和动画等,OnInitiate()函数的返回值是bool类型的,这意味着可以返回一个值告诉游戏框架初始化是否成功,如果初始化失败游戏程序会自动退出。OnRelease()则用于做一些清理的工作,比如释放前面载入的贴图等。只要在程序里提供了OnInitiate()/OnRelease()这两个函数,它们将会在适当的时机由游戏框架自动调用,不用关心时序问题。
载入一个贴图只需简单的调用Texture_Load()函数并传入文件名就可以了,如果有ColorKey也可在后面指定,我们这里用的贴图已经带有Alpha通道了,所以直接载入就可以了,贴图载入后可以被多个精灵或动画复用。 m_aniTex = Texture_Load("ani.png");
精灵用于把一个贴图画到屏幕上,可以在创建精灵时就设置好将会把贴图的哪一部分画到屏幕上,也可以仅仅给它一个贴图指针,在后面的程序里去改变它的贴图区域,在这里我们采用创建的时候就设置的方法,“0, 0, 48, 96”这一串数值告诉精灵要将贴图上从(0, 0)开始,宽度为48高度为96的区域画到屏幕上。 m_picSpr = Sprite_Create(m_aniTex, 0, 0, 48, 96);
动画与精灵类似,只是多了帧数和fps的设置。这里第二个参数表示这个动画共有4帧,第三个参数表示每秒播放4帧。后面四个参数设置了第一帧的贴图范围,后面帧的贴图范围将根据这个来计算,计算方法为:将前一帧贴图范围先向右移一个宽度,如果超出贴图总宽度则下移一个高度并将横坐标设为0,所以要做一个动画用的贴图只需将序列帧从左至右,从上至下排列就可以了。需要注意的是动画创建好后是不会自动播放的,如果要让动画动起来必须手动调用动画的Play()函数,并在每帧刷新时调用动画的Update()函数。 m_upAni = Animation_Create(m_aniTex, 4, 4, 48, 96, 0, 192); m_ upAni ->Play(); m_upAni->Update(dt);
在OnInitiate()函数里调用了一个SetCursor()函数,这个函数用于设置游戏鼠标,接收的参数是一个精灵指针,这样我们也可以把一个动画的精灵指针传进去,以实现动画鼠标,有兴趣可以删掉“SetCursor(m_downAni->GetSprite())”前面的注释符号看看效果:)。
OnRender()里的东西就没啥好说的了,无非就是用各种方式把精灵和动画画到屏幕上,相关函数说明可以查看Galaxy2D游戏引擎的文档。好了,这一节就先到这里,下回见:)
![](http://www.cppblog.com/images/cppblog_com/jianguhan/tutorial3.JPG)
Feedback
# re: Galaxy2D游戏引擎教程3 - 精灵和动画 回复 更多评论
2011-09-01 19:59 by
谢谢您对字体问题的回答,这个例子中的光标设置好像在3.6版本也找不到了,也是被哪个类包含了吗。
# re: Galaxy2D游戏引擎教程3 - 精灵和动画 回复 更多评论
2011-09-02 08:54 by
这个功能被移除了,原因是在后来的使用过程中发现这个功能用处并不大,如果你需要这个功能,可以手动创建一个ggeSprit,在绘制函数的最后用Input_GetMousePosX()/Input_GetMousePosY()函数获取鼠标当前坐标,然后调用ggeSprit的Render()函数画上去就可以了。如果你有多个光标资源,不想人肉管理,也可以使用ggeResManager来管理,在ggeResManager释放时,这些光标资源也会被自动释放。
# re: Galaxy2D游戏引擎教程3 - 精灵和动画 回复 更多评论
2011-09-02 19:29 by
感谢回复,请问Galaxy现在支持flash吗,祝Galaxy引擎越来越强大
# re: Galaxy2D游戏引擎教程3 - 精灵和动画 回复 更多评论
2011-09-03 15:01 by
呵呵,谢谢,因为工作比较忙,业余时间比较少,所以Galaxy2D引擎更新会比较慢,以后会做到怎样也不好说,但至少这个引擎我会一直做下去的,不会像其他很多免费引擎一样,做着做着就没人维护了。
Galaxy2D引擎现在还不支持Flash,之前有试过一下整合Flash进来,以替代现有的GUI系统,但发现会有很多问题,最大的问题是帧率太低,因为除非引擎从底层支持Flash,否则要在引擎里使用Flash,唯一的办法就是先把Flash画到内存里,再从内存复制到纹理上,这个步骤是非常慢的,但是要从底层支持Flash,工作量非常大,我一个人业余时间弄,可能几年都弄不完。
如果你非常需要这个功能,又不怕帧率低的话,可以到网上搜索HGE播放Flash的代码,稍作修改就可以在Galaxy2D引擎里使用了。
# re: Galaxy2D游戏引擎教程3 - 精灵和动画 回复 更多评论
2011-09-04 19:37 by
感谢您的回复,通过使用这个引擎,也学会了不少东西,会一直支持引擎开发的。
# re: Galaxy2D游戏引擎教程3 - 精灵和动画 [未登录] 回复 更多评论
2015-10-14 19:52 by
检验输入语句: if(Input_IsMouseUp(VK_LBUTTON)) 看起来应该是检验鼠标左键抬起,实际上是鼠标右键抬起触发。Input_IsMouseDown(VK_LBUTTON)我这边也是右键。 请核实一下,谢谢!
# re: Galaxy2D游戏引擎教程3 - 精灵和动画 [未登录] 回复 更多评论
2015-10-14 20:01 by
我用的是win7 64 + vc2010。 这个应该是winuser.h的问题,与g2d无关。不过总是很郁闷的,难道和XP不兼容吗? 先百度去了
# re: Galaxy2D游戏引擎教程3 - 精灵和动画 回复 更多评论
2015-10-15 18:33 by
@shepherd 你应该用 GGEK_LBUTTON 而不是 VK_LBUTTON
# re: Galaxy2D游戏引擎教程3 - 精灵和动画 [未登录] 回复 更多评论
2015-10-16 20:00 by
感谢解答!代码已修正! 现在是SAFE_RELEASE这个宏未找到定义。应该#include哪个文件?
# re: Galaxy2D游戏引擎教程3 - 精灵和动画 回复 更多评论
2015-10-17 18:05 by
@shepherd
这个宏已改名成:GGE_RELEASE 了
|