鱼C论坛

 找回密码
 立即注册
查看: 4400|回复: 95

[技术交流] 贪吃蛇

[复制链接]
发表于 2018-8-1 11:53:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
花了两天时间写了一个贪吃蛇,虽然这个游戏已经被写烂了,但还是自己动手写了一下,遇到了不少困难,但是最终也解决了。可能并不是很完善,但是已经可以玩了。



#include <iostream>
#include <graphics.h>
#include <conio.h>
#include <time.h>

using namespace std;

//定义方向
#define UP 'W'
#define DOWN 'S'
#define LEFT 'A'
#define RIGHT 'D'

//定义最小正方形的长度,以及图形界面的长宽,以及长宽的单位
const int minLength = 12;
const int length = 480;
const int width = 480;
const int numberOfx = 40;
const int numberOfy = 40;

class backGround
{
public:
        void setGround();
};

void backGround::setGround()
{
        int x = 0;
        int y = 1;
        setbkcolor(GREEN);
        cleardevice();
        setfillcolor(BLACK);
        for(  ; x < numberOfx ; x++ )
        {
                solidrectangle(minLength * x, 0, minLength * (x + 1), minLength);
        }
       
        x = 0;
        for(  ; x < numberOfx ; x++ )
        {
                solidrectangle(minLength * x, minLength * (numberOfy - 1), minLength * (x + 1), minLength * numberOfy);
        }
       
        for(  ; y < numberOfy - 1 ; y++ )
        {
                solidrectangle(0 ,minLength * y, minLength, minLength * (y + 1));
        }
       
        y = 1;
        for(  ; y < numberOfy - 1 ; y++ )
        {
                solidrectangle(minLength * (numberOfx - 1), minLength * y, minLength * numberOfx, minLength * (y + 1));
        }

        LOGFONT font;
        gettextstyle(&font);
        font.lfHeight = 30;
        _tcscpy(font.lfFaceName, _T("黑体"));
        font.lfQuality = ANTIALIASED_QUALITY;
        settextcolor(RED);
        settextstyle(&font);
        outtextxy(520, 120, "游戏信息");
        font.lfHeight = 20;
        settextstyle(&font);
        outtextxy(520, 170, "名称:贪吃蛇");
        outtextxy(520, 200, "长度:");
        outtextxy(520, 230, "分数:");

        setlinecolor(RED);
        rectangle(480, 0, 680, 480);
        rectangle(481, 1, 679, 479);
        rectangle(482, 2, 678, 478);
        rectangle(483, 3, 677, 477);
        rectangle(484, 4, 676, 476);
       
}

class Food
{
public:
        //定义食物物的位置
        int xpoSition;
        int ypoSition;
       
        void productFood();   //产生食物的函数
        void productFoods();
};

void Food::productFood()
{
        time_t t = time(NULL);
        srand(t);
       
        xpoSition = rand() % (numberOfx - 2) + 1;
        ypoSition = rand() % (numberOfy - 2) + 1;
        setfillcolor(WHITE);
        fillrectangle(xpoSition * minLength, ypoSition * minLength, (xpoSition + 1) * minLength, (ypoSition + 1) *minLength);
       
}

void Food::productFoods()
{
        xpoSition = rand() % (numberOfx - 2) + 1;
        ypoSition = rand() % (numberOfy - 2) + 1;
}

class bodyOfSnake
{
public:
        char direction;
        char lastdirection;
       
        int xposition;
        int yposition;
        class bodyOfSnake *next;
       
        bodyOfSnake()
        {}
       
        void start();   //初始化的构造
        void uMove();
        void dMove();
        void lMove();
        void rMove();
        void Move(char Direc);
};

void bodyOfSnake::start()
{
        setfillcolor(WHITE);
        fillrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
}

void bodyOfSnake::uMove()
{
        clearrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
        yposition -= 1;
        setfillcolor(WHITE);
        fillrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
       
}

void bodyOfSnake::dMove()
{
        clearrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
        yposition += 1;
        setfillcolor(WHITE);
        fillrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
       
}

void bodyOfSnake::lMove()
{
        clearrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
        xposition -= 1;
        setfillcolor(WHITE);
        fillrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
       
}

void bodyOfSnake::rMove()
{
        clearrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
        xposition += 1;
        setfillcolor(WHITE);
        fillrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
       
}

void bodyOfSnake::Move(char Direc)
{
        switch(Direc)
        {
        case UP:uMove();break;
        case DOWN:dMove();break;
        case LEFT:lMove();break;
        case RIGHT:rMove();break;
        }
        cout<<direction<<endl;
}

class headOfSnake
{
public:
        char direction;   //蛇的运动方向
        char lastdirection;
       
