本节讲述以下几个问题(本教程并不是只针对nge,其他图形显示也同样适用):
v:m5f!t3_)*c<q|/~41>y0Ud'Y{,|I0Ug2H6'k.F-y<)L\ZnQ(Id%L%U+A5gd&dUitUo`iA本文来自:V电G玩S天K空Y1 精灵移动的动画显示.nge图片子图显示.
v:m5f!t3_)*c<q|/~41>y0Ud'Y{,|I0Ug2H6'k.F-y<)L\ZnQ(Id%L%U+A5gd&dUitUo`iA本文来自:V电G玩S天K空Y2 SDL的输入控制,包括键盘处理(windows下)joystick(psp下).
v:m5f!t3_)*c<q|/~41>y0Ud'Y{,|I0Ug2H6'k.F-y<)L\ZnQ(Id%L%U+A5gd&dUitUo`iA本文来自:V电G玩S天K空Y3 fps如何限制.一般动作游戏fps限制在60,其他30即可.
v:m5f!t3_)*c<q|/~41>y0Ud'Y{,|I0Ug2H6'k.F-y<)L\ZnQ(Id%L%U+A5gd&dUitUo`iA本文来自:V电G玩S天K空Y本节的程序显示截图:
v:m5f!t3_)*c<q|/~41>y0Ud'Y{,|I0Ug2H6'k.F-y<)L\ZnQ(Id%L%U+A5gd&dUitUo`iA本文来自:V电G玩S天K空Y
人物在画面上移动
v:m5f!t3_)*c<q|/~41>y0Ud'Y{,|I0Ug2H6'k.F-y<)L\ZnQ(Id%L%U+A5gd&dUitUo`iA本文来自:V电G玩S天K空Y
这里采用的是4个方向的精灵图(不少游戏也采用8个方向的精灵图).sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
enum{sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
ANI_RIGHT = 0,sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
ANI_LEFT ,sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
ANI_UP,sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
ANI_DOWNsO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
};
代表精灵的方向.sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
下面是精灵的图片:

nge也是支持子图显示的.sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
RenderQuad的函数原形:sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
virtual void RenderQuad(CTexture* texture,float sx,float sy,float sw,float sh,float dx,float dy,sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
float xscale = 1.0,float yscale = 1.0,float angle = 0.0,int color=0xffffffff)sx,sy,sw,sh就是在图片的显示区域.对应要显示上图的哪个区域,直接设定即可.所以用4个方向的rect来保存坐标和宽,高.每个方向有4个.sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
SDL_Rect clipsRight[ 4 ];sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
SDL_Rect clipsLeft[ 4 ];sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
SDL_Rect clipsUp[ 4 ];sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
SDL_Rect clipsDown[ 4 ];设置坐标,宽,高:set_clip();//精灵的控制类class CAnimationsO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
{sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
public:CAnimation(const char* filename);sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
~CAnimation();sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
//Handles inputsO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
void InputProc(SDL_Event event);sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
//Moves the stick figuresO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
void Update(); sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
//Shows the stick figuresO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
void Show(IVideoDriver* sys); sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
protected:sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
void set_clip();sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
void KeyPressedUpProc(SDL_keysym * keysym);sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
void KeyPressedDownProc(SDL_keysym * keysym);sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
void ButtonPressedDownProc(SDL_JoyButtonEvent * jbutton);sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
void ButtonPressedUpProc(SDL_JoyButtonEvent * jbutton);sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
private:sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
//Its rate of movementsO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
float velocity_x;sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
float velocity_y;sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
//Its current framesO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
int frame;//screen positionfloat offset_x;sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
float offset_y;sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
//Its animation statussO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
int status;sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
//The areas of the sprite sheetsO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
SDL_Rect clipsRight[ 4 ];sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
SDL_Rect clipsLeft[ 4 ];sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
SDL_Rect clipsUp[ 4 ];sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
SDL_Rect clipsDown[ 4 ];sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
CTexture* resouce;sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
};sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
然后是处理按键,这里按键处理采用的是最典型的办法,就是按着不放会有一个速率,就是通常说的加速.包括键盘处理(windows下)joystick(psp下).键盘处理和手柄处理其实都是对等的.详细请看代码,我都写了注释的.最后说一下fps如何限制.一般游戏会有一个固定的fps,例如格斗动作60fps,其他30fps.不然如果fps不固定,游戏就会时而快,时而慢(注意这与跳祯的加速是不同的).所以统一用一个固定的fps这样对于不同的电脑配置显示都是一样的.就不会造成在电脑上飞快,在其他上是慢动作的问题.限制fps有多种方法:最简单的也是最常用就是delay剩下的时间.这种是用在系统fps高于实际需要的fps的情况下.(还有一种就是相反的情况,就要用到跳桢,某些图不画来提高fps)由于nge显示图片能力大大高于实际所需的fps,所以需要delay.这里提一下,如果你作的游戏的系统fps大大超过了实际需要的fps,可以尝试降低psp的工作频率,这样可以省电,不然delay掉了也没啥价值的.sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
fps.start();sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
ani->InputProc(event);sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
ani->Update();sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
sys->BeginScene();sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
sys->RenderQuad(bg,0,0,0,0,0,0);sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
ani->Show(sys);sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
sys->EndScene();sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
sys->ShowFps();sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
//Cap the frame rate.sleep if needsO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND )sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
{sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
//sleep掉多余的时间 SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );sO}W?[(ZEH)2y<wryc2^5s3aQgt%M{p+g>'z/94#a_R@V+>V:A$ln_ocDD8YYTT%p*.4W+LvRD-FL]\(0rF]]gpH本文来自:V电G玩S天K空Y
}其他部分请看lesson3的代码,比较简单的.下载地址:lesson3.rar里面windows版和psp版的都可以直接编译.有问题请看教程00.编译psp版的时候注意makefile路径的设置.例如我psp版我的lesson3是这样放的:libnge_psp\demo\lesson3所以makefile里就写为INCDIR = ../../includeLIBDIR =../../lib不过应该写程序的人都知道的.可能有的人用了本节的程序回发现只有一个画面,画面不能移动,而且可以有走到房子上,这个就是下一节要讨论的tilemap和scolling所要解决的问题.且听下回分解.



