计算机专业的小项目之贪吃蛇

本人计算机小白,从今天开始整理一些小项目,一方面对自己近几天的知识体系进行一个梳理,同时也希望能够给大家一点微薄的帮助。

贪吃蛇作为入门级小型项目编程,实现较为简单,大致实现以下几个模块

 

主要代码如下:

// 贪吃蛇.cpp : 定义控制台应用程序的入口点。
//
#include"stdafx.h"
#include<graphics.h>
#include<iostream>
#include"gotoxy.h"
#include<windows.h>
#include<conio.h>//Console Input/Output
#include<time.h>
using namespace std;
char direction_a, direction_b;            //方向a、b,用于方向的限制 
int scores, num, fool_x, fool_y, speed = 100;    //得分、num用于蛇身起步、食物x坐标、食物y坐标 
bool e;                                //结束标记 
struct node                             //蛇身结点 
{
    int x, y;
    node *next;
}*head = NULL, *p, *tail;

void init();                            //初始化开始界面 
void start();                            //游戏开始入场 
void init_snake();                        //初始化蛇身 
void delete_snake();                    //删除蛇身 
void control();                            //方向控制 
void move();                            //蛇身移动 
void limit();                            //方向限制
void panduan();                            //配合limit限制方向 
void fool();                            //食物的出现以及食物被吞
void isEnd();                            //结束判断 
void zhuangwei();                        //撞尾判断 
void zhuangqiang();                        //撞墙判断 
//void jianbian();
int main()
{
    //initgraph(640, 480);
    //jianbian();
    srand((unsigned)time(NULL));//用系统时间使产生随机数,后面可以直接调用rand()
    init();
    cin >> direction_a;
    if (direction_a != 'y' && direction_a != 'Y')
        return 0;
    do
    {
        system("cls");                    //清除屏幕 
        e = false;
        start();
        delete_snake();
        init_snake();
        scores = 0;
        num = 0;
        fool_x = (rand() % (79 - 2 + 1)) + 2;
        fool_y = (rand() % (22 - 2 + 1)) + 2;
        gotoxy(fool_x, fool_y);
        cout << "#";
        direction_a = _getch();//从控制台读取一个字符,但不显示在屏幕上
        while (direction_a != 'd' && direction_a != 's'&&direction_a != 'w') 
            direction_a = _getch();
        while (true)
        {
            if (num&&direction_a != 'd' && direction_a != 's' && direction_a != 'w' && direction_a != 'a')
            {
                direction_a = direction_b;
            }
            control();
            fool();
            Sleep(speed);
            if (_kbhit())                    //kbhit 非阻塞函数
                                           //   检查当前是否有键盘输入,若有则返回一个非0值,否则返回0。
            {
                direction_a = _getch();    //使用 getch 函数获取键盘输入 
                limit();
            }
            panduan();
            num = 1;
            zhuangqiang();
            zhuangwei();
            if (e) 
                break;
        }
    } 
    while (direction_a == 'y' || direction_a == 'Y');
    return 0;
}
//void jianbian() {
    //initgraph(1080, 960);
    //while (!_kbhit()) {
        //for (int i = 0;i < 300;i++) {
            //Sleep(20);
            //circle(300, 300, i);
            //line(10, 10, i, i);
            //line(400, 400, 2 * i, 3 * i);
            //_getch();
            //closegraph();
        //}
    //}
//}
/*******************************************************
**********************************
**************************/
void init()//初始化界面
{
    gotoxy(35, 8);
    cout << "★贪  吃  蛇★";
    gotoxy(36, 10);
    cout << "开始请输入y:";
}

/**************
****************************************
*****************************************************
****************************/
void start()
{
    for (int i = 0;i <= 79;i++)
    {
        Sleep(10);
        cout << "*";
        gotoxy(i + 1, 24);//调用头文件定义函数
        cout << "*";
        gotoxy(i + 1, 1);//顶部位置
    }
    gotoxy(1, 2);
    for (int i = 0;i <= 32;i++)//24
    {
        Sleep(20);
        cout << "*";
        for (int j = 0;j <= 77;j++)    //存在问题,中间残存一列未消除
            cout << " ";
        cout << " ";
    }
}
/*********************
******************************************************************

*********************************/
void init_snake()//初始化贪吃蛇
{
    int n = 2;//初始节数
    head = new node;
    tail = head;
    head->x = 20;//产生位置
    head->y = 10;
    while (n--)
    {
        p = new node;
        tail->next = p;//初始化蛇身,y不变,横向产生蛇身
        p->x = tail->x - 1;//用到链表知识。
        p->y = tail->y;
        tail = p;
    }
/****************************************************
**********************************************
****用符号可视化蛇******************************/

    tail->next = NULL;//尾部置空。
    node *q = head->next;
    gotoxy(head->x, head->y);
    cout << '#'; //头
    while (q != NULL)//身子
    {
        gotoxy(q->x, q->y);
        cout << '*';
        q = q->next;
    }
}


