1.SDL簡(jiǎn)介
?SDL(Simple DirectMediaLayer)是一套開放源代碼的跨平臺(tái)多媒體開發(fā)庫(kù),使用C語(yǔ)言寫成。SDL提供了數(shù)種控制圖像、聲音、輸出入的函數(shù),讓開發(fā)者只要用相同或是相似的代碼就可以開發(fā)出跨多個(gè)平臺(tái)(Linux、Windows、MacOS X等)的應(yīng)用軟件?,F(xiàn)SDL多用于開發(fā)游戲、模擬器、媒體播放器等多媒體應(yīng)用領(lǐng)域。
2.貪吃蛇游戲
2.1 實(shí)現(xiàn)原理
貪吃蛇游戲?qū)崿F(xiàn)方式很多,可以通過(guò)鏈表方式實(shí)現(xiàn),也可以通過(guò)結(jié)構(gòu)體數(shù)組方式實(shí)現(xiàn)。結(jié)構(gòu)體主要用來(lái)保村蛇身的坐標(biāo)位置和長(zhǎng)度。移動(dòng)蛇身則通過(guò)不斷遍歷結(jié)構(gòu)體數(shù)組,刷新屏幕窗口即可。
2.2 效果展示



2.2 繪制蛇身函數(shù)
/*繪制食物*/
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表示清空*/
}
2.3 繪制食物函數(shù)
/*繪制食物*/
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表示清空*/
}
2.4 判斷是否碰到墻和蛇身函數(shù)
/*判讀蛇頭是否咬到自己或者碰到墻壁*/
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
2.5 移動(dòng)蛇身函數(shù)
/*******************動(dòng)態(tài)移動(dòng)蛇身********************************/
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
2.6 獲取方向鍵和游戲開始函數(shù)
/*******************控制方向,判斷游戲是否結(jié)束********************/
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);
//創(chuàng)建蛇身1
snake_info[node_cnt].x=x;
snake_info[node_cnt].y=y;
node_cnt++;
//創(chuàng)建蛇身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;
//保存蛇頭坐標(biāo)
x=snake_info[node_cnt].x;
y=snake_info[node_cnt].y;
node_cnt++;
SDL_DrawSnakebody(snake_info,node_cnt,1);//繪制蛇身
//生成實(shí)物坐標(biāo)
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=%dn",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);
/*創(chuàng)建字體顯示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,buff,color);
/*創(chuàng)建紋理*/
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)//向上或向下時(shí)y+5
{
snake_info[node_cnt].x=food_x;
snake_info[node_cnt].y=food_y+20;
}
else //向左或向右時(shí)
{
snake_info[node_cnt].x=food_x+20;
snake_info[node_cnt].y=food_y;
}
food_x=((rand()%800)/20)*20;
while(1)//保證重新生成的實(shí)物不再蛇身上
{
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);//清除左右標(biāo)志
if(stat&1<<1){
y+=20;
}//向下時(shí)不能直接向上,保持向下
else
{
stat|=1<<0;//向上
y-=20;
}
Snake_Move(x,y);
break;
case DOWM://下
stat&=~(0x3<<2);//清除左右標(biāo)志
if(stat&1<<0)
{
y-=20;
}//在向上時(shí)不能直接向下,保持向下
else
{
stat|=1<<1;//向下標(biāo)志位
y+=20;
}
Snake_Move(x,y);
break;
case LEFT://左
stat&=~(0x3<<0);//清除上下標(biāo)志
if(stat&1<<3){
x+=20;
}//向右時(shí)不能直接向左,保持向右
else
{
stat|=1<<2;//向左
x-=20;
}
Snake_Move(x,y);
break;
case RIGHT://右
stat&=~(0x3<<0);//清除上下標(biāo)志
if(stat&1<<2){
x-=20;
}//向左時(shí)不能直接向右,保持向左
else
{
stat|=1<<3;
x+=20;
}
Snake_Move(x,y);
break;
case QUIT:
{
node_cnt=0;
/*創(chuàng)建字體顯示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,"正在退出游戲,請(qǐng)稍等。。",color);
/*創(chuàng)建紋理*/
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;
/*創(chuàng)建字體顯示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,"游戲結(jié)束!",color);
/*創(chuàng)建紋理*/
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);/*釋放紋理*/
/*創(chuàng)建字體顯示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,"請(qǐng)按 Space 重新開始游戲 ",color);
/*創(chuàng)建紋理*/
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;
}
2.7 主函數(shù)
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);
/*創(chuàng)建渲染器*/
render=SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED);
/*設(shè)置透明度*/
SDL_SetRenderDrawBlendMode(render,SDL_BLENDMODE_BLEND);
/*設(shè)置渲染器顏色*/
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();
/*打開字庫(kù)*/
ttffont=TTF_OpenFont("simkai.ttf",50);
if(ttffont==NULL)
{
printf("simkai.ttf open failedn");
return 0;
}
/*創(chuàng)建字體顯示表面*/
SDL_Surface *text1_surface=TTF_RenderUTF8_Blended(ttffont,"當(dāng)前得分:",color);
/*創(chuàng)建紋理*/
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);/*釋放紋理*/
/*創(chuàng)建字體顯示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,"Space 開始/暫停 ",color);
/*創(chuàng)建紋理*/
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);/*釋放紋理*/
/*創(chuàng)建字體顯示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,"+/- 移速 ",color);
/*創(chuàng)建紋理*/
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);/*釋放紋理*/
/*創(chuàng)建字體顯示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,"Q 退出",color);
/*創(chuàng)建紋理*/
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);/*釋放紋理*/
/*創(chuàng)建字體顯示表面*/
text1_surface=TTF_RenderUTF8_Blended(ttffont,"貪吃蛇小游戲",color);
/*創(chuàng)建紋理*/
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();/*關(guān)閉SDL*/
return 0;
}
2.8 程序編譯
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)
審核編輯:湯梓紅
-
Linux
+關(guān)注
關(guān)注
88文章
11581瀏覽量
217116 -
游戲
+關(guān)注
關(guān)注
2文章
782瀏覽量
27176 -
SDL
+關(guān)注
關(guān)注
0文章
18瀏覽量
7860 -
貪吃蛇
+關(guān)注
關(guān)注
0文章
30瀏覽量
10040
發(fā)布評(píng)論請(qǐng)先 登錄

Linux下基于SDL庫(kù)貪吃蛇游戲
評(píng)論