IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言——函数的综合运用。自定义函数,gotoxy清屏函数与HideCursor隐藏光标,防闪屏,共同制作打飞机游戏。 -> 正文阅读

[C++知识库]C语言——函数的综合运用。自定义函数,gotoxy清屏函数与HideCursor隐藏光标,防闪屏,共同制作打飞机游戏。

目录

制作准备

1.所需头函数

2.自定义函数

3.设置全局变量

4.清屏函数

5.画面布置

6.成果


制作准备

1.所需头函数

#include<stdio.h>

#include<stdlib.h>

#include<conio.h>

#include<windows.h>

2.自定义函数

①在变量中,我们必须进行定义赋值初始化后,才能在程序中使用,所以需要一个“地方”,整理好这些变量,在程序中整洁一些

void startup()          //数据初始化

?②打出画面中所显示的所需代码,也给一个函数

void show()            //显示画面

③在游戏运行中,飞机的移动,发射等操作必须使用键盘,此时就要进行输入判断,给出相应的函数,实行不同的命令 ,其中分为两种,一种是程序运行时对输入做出变化,另一种是不变化

void updateWithoutInput()       //与用户输入无关的更新
void updateWithInput()          //与用户有关的更新

最后,必不可少的主函数,把它们全部包起来

int main()
{
    startup();
    while(1)
    {
        show();
        updateWithoutInput();
        updateWithInput();
        HideCursor();      
    }
    return 0;
}

3.设置全局变量

首先我们先理解控制台的xy轴方位,这与我们平时所学的数学正方向坐标轴不同,命令提示符窗口

竖方向为X轴,横方向为Y轴。

其中向下为X轴正方向,向右为Y轴正方向

?知道这一点后我们便开始考虑所需要的变量

  1. 窗口大小(高度宽度)
  2. 飞机位置
  3. 子弹位置
  4. 敌机位置
  5. 分数统计

大概有以上几种基本内容,所以我们进行定义

int position_x,position_y;   //飞机位置
int high,width;           //游戏画面尺寸
int bullet_x,bullet_y;    //子弹位置
int enemy_x,enemy_y;      //敌机位置
int score;                //分数

定义后,便在startup()函数中进行初始化

void startup()          //数据初始化
{
    high = 20;
    width = 30;

    position_x = high/2;       //飞机
    position_y = width/2;      

    bullet_x = -2;             //子弹
    bullet_y = position_y;

    enemy_x = 0;               //敌机
    enemy_y = position_y;

    score = 0;                 //分数
}

4.清屏函数

第一种是使用清屏函数system("cls");实现屏幕的刷新

(需要配上#include<stdlib.h>使用)

优点:无需太多代码,简单易懂

缺点:屏幕闪烁严重,影响视觉

第二种使用gotoxy()函数。

void gotoxy(int x,int y)    //将光标移动到(x,y)位置
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);    //获取标准输出设备句柄
    COORD pos={x,y};      //坐标位置
    SetConsoleCursorPosition(handle,pos);   //设置控制台光标位置
}

void HideCursor()
{
    CONSOLE_CURSOR_INFO cursor_info={1,0};  //0表示隐藏光标
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}

优点:屏幕无闪动,轨迹清晰

缺点:仍有光标不停移动(由于过于高级,所以不需要特意背诵,需要时调用出来就好)

此时可上面的HideCursor()进行光标的隐藏


5.画面布置

一个游戏,总得有点画面出现吧,总不能是一块黑布,啥也没有,所以呢,我们得把飞机,敌机,计数得分,子弹等等都printf()出来

这里呢,则是使用的for和else-if的嵌套使用?????????????????放到了我们之前预备好的自定义show函数里

void show()            //显示画面
{
    gotoxy(0,0);       //光标移动到原点位置,以下重画清屏
    int i,j;
    for(i=0;i<high;i++)
    {
        for(j=0;j<width;j++)
        {
            if((i==position_x)&&(j==position_y))
                printf("*");    //输出飞机*
            else if((i==enemy_x)&&(j==enemy_y))
                printf("@");    //输出敌机
            else if((i==bullet_x)&&(j==bullet_y))
                printf("||");    //输出子弹
            else
                printf(" ");    //输出空格
        }
        printf("\n");
    }
    printf("得分:%d\n",score);
}

在上文说到,有两种状态,一种在输入时(即敲打键盘移动、发射)要随之更新,另一种则后台自动更新(敌机的自动移动,分数的自动统计)

很重要的一点,控制飞机的速度,我们使用了if循环,十次循环更新一次敌机位置

(其实还是快了点)

