C++ - 分文件-贪吃蛇

VS2017

Snake.h

#pragma once
#include <iostream>
#include <windows.h>
#include <vector>

using namespace std;

 class Snake
{
public:
     Snake();
     void gotoxy(int x, int y);
     char get_cSnake_b(void); //获取蛇身图形
     int m_iX; //蛇身横向坐标
     int m_iY; //蛇身纵向坐标
     static int c_iX; //公共坐标
     static int c_iY; //公共坐标
private:
    char m_cSnake_b; //蛇身图形
};

Snake_body.h

#pragma once
#include "Snake.h"
#include <conio.h>

class Snake_body :public Snake
{
public:
    Snake_body();
    void m_Int(void);
    void set_vSnake_b(Snake t_x); //往向量里添加新的蛇身
    void prt_vSnake_b(void); //打印蛇身
    void erase_vSnake_b(void); //将老的蛇尾的坐标显示为空,并且删除老的蛇尾
    void ctr_Direction(char c_key); //获取用户按键,控制方向移动
    char ctr_Collide(void); //碰撞
    void ctr_Level(void); //过关
    bool ctr_Food(int x, int y); //吃食物
public:
    static int m_iScore; //得分
    static int m_iLevel; //关卡
    static int key2;
private:
    vector<Snake>m_vSnake_b; //蛇向量

};

Snake_food.h

#include "Snake.h"
#include <time.h>

class Snake_food : public Snake
{
public:
    Snake_food();
    void prtSnake_food(int *x, int *y); //打印食物
    int m_ifX; //食物横坐标
    int m_ifY; //食物纵坐标
private:
    char *m_cSnake_food; //食物图形
};

Snake.cpp

#include "Snake.h"

int Snake::c_iX = 30;
int Snake::c_iY = 10;

Snake::Snake()
{
    m_cSnake_b = '*';
}

