今天我们就是要学习控制精灵的移动。
请看附件中的Player.bmp这个图片,纵向有4组图,分别对应上下左右的图组,每个图组中有3个小图,
分别对应行走的动画,只有不停的切换这3个小图就可以实现行走的动画。
看看代码。
代码: 全选
#include <SDL.h>
#include <stdio.h>
//用键盘控制精灵移动
int main(int argc, char ** argv)
{
SDL_Surface * screen; //主表面
SDL_Surface * image; //用来放MM-----的图片信息(像素)
SDL_Surface * PlayerImage; //用来测试的图片
SDL_Event event;
Uint32 BeginTicks, EndTicks;
SDL_Rect PRect, BRect; //PRect对应精灵的移动的小图位置(实现动画),BRect对应精灵在屏幕的位置。
unsigned char PlayerStarts = 0;
unsigned char PlayerIndex = 0;
bool bAppRun = true;
//初始化SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) {
fprintf(stderr, "SDL_Init %s\n", SDL_GetError());
return -1;
}
//初始化成功设置退出要调用的函数SDL_Quit
atexit(SDL_Quit);
//创建一个640X480 16-bit 模式的主表面 16位可以让MM的效果好看一点
screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);
if (screen == NULL) {
fprintf(stderr, "Couldn't set 640x480x8 video mode %s\n",
SDL_GetError());
return -1;
}
//读取MM图片信息,并创建一个表面,并把数据填入该表面中。
image = SDL_LoadBMP("./mm.bmp"); //请在终端里运行该程序
if (image == NULL) {
fprintf(stderr, "Couldn't load MM, %s\n", SDL_GetError()); //遗憾你不能显示MM了,不过你可以用图片浏览程序看。
return -1;
}
//读取player.bmp
PlayerImage = SDL_LoadBMP("./player.bmp"); //请在终端里运行该程序
if (image == NULL) {
fprintf(stderr, "Couldn't load MM, %s\n", SDL_GetError()); //遗憾你不能显示MM了,不过你可以用图片浏览程序看。
return -1;
}
//读取第一个像素
Uint8 key = *((Uint8 *)PlayerImage->pixels);
//设置色键
SDL_SetColorKey(PlayerImage, SDL_SRCCOLORKEY, key);
//有了MM的表面了,就可以显示了。
//将MM的表面画在我们的主表面上,用MM来作为背景
if (SDL_BlitSurface(image, NULL, screen, NULL) < 0) {
//解释一下NULL,第一个是按照image的尺寸显示,第二个是默认显示。你也可以指定大小,不过要用到SDL_Rect你可以看一看帮助。
fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError()); //看看提示吧
return -1;
}
PRect.x = 0; //初始化动画显示的图片。
PRect.y = 0;
PRect.w = 32;
PRect.h = 48;
BRect.x = 0; //初始化精灵的位置。
BRect.y = 0;
BRect.w = 32;
BRect.h = 48;
//贴上测试用的表面
if (SDL_BlitSurface(PlayerImage, &PRect, screen, &BRect) < 0) {
fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError()); //看看提示吧
return -1;
}
//好了更新显示画出MM
SDL_UpdateRect(screen, 0, 0, image->w, image->h);
BeginTicks = SDL_GetTicks();
while (bAppRun) {
//消息循环
if (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
bAppRun = false; //按下了ESC退出程序。
break;
case SDLK_UP:
PlayerStarts = 1; //向上移动。
PlayerIndex = 0; //动画序号清零
break;
case SDLK_DOWN:
PlayerStarts = 2; //向下移动。
PlayerIndex = 0; //动画序号清零
break;
case SDLK_LEFT:
PlayerStarts = 3; //向左移动
PlayerIndex = 0; //动画序号清零
break;
case SDLK_RIGHT:
PlayerStarts = 4; //向右移动
PlayerIndex = 0; //动画序号清零
break;
}
break;
case SDL_KEYUP:
PlayerStarts = 0; //按键松开。停止切换动画。
break;
case SDL_QUIT:
bAppRun = false;
break;
}
}
EndTicks = SDL_GetTicks();
if ((EndTicks - BeginTicks) > 50) { //到了50MS
BeginTicks = EndTicks;
SDL_FillRect(screen, &BRect, 0); //清除以前的图片。
if (PlayerStarts) {
switch (PlayerStarts) {
case 1: //向上移动。
if ((BRect.y - 5) > 0) { //要移动的位置是否到顶
BRect.y -= 5; //坐标减去5
}
else {
BRect.y = 0; //设置位置在顶部。
}
PRect.x = PlayerIndex * 32; //使用序号计算该显示那个动画图片
PRect.y = 144; //向上的图组
PlayerIndex ++; //动画序号加1
if (PlayerIndex > 2) PlayerIndex = 0; //循环显示动画
break;
case 2:
//以下请大家自己分析。
if ((BRect.y + BRect.h + 5) < screen->h) {
BRect.y += 5;
}
else {
BRect.y = screen->h - BRect.h;
}
PRect.x = PlayerIndex * 32;
PRect.y = 0;
PlayerIndex ++;
if (PlayerIndex > 2) PlayerIndex = 0;
break;
case 3:
if ((BRect.x - 5) > 0) {
BRect.x -= 5;
}
else {
BRect.x = 0;
}
PRect.x = PlayerIndex * 32;
PRect.y = 48;
PlayerIndex ++;
if (PlayerIndex > 2) PlayerIndex = 0;
break;
case 4:
if ((BRect.x + BRect.w + 5) < screen->w) {
BRect.x += 5;
}
else {
BRect.x = screen->w - BRect.w;
}
PRect.x = PlayerIndex * 32;
PRect.y = 96;
PlayerIndex ++;
if (PlayerIndex > 2) PlayerIndex = 0;
break;
}
}
if (SDL_BlitSurface(image, NULL, screen, NULL) < 0) {
//解释一下NULL,第一个是按照image的尺寸显示,第二个是默认显示。你也可以指定大小,不过要用到SDL_Rect你可以看一看帮助。
fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError()); //看看提示吧
return -1;
}
//贴上测试用的表面
if (SDL_BlitSurface(PlayerImage, &PRect, screen, &BRect) < 0) {
fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError()); //看看提示吧
return -1;
}
}
SDL_Flip(screen);
}
//退出了程序释放MM表面的资源
SDL_FreeSurface(image);
return 0;
}
代码: 全选
t5: main.o
g++ -o t5 main.o `sdl-config --libs`
main.o: main.cpp
g++ -c main.cpp `sdl-config --cflags`