c语言贪吃蛇源代码简单_java贪吃蛇源码

c语言贪吃蛇源代码简单_java贪吃蛇源码所用知识:一维数组的使用结构体的使用播放音乐函数的使用电脑按键的检测窗口光标坐标函数的使用相关函数讲解1.光标移动到某一指定坐标的函数#include<windows.h>//坐标的APIvoidgotoxy(intx,inty){ HANDLEhandle=GetStdHandle(STD_OUTPUT_HANDLE); COORDco…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

所用知识:

  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; //横坐标x
	coord.Y = y; //纵坐标y
	SetConsoleCursorPosition(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; //横坐标x
	coord.Y = y; //纵坐标y
	SetConsoleCursorPosition(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-1
		printf(" ");//没有吃到食物的时候要去最后把蛇尾擦除
	}
	else
	{ 
   
		snake.x[snake.len] = snake.x[snake.len - 1];//吃到食物后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;//注意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 200

struct 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; //横坐标x
	coord.Y = y; //纵坐标y
	SetConsoleCursorPosition(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;
}

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/197159.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 整理:数据库设计的六个阶段详解

    整理:数据库设计的六个阶段详解按照规范设计,我们将数据库的设计过程分为六个阶段:1、系统需求分析阶段;2、概念结构设计阶段;3、逻辑结构设计阶段;4、物理结构设计阶段;5、数据库实施阶段;6、数据库运行与维护阶段;每个阶段的详细解析如下:(资料来自:数据库设计(百度文库))一、系统需求分析阶段1、需求分析的任务2、需求分析的两种方法:自顶向下和自底向上二、概念结构设计三、逻辑结构设计

    2025年6月6日
    4
  • vs的安装包_vs2019制作安装包

    vs的安装包_vs2019制作安装包VS安装包注册com组件VS安装包注册com组件1.把你的com组件加入到打包程序。 2.在打包程序中找到该com组件,点击属性。在属性中有Register项,把值选择为vsdrfCOM即可。

    2022年8月22日
    6
  • latex中的括号怎么打_小括号和中括号的简便算法

    latex中的括号怎么打_小括号和中括号的简便算法https://blog.csdn.net/han____shuai/article/details/49679335功能语法显示不好看    (\frac{1}{2})好一点\left(\frac{1}{2}\right)您可以使用\left和\right来显示不同的括号:功能语法显示圆括号,小括号\left( \frac{a}{b}\right)方括号,中括号\left[ \frac…

    2022年10月11日
    5
  • LayoutParams理解和使用「建议收藏」

    LayoutParams理解和使用「建议收藏」LayoutParams理解和使用

    2022年9月21日
    1
  • docker镜像操作_docker 本地镜像

    docker镜像操作_docker 本地镜像前言Docker的三大核心概念:镜像、容器、仓库。初学者对镜像和容器往往分不清楚,学过面向对象的应该知道类和实例,这跟面向对象里面的概念很相似我们可以把镜像看作类,把容器看作类实例化后的对象。|

    2022年7月29日
    6
  • 软件测试面试问题及答案_中软国际测试面试笔试题

    软件测试面试问题及答案_中软国际测试面试笔试题文章目录软测面试题附答案<二>二、接口面试题1、你们公司的接口测试流程是怎样的?2、接口测试里面如何分析一个bug是前端还是后端的?3、Jmeter参数化的方式有哪几种可以实现4、在接口测试中关联是什么含义?一般什么场景需要用到,postman中是怎样用的?5、常用的性能指标名称与具体含义?6、没有接口和文档怎么进行工作?三、自动化面试题1、Selenium中有哪几种元素定位方式?2、隐式等待与显式等待有什么不同?3、自动化测试里面遇到验证码,一般怎么处理比较好?四、安全1、什么是SQL注入攻击

    2022年9月29日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号