void Snake::gotoxy(int x, int y)
{
    COORD pos;
    pos.X = x - 1;
    pos.Y = y - 1;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

//获取蛇身图形
char Snake::get_cSnake_b(void)
{
    return m_cSnake_b;
}

Snake_body.cpp

#include "Snake_body.h"

Snake_body::Snake_body()
{

}

int Snake_body::m_iScore = 0;
int Snake_body::m_iLevel = 1;
int Snake_body::key2 = 1;
void Snake_body::m_Int(void)
{
    Snake tmp;
    for (int i = 0; i < 35; i++)
    {
        cout << "o ";
    }
    cout << endl;
    for (int i = 0; i < 25; i++)
    {
        cout << "o                                                                   o" << endl;
    }
    for (int i = 0; i < 35; i++)
    {
        cout << "o ";
    }
    tmp.gotoxy(80, 2);
    cout << "贪吃蛇";
    tmp.gotoxy(72, 10);
    cout << "游戏说明:";
    tmp.gotoxy(72, 12);
    cout << "使用W、A、S、D控制蛇的移动,";
    tmp.gotoxy(72, 14);
    cout << "每吃一个食物加一分。";
    tmp.gotoxy(77, 25);
    cout << "作者:完美教父";
}

//往向量里添加新的蛇身
void Snake_body::set_vSnake_b(Snake t_x)
{
    m_vSnake_b.push_back(t_x);
}

//打印蛇
void Snake_body::prt_vSnake_b(void)
{
    for (unsigned  i = 0; i < m_vSnake_b.size(); i++)
    {
        this->gotoxy(m_vSnake_b[i].m_iX, m_vSnake_b[i].m_iY);
        cout << m_vSnake_b[i].get_cSnake_b();
    }
}

//删除第一个元素,并且将第一个元素坐标打印成空格,使实现移动
void Snake_body::erase_vSnake_b(void)
{
    //将向量第一个元素的位置打印成空,方便形成蛇移动
    gotoxy(m_vSnake_b[0].m_iX, m_vSnake_b[0].m_iY);
    cout << " ";
    //删除向量中第一个元素
    m_vSnake_b.erase(m_vSnake_b.begin());
}

//碰撞
char Snake_body::ctr_Collide(void)
{
    char Collide_key = '0';
    if (!((m_vSnake_b.back().c_iX < 68 && m_vSnake_b.back().c_iX>2) && (m_vSnake_b.back().c_iY < 26 && m_vSnake_b.back().c_iY>2)))
    {
        this->gotoxy(25, 25);
        cout << "撞墙啦,傻瓜!按任意键...";
        _getch();
        this->gotoxy(25, 25);
        cout << "重新开始吗?回车确定!按ESC退出!";
        Collide_key = _getch();
        return Collide_key;
    }
    for (unsigned i = 0;i < m_vSnake_b.size() - 1;i++)
    {
        if (m_vSnake_b.back().c_iX == m_vSnake_b[i].m_iX&&m_vSnake_b.back().c_iY == m_vSnake_b[i].m_iY)
        {
            this->gotoxy(25, 25);
            cout << "撞身体啦,呆子!按任意键...";
            _getch();
            this->gotoxy(25, 25);
            cout << "重新开始吗?回车确定!按ESC退出!";
            Collide_key = _getch();
            return Collide_key;
        }
    }
    return 0;
}

//吃食物
bool Snake_body::ctr_Food(int x, int y)
{
    Snake *snake = NULL;
    if (m_vSnake_b.back().m_iX == x && m_vSnake_b.back().m_iY == y)
    {
        //吃到食物加分
        Snake_body::m_iScore++;
        //如果吃到食物就加一个身体
        snake = new Snake;
        snake->m_iX = Snake::c_iX;
        snake->m_iY = Snake::c_iY;
        this->set_vSnake_b(*snake);
        return true;
    }
    return false;
}

//控制方向
void Snake_body::ctr_Direction(char c_key)
{
    char c_k = c_key;
    int m_itDirection = 0; //方向标签,表示当时以什么方向移动 1.2.3.4代表上下左右,使用方向标签的作用主要是控制蛇不可以倒着移动,比如向上移动时d,按向下键s时无响应,依此类推
    if (c_k == 'w') //上
    {
        m_itDirection = 1;
        if (Snake_body::key2 == 1 || Snake_body::key2 == 3 || Snake_body::key2 == 4)
        {
            c_iY--;
            Snake_body::key2 = m_itDirection;
        }
        else
        {
            c_iY++;
        }
    }
    else if (c_k == 's') //下
    {
        m_itDirection = 2;
        if (Snake_body::key2 == 2 || Snake_body::key2 == 3 || Snake_body::key2 == 4)
        {
            c_iY++;
            Snake_body::key2 = m_itDirection;
        }
        else
        {
            c_iY--;
        }
    }
    else if (c_k == 'a') //左
    {
        m_itDirection = 3;
        if (Snake_body::key2 == 1 || Snake_body::key2 == 2 || Snake_body::key2 == 3)
        {
            c_iX--;
            Snake_body::key2 = m_itDirection;
        }
        else
        {
            c_iX++;
        }
    }
    else if (c_k == 'd') //右
    {
        m_itDirection = 4;
        if (Snake_body::key2 == 1 || Snake_body::key2 == 2 || Snake_body::key2 == 4)
        {
            c_iX++;
            Snake_body::key2 = m_itDirection;
        }
        else
        {
            c_iX--;
        }
    }
    //在没有按任何键时,默认向右移
    else
    {
        c_iX++;
        m_itDirection = 4;
        Snake_body::key2 = m_itDirection;
    }
    Snake *snake;
    snake = new Snake;
    snake->m_iX = c_iX;
    snake->m_iY = c_iY;
    snake->gotoxy(snake->m_iX, snake->m_iY);
    cout << snake->get_cSnake_b(); //打印出添加的新蛇头
    this->set_vSnake_b(*snake); //将新的蛇头加入向量中
    this->erase_vSnake_b(); //将老的蛇尾的坐标显示为空,并且删除老的蛇尾
}

//控制通关
void Snake_body::ctr_Level(void)
{
    switch (m_iLevel)
    {
    case 1:
        if (m_iScore == 10)
        {
            m_iLevel++;
            m_iScore = 0;
            this->gotoxy(73, 5);
            cout << "                   ";
        }
        break;
    case 2:
        if (m_iScore == 60)
        {
            m_iLevel++;
            m_iScore = 0;
            this->gotoxy(73, 5);
            cout << "                   ";
        }
        break;
    case 3:
        if (m_iScore == 100)
        {
            this->gotoxy(25, 15);
            cout << "恭喜你通关!你真棒!";
            this->gotoxy(25, 17);
            cout << "按任意键退出!";
            _getch();
            exit(1);
        }
        break;
    }
}

Snake_food.cpp

#include "Snake_food.h"

Snake_food::Snake_food()
{
    m_cSnake_food = new char;
    *m_cSnake_food = '&';
    m_ifX = 5;
    m_ifY = 5;
}

//打印食物
void Snake_food::prtSnake_food(int *x, int *y)
{
    srand((unsigned)time(NULL));
    *x = rand() % 62 + 5;
    *y = rand() % 24 + 2;
    this->gotoxy(*x, *y);
    cout << *m_cSnake_food;
}

Star.cpp

#include "Snake.h"
#include "Snake_body.h"
#include "Snake_food.h"
#include <stdlib.h>
#include <conio.h>
using namespace std;

#define SNAKE_COUNT 6 //初始化蛇身长度
#define SNAKE_SPEED 100 //游戏速度

int main(void)
{
rst:
    Snake *snake = NULL; //单个蛇身
    Snake_body snake_b; //蛇
    Snake_food snake_f; //食物
    snake_b.m_Int(); //初始化界面
    char key = 0; //接收用户的按键
    char key1 = 0; //使用暂停
    //初始化蛇身
    for (int i = 0; i < SNAKE_COUNT; i++)
    {
        snake = new Snake;
        snake->m_iX = Snake::c_iX;
        snake->m_iY = Snake::c_iY;
        snake_b.set_vSnake_b(*snake);
        Snake::c_iX++;
    }

    //打印初始化的蛇身
    snake_b.prt_vSnake_b();
    Snake::c_iX -= 1;

    //打印初始化的食物
    snake_f.prtSnake_food(&snake_f.m_ifX, &snake_f.m_ifY);

    //循环游戏开始
    while (1)
    {
        //监听键盘操作
        if (_kbhit())
        {
            key = _getch();
        }
        //用户输入处理
        if (key == 13)
        {
            snake_b.gotoxy(25, 25);
            cout << "暂停游戏中。。。!";
            _getch();
            key = key1;
            snake_b.gotoxy(25, 25);
            cout << "                                          ";
        }
        else if (key == 27)
        {
            snake_b.gotoxy(25, 25);
            cout << "确定退出吗?回车键退出!其它任意键返回!";
            char key2 = _getch();
            if (key2 == 13)
            {
                exit(1);
            }
            key = key1;
            snake_b.gotoxy(25, 25);
            cout << "                                          ";
        }
        else
        {
            //从暂停恢复游戏
            key1 = key;
        }
        //控制蛇的移动方向
        snake_b.ctr_Direction(key);
        //检测碰撞及碰撞后的按键处理
        char tmp_Collide = snake_b.ctr_Collide();
        if (tmp_Collide == 13)
        {
            Snake_body::m_iScore = 0;
            Snake::c_iX = 30;
            Snake::c_iY = 10;
            system("cls");
            goto rst;
        }
        else if (tmp_Collide == 27)
        {
            exit(1);
        }
        else if (0 != tmp_Collide)
        {
            snake_b.gotoxy(25, 25);
            cout << "输入错误!按任意键退出!                 ";
            _getch();
            exit(1);
        }
        //判断是否吃到食物
        if (snake_b.ctr_Food(snake_f.m_ifX, snake_f.m_ifY))
        {
            //打印初始化的食物(再刷个食物出来)
            snake_f.prtSnake_food(&snake_f.m_ifX, &snake_f.m_ifY);
        }
        snake_b.gotoxy(72, 5);
        cout << "得分: " << Snake_body::m_iScore;
        snake_b.gotoxy(72, 7);
        cout << "关卡: " << Snake_body::m_iLevel;
        snake_b.ctr_Level();
        Sleep(SNAKE_SPEED);
    }
    system("pause");
    return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

完美教父

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值