livcui 发表于 2020-8-21 16:33:19

贪吃蛇:C++

本帖最后由 livcui 于 2020-8-22 21:22 编辑


使用 EasyX 库制作的贪吃蛇,下面是源代码:    (没hide权限,骗不了回复{:10_266:})

另外,EasyX 仅支持 VC ,这是下载地址 https://easyx.cn/downloads/

如果不想安装 EasyX,可下载打包好的 EXE 文件



源文件:
// Code.cpp
#include "Snake.h"
#include <cstdio>
#include <string>
#include <sstream>
#include <time.h>
#include <conio.h>

Snake::Snake(): hwnd(initgraph(480 + 153, 480))// 设置窗口大小 (730, 480)
                              , speed(50), level_ () {

      setbkcolor(WHITE);                // 窗口颜色为白 White

      // 初始化蛇
      snake.num = 3;                              // 初始化时为三节
      snake.snakeXY.x = 20;      // 间隔10像素
      snake.snakeXY.y = 0;
      snake.snakeXY.x = 10;
      snake.snakeXY.y = 0;
      snake.snakeXY.x = 0;
      snake.snakeXY.y = 0;
      snake.postion = right;                // 初始化方向为右

      // 初始化食物
      food.foodXY.x = rand() % 65 * 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) {
                        food.foodXY.x = rand() % 65 * 10;
                        food.foodXY.y = rand() % 48 * 10;
                }
      }
}
Snake::~Snake() {}

// 按键处理
void Snake::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;

                // 调整速度(数字键 1, 2, 3, 4, ... , 10)
      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 Snake::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);
      }
}
// 移动蛇
void Snake::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;
      }
}
// 移动蛇 - 穿墙
void Snake::moveSnake_2() {

      // 除蛇第一节以外的移动坐标处理
      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;
      }

      if (snake.snakeXY.x > 470) snake.snakeXY.x = 0;
      if (snake.snakeXY.x < 0) snake.snakeXY.x = 470;
      if (snake.snakeXY.y > 470) snake.snakeXY.y = 0;
      if (snake.snakeXY.y < 0) snake.snakeXY.y = 470;
}
// 初始化食物
void Snake::initFood() {

      srand(time(NULL));
      food.foodXY.x = rand() % 48 * 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) {
                        food.foodXY.x = rand() % 48 * 10;      // 随机生成坐标
                        food.foodXY.y = rand() % 48 * 10;
                }
      }
}
// 画食物
void Snake::drawFood() {

      fillrectangle(food.foodXY.x, food.foodXY.y, food.foodXY.x + 10, food.foodXY.y + 10);
      setlinecolor(BLACK);      //矩形边框颜色为黑Black
      setfillcolor(BLUE);                //矩形内部颜色为蓝blue

}
// 吃食物
void Snake::eatFood() {

      if (snake.snakeXY.x == food.foodXY.x and snake.snakeXY.y == food.foodXY.y) {

                // 蛇吃掉后长度 +1
                snake.num++;
                food.eatGrade += 1;
                food.flag = 0;

                // 蛇吃掉后重新画食物
                void drawFood();
      }
}
// 判断蛇撞墙而死
void Snake::snakeWallDie() {

      if (snake.snakeXY.x > 470 or
                snake.snakeXY.x < 0 or
                snake.snakeXY.y > 470 or
                snake.snakeXY.y < 0 ) {
                outtextxy(200, 200, "你撞墙了!");
                snake.flag = 1;                // 蛇死亡
      }
}
// 判断蛇自杀而死
void Snake::snakeBodyDie() {

      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, "你自杀了!");

                        snake.flag = 1;                // 蛇死亡
                }
      }
}
// 显示分数
void Snake::showGrade() {

      //char arr;
      //sprintf(arr, "%d", food.eatGrade);
      std::ostringstream ss;
      ss << food.eatGrade;
      std::string str = ss.str();
      setbkmode(BLUE);
      settextcolor(BLACK);
      outtextxy(500, 25, "分数");
      outtextxy(550, 25, str.c_str());
}

