1.SDL簡介
?SDL(Simple DirectMediaLayer)是一套開放源代碼的跨平臺多媒體開發庫,使用C語言寫成。SDL提供了數種控制圖像、聲音、輸出入的函數,讓開發者只要用相同或是相似的代碼就可以開發出跨多個平臺(Linux、Windows、MacOS X等)的應用軟件。現SDL多用于開發游戲、模擬器、媒體播放器等多媒體應用領域。
2.貪吃蛇游戲
2.1 實現原理
貪吃蛇游戲實現方式很多,可以通過鏈表方式實現,也可以通過結構體數組方式實現。結構體主要用來保村蛇身的坐標位置和長度。移動蛇身則通過不斷遍歷結構體數組,刷新屏幕窗口即可。
2.2 效果展示
2.2 繪制蛇身函數
/*繪制食物*/ 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 繪制食物函數
/*繪制食物*/ 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 判斷是否碰到墻和蛇身函數
/*判讀蛇頭是否咬到自己或者碰到墻壁*/ 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 移動蛇身函數
/*******************動態移動蛇身********************************/ 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 獲取方向鍵和游戲開始函數
/*******************控制方向,判斷游戲是否結束********************/ 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=%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); /*創建字體顯示表面*/ 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; }
2.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初始化*/ TTF_Init(); /*打開字庫*/ ttffont=TTF_OpenFont("simkai.ttf",50); if(ttffont==NULL) { printf("simkai.ttf open failedn"); 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; }
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
+關注
關注
87文章
11292瀏覽量
209322 -
游戲
+關注
關注
2文章
742瀏覽量
26312 -
SDL
+關注
關注
0文章
18瀏覽量
7395 -
貪吃蛇
+關注
關注
0文章
30瀏覽量
9806
發布評論請先 登錄
相關推薦
貪吃蛇游戲的電路實現
最近論壇好冷清,在此發一貼暖暖身,回到正題,大家都玩過“貪吃蛇”游戲,用代碼實現該游戲想必難不倒大神,在網上也有一大堆針對該游戲的代碼實現,如果擺脫代碼,用硬件來實現“
發表于 11-19 17:52
【FPGA DEMO】Lab 9:貪吃蛇小游戲
` 本帖最后由 zhangyue510 于 2021-7-30 16:32 編輯
項目名稱:貪吃蛇小游戲具體要求:在Perf-V實現貪吃蛇小游戲的運行。系統設計:
發表于 07-30 15:53
基于stm32的貪吃蛇小游戲的設計資料分享
指南者開發板上,使其能在觸摸屏上顯示,并且添加了暫停/繼續的觸摸按鍵以及簡單的游戲結束顯示,大體再現了貪吃蛇這款小游戲。一、主要功能上圖是整個顯示屏的布局以及對應功能。游戲界面是240
發表于 02-21 07:27
基于嵌入式linux開發板的貪吃蛇游戲運行
如何在嵌入式linux開發板上運行貪吃蛇游戲呢?本文以EasyARM-i.MX283A為硬件載體,簡述其運行貪吃蛇小游戲的方法及步驟。
評論