zoukankan      html  css  js  c++  java
  • 贪吃蛇C++

    这是贪吃蛇的效果图。一边看《新三国》,一边写的结果。第一次写C++的,用类实现,还挺好玩的。

    设计总共分为3个类:地图,蛇,食物

    先上传全部代码:头文件

    #include <stdio.h>  
    #include <stdlib.h>  
    #include <string>  
    #include <iterator>  
    #include <algorithm>  
    #include <iostream>  
    #include <vector>  
    #include <deque>  
    #include <list>  
    #include <set> 
    #include<Windows.h>  
    #include<conio.h> 
    
    using namespace std;
    
    typedef unsigned char  uchar;
    
    struct Point{
        int x;
        int y;
    };
    
    enum SnakeState{
        Eat = 0,
        NotEat = 1,
        HitWall = -1,
        Common = 10
    }snakeState;
    
    enum SnakeDir{
        Up = 72,
        Down = 80,
        Left = 75,
        Right = 77
    };
    
    class CSnake;
    class CFood;
    
    class CMap{
    public:
        CMap(int t, int l, int w, int h);
        ~CMap();
    
        void mapUpdate(CSnake& s,CFood& f);
        bool mapShow();
    
    private:
        int top;
        int left;
        int width;
        int height;
        
        uchar **mat;
        uchar dir;
        uchar lastDir;
    
        CSnake *snake;
        CFood *food;
    };
    
    class CSnake{
        
    public:
        CSnake(int t, int l, int w, int h);
        ~CSnake();
    
        friend class CMap;
    
        int newHeadPoint(uchar dir, Point foodpoint);
    
    private:
        int top;
        int left;
        int width;
        int height;
    
        vector<Point*> snakeBody;
        Point headPoint;
    };
    
    class CFood{
    public:
        CFood(int t, int l, int w, int h);
        ~CFood();
    
        friend class CMap;
    
        Point newFoodPoint();
    private:
        int top;
        int left;
        int width;
        int height;
    
        Point foodPoint;
    };

    cpp文件:

    #include <stdio.h>  
    #include <stdlib.h>  
    #include <string>  
    #include <iterator>  
    #include <algorithm>  
    #include <iostream>  
    #include <vector>  
    #include <deque>  
    #include <list>  
    #include <set> 
    #include<Windows.h>  
    #include<conio.h> 
    #include "main.h"
    
    using namespace std;
    
    void delay(int n)
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                int k = 100 + 100;
            }
        }
    }
    
    CMap::CMap(int t, int l, int w, int h)
    {
        top = t;
        left = l;
        width = w;
        height = h;
    
        dir = Down;
        lastDir = Down;
    
        //内存分配
        mat = new uchar*[height];
        for (int i = 0; i < height; i++)
        {
            mat[i] = new uchar[width];
        }
    
        //初始化路径矩阵边界
        for (int i = 0; i < height; i++)
        {
            mat[i][0] = '#';
            for (int j = 1; j < width - 1; j++)
            {
                if (i == 0 || i == height - 1)
                {
                    mat[i][j] = '#';
                }
                else
                {
                    mat[i][j] = ' ';
                }
            }
            mat[i][width - 1] = '#';
        }
    
        snake = new CSnake(0, 0, 50, 25);
        food = new CFood(0, 0, 50, 25);
    }
    CMap::~CMap()
    {
        for (int i = 0; i < height; i++)
        {
            delete mat[i];
        }
        delete mat;
    }
    void CMap::mapUpdate(CSnake& s, CFood& f)
    {
        mat[f.foodPoint.y][f.foodPoint.x] = 'O';
    
        for (int i = 0; i < s.snakeBody.size(); i++)
        {
            if (i == 0)
            {
                mat[s.snakeBody[i]->y][s.snakeBody[i]->x] = '@';
            }
            else
            {
                mat[s.snakeBody[i]->y][s.snakeBody[i]->x] = '*';
            }
        }
    }
    bool CMap::mapShow()
    {
        //设置顶点坐标,使得绘制一直在起点
        COORD coord;
        coord.X = top;
        coord.Y = left;
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    
        for (int i = 1; i < height - 1; i++)
        {
            memset(mat[i] + 1, ' ', width - 2);
        }
    
        //更新食物坐标和蛇坐标
        mapUpdate(*snake, *food);
    
        while (kbhit())
        {
            dir = getch();
            if (lastDir + dir == 152)//利用ascii码特性,防止蛇走反方向
            {
                dir = lastDir;
            }
        }
        //更新蛇坐标
        int res = snake->newHeadPoint(dir,food->foodPoint);
        lastDir = dir;
    
        if (res == Eat)
        {
            //产生新的食物坐标
            food->newFoodPoint();
        }
        
        //绘制所有,包括地图,蛇,食物
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                cout << mat[i][j];
            }
            cout << endl;
        }
        if (res == HitWall)
        {
            return true;
        }
        return false;
    }
    
    CSnake::CSnake(int t, int l, int w, int h)
    {
        top = t;
        left = l;
        width = w;
        height = h;
    
        //随机起始坐标
        srand(5);
        headPoint.x = rand() % (width - 2) + 1;
        headPoint.y = rand() % (height - 2) + 1;
        Point *tmp = new Point(); tmp->x = headPoint.x; tmp->y = headPoint.y;
        snakeBody.push_back(tmp);
    }
    CSnake::~CSnake()
    {
        for (int i = 0; i < snakeBody.size(); i++)
        {
            delete snakeBody[i];
        }
    }
    
    int CSnake::newHeadPoint(uchar dir, Point foodpoint)
    {
        switch (dir)
        {
            //
        case Up:headPoint.y--; break;
            //
        case Down:headPoint.y++; break;
            //
        case Left:headPoint.x--; break;
            //
        case Right:headPoint.x++; break;
    
        default:
            break;
        }
        if ((headPoint.x == 0) || (headPoint.x == width - 1) || (headPoint.y == 0) || (headPoint.y == height - 1))
        {
            return HitWall;
        }
    
        //吃到食物
        if ((headPoint.x == foodpoint.x) && (headPoint.y == foodpoint.y))
        {
            Point *tmp = new Point(); tmp->x = foodpoint.x; tmp->y = foodpoint.y;
            snakeBody.insert(snakeBody.begin(), tmp);
            headPoint.x = foodpoint.x; headPoint.y = foodpoint.y;
            return Eat;
        }
        else//没吃到食物
        {
            for (int i = snakeBody.size() - 1; i > 0; i--)
            {
                snakeBody[i]->x = snakeBody[i - 1]->x;
                snakeBody[i]->y = snakeBody[i - 1]->y;
            }
            snakeBody[0]->x = headPoint.x; snakeBody[0]->y = headPoint.y;
            return NotEat;
        }
        return Common;
        
    }
    
    CFood::CFood(int t, int l, int w, int h)
    {
        top = t;
        left = l;
        width = w;
        height = h;
    
        srand(8);
        newFoodPoint();
    }
    CFood::~CFood()
    {
    }
    Point CFood::newFoodPoint()
    {
        foodPoint.x = rand() % (width - 2) + 1;
        foodPoint.y = rand() % (height - 2) + 1;
    
        return foodPoint;
    }
    
    int main(int argc, char *argv[])
    {
        CMap map(0, 0, 50, 25);
        while (1)
        {
            bool res= map.mapShow();
            delay(8000);
            if (res)
            {
                cout << "GAME OVER!" << endl;
                break;
            }
        }
        return 0;
    }

    首先看食物类:

    class CFood{
    public:
        CFood(int t, int l, int w, int h);
        ~CFood();
    
        friend class CMap;
    
        Point newFoodPoint();
    private:
        int top;
        int left;
        int width;
        int height;
    
        Point foodPoint;
    };
    
    CFood::CFood(int t, int l, int w, int h)
    {
        top = t;
        left = l;
        width = w;
        height = h;
    
        srand(8);
        newFoodPoint();
    }
    CFood::~CFood()
    {
    }
    Point CFood::newFoodPoint()
    {
        foodPoint.x = rand() % (width - 2) + 1;
        foodPoint.y = rand() % (height - 2) + 1;
    
        return foodPoint;
    }

    newFoodPoint函数用于产生随机的食物坐标点,当吃掉食物时调用这个函数。这个类比较简单。

    class CSnake{
        
    public:
        CSnake(int t, int l, int w, int h);
        ~CSnake();
    
        friend class CMap;
    
        int newHeadPoint(uchar dir, Point foodpoint);
    
    private:
        int top;
        int left;
        int width;
        int height;
    
        vector<Point*> snakeBody;
        Point headPoint;
    };
    CSnake::CSnake(int t, int l, int w, int h)
    {
        top = t;
        left = l;
        width = w;
        height = h;
    
        //随机起始坐标
        srand(5);
        headPoint.x = rand() % (width - 2) + 1;
        headPoint.y = rand() % (height - 2) + 1;
        Point *tmp = new Point(); tmp->x = headPoint.x; tmp->y = headPoint.y;
        snakeBody.push_back(tmp);
    }
    CSnake::~CSnake()
    {
        for (int i = 0; i < snakeBody.size(); i++)
        {
            delete snakeBody[i];
        }
    }
    
    int CSnake::newHeadPoint(uchar dir, Point foodpoint)
    {
        switch (dir)
        {
            //
        case Up:headPoint.y--; break;
            //
        case Down:headPoint.y++; break;
            //
        case Left:headPoint.x--; break;
            //
        case Right:headPoint.x++; break;
    
        default:
            break;
        }
        if ((headPoint.x == 0) || (headPoint.x == width - 1) || (headPoint.y == 0) || (headPoint.y == height - 1))
        {
            return HitWall;
        }
    
        //吃到食物
        if ((headPoint.x == foodpoint.x) && (headPoint.y == foodpoint.y))
        {
            Point *tmp = new Point(); tmp->x = foodpoint.x; tmp->y = foodpoint.y;
            snakeBody.insert(snakeBody.begin(), tmp);
            headPoint.x = foodpoint.x; headPoint.y = foodpoint.y;
            return Eat;
        }
        else//没吃到食物
        {
            for (int i = snakeBody.size() - 1; i > 0; i--)
            {
                snakeBody[i]->x = snakeBody[i - 1]->x;
                snakeBody[i]->y = snakeBody[i - 1]->y;
            }
            snakeBody[0]->x = headPoint.x; snakeBody[0]->y = headPoint.y;
            return NotEat;
        }
        return Common;
        
    }

    这个是蛇的类,主要实现一个newHeadPoint的函数用于规划蛇身体snakeBody的位置坐标。还有一个headPoint的点结构体。

    输入参数是一个方向参数dir和食物坐标参数。方向来控制蛇身的移动,食物坐标来检测是否吃到食物。

    通过不断移动蛇身体的坐标,最后把headPoint点赋给第一个点来实现蛇身体的移动。

    class CMap{
    public:
        CMap(int t, int l, int w, int h);
        ~CMap();
    
        void mapUpdate(CSnake& s,CFood& f);
        bool mapShow();
    
    private:
        int top;
        int left;
        int width;
        int height;
        
        uchar **mat;
        uchar dir;
        uchar lastDir;
    
        CSnake *snake;
        CFood *food;
    };
    
    CMap::CMap(int t, int l, int w, int h)
    {
        top = t;
        left = l;
        width = w;
        height = h;
    
        dir = Down;
        lastDir = Down;
    
        //内存分配
        mat = new uchar*[height];
        for (int i = 0; i < height; i++)
        {
            mat[i] = new uchar[width];
        }
    
        //初始化路径矩阵边界
        for (int i = 0; i < height; i++)
        {
            mat[i][0] = '#';
            for (int j = 1; j < width - 1; j++)
            {
                if (i == 0 || i == height - 1)
                {
                    mat[i][j] = '#';
                }
                else
                {
                    mat[i][j] = ' ';
                }
            }
            mat[i][width - 1] = '#';
        }
    
        snake = new CSnake(0, 0, 50, 25);
        food = new CFood(0, 0, 50, 25);
    }
    CMap::~CMap()
    {
        for (int i = 0; i < height; i++)
        {
            delete mat[i];
        }
        delete mat;
    }
    void CMap::mapUpdate(CSnake& s, CFood& f)
    {
        mat[f.foodPoint.y][f.foodPoint.x] = 'O';
    
        for (int i = 0; i < s.snakeBody.size(); i++)
        {
            if (i == 0)
            {
                mat[s.snakeBody[i]->y][s.snakeBody[i]->x] = '@';
            }
            else
            {
                mat[s.snakeBody[i]->y][s.snakeBody[i]->x] = '*';
            }
        }
    }
    bool CMap::mapShow()
    {
        //设置顶点坐标,使得绘制一直在起点
        COORD coord;
        coord.X = top;
        coord.Y = left;
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    
        for (int i = 1; i < height - 1; i++)
        {
            memset(mat[i] + 1, ' ', width - 2);
        }
    
        //更新食物坐标和蛇坐标
        mapUpdate(*snake, *food);
    
        while (kbhit())
        {
            dir = getch();
            if (lastDir + dir == 152)//利用ascii码特性,防止蛇走反方向
            {
                dir = lastDir;
            }
        }
        //更新蛇坐标
        int res = snake->newHeadPoint(dir,food->foodPoint);
        lastDir = dir;
    
        if (res == Eat)
        {
            //产生新的食物坐标
            food->newFoodPoint();
        }
        
        //绘制所有,包括地图,蛇,食物
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                cout << mat[i][j];
            }
            cout << endl;
        }
        if (res == HitWall)
        {
            return true;
        }
        return false;
    }

    地图类。类的初始化会把mat数组给初始化了。边界为#,蛇身为*,食物为O

    mapUpdate函数用于更新mat数组。mapShow为界面显示地图。这个都比较简单。

    流程为:

    清空mat矩阵中部——更新数组——按键检测——蛇移动——绘制所有

  • 相关阅读:
    学习Mybatis中的一对多表关联
    学习Mybatis中的一对一表关联
    学习Mybatis中的动态sql
    学习Mybatis中的约定大于配置、数据库配置优化、定义别名、类型处理器、resultMap和parameterType
    第八周进度
    构建之法阅读笔记07
    正则表达式
    梦断代码之阅读笔记02
    顶会热词统计
    本周进度
  • 原文地址:https://www.cnblogs.com/wyc199288/p/6365932.html
Copyright © 2011-2022 走看看