C语言控制台贪吃蛇3

蛇动起来及随方向移动

一、🐍蛇直线动

  1、逻辑:从尾巴向头,每个节点完全复制前一个节点,蛇头单独处理

    (1)蛇方向的枚举变量中对方向进行赋值:

//蛇方向
enum {to_east = 2, to_west = -2, to_south = 1, to_north = -1};

    (2)在蛇移动函数中进行从蛇尾向蛇头遍历,并初始化蛇移动方向为向西:

#define DEF_SNAKE_LONG 20

int g_nSnakeDir = to_west;//自动向西移动

int i = DEF_SNAKE_LONG - 1;
//从后向前遍历
for(; i >= 1; i--)
{
    //过滤掉非法蛇身
    if(0 == g_arrSnake[i][1])
    {
        continue;
    }
    //把前面一个节点的值赋给前一个节点
    g_arrSnake[i][0] = g_arrSnake[i-1][0];
    g_arrSnake[i][1] = g_arrSnake[i-1][1];
    g_arrSnake[i][2] = g_arrSnake[i-1][2];
}

g_arrSnake[0][2] = g_nSnakeDir;

    (3)处理蛇头:

//处理蛇头
if(to_west == g_arrSnake[0][2] || to_east == g_arrSnake[0][2])
{
    g_arrSnake[0][1] += g_arrSnake[0][2];
}
else
{
    g_arrSnake[0][0] += g_arrSnake[0][2];
}

    (4)之后要重新画出蛇身,调用DrawSnake函数

  

  2、销毁残留蛇身

//遍历每行,遇到初始蛇的位置拷贝方块空格
for(; g_arrSnake[i][0] != 0; i++)
{
    strncpy(&g_strgameback[g_arrSnake[i][0]][g_arrSnake[i][1]], "  ", 2);
}

 

二、加入方向键,让蛇随方向键动起来

  1、定义函数void SnakeDir()//改变蛇的方向,用到异步检测按键(同步和异步的区别):GetAsyncKeyState()

代码如下:

if(GetAsyncKeyState('W'))
{
    g_nSnakeDir = to_north;
}
else if(GetAsyncKeyState('S'))
{
    g_nSnakeDir = to_south;
}
else if(GetAsyncKeyState('A'))
{
    g_nSnakeDir = to_west;
}
if(GetAsyncKeyState('D'))
{
    g_nSnakeDir = to_east;
}

 

 

全部代码(此时并未进行蛇的死亡判断,当蛇移动到边界时不会死亡并会出现BUG):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#include <time.h>

typedef int bool;
#define true 1
#define false 0

//三件套:添加音乐的函数
#include <Windows.h>
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")

#define DEF_SNAKE_LONG 20

//定义边框数组
char g_strgameback[20][48] = { 
    "■■■■■■■■■■■■■■■■■■■■■■■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■                                          ■\n",
    "■■■■■■■■■■■■■■■■■■■■■■■\n"};

//定义蛇数组
int g_arrSnake[DEF_SNAKE_LONG][3] = {0};

//蛇方向
enum {to_east = 2, to_west = -2, to_south = 1, to_north = -1};

int g_nSnakeDir = to_west;

void Cover();//显示首页
void BGM();//播放音乐
void ButtonTest();//显示首页
void ShowBack();//打印游戏边框
void SetSnakeRandPos();//为蛇产生随机位置
void DrawSnake();//将蛇显示到背景上
void Snakemove();//蛇动起来
void Clean();//销毁残留蛇身
void SnakeDir();//改变蛇的方向

int main()
{
    BGM();//播放音乐
    Cover();//显示首页
    ButtonTest();//检测按键
    PlaySound(NULL, 0, 0);//停止播放
    system("cls");//清屏

    SetSnakeRandPos();//为蛇产生随机位置
    ShowBack();

    while(1)
    {
        system("cls");
        SnakeDir();//改变蛇的方向
        
        Snakemove();//蛇动
        ShowBack();//显示背景

        Sleep(500);
    }

    system("pause");
    return 0;
}

