Linux下基于SDL库贪吃蛇游戏
??SDL(Simple DirectMediaLayer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、MacOS X等)的应用软件。现SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
1.效果展示
2.绘制蛇身函数
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)
{
SDL_RenderCopy(render,sdltext,NULL,&rect);
}
else SDL_RenderFillRect(render,&rect);
}
3.绘制食物函数
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)
{
SDL_RenderCopy(render,food_sdltext,NULL,&rect);
}
else SDL_RenderFillRect(render,&rect);
}
4.判断是否碰到墙和蛇身函数
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;
}
5.移动蛇身函数
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);
}
6. 获取方向键和游戏开始函数
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);
snake_info[node_cnt].x=x;
snake_info[node_cnt].y=y;
node_cnt++;
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)
{
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);
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);
SDL_DestroyTexture(texture);
node_cnt++;
if(stat&1<<0 || stat&1<<1)
{
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);
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);
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);
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);
SDL_DestroyTexture(texture);
text1_surface=TTF_RenderUTF8_Blended(ttffont,"请按 Space 重新开始游戏 ",color);
texture=SDL_CreateTextureFromSurface(render,text1_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);
SDL_DestroyTexture(texture);
SDL_RenderPresent(render);
quit=false;
continue;
}
SDL_RenderPresent(render);
SDL_Delay(movi_speed);
}
return res;
}
7.主函数
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_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);
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);
SDL_DestroyTexture(texture);
text1_surface=TTF_RenderUTF8_Blended(ttffont,"Space 开始/暂停 ",color);
texture=SDL_CreateTextureFromSurface(render,text1_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);
SDL_DestroyTexture(texture);
text1_surface=TTF_RenderUTF8_Blended(ttffont,"+/- 移速 ",color);
texture=SDL_CreateTextureFromSurface(render,text1_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);
SDL_DestroyTexture(texture);
text1_surface=TTF_RenderUTF8_Blended(ttffont,"Q 退出",color);
texture=SDL_CreateTextureFromSurface(render,text1_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);
SDL_DestroyTexture(texture);
text1_surface=TTF_RenderUTF8_Blended(ttffont,"贪吃蛇小游戏",color);
texture=SDL_CreateTextureFromSurface(render,text1_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);
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();
return 0;
}
8. Makefile文件
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
|