所用知识:

  1. 一维数组的使用
  2. 结构体的使用
  3. 播放音乐函数的使用
  4. 电脑按键的检测
  5. 窗口光标坐标函数的使用

相关函数讲解

1.光标移动到某一指定坐标的函数

#include <windows.h>//坐标的API
void gotoxy(int x, int y)
{HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);COORD coord; //定义结构体coord (坐标系coord)coord.X = x; //横坐标xcoord.Y = y; //纵坐标ySetConsoleCursorPosition(handle, coord); //移动光标
}

2.kbhit按键检测函数

#include <conio.h>//按键

引用一下其他网友的解答:

#include <conio.h>
#include
using namespace std;
int main()
{
while(!kbhit()) //当没有键按下
{
cout<<“无键按下”<<endl;
}
cout<<“有键按下”<<endl; //有键按下时输出这
system(“pause”);
}
kbhit() 在执行时,检测是否有按键按下,有按下返回非0值,一般是1
没有按下返回0;是非阻塞函数
getch() 在执行时,检测按下什么键,如果不按键该函数不返回;是阻塞函数
类似地
在Tc2.0中有一个处理键盘输入的函数bioskey();
int bioskey(int cmd);
当cmd为1时,bioskey()检测是否有键按下。没有键按下时返回0;有键按下时返回按键码(
任何按键码都不为0),但此时并不将检测到的按键码从键盘缓冲队列中清除。 是非阻塞参数。
当cmd为0时,bioskey()返回键盘缓冲队列中的按键码,并将此按键码从键盘缓冲队列中清
除。如果键盘缓冲队列为空,则一直等到有键按下,才将得到的按键码返回。是阻塞调用。
//个人理解kbhit()有点像bioskey(1)
具体搜索bioskey词条吧 :)

3.playsound函数
引用一下这个函数的详细说明
所需头文件,顺序要这样子

#include <windows.h>//坐标的API
#include <MMSystem.h>
#pragma comment(lib,"winmm.lib")

在main函数里面使用,m1.wav为文件名,我放在跟cpp文件同目录下来了

