一、贪吃蛇小游戏简介:
用上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,也不能咬到自己的身体,等到了一定的分数,就能过关。
二、函数框架
三、数据结构
typedef struct Snake { size_t x; //行 size_t y; //列 struct Snake* next; }Snake, *pSnake;
定义蛇的结构体,利用单链表来表示蛇,每个结点为蛇身体的一部分。
四、代码实现(vs2010 c语言)
1.Snake.h
#ifndef __SNAKE_H__ #define __SNAKE_H__ #include <stdio.h> #include <stdlib.h> #include <Windows.h> #include <time.h> #include <malloc.h> #include <assert.h> //标识地图大小 #define ROW_MAP 10 //地图的行 #define COL_MAP 20 //地图的列 #define SUCCESS_SCORE 10//通关分数 enum Direction //蛇行走的方向 { R, //右 L, //左 U, //上 D //下 }Direction; enum State { ERROR_SELF, //咬到自己 ERROR_WALL, //撞到墙 NORMAL, //正常状态 SUCCESS //通关 }State; typedef struct Snake { size_t x; //行 size_t y; //列 struct Snake* next; }Snake, *pSnake; void StartGame(); void RunGame(); void EndGame(); #endif
2.Snake.c
#include "Snake.h" pSnake head = NULL; //定义蛇头指针 pSnake Food = NULL; //定义食物指针 int sleeptime = 500;//间隔时间,用来控制速度 int Score = 0; //总分 int everyScore = 1; //每步得分 //定义游戏中用到的符号 const char food = '#'; const char snake = '*'; void Pos(int x, int y) //控制输出光标 { COORD pos; //pos为结构体 pos.X = x; //控制列 pos.Y = y; //控制行 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);//读取标准输出句柄来控制光标为pos } void Face() { system("color 0C"); printf("*******************************************************\n"); printf("* Welcome to Snake Game! *\n"); printf("* *\n"); printf("* ->开始游戏请按 enter键 *\n"); printf("* ->退出游戏请按 esc键 *\n"); printf("* ->暂停游戏请按 space键 *\n"); printf("* ->通过上下左右键来控制蛇的移动 *\n"); printf("* ->通过F1键减速 F2键加速 *\n"); printf("*******************************************************\n"); } void Map() //初始化地图 { int i = 0; for(i = 0; i<COL_MAP; i+=2) //打印上下边框(每个■占用两列) { Pos(i, 0); printf("■"); Pos(i, ROW_MAP-1); printf("■"); } for(i = 0; i<ROW_MAP; i++) //打印左右边框 { Pos(0, i); printf("■"); Pos(COL_MAP-2, i); printf("■"); } } void PrintSnake() //打印蛇 { pSnake cur = head; while(cur) { Pos(cur->y, cur->x); printf("%c", snake); cur = cur->next; } } void InitSnake() //初始化蛇身 { int initNum = 3; int i = 0; pSnake cur; head = (pSnake)malloc(sizeof(Snake)); head->x = 5; head->y = 10; head->next = NULL; cur = head; for(i = 1; i < initNum; i++) { pSnake newNode = (pSnake)malloc(sizeof(Snake)); newNode->x = 5+i; newNode->y = 10; newNode->next = NULL; cur->next = newNode; cur = cur->next; } PrintSnake(); } void CreateFood() //在地图上随机产生一个食物 { pSnake cur = head; Food = (pSnake)malloc(sizeof(Snake)); //产生x~y的随机数 k=rand()%(Y-X+1)+X; srand((unsigned)time(NULL)); Food->x = rand()%(ROW_MAP-2 - 1 + 1)+1; Food->y = rand()%(COL_MAP-3 - 2 + 1)+2; Food->next = NULL; while(cur) //检查食物是否与蛇身重合 { if(cur->x == Food->x && cur->y == Food->y) { free(Food); Food = NULL; CreateFood(); return; } cur = cur->next; } Pos(Food->y, Food->x); printf("%c", food); } void StartGame() //游戏开始的所有设置 { Face(); system("pause"); if(GetAsyncKeyState(VK_RETURN)) { system("cls"); Pos(COL_MAP+5, 1); printf("当前分数/通关分数:"); Pos(COL_MAP+20, 1); printf("%d/%d", Score, SUCCESS_SCORE); Pos(COL_MAP+5, 2); printf("当前分每步得分:"); Pos(COL_MAP+20, 2); printf("%d", everyScore); Pos(COL_MAP+5, 3); printf("\n"); Pos(COL_MAP+5, 4); printf("速度越快 得分越高哦!!\n"); Map(); InitSnake(); CreateFood(); } else if(GetAsyncKeyState(VK_ESCAPE)) { exit(0); } } int IsCrossWall() //判断是否碰到墙 { if(head->x <= 0 || head->x >= ROW_MAP-1 ||head->y <= 1 || head->y >= COL_MAP-2) { State = ERROR_WALL; return 0; } return 1; } int IsEatSelf(pSnake newHead) //判断是否咬到自己 { pSnake cur = head; assert(newHead); while(cur) { if(cur->x == newHead->x && cur->y == newHead->y) { State = ERROR_SELF; return 0; } cur = cur->next; } return 1; } int IsFood(pSnake pos) //判断该位置是不是食物 { assert(pos); if(pos->x == Food->x && pos->y == Food->y) { return 1; } return 0; } void SnakeMove() //蛇移动一次 { pSnake newHead = NULL; newHead = (pSnake)malloc(sizeof(Snake)); if(Direction == R) { newHead->x = head->x; newHead->y = head->y+1; newHead->next = head; } else if(Direction == L) { newHead->x = head->x; newHead->y = head->y-1; newHead->next = head; } else if(Direction == U) { newHead->x = head->x-1; newHead->y = head->y; newHead->next = head; } else if(Direction == D) { newHead->x = head->x+1; newHead->y = head->y; newHead->next = head; } if(IsFood(newHead)) { head = newHead; PrintSnake(); CreateFood(); Score += everyScore; Pos(COL_MAP+20, 1); printf("%d/%d", Score, SUCCESS_SCORE); if(Score >= SUCCESS_SCORE) { State = SUCCESS; } } else { if(IsCrossWall() && IsEatSelf(newHead)) { pSnake cur = NULL; head = newHead; cur = head; //删除蛇尾并打印 while(cur->next->next != NULL) { Pos(cur->y, cur->x); printf("%c", snake); cur = cur->next; } Pos(cur->y, cur->x); printf("%c", snake); Pos(cur->next->y, cur->next->x); printf(" "); //打印空格来覆盖频幕上的蛇尾 free(cur->next); cur->next = NULL; } else { free(newHead); newHead = NULL; } } } void Pause() { while(1) { Sleep(sleeptime); if(GetAsyncKeyState(VK_SPACE)) { break; } } } void ControlSnake() //用键盘控制游戏 { if(GetAsyncKeyState(VK_UP) && Direction!=D) { Direction = U; } else if(GetAsyncKeyState(VK_DOWN) && Direction!=U) { Direction = D; } else if(GetAsyncKeyState(VK_LEFT) && Direction!=R) { Direction = L; } else if(GetAsyncKeyState(VK_RIGHT) && Direction!=L) { Direction = R; } else if(GetAsyncKeyState(VK_F1)) { if(sleeptime != 500) { sleeptime = 500; everyScore = 1; Pos(COL_MAP+20, 2); printf("%d", everyScore); } } else if(GetAsyncKeyState(VK_F2)) { if(sleeptime != 300) { sleeptime = 300; everyScore = 2; Pos(COL_MAP+20, 2); printf("%d", everyScore); } } else if(GetAsyncKeyState(VK_SPACE)) { Pause(); } else if(GetAsyncKeyState(VK_ESCAPE)) { exit(0); } } void StateGame() //判断游戏失败或成功 { if(State == ERROR_SELF) { system("cls"); printf("很遗憾,蛇咬到自己,游戏失败!\n"); } else if(State == ERROR_WALL) { system("cls"); printf("很遗憾,蛇碰到墙壁,游戏失败!\n"); } else if(State == SUCCESS) { system("cls"); printf("恭喜您,已通关!!!\n"); } } void RunGame() { Direction = R; //蛇初始行走方向为右 State = NORMAL;//游戏初始为正常状态 while(1) { ControlSnake(); SnakeMove(); if(State != NORMAL) { StateGame(); break; } Sleep(sleeptime); } } void EndGame() //释放链表并恢复默认值 { pSnake cur = head; while(cur) { pSnake del = cur; cur = cur->next; free(del); del = NULL; } head = NULL; if(Food != NULL) { free(Food); Food = NULL; } Score = 0; everyScore = 1; sleeptime = 500; }
3.Test.c
#include "Snake.h" int main() { while(1) { StartGame(); RunGame(); EndGame(); } system("pause"); return 0; }
五、运行界面展示
1.欢迎界面
2.游戏界面
小小的c语言项目,用来练手,仅供参考哦!!
谢谢阅读,如有问题,欢迎提出。
更多有趣的经典小游戏实现专题,分享给大家:
C++经典小游戏汇总
python经典小游戏汇总
python俄罗斯方块游戏集合
JavaScript经典游戏 玩不停
java经典小游戏汇总
javascript经典小游戏汇总
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍C语言单链表贪吃蛇小游戏,包括了C语言单链表贪吃蛇小游戏的使用技巧和注意事项,需要的朋友参考一下 C语言实现单链表控制台贪吃蛇小游戏,供大家参考。 编译环境:vs2019 需求: 统计游戏开始后的时间,控制贪吃蛇;吃到食物蛇身加长,得分加一;碰墙或蛇头碰到身体减一条生命;生命消耗完则结束游戏。 思路: 使用wasd键控制蛇的移动方向,蛇头碰到食物得分加一,并在地图上随机产生一个食物,
本文向大家介绍js实现经典贪吃蛇小游戏,包括了js实现经典贪吃蛇小游戏的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了js实现贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
本文向大家介绍C语言链表实现贪吃蛇游戏,包括了C语言链表实现贪吃蛇游戏的使用技巧和注意事项,需要的朋友参考一下 阅读学习了源代码,并做了简单的注释和修改,里面只用了链表数据结构,非常适合C语言入门者学习阅读。 程序可在VS2013下编译运行。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
本文向大家介绍Android开发之经典游戏贪吃蛇,包括了Android开发之经典游戏贪吃蛇的使用技巧和注意事项,需要的朋友参考一下 前言 这款游戏实现的思路和源码参考了Google自带的Snake的例子,其中修改了一些个人认为还不够完善的地方,加入了一些新的功能,比如屏幕上的方向操作盘,暂停按钮,开始按钮,退出按钮。另外,为了稍微增加些用户体验,除了游戏的主界面,本人自己新增了5个界面,分别是登陆
本文向大家介绍C语言循环链表实现贪吃蛇游戏,包括了C语言循环链表实现贪吃蛇游戏的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了C语言表实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下 总体思想 利用循环链表将一条蛇的坐标进行存储,然后利用gotoxy()函数(可以将光标定位到指定的位置),此时根据蛇的坐标进行输出“@”,输出多几个既可以产生一条蛇。通过遍历循环链表进行蛇的移动,对循
本文向大家介绍C语言实现链表贪吃蛇,包括了C语言实现链表贪吃蛇的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了C语言实现贪吃蛇的具体代码,供大家参考,具体内容如下 用C语言链表写的贪吃蛇(程序设计时做的,做的不好大佬勿喷) 借助游戏内容分析贪吃蛇所需的功能主要包括这几块: 1.移动光标模块 2.打印地图模块和基本规则信息 读取最高分文件 3.打印初始蛇模块 打印时给予蛇的初始移动方向