        //蛇头的位置坐标
        int xposition;
        int yposition;
       
        headOfSnake()
        {}
        void start();   //初始化函数
        void uMove();   //移动函数
        void dMove();
        void lMove();
        void rMove();
        void Move(char Direc);
       
};

void headOfSnake::start()
{
        time_t t = time(NULL);
        srand(t + 10);
        xposition = rand() % (numberOfx - 2) + 1;
        yposition = rand() % (numberOfy - 2) + 1;
       
        setfillcolor(RED);
        fillrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
}

void headOfSnake::uMove()
{
        Sleep(200);
        clearrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
        yposition -= 1;
        setfillcolor(RED);
        fillrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
       
}

void headOfSnake::dMove()
{
        Sleep(200);
        clearrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
        yposition += 1;
        setfillcolor(RED);
        fillrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
       
}

void headOfSnake::lMove()
{
        Sleep(200);
        clearrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
        xposition -= 1;
        setfillcolor(RED);
        fillrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
       
}

void headOfSnake::rMove()
{
        Sleep(200);
        clearrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
        xposition += 1;
        setfillcolor(RED);
        fillrectangle(xposition * minLength, yposition * minLength, (xposition + 1) * minLength, (yposition + 1) * minLength);
       
}

void headOfSnake::Move(char Direc)
{
        switch(Direc)
        {
        case UP:uMove();break;
        case DOWN:dMove();break;
        case LEFT:lMove();break;
        case RIGHT:rMove();break;
        }
}

class Snake
{
public:
        int length;
        int score;
        headOfSnake head;
        bodyOfSnake *body;
       
        Snake()
        {
                length = 1;
                score = 0;
                body = NULL;
        }
        ~Snake()
        {
                if(body)
                       
                {
                        bodyOfSnake *temp;
                        temp = body;
                        bodyOfSnake *temps;
                        while(temp)
                        {
                                temps = temp;
                                temp = temp->next;
                                delete temps;
                        }
                }
               
        }
       
       
        int iseat(Food food);   //判断是否吃到失物
        void eating(bodyOfSnake **body);   //吃到食物后的处理工作
        int foodjudge(int x, int y);
        int gameover();   //游戏结束的监测
        //显示长度和分数
        void showscore();
       
};

int Snake::iseat(Food food)
{
        if(head.xposition == food.xpoSition && head.yposition == food.ypoSition)
                return 1;
        return 0;
}

void Snake::eating(bodyOfSnake **body)
{
        if(length == 1)
        {
                (*body) = new bodyOfSnake;
                switch(head.direction)
                {
                case UP:
                        {
                                (*body)->xposition = head.xposition;
                                (*body)->yposition = head.yposition + 1;
                                (*body)->next = NULL;
                                (*body)->start();
                        };break;
                case DOWN:
                        {
                                (*body)->xposition = head.xposition;
                                (*body)->yposition = head.yposition - 1;
                                (*body)->start();
                                (*body)->next = NULL;
                        };break;
                case LEFT:
                        {
                                (*body)->xposition = head.xposition + 1;
                                (*body)->yposition = head.yposition;
                                (*body)->next = NULL;
                                (*body)->start();
                        };break;
                case RIGHT:
                        {
                                (*body)->xposition = head.xposition - 1;
                                (*body)->yposition = head.yposition;
                                (*body)->next = NULL;
                                (*body)->start();
                        };break;
                }
        }
        else
        {
                bodyOfSnake *temp;
                temp = (*body);
                while(temp->next)
                {
                        temp = temp->next;
                }
                bodyOfSnake *temps = new bodyOfSnake;
               
                //temp指向最后一节身体
                switch(temp->direction)
                {
                case UP:
                        {
                                temps->xposition = temp->xposition;
                                temps->yposition = temp->yposition + 1;
                                temps->next = NULL;
                                temps->start();
                        };break;
                case DOWN:
                        {
                                temps->xposition = temp->xposition;
                                temps->yposition = temp->yposition - 1;
                                temps->next = NULL;
                                temps->start();
                        };break;
                case LEFT:
                        {
                                temps->xposition = temp->xposition + 1;
                                temps->yposition = temp->yposition;
                                temps->next = NULL;
                                temps->start();
                        };break;
                case RIGHT:
                        {
                                temps->xposition = temp->xposition - 1;
                                temps->yposition = temp->yposition;
                                temps->next = NULL;
                                temps->start();
                        };break;
                }
               
                temp->next = temps;
        }

        length++;
        score +=10;
       
}