/*********************************************************
***********************************************
***********************************/
void delete_snake() //???
{
    while (head != NULL)//从头删除
    {
        node *q = head;
        head = q->next;
        delete q;
    }
}


/********************************************
**************************************
*************************************************************
**********************/
void move()
{
    gotoxy(tail->x, tail->y);//尾部擦除
    cout << " ";
    gotoxy(head->next->x, head->next->y);
    cout << '*';
    gotoxy(head->x, head->y);
    cout << '#';
    node *q = tail;
    tail = head;
    while (tail->next != q)
    {
        tail = tail->next;
    }
    tail->next = NULL;
    delete q;//与下面结合理解
}

/******************************
*****************
*****************************
***************/
void control()
{
    node *q = new node;//q为蛇头接下来运动到的点
    q->next = head;
    q->x = head->x;
    q->y = head->y;
    head = q;
    switch (direction_a)//原点位置为左上角
    {
    case 'w':    head->y--;break; //上减下加,左减右加
    case 's':    head->y++;break;
    case 'a':    head->x--;break;
    case 'd':    head->x++;break;
    default:    break;
    }
    move();
}

/***************************
***保持目前前进方向,执行相反方向是,不执行***
**防止出现逆序死亡bug***/

void limit()
{

    if (direction_b == 's' &&  direction_a == 'w') direction_a = 's';
    if (direction_b == 'w' &&  direction_a == 's') direction_a = 'w';
    if (direction_b == 'a' &&  direction_a == 'd') direction_a = 'a';
    if (direction_b == 'd' &&  direction_a == 'a') direction_a = 'd';
}


void panduan()
{
    if (direction_a == 's') direction_b = 's';
    if (direction_a == 'w') direction_b = 'w';
    if (direction_a == 'd') direction_b = 'd';
    if (direction_a == 'a') direction_b = 'a';
}

void fool()
{
    node *q;
    if (head->x == fool_x  &&  head->y == fool_y)
    {
        fool_x = (rand() % (79 - 2 + 1)) + 2;//%width
        fool_y = (rand() % (22 - 2 + 1)) + 2;//%heighth
        gotoxy(fool_x, fool_y);
        cout << "#";
        num = 0;//??
        scores++;
        node *q = new node;//得分,尾部增长
        q->x = tail->x;
        q->y = tail->y;
        tail->next = q;
        tail = q;
        tail->next = NULL;
    }

    /**********************************
    *******************?????***/
    q = head;
    while (q != NULL)
    {
        if ((q->x == fool_x)&&(q->y == fool_y))//&
        {
            fool_x = (rand() % (79 - 2 + 1)) + 2;
            fool_y = (rand() % (22 - 2 + 1)) + 2;
            gotoxy(fool_x, fool_y);
            cout << "*";
            q = head;
            continue;
        }
        q = q->next;
    }
}

/********************************************
****************************
******************/
void isEnd()
{
    e = true;
    Sleep(600);
    system("cls");
    gotoxy(35, 8);
    cout << "您 输 啦 ~";
    gotoxy(33, 10);
    cout << "您的分数为: " << scores;
    gotoxy(31, 12);
    cout << "重新开始请输入y:";
    cin >> direction_a;
}

/*********************************
****************实际判断链表的头部是否和链表的子部分坐标相等*/

void zhuangwei()//撞到身子
{
    node *q = head->next;
    while (q != NULL)
    {
        if (head->x == q->x  &&  head->y == q->y)
        {
            isEnd();
            break;
        }
        q = q->next;
    }
}


/***************************************
*********************判断链表头是否越界*/

void zhuangqiang()  //撞到墙
{
    if (head->x == 80 || head->x == 1 || head->y == 24 || head->y == 1)//
        isEnd();

}

添加头文件gotoxy.h

#include<windows.h>
void gotoxy(int x, int y)
{
    COORD pos;
    pos.X = x - 1;
    pos.Y = y - 1;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);//主要功能是在屏幕上出现字符

}

ps:还存在一些bug,希望大神勿喷

猜你喜欢

转载自blog.csdn.net/Li060703/article/details/88773908