C++贪吃蛇错误
#include <iostream>#include <cstdio>
#include <graphics.h>
#include <Windows.h>
#include <conio.h>
#include <time.h>
/********************************
* 初始化蛇1 intiSnake
* 初始化蛇2 intiSnake_2
* 画蛇1 drawSnake
* 画蛇2 drawSnake_2
* 移动蛇1 moveSnake
* 移动蛇2 moveSnake_2
* 按键处理 keyDown
* 初始化食物 initFood
* 画食物 drawFood
* 蛇1吃食物 eatFood
* 蛇2吃食物 eatFood_2
* 判断蛇1死亡 snakeDie
* 判断蛇2死亡 snakeDie_2
* 显示蛇1分数 showGrade
* 显示蛇2分数 showGrade_2
*********************************/
void initSnake();
void initSnake_2();
void drawSnake();
void drawSnake_2();
void moveSnake();
void moveSnake_2();
void keyDown();
void initFood();
void drawFood();
void eatFood();
void eatFood_2();
void snakeDie();
void snakeDie_2();
void showGrade();
void showGrade_2();
//坐标
struct point_XY {
int x;
int y;
};
//蛇属性
struct {
int num; //蛇的节数
point_XY snakeXY;//最多100节
char postion; //方向
int flag; //判断是否蛇死亡
}snake, snake_2;
//食物的属性
struct {
point_XY foodXY; //食物坐标(X和Y)
int eatGrade; //吃掉食物所得分数
int flag; //食物是否存在
}food;
//枚举方向模拟键码值
enum movPostion {
right = 72, left = 75, down = 77, up = 80, //对应右左下上键的键码值
right_2 = 68, left_2 = 65, down_2 = 83, up_2 = 87 //对应dasw的键码值
};
HWND hwnd;
int speed = 50;
int main() {
using namespace std;
srand((unsigned int)time(NULL));
hwnd = initgraph(640, 480);
setbkcolor(WHITE); //窗口颜色为白White
cleardevice(); //刷新
initSnake(); //创建蛇1
initSnake_2(); //创建蛇2
snake.flag = 0; //蛇1活着
snake_2.flag = 0; //蛇2活着
initFood(); //创建食物
while (true) {
cleardevice(); //刷新背景
drawSnake(); //画蛇1
drawSnake_2(); //画蛇2
moveSnake(); //移动蛇1
moveSnake_2(); //移动蛇2
snakeDie(); //判断蛇1死亡
snakeDie_2(); //判断蛇2死亡
if (snake.flag == 1 or snake_2.flag == 1) break; //如果死了,停止循环
if (food.flag != 1) initFood(); //初始化食物
if (food.flag == 1) drawFood(); //画食物
eatFood();
eatFood_2();
while (_kbhit()) {
keyDown(); //如果有键盘输入,检测输入
}
Sleep(speed); //间隔时间50ms
}
getchar();
return 0;
}
//初始化蛇1
void initSnake() {
snake.num = 3; //初始化时为三节
snake.snakeXY.x = 20;
snake.snakeXY.y = 0;
snake.snakeXY.x = 10; //间隔10像素
snake.snakeXY.y = 0;
snake.snakeXY.x = 0;
snake.snakeXY.y = 0;
snake.postion = right; //初始化方向为右
food.flag = 0;
}
//初始化蛇2
void initSnake_2() {
snake_2.num = 3; //初始化时为三节
snake_2.snakeXY.x = 10;
snake_2.snakeXY.y = 300;
snake_2.snakeXY.x = 10; //间隔10像素
snake_2.snakeXY.y = 290;
snake_2.snakeXY.x = 10;
snake_2.snakeXY.y = 280;
snake_2.postion = down_2; //初始化方向为右
food.flag = 0;
}
//画蛇1
void drawSnake() {
for (int i = 0; i < snake.num; i++) {
setlinecolor(BLACK); //矩形边框颜色为黑Black
setfillcolor(BLUE); //矩形内部颜色为蓝blue
fillrectangle(snake.snakeXY.x, snake.snakeXY.y, snake.snakeXY.x + 10, snake.snakeXY.y + 10);
}
}
//画蛇2
void drawSnake_2() {
for (int i = 0; i < snake.num; i++) {
setlinecolor(BLACK); //矩形边框颜色为黑Black
setfillcolor(GREEN); //矩形内部颜色为绿Green
fillrectangle(snake_2.snakeXY.x, snake_2.snakeXY.y, snake_2.snakeXY.x + 10, snake_2.snakeXY.y + 10);
}
}
//移动蛇1
void moveSnake() {
//除蛇第一节以外的移动坐标处理
for (int i = snake.num - 1; i > 0; i--) {
snake.snakeXY.x = snake.snakeXY.x;
snake.snakeXY.y = snake.snakeXY.y;
}
//第一节坐标处理
switch (snake.postion) {
case right:
snake.snakeXY.x += 10;
break;
case left:
snake.snakeXY.x -= 10;
break;
case down:
snake.snakeXY.y += 10;
break;
case up:
snake.snakeXY.y -= 10;
break;
default:
break;
}
}
//移动蛇2
void moveSnake_2() {
//除蛇第一节以外的移动坐标处理
for (int i = snake_2.num - 1; i > 0; i--) {
snake_2.snakeXY.x = snake_2.snakeXY.x;
snake_2.snakeXY.y = snake_2.snakeXY.y;
}
//第一节坐标处理
switch (snake_2.postion) {
case right_2:
snake_2.snakeXY.x += 10;
break;
case left_2:
snake_2.snakeXY.x -= 10;
break;
case down_2:
snake_2.snakeXY.y += 10;
break;
case up_2:
snake_2.snakeXY.y -= 10;
break;
default:
break;
}
}
//按键处理
void keyDown() {
char userKey;
userKey = _getch();
switch (userKey) {
case right:
if (snake.postion != down) snake.postion = up;
break;
case left:
if (snake.postion != right) snake.postion = left;
break;
case down:
if (snake.postion != left) snake.postion = right;
break;
case up:
if (snake.postion != up) snake.postion = down;
break;
case right_2:
if (snake_2.postion != down_2) snake_2.postion = up_2;
break;
case left_2:
if (snake_2.postion != right_2) snake_2.postion = left_2;
break;
case down_2:
if (snake_2.postion != left_2) snake_2.postion = right_2;
break;
case up_2:
if (snake_2.postion != up_2) snake_2.postion = down_2;
break;
case 49:
speed = 10;
break;
case 50:
speed = 20;
break;
case 51:
speed = 30;
break;
case 52:
speed = 40;
break;
case 53:
speed = 50;
break;
case 54:
speed = 60;
break;
case 55:
speed = 70;
break;
case 56:
speed = 80;
break;
case 57:
speed = 90;
break;
case 48:
speed = 100;
break;
default:
break;
}
}
//初始化食物
void initFood() {
food.foodXY.x = rand() % 65 * 10; //坐标一定要是10的倍数
food.foodXY.y = rand() % 48 * 10;
food.flag = 1;
for (int i = 0; i < snake.num; i++) {
//如果坐标重复,重新生成
if (food.foodXY.x == snake.snakeXY.x and food.foodXY.y == snake.snakeXY.y or food.foodXY.x == snake_2.snakeXY.x and food.foodXY.y == snake_2.snakeXY.y) {
food.foodXY.x = rand() % 65 * 10;
food.foodXY.y = rand() % 48 * 10;
}
}
}
//画食物
void drawFood() {
fillrectangle(food.foodXY.x, food.foodXY.y, food.foodXY.x + 10, food.foodXY.y + 10);
setlinecolor(BLACK); //矩形边框颜色为黑Black
setfillcolor(BLUE); //矩形内部颜色为蓝blue
}
//蛇1吃食物
void eatFood() {
//蛇变长了
if (snake.snakeXY.x == food.foodXY.x and snake.snakeXY.y == food.foodXY.y) {
snake.num++;
food.eatGrade += 10;
food.flag = 0;
//重新画食物
void drawFood();
}
}
//蛇2吃食物
void eatFood_2() {
//蛇变长了
if (snake_2.snakeXY.x == food.foodXY.x and snake_2.snakeXY.y == food.foodXY.y) {
snake_2.num++;
food.eatGrade += 10;
food.flag = 0;
//重新画食物
void drawFood();
}
}
//判断蛇1死亡
void snakeDie() {
//撞墙而死
if (snake.snakeXY.x > 640 or snake.snakeXY.x < 0 or snake.snakeXY.y > 480 or snake.snakeXY.y < 0) {
outtextxy(200, 200, "玩家1撞南墙了!");
MessageBox(hwnd, "玩家2赢了!", "玩家1撞墙了!!!", MB_OK);
snake.flag = 1; //蛇1死亡,游戏结束
}
//自杀而死
for (int i = 1; i < snake.num; i++) {
if (snake.snakeXY.x == snake.snakeXY.x and snake.snakeXY.y == snake.snakeXY.y) {
outtextxy(200, 200, "玩家1撞自己了!");
MessageBox(hwnd, "玩家2赢了了!", "玩家1自杀了!!!", MB_OK);
snake.flag = 1; //蛇1死亡,游戏结束
}
}
//头撞到对方身上而死
for (int i = 1; i < snake_2.num; i++) {
if (snake.snakeXY.x == snake_2.snakeXY.x and snake.snakeXY.y == snake_2.snakeXY.y) {
outtextxy(200, 200, "玩家2赢了了!");
MessageBox(hwnd, "玩家1撞到玩家2了", "GameOver!!!", MB_OK);
snake.flag = 1; //蛇1死亡,游戏结束
}
}
//两头相撞而死
if (snake.snakeXY.x == snake_2.snakeXY.x and snake.snakeXY.y == snake_2.snakeXY.y) {
outtextxy(200, 200, "两头蛇相撞了");
MessageBox(hwnd, "两个都输了!", "两败俱伤!!!", MB_OK);
snake.flag = 1; //两蛇死亡,游戏结束
}
}
//判断蛇2死亡
void snakeDie_2() {
//撞墙而死
if (snake_2.snakeXY.x > 640 or snake_2.snakeXY.x < 0 or snake_2.snakeXY.y > 480 or snake_2.snakeXY.y < 0) {
outtextxy(200, 200, "玩家2撞南墙了!");
MessageBox(hwnd, "玩家1赢了!!!", "玩家2撞南墙了!!!", MB_OK);
snake_2.flag = 1; //蛇2死亡,游戏结束
}
//自杀而死
for (int i = 1; i < snake_2.num; i++) {
if (snake_2.snakeXY.x == snake_2.snakeXY.x and snake_2.snakeXY.y == snake_2.snakeXY.y) {
outtextxy(200, 200, "玩家2撞自己了!");
MessageBox(hwnd, "GameOver!!!", "玩家2自杀了!!!", MB_OK); //蛇死亡,游戏结束
snake_2.flag = 1; //蛇2死亡,游戏结束
}
}
//头撞到对方身上而死
for (int i = 1; i < snake_2.num; i++) {
if (snake_2.snakeXY.x == snake.snakeXY.x and snake_2.snakeXY.y == snake.snakeXY.y) {
outtextxy(200, 200, "玩家1赢了了!");
MessageBox(hwnd, "玩家2撞到玩家1了!", "玩家1赢了了!!!", MB_OK);
snake_2.flag = 1; //蛇2死亡,游戏结束
}
}
}今天把我之前写的贪吃蛇改成双人模式,结果最后运行发现第二条蛇控制不了(用asdw键),第一条蛇上下左右键还可以正常控制(头大{:10_243:}),希望有dalao看看我的代码
/********************************
* 初始化蛇1 intiSnake
* 初始化蛇2 intiSnake_2
* 画蛇1 drawSnake
* 画蛇2 drawSnake_2
* 移动蛇1 moveSnake
* 移动蛇2 moveSnake_2
* 按键处理 keyDown
* 初始化食物 initFood
* 画食物 drawFood
* 蛇1吃食物 eatFood
* 蛇2吃食物 eatFood_2
* 判断蛇1死亡 snakeDie
* 判断蛇2死亡 snakeDie_2
* 显示蛇1分数 showGrade
* 显示蛇2分数 showGrade_2
*********************************/
intiSnake是什么 其他我找不出来
我还是个小学生 本帖最后由 superbe 于 2020-7-12 22:32 编辑
按键控制乱了,替换以下代码,应该就可以了
//枚举方向模拟键码值
enum movPostion {
up = 72, down = 80, left = 75, right = 77,
up_2 = 87, down_2 = 83, left_2 = 65, right_2 = 68
};
//画蛇2
void drawSnake_2() {
for (int i = 0; i < snake_2.num; i++) {
setlinecolor(BLACK); //矩形边框颜色为黑Black
setfillcolor(GREEN); //矩形内部颜色为绿Green
fillrectangle(snake_2.snakeXY.x, snake_2.snakeXY.y, snake_2.snakeXY.x + 10, snake_2.snakeXY.y + 10);
}
}
//按键处理
void keyDown() {
char userKey;
userKey = _getch();
//if (userKey == 0 || userKey == -32)
// userKey = _getch();
switch (userKey) {
case up:
if (snake.postion != down) snake.postion = up;
break;
case down:
if (snake.postion != up) snake.postion = down;
break;
case left:
if (snake.postion != right) snake.postion = left;
break;
case right:
if (snake.postion != left) snake.postion = right;
break;
case up_2:
case up_2 + 32:
if (snake_2.postion != down_2) snake_2.postion = up_2;
break;
case down_2:
case down_2 + 32:
if (snake_2.postion != up_2) snake_2.postion = down_2;
break;
case left_2:
case left_2 + 32:
if (snake_2.postion != right_2) snake_2.postion = left_2;
break;
case right_2:
case right_2 + 32:
if (snake_2.postion != left_2) snake_2.postion = right_2;
break;
case 49:
speed = 10;
break;
case 50:
speed = 20;
break;
case 51:
speed = 30;
break;
case 52:
speed = 40;
break;
case 53:
speed = 50;
break;
case 54:
speed = 60;
break;
case 55:
speed = 70;
break;
case 56:
speed = 80;
break;
case 57:
speed = 90;
break;
case 48:
speed = 100;
break;
default:
break;
}
} superbe 发表于 2020-7-10 21:23
按键控制乱了,替换以下代码,应该就可以了
确实是你所说的按键的问题,我也尝试着改过,但我觉得可能还是因为getch()函数用的键码值不是代码上的那些(一开始我不确定用的是哪个键码值,而我的代码里所用的是ASCII键码值,而后来我发现字母a ~ z的ASCII键码值是65 ~ 90,这就和我已经确认正确上下左右键的键码值72、80、75、77冲突了),但我又找不到这个函数用的键码值,所以我也放弃了。 本帖最后由 superbe 于 2020-7-12 22:28 编辑
别放弃。。。改成虚拟键码试试,字母键的虚拟键码就是ASCII码,方向键的虚拟键码要调用函数得到。
大概是下面这样的,不知道我的理解对不对,参考下。
enum movPostion {
up = VK_UP, down = VK_DOWN, left = VK_LEFT, right = VK_RIGHT,
up_2 = 87, down_2 = 83, left_2 = 65, right_2 = 68
};
void keyDown() {
int userKey = virtkey();
switch (userKey) {
(下面代码同上......)
}
int virtkey()
{
int ch = _getch();
if (ch == 0 || ch == 0xE0)
ch = MapVirtualKey(_getch(), MAPVK_VSC_TO_VK_EX);
return ch;
}
在VS2015下运行是正常的,其它环境没测试。
页:
[1]