void Snake::showscore()
{
        LOGFONT font;
        gettextstyle(&font);
        font.lfHeight = 30;
        _tcscpy(font.lfFaceName, _T("黑体"));
        font.lfQuality = ANTIALIASED_QUALITY;
        settextcolor(RED);
        font.lfHeight = 20;
        settextstyle(&font);
        char s1[5];
        sprintf(s1, "%d", length);
        char s2[10];
        sprintf(s2, "%d", score);
        outtextxy(620, 200, s1);
        outtextxy(620, 230, s2);

}

int Snake::gameover()
{
        //因为有身体时才会咬到自己
        bodyOfSnake *temp = body;
        while(temp != NULL)
        {
                if(head.xposition == temp->xposition && head.yposition == temp->yposition)
                {
                        setfillcolor(RED);
                        fillrectangle(head.xposition * minLength, head.yposition * minLength, (head.xposition + 1) * minLength, (head.yposition + 1) * minLength);
                        return 0;
                }
                temp = temp->next;
        }
       
        if(head.xposition == 0 || head.xposition == numberOfx - 1 || head.yposition == 0 || head.yposition == numberOfy - 1)
                return 0;
        return 1;
       
       
}

int Snake::foodjudge(int x, int y)
{
        if(body)
        {
                bodyOfSnake *temp = body;
                while(temp)
                {
                        if(temp->xposition == x && temp->yposition == y)
                                return 0;
                        temp = temp->next;
                }
        }
        if(head.xposition == x && head.yposition == y)
                return 0;
        return 1;
}

int main()
{
        system("color 3F");
        initgraph(length + 200, width);
       
        //背景初始化
        backGround Back;
        Back.setGround();
       
        //食物初始化
        Food food;
        food.productFood();
       
        //贪吃蛇初始化
        Snake snake;
        snake.head.start();
        snake.showscore();
       
       
       
        int flag = 1;
        char direction = getch();
        char tempdirection;
        snake.head.direction = snake.head.lastdirection = direction;
        bodyOfSnake *temp;
        while(flag)
        {
                if(snake.iseat(food))
                {
                        snake.eating(&snake.body);
                        food.productFood();
                        while(!snake.foodjudge(food.xpoSition, food.ypoSition))
                        {
                                food.productFoods();
                        }
                        snake.showscore();
                }
                temp = snake.body;
                snake.head.Move(snake.head.direction);
                tempdirection = snake.head.lastdirection;
                snake.head.lastdirection = snake.head.direction;
                while(temp != NULL)
                {
                        temp->direction = tempdirection;
                        temp->Move(temp->direction);
                        tempdirection = temp->lastdirection;
                        temp->lastdirection = temp->direction;
                        temp = temp->next;
                }
                if(!snake.gameover())
                {
                        LOGFONT font;
                        gettextstyle(&font);
                        font.lfHeight = 30;
                        _tcscpy(font.lfFaceName, _T("黑体"));
                        font.lfQuality = ANTIALIASED_QUALITY;
                        settextcolor(RED);
                        settextstyle(&font);
                        outtextxy(520, 280, "游戏结束");
                        flag = 0;
                }
               
                if(_kbhit())
                {
                        direction = getch();
                        if(direction == 'Q')
                                flag = 0;
                        switch(direction)
                        {
                        case UP:
                                {
                                        if(snake.head.lastdirection != DOWN)
                                                snake.head.direction = direction;
                                };break;
                        case DOWN:
                                {
                                        if(snake.head.lastdirection != UP)
                                                snake.head.direction = direction;
                                };break;
                        case LEFT:
                                {
                                        if(snake.head.lastdirection != RIGHT)
                                                snake.head.direction = direction;
                                };break;
                        case RIGHT:
                                {
                                        if(snake.head.lastdirection != LEFT)
                                                snake.head.direction = direction;
                                };break;
                        }
                }
        }
       
        getch();
        closegraph();

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-8-1 13:08:21 | 显示全部楼层
学习到爆炸
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-1 16:17:06 | 显示全部楼层
学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-2 14:15:17 From FishC Mobile | 显示全部楼层
学习一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-2 14:56:48 | 显示全部楼层
回复看帖
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-2 19:52:15 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-8-2 20:14:04 | 显示全部楼层
看一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-3 00:19:22 | 显示全部楼层
加油
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-8-6 15:18:58 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-8-6 15:47:38 | 显示全部楼层
^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-8-6 20:34:34 | 显示全部楼层
学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-7 20:10:31 | 显示全部楼层
牛逼!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-8-7 21:06:38 | 显示全部楼层
1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-8-7 21:42:00 | 显示全部楼层

学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-7 21:46:44 | 显示全部楼层

学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-7 23:39:57 | 显示全部楼层
学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-8 08:46:34 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-8-8 12:40:03 | 显示全部楼层
学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-8-8 13:22:46 | 显示全部楼层
学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-9 09:04:47 | 显示全部楼层
啦啦啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-30 09:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表