SDL游戏编程3

C、C++和Java语言
回复
rayfox
帖子: 39
注册时间: 2007-02-03 9:12
送出感谢: 0
接收感谢: 0

SDL游戏编程3

#1

帖子 rayfox » 2007-05-26 17:41

让图片移动起来

代码: 全选

#include <SDL.h>
#include <stdio.h>
	
//让图片动起来

int main(int argc, char ** argv)
{
	SDL_Surface * screen; //主表面
	SDL_Surface * image; //用来放MM-----的图片信息(像素)
	SDL_Event     event;
	
	bool bAppRun = true;
	bool bTopBottom = true; //为true时向下移动,为false时向上移动
	bool bLeftRight = true; //为true时向又移动,为false时向左移动
	Uint32 TimeBegin, TimeEnd; //TimeBegin存放时间的开始数据,TimeEnd存放时间的结束数据
	SDL_Rect MMRect;//看看它有什么用
	//初始化SDL加上SDL_INIT_TIMER标志,这里我们要用时间
	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;
	}
	
	//初始化MMRect
	MMRect.x = 0;
	MMRect.y = 0;
	MMRect.w = image->w;
	MMRect.h = image->h;
	
	//有了MM的表面了,就可以显示了。
	//将MM的表面画在我们的主表面上
	if (SDL_BlitSurface(image, NULL, screen, &MMRect) < 0) {
		//解释一下NULL,第一个是按照image的尺寸显示,第二个是默认显示。你也可以指定大小,不过要用到SDL_Rect你可以看一看帮助。 
		fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError()); //看看提示吧
		//退出了程序释放MM表面的资源
		SDL_FreeSurface(image);
		return -1;
	}
	//好了更新显示画出MM
	SDL_UpdateRect(screen, 0, 0, image->w, image->h);
	
	//获取一个时间滴答
	TimeBegin = SDL_GetTicks();
	while (bAppRun) {
		//消息循环
		if (SDL_PollEvent(&event)) {
			switch (event.type) {
				case SDL_KEYDOWN:
					//按下任意键退出
					bAppRun = false;
				break;
			}
		}
		//获取时间滴答
		TimeEnd = SDL_GetTicks();
		if ((TimeEnd - TimeBegin) > 25) { //判断时间滴答是否大于了25ms
			//达到了25ms
			//交换数据
			TimeBegin = TimeEnd;
			
			//先用黑色清除背景
			SDL_FillRect(screen, &MMRect, 0);
			
			//下面只是一个小把戏,留给大家自己分析.
			if (bTopBottom) {
				if ((MMRect.y + MMRect.h + 5) < screen->h) {
					MMRect.y += 5;
				}
				else {
					bTopBottom = false;
					MMRect.y = screen->h - MMRect.h;
				}
			} else {
				if ((MMRect.y - 5) > 0) {
					MMRect.y -= 5;
				}
				else {
					bTopBottom = true;
					MMRect.y = 0;
				}
			}
			
			if (bLeftRight) {
				if ((MMRect.x + MMRect.w + 5) < screen->w) {
					MMRect.x += 5;
				}
				else {
					bLeftRight = false;
					MMRect.x = screen->w - MMRect.w;
				}
			} else {
				if ((MMRect.x - 5) > 0) {
					MMRect.x -=5;
				}
				else {
					bLeftRight = true;
					MMRect.x = 0;
				}
			}
			
			//将MM的表面画在我们的主表面上
			if (SDL_BlitSurface(image, NULL, screen, &MMRect) < 0) {
				fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError()); //看看提示吧
				//退出了程序释放MM表面的资源
				SDL_FreeSurface(image);
				return -1;
			}
			
			//更新显示
			SDL_Flip(screen);
		}
	}
	
	//退出了程序释放MM表面的资源
	SDL_FreeSurface(image);
	
	return 0;
}

makefile

代码: 全选

t3: main.o
	g++ -o t3 main.o `sdl-config --libs`