void updateWithoutInput()       //与用户输入无关的更新
{
    if(bullet_x>-1)
    bullet_x--;
    // 用来控制敌机移动速度
    // 这样修改,虽然用户按键的交互速度还是很快,
    // 但NPC移动速度降低
    static int speed = 0;
    if(speed<10)
    {
        speed++;
    }
    if(speed==10)
    {
        enemy_x++;
        speed = 0;
    }
//击中飞机时:加分
    if((bullet_x==enemy_x)&&(bullet_y==enemy_y))
    {
        score++;                  //分数加1
        enemy_x = -1;             //产生新的飞机
        enemy_y = rand()%width;
        bullet_x = -2;            //子弹无效
    }
//未击中飞机时;飞机离开
    if(enemy_x>high)              //敌机跑出显示屏幕
    {
        enemy_x = -1;             //产生新的飞机
        enemy_y = rand()%width;
    }
}

这时就要注意末尾的一个代码,需要特别重视,在我的另一篇博客的末尾有提及(一丢丢)

C语言程序入门——if-else及switch分支结构与for、do-while循环1.1.2

不废话,就是这个rand()%width,让系统自动调用一个随机数,从而在循环中达到随机位置输出敌机的作用


这是与用户输入无关的更新,那接下来就是与用户输入有关的更新了?

即游戏四键 “上上下下左右左右(BABA)”(doge保命)还有一个发射子弹(此处使用空格)

正常代码中进行下一步时,需使用回车确认,很明显,我们打游戏总不能走一步用一次回车嘛,由此我们引申出——kbhit()


kbhit是一个无阻碍函数,可以在输入时直接进入后续代码而不卡位置,实现输入即反馈

而与之相反,我们使用阻碍函数getch()实现输入WSAD后进行相应的上下左右移动

6.成果

到了最后,串起来的完整代码附在文末

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

void gotoxy(int x,int y)    //将光标移动到(x,y)位置
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);    //获取标准输出设备句柄
    COORD pos={x,y};      //坐标位置
    SetConsoleCursorPosition(handle,pos);   //设置控制台光标位置
}

void HideCursor()
{
    CONSOLE_CURSOR_INFO cursor_info={1,0};  //0表示隐藏光标
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}
//全局变量
int position_x,position_y;   //飞机位置
int high,width;           //游戏画面尺寸
int bullet_x,bullet_y;    //子弹位置
int enemy_x,enemy_y;      //敌机位置
int score;

void startup()          //数据初始化
{
    high = 20;
    width = 30;

    position_x = high/2;       //飞机
    position_y = width/2;      

    bullet_x = -2;             //子弹
    bullet_y = position_y;

    enemy_x = 0;               //敌机
    enemy_y = position_y;

    score = 0;                 //分数
}

void show()            //显示画面
{
    gotoxy(0,0);       //光标移动到原点位置,以下重画清屏
    int i,j;
    for(i=0;i<high;i++)
    {
        for(j=0;j<width;j++)
        {
            if((i==position_x)&&(j==position_y))
                printf("*");    //输出飞机*
            else if((i==enemy_x)&&(j==enemy_y))
                printf("@");    //输出敌机
            else if((i==bullet_x)&&(j==bullet_y))
                printf("||");    //输出子弹
            else
                printf(" ");    //输出空格
        }
        printf("\n");
    }
    printf("得分:%d\n",score);
}

void updateWithoutInput()       //与用户输入无关的更新
{
    if(bullet_x>-1)
    bullet_x--;
    // 用来控制敌机移动速度
    // 这样修改,虽然用户按键的交互速度还是很快,
    // 但NPC移动速度降低
    static int speed = 0;
    if(speed<10)
    {
        speed++;
    }
    if(speed==10)
    {
        enemy_x++;
        speed = 0;
    }
//击中飞机时:加分
    if((bullet_x==enemy_x)&&(bullet_y==enemy_y))
    {
        score++;                  //分数加1
        enemy_x = -1;             //产生新的飞机
        enemy_y = rand()%width;
        bullet_x = -2;            //子弹无效
    }
//未击中飞机时;飞机离开
    if(enemy_x>high)              //敌机跑出显示屏幕
    {
        enemy_x = -1;             //产生新的飞机
        enemy_y = rand()%width;
    }
}

void updateWithInput()          //与用户有关的更新
{
    char input;
    if(kbhit())      //根据用户的不同输入来移动,不必输入回车
    {
        input = getch();
        if(input=='a')
            position_y--;
        if(input=='d')
            position_y++;
        if(input=='w')
            position_x--;
        if(input=='s')
            position_x++;
        if(input==' ')
        {
            bullet_x = position_x-1;    //从飞机正上方发生子弹
            bullet_y = position_y;
        }
    }
}

int main()
{
    startup();
    while(1)
    {
        show();
        updateWithoutInput();
        updateWithInput();
        HideCursor();       //隐藏光标
    }
    return 0;
}

学艺不精,多多包涵

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-15 01:47:57  更:2022-09-15 01:50:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:27:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码