Linux下基于SDL库贪吃蛇游戏-贪吃蛇游戏设计方案

1.SDL简介

 SDL(Simple DirectMediaLayer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、MacOS X等)的应用软件。现SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。

2.贪吃蛇游戏

2.1 实现原理

贪吃蛇游戏实现方式很多,可以通过链表方式实现,也可以通过结构体数组方式实现。结构体主要用来保村蛇身的坐标位置和长度。移动蛇身则通过不断遍历结构体数组,刷新屏幕窗口即可。

2.2 效果展示

Linux下基于SDL库贪吃蛇游戏-贪吃蛇游戏设计方案Linux下基于SDL库贪吃蛇游戏-贪吃蛇游戏设计方案Linux下基于SDL库贪吃蛇游戏-贪吃蛇游戏设计方案

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下基于SDL库贪吃蛇游戏-贪吃蛇游戏设计方案 https://www.yhzz.com.cn/a/5811.html

上一篇 2023-04-12 15:01:06
下一篇 2023-04-12 15:04:46

相关推荐

联系云恒

在线留言: 我要留言
客服热线:400-600-0310
工作时间:周一至周六,08:30-17:30,节假日休息。