PlaySound(L"m1.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);//播放声音

基本要素

  1. 画地图(包含刚开始的画蛇和食物)
  2. 按键检测
  3. 产生食物
  4. 判断蛇的状态

代码

game.cpp

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>//坐标的API
#include <conio.h>//按键
#include <time.h>//产生随机数要用到
#include"game.h"SNAKE snake;//定义SNAKE 类型的snake,不可在.h文件中定义
FOOD food;//同上
int score = 0;//得分
char key = 'W';//键盘获得的方向
char tempkey = 'W';//当前蛇行进方向
bool changeflag = false;//用于有无吃到食物的标志//到某一指定坐标的函数
void gotoxy(int x, int y)
{HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);COORD coord; //定义结构体coord (坐标系coord)coord.X = x; //横坐标xcoord.Y = y; //纵坐标ySetConsoleCursorPosition(handle, coord); //移动光标
}
//画地图
void drawmap()
{gotoxy(50, 8);printf("——游戏开始——");gotoxy(43, 10);printf("——切换键盘为大写字母模式——");gotoxy(51, 12);system("pause");system("CLS");for (int i = 0; i <= MAP_HIGHT; i++){gotoxy(0, i);printf("■");gotoxy(MAP_WIDTH, MAP_HIGHT-i);//不同方向打印printf("■");Sleep(20);//有一个一个打印的延时效果}for (int i = 0; i < MAP_WIDTH; i += 2){gotoxy(i, 0);printf("■");//占两个横坐标,一个纵坐标gotoxy(MAP_WIDTH - i, MAP_HIGHT);printf("■");Sleep(20);}//打印说明gotoxy(100, 7);printf("按键说明:");gotoxy(100, 10);printf("W:向上");gotoxy(100, 13);printf("A:向左");gotoxy(100, 16);printf("S:向下");gotoxy(100, 19);printf("D:向右");gotoxy(100, 22);printf("当前分数:%d", score);//初始画蛇头snake.x[0] = MAP_WIDTH / 2 +1;//蛇头的坐标必须是偶数,因为■横坐标是占了两节,不明白的话把1去掉试试效果snake.y[0] = MAP_HIGHT / 2;gotoxy(snake.x[0], snake.y[0]);printf("●");//打印蛇身,方向要与初始的方向一致for (int i = 1; i < snake.len; i++) {snake.x[i] = snake.x[0];snake.y[i] = snake.y[0] + i;gotoxy(snake.x[i], snake.y[i]);printf("●");}//初始画食物food.x = MAP_WIDTH / 4;food.y = MAP_HIGHT / 2;gotoxy(food.x, food.y);printf("◆");
}
void KeyDown()
{   //无按键操作if (_kbhit()){fflush(stdin);key = _getch();//当行进方向与按键方向相反时防止自杀现象if (key != 'w' && key != 'W' && key != 's' && key != 'S' && key != 'A' && key != 'a' && key != 'd' && key != 'D')key = tempkey;else {if (tempkey == 'w' || tempkey == 'W')if (key == 's' || key == 'S')key = tempkey;if (tempkey == 's' || tempkey == 'S')if (key == 'w' || key == 'W')key = tempkey;if (tempkey == 'a' || tempkey == 'A')if (key == 'D' || key == 'd')key = tempkey;if (tempkey == 'D' || tempkey == 'd')if (key == 'a' || key == 'A')key = tempkey;tempkey = key;//非wasd键}}if (!changeflag){gotoxy(snake.x[snake.len-1 ], snake.y[snake.len-1 ]);//总共有len个蛇的身体单元●,因为数组,最后一个是len-1printf("  ");//没有吃到食物的时候要去最后把蛇尾擦除}else{snake.x[snake.len] = snake.x[snake.len - 1];//吃到食物后len+1snake.y[snake.len] = snake.y[snake.len - 1];snake.len++;}for (int i = snake.len - 1; i > 0; i--){snake.x[i] = snake.x[i - 1];snake.y[i] = snake.y[i - 1];}switch (key){case 'W':case 'w': snake.y[0]--; break;//注意gotoxy的坐标原点是左上角case 'S':case 's': snake.y[0]++; break;case 'A':case 'a': snake.x[0] -= 2; break;//占两个字符case 'D':case 'd': snake.x[0] += 2; break;default: break;}gotoxy(snake.x[0], snake.y[0]);printf("●");changeflag = false;
}
void CreatFood()
{//随机种子,产生随机数srand((unsigned)time(NULL));if (snake.x[0] == food.x&&snake.y[0] == food.y)//判断吃到食物{score++;gotoxy(100, 22);printf("当前分数:%d", score);//打印分数if (score % 10 == 0){snake.speed -= 10;}while (1){bool flag = 1;food.x = rand() % (MAP_WIDTH - 4) + 2;//减掉左右两列4个坐标,然后加上最左一列2个坐标就是宽了food.y = rand() % (MAP_HIGHT - 2) + 1;for (int i = 0; i < snake.len; i++){if (food.x == snake.x[i] && food.y == snake.y[i])//食物不能出现在自己身上{flag = 0;break;}}if (flag&&food.x % 2 == 0)//食物x坐标要为偶数{break;}}gotoxy(food.x, food.y);printf("◆");changeflag = true;}}
int SnakeState(void)
{//判断是否撞墙if (snake.x[0] == 0 || snake.x[0] == MAP_WIDTH || snake.y[0] == 0 || snake.y[0] == MAP_HIGHT)return false;for (int i = 1; i < snake.len; i++){if (snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i])return false;}return true;
}

game.h

#pragma once
#ifndef GAME_H
#define GAME_H#define MAP_HIGHT 29
#define MAP_WIDTH 90
#define snake_max_len 200
#define snake_begin_len 3
#define snake_begin_speed 200struct SNAKE
{int len = snake_begin_len;int x[snake_max_len];int y[snake_max_len];int speed = snake_begin_speed;
};
struct FOOD
{int x;int y;};extern SNAKE snake;
extern FOOD food;extern int score;void gotoxy(int x, int y);
void drawmap(void);
void KeyDown(void);
void CreatFood(void);
int SnakeState(void);
#endif // !GAME_H

main.cpp

#include <stdio.h>
#include <windows.h>//坐标的API
#include <MMSystem.h>
#pragma comment(lib,"winmm.lib")
#include "game.h"int main()
{PlaySound(L"m1.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);//播放声音//隐藏光标HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO cci;GetConsoleCursorInfo(hOut, &cci);cci.bVisible = FALSE;SetConsoleCursorInfo(hOut, &cci);system("CLS");drawmap();while (1){KeyDown();Sleep(snake.speed);CreatFood();if (SnakeState()==false){break;}}system("CLS");gotoxy(50, 8);printf("——游戏结束——");gotoxy(52, 10);printf("你的分数为:%d\n", score);gotoxy(51, 12);system("pause");return 0;
}

效果图

一个.cpp文件的版本(差别不大)

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>//坐标的API
#include <MMSystem.h>
#pragma comment(lib,"winmm.lib")
#include <conio.h>//按键
#include <time.h>#define MAP_HIGHT 29
#define MAP_WIDTH 90
#define snake_max_len 200
#define snake_begin_len 3
#define snake_begin_speed 200
int score=0;//得分
char key = 'W';
char tempkey = 'W';
bool changeflag = false;
struct SNAKE
{int len= snake_begin_len;int x[snake_max_len];int y[snake_max_len];int speed = snake_begin_speed;
}snake;
struct FOOD
{int x;int y;}food;
void gotoxy(int x, int y)
{HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);COORD coord; //定义结构体coord (坐标系coord)coord.X = x; //横坐标xcoord.Y = y; //纵坐标ySetConsoleCursorPosition(handle, coord); //移动光标
}
void drawmap()
{for (int i = 0; i <= MAP_HIGHT; i++){gotoxy(0, i);printf("■");gotoxy(MAP_WIDTH, i);printf("■");Sleep(20);}for (int i = 0; i < MAP_WIDTH; i+=2){gotoxy(i, 0);printf("■");gotoxy(MAP_WIDTH -i, MAP_HIGHT);printf("■");Sleep(20);}gotoxy(100, 7);printf("按键说明:");gotoxy(100, 10);printf("W:向上");gotoxy(100, 13);printf("A:向左");gotoxy(100, 16);printf("S:向下");gotoxy(100, 19);printf("D:向右");gotoxy(100, 22);printf("当前分数:%d", score);//画蛇snake.x[0] = MAP_WIDTH/2+1;//偶数snake.y[0] = MAP_HIGHT/2;gotoxy(snake.x[0], snake.y[0]);printf("●");for (int i = 1; i < snake.len; i++) {snake.x[i] = snake.x[0];snake.y[i] = snake.y[0] + i;gotoxy(snake.x[i], snake.y[i]);printf("●");}//画食物food.x = MAP_WIDTH / 4;food.y = MAP_HIGHT / 2;gotoxy(food.x, food.y);printf("◆");
}
void KeyDown()
{   //无按键操作if (_kbhit()){fflush(stdin);key = _getch();if (key != 'w' && key != 'W' && key != 's' && key != 'S' && key != 'A' && key != 'a' && key != 'd' && key != 'D')    key = tempkey;else {if (tempkey == 'w' || tempkey == 'W')if (key == 's' || key == 'S')key = tempkey;if (tempkey == 's' || tempkey == 'S')if (key == 'w' || key == 'W')key = tempkey;if (tempkey == 'a' || tempkey == 'A')if (key == 'D' || key == 'd')key = tempkey;if (tempkey == 'D' || tempkey == 'd')if (key == 'a' || key == 'A')key = tempkey;tempkey = key;//非wasd键}}if (!changeflag){gotoxy(snake.x[snake.len-1], snake.y[snake.len - 1]);printf("  ");}else{snake.x[snake.len] = snake.x[snake.len-1];snake.y[snake.len] = snake.y[snake.len-1];snake.len++;}for (int i = snake.len-1; i >0; i--){snake.x[i] = snake.x[i - 1];snake.y[i] = snake.y[i - 1];}switch (key){case 'W':case 'w': snake.y[0]--; break;case 'S':case 's': snake.y[0]++; break;case 'A':case 'a': snake.x[0]-=2; break;//占两个字符case 'D':case 'd': snake.x[0]+=2; break;default: break;}gotoxy(snake.x[0], snake.y[0]);printf("●");changeflag = false;
}
void CreatFood()
{srand((unsigned)time(NULL));if (snake.x[0]==food.x&&snake.y[0] == food.y){//PlaySound(L"m2.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);score++;gotoxy(100, 22);printf("当前分数:%d", score);//打印分数if (score%15==0){snake.speed -= 20;}while (1){bool flag = 1;food.x = rand() % (MAP_WIDTH - 4) + 2;food.y = rand() % (MAP_HIGHT - 2) + 1;for (int i = 0; i < snake.len; i++){if (food.x ==snake.x[i] && food.y == snake.y[i]){flag = 0;break;}}if (flag&&food.x % 2 == 0){break;}}gotoxy(food.x, food.y);printf("◆");changeflag = true;}}
int SnakeState(void)
{if (snake.x[0] == 0 || snake.x[0] == MAP_WIDTH || snake.y[0] == 0 || snake.y[0] == MAP_HIGHT)return false;for (int  i = 1; i < snake.len; i++){if (snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i])return false;}return true;
}
int main()
{PlaySound(L"m1.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);//隐藏光标HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO cci;GetConsoleCursorInfo(hOut, &cci);cci.bVisible = FALSE;SetConsoleCursorInfo(hOut, &cci);system("CLS");drawmap();while (1){KeyDown();Sleep(snake.speed);CreatFood();if (SnakeState()==false){break;}}system("CLS");gotoxy(50, 8);printf("——游戏结束——");gotoxy(52, 10);printf("你的分数为%d\n", score);system("pause");return 0;
}

单文件没有详细的讲解,讲解看看多文件版本。

超简单的C语言贪吃蛇(附源码)相关推荐

  1. c语言贪吃蛇游戏源码下载,c语言贪吃蛇游戏源码.doc

    c语言贪吃蛇游戏源码.doc /*运行是按任意键开始,不过呢,反向也算输哟*/include include include include include include include defin ...

  2. 超简单的C语言贪吃蛇 不闪屏 双缓冲

    C语言贪吃蛇 今天把以前自己写的贪吃蛇总结了一下,发到博客上,怕放在电脑上哪天丢失了都不知道, 有不当之处还望指教 (*・ω< ) ヾ(◍°∇°◍)ノ゙ 贪吃蛇中, 我们看到的蛇在不断的移动,其 ...

  3. 美团饿了么外卖CPS项目怎么做?简单推广每天躺赚(附源码和搭建教程)

    美团饿了么外卖CPS项目怎么做?简单推广每天躺赚(附源码和搭建教程) 要成为金钱的主人,而不是它的奴隶,这就是财商 外卖cps项目,可能接触的人非常多,但是真正去做的人还是没几个,但这个项目比较好的地 ...

  4. 贪吃蛇 java下载_Java实现贪吃蛇游戏源码

    本文实例为大家分享了Java实现贪吃蛇游戏源码的具体代码,供大家参考,具体内容如下 1.StartGame package com.qiang.snake; import javax.swing.*; ...

  5. C语言贪吃蛇课程设计实验报告(包含贪吃蛇项目源码)

    文末有贪吃蛇代码全览,代码有十分细致的注释!!! 文末有贪吃蛇代码全览,代码有十分细致的注释!!! 文末有贪吃蛇代码全览,代码有十分细致的注释!!! 码文不易,给个免费的小星星和免费的赞吧,关注也行呀 ...

  6. c语言vc6.0编写贪吃蛇,基于VC6.0的贪吃蛇游戏源码

    //******************************************************* //**************************************** ...

  7. 谁说程序员不懂浪漫——我的C语言结婚请柬(附源码)

    前言:但行好事,莫问前程--<增广贤文> 从上学起开始学C++,后面也做过H5,现在做Android.无论是学习用的,还是工作用的,上百个软件不止.但最另我骄傲的是,我用程序烂漫了一把. ...

  8. 简单实现 Android M 指纹识别(附源码)

    众所周知, Android阵营里的指纹兼容真可谓是一团糟, 每个厂家几乎都有一套自己的API, 直到Android M的出现, 才慢慢地走上正途. 那么今天我们就一起来探讨一下, Android M里 ...

  9. c语言实战项目之一 贪吃蛇(源码免费开放)

    朋友们,经过我的c语言前十章的知识,大家应该已经入门了,我个人认为学习c语言最好的方法就是造轮子,写项目就是最好的提高方法,可以把我们学过的知识串联起来. 源码如下: #include<stdi ...

  10. JAVA游戏开发-超炫酷贪吃蛇游戏源码及教程

    一.前言 某日,看见隔壁家的小朋友在玩一款网络爆款贪吃蛇游戏,感觉很好玩.自己刚好正在学习JAVA编程,也想实现一个类似功能的游戏Demo练手,在网上查看了不少源码案例,全都是很古老的方块式贪吃蛇游戏 ...

最新文章

  1. Python单元测试框架之pytest---如何执行测试用例
  2. ASP.NET MVC 3拥抱动态类型,徐汇区网站设计
  3. keyvaluepair_C# KeyValuePairTKey,TValue的用法【转】 .
  4. 局域网通过专线上网的维护经验点滴
  5. linux系统中条码如何识别的,如何(可靠地)在嵌入式(无头)Linux中读取USB条形码扫描仪?...
  6. 从0到100——知乎架构变迁史
  7. 当AR落地B端行业应用,它的无限可能在哪?
  8. SecureCRT学习之道:SecureCRT经常使用快捷键设置与字体设置方法
  9. 在Linux系统里安装Virtual Box的详细步骤 1
  10. 使用with 创建视图
  11. 关于Unity中的Mesh Collider碰撞器
  12. 如何快速构建嵌入式全栈知识体系?
  13. IBM X60/X61无光驱安装XP
  14. php 中抽象类的作用,解释PHP中的抽象类。
  15. git merge 回退_git+vscode进行版本控制
  16. 改写js原装的alert样式
  17. Ubuntu中vim编辑器的常用操作
  18. Vivado ROM IP核
  19. ブリアー / 三星枪
  20. 推荐几个9月爆火的 GitHub 电商项目

热门文章

  1. SHT30温湿度传感器工作原理
  2. 杨柳絮-Info:太原市多部门通力合作科学治理杨柳飞絮效果好
  3. 自然语言处理NLP训练营---贪心科技
  4. 2018会考计算机知识点,2018高中地理会考知识点总结:地理信息技术
  5. 终于,连字节、腾讯都烧不起钱了
  6. 蓝底换白底边缘不干净_PS∶红底证件照换成蓝色背景,边缘怎样处理,让照片更自然呢?...
  7. 域名检测工具图文教程
  8. JS-获取视频总时长
  9. android照片同步到另一部手机,怎样可以把以前手机里的照片导入另一个手机?...
  10. 作为一位爬虫,说说代理IP哪家强?