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文章
11304浏览量
209483 -
游戏
+关注
关注
2文章
742浏览量
26316 -
SDL
+关注
关注
0文章
18浏览量
7401 -
贪吃蛇
+关注
关注
0文章
30浏览量
9808
发布评论请先 登录
相关推荐
贪吃蛇游戏的电路实现
最近论坛好冷清,在此发一贴暖暖身,回到正题,大家都玩过“贪吃蛇”游戏,用代码实现该游戏想必难不倒大神,在网上也有一大堆针对该游戏的代码实现,如果摆脱代码,用硬件来实现“
发表于 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为硬件载体,简述其运行贪吃蛇小游戏的方法及步骤。
评论