//显示首页
void Cover()
{
    printf("\n\n\n\t\t\t       <<SNAKE>>\n\n");
    printf("\n\n\n\t\t\t<<W,S,A,D control move>>\n\n");
    printf("\n\n\n\t\t\t    <<space begin>>\n\n\n\n");
}

//播放音乐
void BGM()
{
    PlaySound("C:\\Windows\\Media\\Alarm03.wav" , NULL, SND_FILENAME | SND_ASYNC);
    //以C盘系统文件中.wav文件为例
}

//检测按键
void ButtonTest()
{
    char chinput;

    //检测空格
    while(1)
    {
        chinput = _getch();
        if(' ' == chinput)
        {
            break;
        }
    }
}

//打印游戏边框
void ShowBack()
{
    int i = 0;

    for(; i < 20; i++)
    {
        printf(g_strgameback[i]);
    }
}

//为蛇产生随机位置
void SetSnakeRandPos()
{
    int nX = -1;
    int nY = -1;

    //产生随机数
    srand((unsigned int)time(NULL));//中种子
    nX = rand()%19 + 1;//对19取余得0~18,+1得0~19
    nY = rand()%18 + 1;

    //初始化的三个节点
    g_arrSnake[0][0] = nY;        //
    g_arrSnake[0][1] = nY*2;    //
    g_arrSnake[0][2] = to_west;    //方向

    g_arrSnake[1][0] = nY;        
    g_arrSnake[1][1] = nY*2 + 2;    
    g_arrSnake[1][2] = to_west;    

    g_arrSnake[2][0] = nY;        
    g_arrSnake[2][1] = nY*2 + 4;    
    g_arrSnake[2][2] = to_west;    

    //将蛇显示到背景上
    DrawSnake();
}

//将蛇显示到背景上
void DrawSnake()
{
    int i = 0;
    for(; g_arrSnake[i][0] != 0; i++)//遍历每行,遇到初始蛇的位置拷贝方块
    {
        strncpy(&g_strgameback[g_arrSnake[i][0]][g_arrSnake[i][1]], "", 2);
    }
}

//蛇动起来
void Snakemove()
{
    int i = DEF_SNAKE_LONG - 1;

    Clean();//销毁残留蛇身

    //从后向前遍历
    for(; i >= 1; i--)
    {
        //过滤掉非法蛇身
        if(0 == g_arrSnake[i][1])
        {
            continue;
        }
        //把前面一个节点的值赋给前一个节点
        g_arrSnake[i][0] = g_arrSnake[i-1][0];
        g_arrSnake[i][1] = g_arrSnake[i-1][1];
        g_arrSnake[i][2] = g_arrSnake[i-1][2];
    }

    g_arrSnake[0][2] = g_nSnakeDir;

    //处理蛇头
    if(to_west == g_arrSnake[0][2] || to_east == g_arrSnake[0][2])
    {
        g_arrSnake[0][1] += g_arrSnake[0][2];
    }
    else
    {
        g_arrSnake[0][0] += g_arrSnake[0][2];
    }

    //画蛇
    DrawSnake();
}

//销毁残留蛇身
void Clean()
{
    //同画蛇的代码,只不过拷贝上的是空格
    int i = 0;
    for(; g_arrSnake[i][0] != 0; i++)//遍历每行,遇到初始蛇的位置拷贝方块空格
    {
        strncpy(&g_strgameback[g_arrSnake[i][0]][g_arrSnake[i][1]], "  ", 2);
    }
}

//改变蛇的方向
void SnakeDir()
{
    if(GetAsyncKeyState('W'))
    {
        g_nSnakeDir = to_north;
    }
    else if(GetAsyncKeyState('S'))
    {
        g_nSnakeDir = to_south;
    }
    else if(GetAsyncKeyState('A'))
    {
        g_nSnakeDir = to_west;
    }
    if(GetAsyncKeyState('D'))
    {
        g_nSnakeDir = to_east;
    }
}

 

posted @ 2017-10-25 22:44  第二根杈  阅读(286)  评论(0编辑  收藏  举报