main.o: main.cpp
	g++ -c main.cpp `sdl-config --cflags`
我们现在讲了3课了,我来总结一下这3课用到的SDL函数

名称 SDL_Init:
原型 int SDL_Init(Uint32 flags);
功能 初始化SDL库它只有一个参数 flags, flags可以是一下几种标识,分别代表SDL的子系统。
SDL_INIT_TIMER 初始化时间子系统.
SDL_INIT_AUDIO 初始化声音子系统.
SDL_INIT_VIDEO 初始化视频子系统.
SDL_INIT_CDROM 初始化CDROM子系统.
SDL_INIT_JOYSTICK 初始化游戏手柄子系统.
这些标识可以组合在一起。

名称 SDL_SetVideoMode
原型 SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
功能 按照width,height,bpp,flags设置一个屏幕表面(我称为主表面).
width 表面的宽度
height 表面的高度
bpp 表面的色深 (就是8位,16位,24位,32位)
flags 表面的标识,有以下几个常用选项:
SDL_SWSURFACE 创建一个表面在系统内存
SDL_HWSURFACE 创建一个表面在显卡内存
SDL_DOUBLEBUF 使用双缓冲区
SDL_FULLSCREEN 全屏模式显示
SDL_OPENGL 创建一个OpenGL表面
SDL_RESIZABLE 创建一个尺寸可变的窗口
还有一些其他的选项大家可以自己去看一下帮助。

名称 SDL_LoadBMP
原型 SDL_Surface *SDL_LoadBMP(const char *file);
功能 读取以file指定的位图文件,并返回该位图文件的表面。
参数只有一个file,位图的文件名。

名称 SDL_BlitSurface
原型 int SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect);
功能 把一个src表面画到dst表面上,返回0失败,大于0成功
src 源表表面
srcrect 源表面的尺寸
dst 目标表面
dstrect 目标表面的尺寸

名称 SDL_UpdateRect
原型 void SDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Sint32 w, Sint32 h);
功能 更新srceen指定的表明区域。
screen 要更新的表面
x X坐标
y Y坐标
w 宽度
h 高度
x, y, w, h构成了一个区域。

名称 SDL_GetTicks
原型 Uint32 SDL_GetTicks(void);
功能 获取一个时间滴答
返回一个时间滴答

名称 SDL_FillRect
原型 int SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
功能 使用color指定的颜色,以dstrect指定的区域填充dst指定的表面。

名称 SDL_FreeSurface
原型 void SDL_FreeSurface(SDL_Surface *surface);
功能 释放surface指定的表面资源。

名称 SDL_Flip
原型 int SDL_Flip(SDL_Surface *screen);
功能 更新screen指定的全部区域。
附件
t3.tar.gz
(117.93 KiB) 下载 110 次
头像
titainium
帖子: 689
注册时间: 2006-12-02 12:25
送出感谢: 0
接收感谢: 0

#2

帖子 titainium » 2007-05-27 11:49

通通收藏地干活 :em08
Titainium
Brand
帖子: 51
注册时间: 2006-12-25 16:03
送出感谢: 0
接收感谢: 0
联系:

#3

帖子 Brand » 2007-05-27 11:58

十分的谢谢了 !学了不少东西,期待下一课!
dinghwy
帖子: 44
注册时间: 2006-07-10 17:40
送出感谢: 0
接收感谢: 0

#4

帖子 dinghwy » 2007-06-05 14:39

看了 一下 这个程序在我的console下不能退出,不知道问题是成学的问题 还是我机器配置的问题。
头像
lysting
帖子: 41
注册时间: 2006-07-13 11:43
来自: 深圳
送出感谢: 0
接收感谢: 0
联系:

#5

帖子 lysting » 2007-06-05 15:26

赞!
以后makefile 可以添加清除哦,不然每次都得自己加,哈哈

代码: 全选

clean:
        -rm *.o *~ t3
PS:) 最好把 makefile 改成 Makefile
回复

回到 “C/C++/Java”