#include<iostream>
#include<conio.h>
#include<windows.h>
#include<time.h>
using namespace std;
#define W 60
#define H 40
// 函数声明
void setPos(int x,int y); // 设置光标位置
void COLOR_PRINT(const char* s, int color); // 带颜色的输出
char key;
int FPS = 200;
int Foodx, Foody, Foodt=0;
int speed = (220-FPS)/20;
struct Body{
int x,y;
};
struct Player{
int len; // 长度
int speed; // 速度
int HP; // 血量
int dir; // 移动方向 1 2 3 4
int color; // 蛇头的颜色
Body body[W*H]; // 身体结构体
// 初始化
void init(int _len, int x, int y, int hp, int c){
// 初始化蛇
color = c;
HP = hp;
dir = 2;
len = _len;
body[0].x = x;
body[0].y = y;
for(int i=1;i<len;i++){
body[i].x = body[i-1].x;
body[i].y = body[i-1].y - 1;
}
}
// 移动
void move(){
int dx = 0, dy = 0;
if(dir == 1) dy = -1;
else if(dir == 2) dy = 1;
else if(dir == 3) dx = -1;
else if(dir == 4) dx = 1;
setPos(body[len-1].x*2,body[len-1].y);
printf(" ");
for(int i=len-1;i>=1;i--){
body[i].x = body[i-1].x;
body[i].y = body[i-1].y;
}
body[0].x = body[0].x + dx;
body[0].y = body[0].y + dy;
}
// 吃到食物
void eatFood(int& foodx, int& foody, int& foodt){
if(body[0].x == foodx && body[0].y == foody){
len++;
for(int i=len-1;i>=1;i--){
body[i].x = body[i-1].x;
body[i].y = body[i-1].y;
}
body[0].x = foodx;
body[0].y = foody;
setPos(foodx*2,foody);
printf(" ");
if(foodt == 1) HP++;
else if(foodt != 0) FPS += foodt;
foodx = foody = foodt = 0;
}
}
// 画出蛇身
void draw(){
for(int i=0;i<len;i++){
setPos(body[i].x*2,body[i].y);
// printf("■");
if(i == 0) COLOR_PRINT("■", color);
else COLOR_PRINT("■", 14);
}
}
// 游戏
void isOver(const Player& p2){
// 撞墙
if(body[0].x >= W-1 || body[0].x <= 0 || body[0].y >= H-1 || body[0].y <= 0){
HP = 0;
return;
}
// 撞到别人
for(int i=0;i<p2.len;i++){
if(body[0].x == p2.body[i].x && body[0].y == p2.body[i].y){
HP--;
return;
}
}
}
// 更新
void update(){
move();
eatFood(Foodx, Foody, Foodt);
draw();
}
};
// 玩家1 和 玩家2
Player player1, player2;
// 设置光标位置
void setPos(int x,int y) {
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
HANDLE hConsoleOut;
hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);
csbiInfo.dwCursorPosition.X = x;
csbiInfo.dwCursorPosition.Y = y;
SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition);
}
// 带颜色的输出
void COLOR_PRINT(const char* s, int color){
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | color);
printf(s);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | 7);
}
// 随机生成食物
void createFood(){
srand(time(0));
int seed = rand()%10+1;
if(seed>=5) Foodt = 0; // 普通食物,只加长度
else if(seed == 1 || seed == 2) Foodt = 1; // 特殊食物,增加血量
else if(seed == 3)Foodt = 20; // 特殊食物,加快游戏速度
else if(seed == 4)Foodt = -20; // 特殊食物,加快游戏速度
Foodx = rand()%(W-2)+1;
Foody = rand()%(H-2)+1;
}
// 初始化
void init(){
player1.init(4, 4, 4, 3, 4);
player2.init(4, W-5, 4, 3, 1);
createFood();
}
void info(){
setPos(W*2+4, 3);
printf("游戏说明:\n");
setPos(W*2+4, 5);
printf("玩家1:按W A S D操控\n");
setPos(W*2+4, 7);
printf("玩家2:按小键盘↑ ↓ ← → 操控\n");
setPos(W*2+4, 9);
printf("玩家1血量:%d\n", player1.HP);
setPos(W*2+4, 11);
printf("玩家2血量:%d\n", player2.HP);
setPos(W*2+4, 13);
printf("当前游戏速度等级:%d\n", speed);
}
// 游戏更新
void update(){
// 画地图
for(int i=0;i<W;i++){
for(int j=0;j<H;j++){
if(i==0 || j==0 || i == W-1 || j == H-1) {
setPos(i*2,j);
printf("■");
}
}
}
// 画食物
setPos(Foodx*2,Foody);
// printf("■");
COLOR_PRINT("■", 10);
// 更新游戏数据
FPS = min(FPS, 200);
FPS = max(FPS, 60);
speed = (220-FPS)/20;
info();
}
// 游戏结束判断
bool GemeStatus(){
if(player1.HP == 0){
setPos((W+1)/2,(H-1)/2);
COLOR_PRINT("游戏结束!,玩家2胜利,获得:", 4);
printf("%d分", player2.HP*speed*100);
setPos(0,H+2);
return 1;
}
else if(player2.HP == 0){
setPos((W+1)/2,(H-1)/2);
COLOR_PRINT("游戏结束!,玩家1胜利,获得:", 4);
printf("%d分", player1.HP*speed*100);
setPos(0,H+2);
return 1;
}
return false;
}
// 按键响应
void keydown(){
while(kbhit()) key = _getch();
if((key == 'w' || key == 'W') && player1.dir!=2) player1.dir = 1;
else if((key == 's' || key == 'S') && player1.dir!=1) player1.dir = 2;
else if((key == 'a' || key == 'A') && player1.dir!=4) player1.dir = 3;
else if((key == 'd' || key == 'D') && player1.dir!=3) player1.dir = 4;
if(key == 72 && player2.dir != 2) player2.dir = 1;
else if(key == 80 && player2.dir != 1) player2.dir = 2;
else if(key == 75 && player2.dir != 4) player2.dir = 3;
else if(key == 77 && player2.dir != 3) player2.dir = 4;
}
void Game(){
init();
while(1){
update();
keydown();
player1.update();
player2.update();
if(Foodx==0 && Foody==0) createFood();
player1.isOver(player2);
player2.isOver(player1);
if(GemeStatus()) break;
Sleep(FPS);
}
}
void menu(){
int t = 6;
COLOR_PRINT("抵制不良游戏,拒绝盗版游戏。 \n\n", 11);
COLOR_PRINT("注意自我保护,谨防受骗上当。 \n\n", 11);
COLOR_PRINT("适度游戏益脑,沉迷游戏伤身。 \n\n", 11);
COLOR_PRINT("合理安排时间,享受健康生活。 \n\n", 11);
while(t--!=1){
COLOR_PRINT("正在加载中,", t);
printf("%d",t);
COLOR_PRINT("秒后进入游戏...\n", t);
Sleep(1000);
}
system("pause");
system("cls");
printf("以下是游戏介绍,请认真阅读哦!\n");
printf("1、游戏可以两个玩家一起对战,玩家1在左边,玩家2在右边。\n");
printf("2、关于操作,玩家1使用W、A、S、D, 玩家2使用小键盘的上、下、左、右。\n");
COLOR_PRINT("3、在按键时请不要长按键盘,不然会影响游戏体验。需要转向时按一下键盘即可,即使你长按也没用,蛇会自己移动。\n",4);
printf("4、地图边框出现问号时,说明你的黑窗口不支持中文,需要以旧版控制台运行。\n");
printf("5、游戏地图会闪,说明你的屏幕比较小或者没有全屏,需要把代码6、7行中的数字改的小一点(W表示地图的宽,H表示地图的高。)\n");
COLOR_PRINT("6、读到这条请将你的电脑全屏,以便获得更好的游戏体验。\n\n",4);
printf("游戏规则:\n");
printf("1、每个玩家开始的生命值为3。\n");
COLOR_PRINT("2、撞到地图的墙,生命值直接归零。\n",4);
COLOR_PRINT("3、自己撞到自己不会死,撞到对手身体扣一滴血。\n",4);
printf("4、当有任意一方生命值为零时,游戏结束。\n\n");
printf("食物介绍:\n");
printf("目前共有4种食物:\n");
printf("1、普通食物,生成概率为60%%。\n");
printf("2、加一滴血食物,生成概率为20%%。\n");
printf("3、游戏加速食物,生成概率为10%%。\n");
printf("4、游戏减速食物,生成概率为10%%。\n");
printf("5、食物每次只会生成一个,吃到了才会生成下一个食物。\n");
printf("6、不同食物没有区分,以盲盒形式存在(主要是我懒,不想写代码了^_^)。\n");
printf("7、当你读到这条请再次确认是否全屏,以便获得更好的游戏体验。\n\n");
system("pause");
system("cls");
}
int main(){
menu();
Game();
system("pause");
return 0;
}
持续更新。。。
欢迎找bug
共 9 条回复
顶
是少了一个<time.h>头文件,已修复
好像少加了一个ctime文件(别问我怎么知道的,随机数大佬)
@zyl z老师尼想不想活了!还是有错!
134还是有错
把NULL改成0就可以了,已修复
134有错
6
134行报错了→←