// 运行
void Snake::run() {

      setbkcolor(BLACK);                // 窗口颜色为黑 BLACK
      settextcolor(WHITE);      // 文字颜色
      outtextxy(50, 50, "选择模式");
      outtextxy(60, 80, "( 1    经典");
      outtextxy(60, 100, "( 2    围墙");
      
      switch (_getch()) {

      case '1':
                level_ = 0;
                break;
      case '2':
                level_ = 1;
                break;
      default:
                level_ = 0;
      }
      setbkcolor(WHITE);                // 窗口颜色为白 WHITE

loop:
      while (true) {
      
                while (_kbhit()) {

                        keyDown();                // 如果有键盘输入, 检测输入
                }
                cleardevice();      // 刷新
                switch (level_){      // 不同模式
                case 0:
                        snakeBodyDie();
                        moveSnake_2();                              // 移动蛇 - 穿墙
                        setlinecolor(BLACK);                // 画线颜色为黑 Black
                        setlinestyle(PS_DASH, 2);      // 设置线 (虚线, 宽 2)
                        line(480, 480, 480, 0);                // 画线
                        // 线条恢复默认
                        setlinestyle(PS_SOLID, 1);      // 设置线 (实线, 宽 1)
                        outtextxy(500, 60, "游戏模式 : ");
                        outtextxy(590, 60, "经典");
                        break;
                case 1:
                        snakeWallDie();
                        snakeBodyDie();
                        moveSnake();                              // 移动蛇 - 围墙
                        setlinecolor(BLACK);                // 画线颜色为黑 Black
                        setlinestyle(PS_SOLID, 5);      // 设置线 (实线, 宽 5)
                        line(480, 480, 480, 0);                // 画线
                        line(1, 1, 1, 480);
                        line(479, 479, 1, 479);
                        line(1, 1, 480, 1);
                        // 线条恢复默认
                        setlinestyle(PS_SOLID, 1);      // 设置线 (实线, 宽 1)
                        outtextxy(500, 60, "游戏模式 : ");
                        outtextxy(590, 60, "围墙");
                        break;
                default:
                        snakeBodyDie();
                        moveSnake_2();      // 移动蛇 - 穿墙
                        setlinecolor(BLACK);                // 画线颜色为黑 Black
                        setlinestyle(PS_DASH, 2);      // 设置线 (虚线, 宽 2)
                        line(480, 480, 480, 0);                // 画线
                        // 线条恢复默认
                        setlinestyle(PS_SOLID, 1);      // 设置线 (实线, 宽 1)
                        break;
                }
                drawSnake();      // 画蛇
                if (snake.flag == 1) {                // 如果蛇死了...

                        if (MessageBox(NULL, "再玩一局?", "GameOver", MB_YESNO) != IDYES) return;
                        else {
                              snake.flag = 0;
                              snake.num = 3;
                              snake.snakeXY.x = 20;
                              snake.snakeXY.y = 0;
                              snake.snakeXY.x = 10;
                              snake.snakeXY.y = 0;
                              snake.snakeXY.x = 0;
                              snake.snakeXY.y = 0;
                              snake.postion = right;
                              food.eatGrade = 0;
                              goto loop;
                              
                        }
                }
                if (food.flag != 1) initFood();                // 初始化食物
                if (food.flag == 1) drawFood();                // 画食物
                eatFood();                // 吃食物
                showGrade();                // 显示分数

                outtextxy(530, 450, "作者: livcui");

                Sleep(speed);                // 间隔时间50ms
      }

      char ch = getchar();      // 退出
}
// Main.cpp
#include "Snake.h"
#include <Windows.h>
#include <graphics.h>
#include <conio.h>

int main() {

      Snake snake;
      snake.run();

      return 0;
}

头文件:
// Snake.h
#ifndef SNAKE_H_
#define SNAKE_H_
#include <graphics.h>
#include <conio.h>

class Snake {

private:

      HWND hwnd;
      int speed;
      int level_;

      // 坐标 XY
      struct pointXY {
                int x;
                int y;
      };
      // 蛇属性
      struct snakeProperty {
                int num;                              //蛇的节数
                pointXY snakeXY;   //节数最多100节
                char postion;                        //方向
                int flag;                              //蛇是否死亡
      } snake;
      // 枚举方向
      enum movPostion {

                right = 72, left = 75, down = 77, up = 80      //对应上下左右键的键码值
                //right = 'd', left = 'a', down = 's', up = 'w'      //对应dasw键的键码值
      };

      //食物的属性
      struct foodProperty {

                pointXY foodXY;                // 食物坐标
                int eatGrade;                // 吃掉食物所得分数
                int flag;                  // 食物是否存在

      }food;

      void keyDown();                // 按键处理
      void drawSnake();      // 画蛇
      void moveSnake();      // 移动蛇
      void moveSnake_2();      // 移动蛇 - 穿墙
      void drawFood();      // 画食物
      void eatFood();                // 吃食物
      void snakeDie();      // 判断蛇死亡
      void snakeWallDie();// 判断蛇撞墙死亡
      void snakeBodyDie();// 判断蛇自杀而死
      void showGrade();      // 显示分数
      void initFood();      // 初始化食物

public:
      Snake();
      ~Snake();
      void run();

};

#endif

livcui 发表于 2020-8-21 16:33:59

本帖最后由 livcui 于 2020-8-21 16:35 编辑

自占沙发

嘉岳呀 发表于 2020-8-21 16:40:07



嘉岳呀 发表于 2020-8-21 16:41:27

用exe试的呀

Hello. 发表于 2020-8-21 16:49:58

不错哦

zltzlt 发表于 2020-8-21 17:02:20

顶{:10_256:}

Kehui 发表于 2020-8-21 17:39:25

厉害了!

weiter 发表于 2020-8-21 17:48:25

谢谢大佬!

livcui 发表于 2020-8-21 17:58:41

本帖最后由 livcui 于 2020-8-21 22:30 编辑

嘉岳呀 发表于 2020-8-21 16:40


bangbang-ande 发表于 2020-8-21 19:59:21

嘉岳呀 发表于 2020-8-21 16:40


me too

子非鱼焉知鱼 发表于 2020-8-21 20:29:37

牛啊

aaron.yang 发表于 2020-8-21 20:35:37

厉害{:10_275:}

aaron.yang 发表于 2020-8-21 21:04:56

嘉岳呀 发表于 2020-8-21 16:40


我也一样{:10_266:}

叙白 发表于 2020-8-21 21:14:08

大佬{:7_146:}

紫癜聪 发表于 2020-8-21 21:25:36

66666

小白python! 发表于 2020-8-21 23:06:36


蠢蠢熊 发表于 2020-8-22 18:29:58

厉害

蠢蠢熊 发表于 2020-8-22 18:30:30

玩玩

蠢蠢熊 发表于 2020-8-22 18:31:02

6666

xu007xu 发表于 2020-8-22 19:43:35

页: [1] 2 3 4 5
查看完整版本: 贪吃蛇:C++