大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
所用知识:
- 一维数组的使用
- 结构体的使用
- 播放音乐函数的使用
- 电脑按键的检测
- 窗口光标坐标函数的使用
相关函数讲解
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);//播放声音
基本要素
- 画地图(包含刚开始的画蛇和食物)
- 按键检测
- 产生食物
- 判断蛇的状态
代码
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;
}
单文件没有详细的讲解,讲解看看多文件版本。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/197159.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...