SDL(Simple DirectMediaLayer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、MacOS X等)的应用软件。现SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
/*绘制蛇身*/
static void SDL_DrawSnake(int x,int y,int stat)
{
SDL_Rect rect;
rect.x=x;
rect.y=y;
rect.w=20;
rect.h=20;
if((x>800-20 || y>480-20) || (x<0 || y<100))//判断是否撞墙
{
return ;
}
if(stat)/*1表示绘制*/
{
SDL_RenderCopy(render,sdltext,NULL,&rect);
}
else SDL_RenderFillRect(render,&rect);/*0表示清空*/
}
/*绘制食物*/
static void SDL_Drawfood(int x,int y,int stat)
{
SDL_Rect rect;
rect.x=x;
rect.y=y;
rect.w=15;
rect.h=15;
if(stat)/*1表示绘制*/
{
SDL_RenderCopy(render,food_sdltext,NULL,&rect);
}
else SDL_RenderFillRect(render,&rect);/*0表示清空*/
}
/*判读蛇头是否咬到自己或者碰到墙壁*/
static int SDL_GetSnakedeath(struct SNAKE *buff,int cnt)
{
int i=0;
int x=buff[cnt-1].x;
int y=buff[cnt-1].y;
if((x>800-20 || y>480-20) || (x<0 || y<100))//判断是否撞墙
{
return 1;
}
for(i=0;i<cnt-1;i++)
{
if(x==buff[i].x && y==buff[i].y)
{
printf("i=%d\n",i);
return 1;
}
}
return 0;
}
/*******************动态移动蛇身********************************/
static void Snake_Move(int x,int y)
{
int i=0;
SDL_DrawSnake(snake_info[0].x,snake_info[0].y,0);//清除蛇尾
for(i=0;i<node_cnt-1;i++)//节点往前偏移
{
snake_info[i].x= snake_info[i+1].x;
snake_info[i].y=snake_info[i+1].y;
}
/*蛇头节点坐标*/
snake_info[node_cnt-1].x=x;
snake_info[node_cnt-1].y=y;
SDL_DrawSnake(snake_info[node_cnt-1].x,snake_info[node_cnt-1].y,1);//显示蛇头节点
}
/*******************控制方向,判断游戏是否结束********************/
int SnakeGameStart(void)
{
SDL_Surface *text1_surface;
SDL_Texture * texture;
SDL_Rect dstrect;
static int start_stop=0;/*暂停与开始*/
int count=0;
int x=0;
int y=120;
int stat=0;
int food_x,food_y;
char buff[20];
SDL_Rect rect={0,100,800,380};
SDL_RenderFillRect(render,&rect);
//创建蛇身1
snake_info[node_cnt].x=x;
snake_info[node_cnt].y=y;
node_cnt++;
//创建蛇身2
snake_info[node_cnt].x=x+20;
snake_info[node_cnt].y=y;
node_cnt++;
snake_info[node_cnt].x=x+20*2;
snake_info[node_cnt].y=y;
//保存蛇头坐标
x=snake_info[node_cnt].x;
y=snake_info[node_cnt].y;
node_cnt++;
SDL_DrawSnakebody(snake_info,node_cnt,1);//绘制蛇身
//生成实物坐标
food_x=((rand()%800)/20)*20;
food_y=((rand()%380)/20)*20+100;
SDL_Drawfood(food_x,food_y,1);
bool quit= true;
SDL_Event event;/*获取事件*/
int key_value=4;
int res=0;
while(quit)
{
while(SDL_PollEvent(&event))
{
if(event.type==SDL_QUIT)
{
quit=false;
continue;
}
if(event.type==SDL_KEYDOWN)//键盘事件
{
//printf("key=%d\n",event.key.keysym.sym);
if(event.key.keysym.sym==SDLK_UP)key_value=1;
else if(event.key.keysym.sym==SDLK_DOWN)key_value=2;
else if(event.key.keysym.sym==SDLK_LEFT)key_value=3;
else if(event.key.keysym.sym==SDLK_RIGHT)key_value=4;
else if(event.key.keysym.sym==SDLK_q)key_value=5;/*退出*/
else if(event.key.keysym.sym==SDLK_SPACE)/*空格键*/
{
start_stop=!start_stop;
}
else if(event.key.keysym.sym==SDLK_EQUALS)/*加速*/
{
if(movi_speed>100)movi_speed-=100;
}
else if(event.key.keysym.sym==SDLK_MINUS)/*减速*/
{
if(movi_speed<600)movi_speed+=100;
}
}
}
if(snake_info[node_cnt-1].x==food_x && snake_info[node_cnt-1].y==food_y)//判断是否吃到食物
{
count+=5;
snprintf(buff,sizeof(buff),"%d",count);
/*创建字体显示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,buff,color);
/*创建纹理*/
texture=SDL_CreateTextureFromSurface(render,text1_surface);
/*将surface拷贝到渲染器*/
dstrect.x=80+235;/*显示的起始位置*/
dstrect.y=25;/*显示的起始位置*/
dstrect.w=text1_surface->w;/*显示的宽度*/
dstrect.h=text1_surface->h;/*显示的高度*/
SDL_RenderFillRect(render,&dstrect);
SDL_RenderCopy(render,texture,NULL,&dstrect);
SDL_FreeSurface(text1_surface);/*释放surface*/
SDL_DestroyTexture(texture);/*释放纹理*/
node_cnt++;
if(stat&1<<0 || stat&1<<1)//向上或向下时y+5
{
snake_info[node_cnt].x=food_x;
snake_info[node_cnt].y=food_y+20;
}
else //向左或向右时
{
snake_info[node_cnt].x=food_x+20;
snake_info[node_cnt].y=food_y;
}
food_x=((rand()%800)/20)*20;
while(1)//保证重新生成的实物不再蛇身上
{
if(SDL_GetSnakeFoodX(food_x,node_cnt)==0)break;
if(food_x<780)food_x+=20;
else food_x=0;
}
food_y=((rand()%380)/20)*20+100;
while(1)
{
if(SDL_GetSnakeFoodY(food_y,node_cnt)==0)break;
if(food_y<460)food_y+=20;
else food_y=100;
}
SDL_Drawfood(food_x,food_y,1);
}
if(start_stop)
{
continue;/*暂停*/
}
switch(key_value)
{
case UP://上
stat&=~(0x3<<2);//清除左右标志
if(stat&1<<1){
y+=20;
}//向下时不能直接向上,保持向下
else
{
stat|=1<<0;//向上
y-=20;
}
Snake_Move(x,y);
break;
case DOWM://下
stat&=~(0x3<<2);//清除左右标志
if(stat&1<<0)
{
y-=20;
}//在向上时不能直接向下,保持向下
else
{
stat|=1<<1;//向下标志位
y+=20;
}
Snake_Move(x,y);
break;
case LEFT://左
stat&=~(0x3<<0);//清除上下标志
if(stat&1<<3){
x+=20;
}//向右时不能直接向左,保持向右
else
{
stat|=1<<2;//向左
x-=20;
}
Snake_Move(x,y);
break;
case RIGHT://右
stat&=~(0x3<<0);//清除上下标志
if(stat&1<<2){
x-=20;
}//向左时不能直接向右,保持向左
else
{
stat|=1<<3;
x+=20;
}
Snake_Move(x,y);
break;
case QUIT:
{
node_cnt=0;
/*创建字体显示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,"正在退出游戏,请稍等。。",color);
/*创建纹理*/
texture=SDL_CreateTextureFromSurface(render,text1_surface);
/*将surface拷贝到渲染器*/
dstrect.x=800/2-text1_surface->w/2;/*显示的起始位置*/
dstrect.y=480/2-text1_surface->h/2;/*显示的起始位置*/
dstrect.w=text1_surface->w;/*显示的宽度*/
dstrect.h=text1_surface->h;/*显示的高度*/
SDL_RenderFillRect(render,&dstrect);
SDL_RenderCopy(render,texture,NULL,&dstrect);
SDL_FreeSurface(text1_surface);/*释放surface*/
SDL_DestroyTexture(texture);/*释放纹理*/
SDL_RenderPresent(render);
quit=false;
SDL_Delay(2000);
res= 2;
quit=false;
}
break;
}
if(SDL_GetSnakedeath(snake_info,node_cnt))
{
node_cnt=0;
res= 1;
/*创建字体显示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,"游戏结束!",color);
/*创建纹理*/
texture=SDL_CreateTextureFromSurface(render,text1_surface);
/*将surface拷贝到渲染器*/
dstrect.x=800/2-text1_surface->w/2;/*显示的起始位置*/
dstrect.y=480/2-text1_surface->h/2-30;/*显示的起始位置*/
dstrect.w=text1_surface->w;/*显示的宽度*/
dstrect.h=text1_surface->h;/*显示的高度*/
SDL_RenderFillRect(render,&dstrect);
SDL_RenderCopy(render,texture,NULL,&dstrect);
SDL_FreeSurface(text1_surface);/*释放surface*/
SDL_DestroyTexture(texture);/*释放纹理*/
/*创建字体显示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,"请按 Space 重新开始游戏 ",color);
/*创建纹理*/
texture=SDL_CreateTextureFromSurface(render,text1_surface);
/*将surface拷贝到渲染器*/
dstrect.x=800/2-text1_surface->w/2;/*显示的起始位置*/
dstrect.y=480/2-text1_surface->h/2+30;/*显示的起始位置*/
dstrect.w=text1_surface->w;/*显示的宽度*/
dstrect.h=text1_surface->h;/*显示的高度*/
SDL_RenderCopy(render,texture,NULL,&dstrect);
SDL_FreeSurface(text1_surface);/*释放surface*/
SDL_DestroyTexture(texture);/*释放纹理*/
SDL_RenderPresent(render);
quit=false;
continue;
}
SDL_RenderPresent(render);
SDL_Delay(movi_speed);
}
return res;
}
int main(int argc,char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *window=SDL_CreateWindow("SDL test",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,800,480,SDL_WINDOW_SHOWN);
/*创建渲染器*/
render=SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED);
/*设置透明度*/
SDL_SetRenderDrawBlendMode(render,SDL_BLENDMODE_BLEND);
/*设置渲染器颜色*/
SDL_SetRenderDrawColor(render, 255, 255, 255, 255);
/*清空渲染器*/
SDL_RenderClear(render);
SDL_SetRenderDrawColor(render, 255,0, 0, 255);
int i=0;
for(i=0;i<3;i++)
{
SDL_RenderDrawLine(render,0,96+i,800,96+i);
}
SDL_SetRenderDrawColor(render, 255, 255, 255, 255);
SDL_RenderPresent(render);
surface=IMG_Load("bg6.png");
sdltext=SDL_CreateTextureFromSurface(render,surface);
food_surface=IMG_Load("food.jpg");
food_sdltext=SDL_CreateTextureFromSurface(render,food_surface);
/*TTF初始化*/
TTF_Init();
/*打开字库*/
ttffont=TTF_OpenFont("simkai.ttf",50);
if(ttffont==NULL)
{
printf("simkai.ttf open failed\n");
return 0;
}
/*创建字体显示表面*/
SDL_Surface *text1_surface=TTF_RenderUTF8_Blended(ttffont,"当前得分:",color);
/*创建纹理*/
SDL_Texture * texture=SDL_CreateTextureFromSurface(render,text1_surface);
/*将surface拷贝到渲染器*/
SDL_Rect dstrect;
dstrect.x=80;/*显示的起始位置*/
dstrect.y=25;/*显示的起始位置*/
dstrect.w=text1_surface->w;/*显示的宽度*/
dstrect.h=text1_surface->h;/*显示的高度*/
SDL_RenderCopy(render,texture,NULL,&dstrect);
SDL_FreeSurface(text1_surface);/*释放surface*/
SDL_DestroyTexture(texture);/*释放纹理*/
/*创建字体显示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,"Space 开始/暂停 ",color);
/*创建纹理*/
texture=SDL_CreateTextureFromSurface(render,text1_surface);
/*将surface拷贝到渲染器*/
dstrect.x=800/2-text1_surface->w/2;/*显示的起始位置*/
dstrect.y=150;/*显示的起始位置*/
dstrect.w=text1_surface->w;/*显示的宽度*/
dstrect.h=text1_surface->h;/*显示的高度*/
SDL_RenderCopy(render,texture,NULL,&dstrect);
SDL_FreeSurface(text1_surface);/*释放surface*/
SDL_DestroyTexture(texture);/*释放纹理*/
/*创建字体显示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,"+/- 移速 ",color);
/*创建纹理*/
texture=SDL_CreateTextureFromSurface(render,text1_surface);
/*将surface拷贝到渲染器*/
dstrect.x=800/2-text1_surface->w/2;/*显示的起始位置*/
dstrect.y=210;/*显示的起始位置*/
dstrect.w=text1_surface->w;/*显示的宽度*/
dstrect.h=text1_surface->h;/*显示的高度*/
SDL_RenderCopy(render,texture,NULL,&dstrect);
SDL_FreeSurface(text1_surface);/*释放surface*/
SDL_DestroyTexture(texture);/*释放纹理*/
/*创建字体显示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,"Q 退出",color);
/*创建纹理*/
texture=SDL_CreateTextureFromSurface(render,text1_surface);
/*将surface拷贝到渲染器*/
dstrect.x=800/2-text1_surface->w/2;/*显示的起始位置*/
dstrect.y=270;/*显示的起始位置*/
dstrect.w=text1_surface->w;/*显示的宽度*/
dstrect.h=text1_surface->h;/*显示的高度*/
SDL_RenderCopy(render,texture,NULL,&dstrect);
SDL_FreeSurface(text1_surface);/*释放surface*/
SDL_DestroyTexture(texture);/*释放纹理*/
/*创建字体显示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,"贪吃蛇小游戏",color);
/*创建纹理*/
texture=SDL_CreateTextureFromSurface(render,text1_surface);
/*将surface拷贝到渲染器*/
dstrect.x=800/2-text1_surface->w/2;/*显示的起始位置*/
dstrect.y=330;/*显示的起始位置*/
dstrect.w=text1_surface->w;/*显示的宽度*/
dstrect.h=text1_surface->h;/*显示的高度*/
SDL_RenderCopy(render,texture,NULL,&dstrect);
SDL_FreeSurface(text1_surface);/*释放surface*/
SDL_DestroyTexture(texture);/*释放纹理*/
SDL_RenderPresent(render);
int stat=0;
bool quit= true;
SDL_Event event;/*获取事件*/
AA:
quit= true;
while(quit)
{
while(SDL_PollEvent(&event))
{
if(event.type==SDL_QUIT)
{
quit=false;
continue;
}
if(event.type==SDL_KEYDOWN)//键盘事件
{
if(event.key.keysym.sym==SDLK_q)
{
quit=false;
continue;
}
else if(event.key.keysym.sym==SDLK_SPACE)
{
quit=false;
stat=1;
continue;
}
}
}
}
if(stat)
{
stat=0;
if(SnakeGameStart()==1)goto AA;
}
SDL_FreeSurface(surface);
SDL_DestroyRenderer(render);
SDL_DestroyWindow(window);/*销毁窗口*/
SDL_Quit();/*关闭SDL*/
return 0;
}
CFLAGS =-I/home/wbyq/src_pack/SDL2-2.0.14/_install/include -I/home/wbyq/src_pack/SDL2-2.0.14/_install/include/SDL2 -L/home/wbyq/src_pack/SDL2-2.0.14/_install/lib
CFLAGS +=-L/home/wbyq/src_pack/SDL2_image-2.0.5/_install/lib -I/home/wbyq/src_pack/SDL2_image-2.0.5/_install/include -I/home/wbyq/src_pack/SDL2_image-2.0.5/_install/include/SDL2
CFLAGS +=-I/home/wbyq/src_pack/SDL2_ttf-2.0.15/_install/include/SDL2 -L/home/wbyq/src_pack/SDL2_ttf-2.0.15/_install/lib
CFLAGS+=-lSDL2 -lpthread -lm -ldl -lSDL2_image -lSDL2_ttf
app:
gcc sdl_test.c $(CFLAGS)
SDL2.0库编译参考:SDL2.0
SDL_ttf库编译参考:SDL_ttf