目录

前言

飞翔小鸟的代码

实现代码

1、下落的小鸟

2、打印障碍物

3、移动障碍物

4、判断是否相撞

5、障碍物的循环出现

总结


前言

代码参考了《C语言课程设计与游戏开发实践教程》

小游戏介绍:

        玩家通过空格键来控制正在下落的小鸟 ' @ ' 飞起来,并躲过障碍物 ' * '。

飞翔小鸟的代码

        首先我们来看整个的代码:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <Windows.h>

// 全局变量
int high, width;                   // 游戏画面大小
int bird_x, bird_y;                // 小鸟的坐标
int bar1_y, bar1_xDown, bar1_xTop; // 障碍物1的相关坐标
int score;                         // 得分,经过障碍物的个数

void gotoxy(int x, int y) // 光标移动到(x,y)位置
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(handle, pos);
}

void startup() // 数据初始化
{
    high = 20;
    width = 20;
    bird_x = high / 2;
    bird_y = 3;
    bar1_y = width;
    bar1_xDown = high / 3;
    bar1_xTop = high / 2;
    score = 0;
}

void show() // 显示画面
{
    gotoxy(0, 0); // 光标移动到原点位置,以下重画清屏
    int i, j;

    for (i = 0; i < high; i++)
    {
        for (j = 0; j < width; j++)
        {
            if ((i == bird_x) && (j == bird_y))
                printf("@"); //   输出小鸟
            else if ((j == bar1_y) && ((i < bar1_xDown) || (i > bar1_xTop)))
                printf("*"); //   输出墙壁
            else
                printf(" "); //   输出空格
        }
        printf("\n");
    }
    printf("得分:%d\n", score);
}

void updateWithoutInput() // 与用户输入无关的更新
{
    bird_x++;
    bar1_y--;
    if (bird_y == bar1_y)
    {
        if ((bird_x >= bar1_xDown) && (bird_x <= bar1_xTop))
            score++;
        else
        {
            printf("游戏失败\n");
            system("pause");
            exit(0);
        }
    }
    if (bar1_y <= 0) // 再新生成一个障碍物
    {
        bar1_y = width;
        int temp = rand() % (int)(high * 0.8);
        bar1_xDown = temp - high / 10;
        bar1_xTop = temp + high / 10;
    }

    Sleep(150);
}

void updateWithInput() // 与用户输入有关的更新
{
    char input;
    if (kbhit()) // 判断是否有输入
    {
        input = getch(); // 根据用户的不同输入来移动,不必输入回车
        if (input == ' ')
            bird_x = bird_x - 2;
    }
}

int main()
{
    startup(); // 数据初始化
    while (1)  //  游戏循环执行
    {
        show();               // 显示画面
        updateWithoutInput(); // 与用户输入无关的更新
        updateWithInput();    // 与用户输入有关的更新
    }
    return 0;
}

接下来再来对代码进行一一解析

实现代码

1、下落的小鸟

        首先我们来实现一个移动光标到指定位置的函数

void gotoxy(int x, int y) // 光标移动到(x,y)位置
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(handle, pos);
}

GetStdHandle函数:具体请看这里

SetConsoleCursorPosition:具体请看这里

        接下来我们就开始打印小鸟 ' @ ' ,这里我将打印小鸟放在了显示所有画面的函数中

void show() // 显示画面
{
    gotoxy(0, 0); // 光标移动到原点位置,以下重画清屏
    int i, j;

    for (i = 0; i < high; i++)
    {
        for (j = 0; j < width; j++)
        {
            if ((i == bird_x) && (j == bird_y))
                printf("@"); //   输出小鸟
            else if ((j == bar1_y) && ((i < bar1_xDown) || (i > bar1_xTop)))
                printf("*"); //   输出墙壁
            else
                printf(" "); //   输出空格
        }
        printf("\n");
    }
    printf("得分:%d\n", score);
}

        实现小鸟的打印后我们就要开始让小鸟实现下落了,这里只需要让小鸟的横坐标增加就可以了。纵坐标就不要动了,让障碍物的移动来让小鸟看起来是在移动,而障碍物没有移动。

2、打印障碍物

        同上面的打印下落的小鸟,这里我们先实现静止的障碍物(也就是墙壁 ' * '),障碍物的移动和小鸟的移动我们统一放在同一个函数里面。

void show() // 显示画面
{
    gotoxy(0, 0); // 光标移动到原点位置,以下重画清屏
    int i, j;

    for (i = 0; i < high; i++)
    {
        for (j = 0; j < width; j++)
        {
            if ((i == bird_x) && (j == bird_y))
                printf("@"); //   输出小鸟
            else if ((j == bar1_y) && ((i < bar1_xDown) || (i > bar1_xTop)))
                printf("*"); //   输出墙壁
            else
                printf(" "); //   输出空格
        }
        printf("\n");
    }
    printf("得分:%d\n", score);
}

3、移动障碍物

        当我们打印障碍物后就来实现障碍物的移动。和之前我们移动小鸟一样,让障碍物的横坐标减小就可以了。这个时候会发现小鸟和障碍物的移动速度太快了,处理这个问题,我们就要使用一个函数( Sleep() )来实现这个功能。

Sleep() 函数:具体请看这里

4、判断是否相撞

        我们已经将小鸟和障碍物都打印出来了,接下来我们就要来实现判断小鸟和障碍物是否相撞(判断小鸟的坐标和障碍物的坐标有没有重合,没有重合就表明两者没有相撞,重合就表明两者想相撞了)。

void updateWithoutInput() // 与用户输入无关的更新
{
    bird_x++;
    bar1_y--;
    if (bird_y == bar1_y)
    {
        if ((bird_x >= bar1_xDown) && (bird_x <= bar1_xTop))
            score++;
        else
        {
            printf("游戏失败\n");
            system("pause");
            exit(0);
        }
    }
    if (bar1_y <= 0) // 再新生成一个障碍物
    {
        bar1_y = width;
        int temp = rand() % (int)(high * 0.8);
        bar1_xDown = temp - high / 10;
        bar1_xTop = temp + high / 10;
    }

    Sleep(150);
}

相撞了就结束游戏,没有就继续生成障碍物,同时分数加一(分数可以增加别的分数)。

5、障碍物的循环出现

        没有相撞就重新生成障碍物,这里用随机数来生成。

if (bar1_y <= 0) // 再新生成一个障碍物
    {
        bar1_y = width;
        int temp = rand() % (int)(high * 0.8);
        bar1_xDown = temp - high / 10;
        bar1_xTop = temp + high / 10;
    }

写到这里就已经结束了,下次再见。

总结

飞翔的小鸟主要就是通过移动光标来打印符号、符号位置的变化以及判断符号之间的位置是否重合。