C语言课设心得之倒计时和暂停的实现

C语言课设心得之倒计时和暂停的实现,第1张

C语言课设心得之倒计时和暂停的实现

前言:

        本教程适用的C语言课设游戏类型:需要倒计时和暂停的游戏。

        本文章不会耽误任何人做生意!

        本人学艺不精,教程可能会有不严谨和错误的地方,希望大家多多批评,在评论区多多指出。需要视频教学的话,也可以联系我,我会考虑在b站出一些视频之类的,感谢!

目录

一.头文件及相关的变量

1.头文件需求

2.变量

二.倒计时的思路和代码实现

1.time_t变量写在哪里合适

2.time_t和tm结构体的代码实现

3.思路和代码实现

三.暂停的思路和实现

1.问题

2.追根溯源

3.解决办法


一.头文件及相关的变量 1.头文件需求
# include 
2.变量

        (1)time_t:时间类型的变量

        (2)tm:结构体

二.倒计时的思路和代码实现 1.time_t变量写在哪里合适

        很多同学会把用户 *** 作和交互写在一个函数里,并且在函数里面用while(1)循环保证 *** 作能被持续读取(比如我这样);也会有很多同学会把while直接写在main函数里,依靠循环读取 *** 作来实现。因此本教程根据这两种思路分别教大家在哪里写time_t变量合适。在下文我们把这类的函数叫为play函数

2.time_t和tm结构体的代码实现

        首先定义一个简单的time_t类型变量,通过下面的代码来获取本地的时间,然后通过tm结构体获取可以读取的时分秒等。

time_t time;                          // 定义一个叫time的time_t变量
time(&time);                          // 获取本地时间
struct tm time_tm;                    // 定义一个叫time_tm的tm结构体
localtime_s(&time_tm, &time);         // 将time获取的本地时间信息,通过本函数转换到time_tm结构                    
                                         体里边,以便于后续 *** 作
// 此时我们就可以通过time_tm来读取time获取的本地时间了
// 我们倒计时用到的就是 时分秒就够了
// 下面的 *** 作就是将当前时间,如:14点12分36秒,全部转换成秒
int second = time_tm.tm_hour * 3600 + time_tm.tm_min * 60 + time_tm.tm_sec;
// 等价于 14h * 3600 + 12min * 60 + 36


注意:time_t的最小单位就是“秒”

3.思路和代码实现

(1)写法一:main函数里调用play函数,把while写到play函数里

        简单的倒计时,我们首先要明确,需要两个time_t变量来实现。不妨设两个变量分别为begin和current。在进入本关的瞬间,我们只需要读取一次本地时间,存在begin里面。进入play函数的while循环之后,我们需要不断读取我们的current,即不断更新当前的时间。然后我们通过之前的转换法,把begin和current都转换为秒,然后作差,就能得到我们当前游玩的时间和游戏开始时间的差值。假如我们的倒计时是90秒,那么90-差值,就是我们的倒计时时间。我们的倒计时就做好了!剩下的绘图相信大家没问题了,这里就不写代码了

// 这只是一段示范的代码,只是为了展示核心思路,仅供参考

int main(void)
{
    initgraph();

    play();
    
    xxxx;
}

void play(传参传参.....)
{
    // current在循环内外定义都可,这里定义在了while里
    // 创建我们的start
    time_t start;
    time(&start);
    struct tm start_tm;
    localtime_s(&start_tm, &start);
    
    // 进入游戏 *** 作识别
    while(1)
    {
        // 创建我们的current
        time_t current;
        // 更新current
        time(¤t);
        // 计算倒计时
        struct tm current_tm;
        localtime_s(¤t_tm, ¤t);
        // 倒计时为90秒
        int now = 90 - (current_tm.tm_hour * 3600 + current_tm.tm_min * 60 + current_tm.tm_sec) + (start_tm.tm_hour * 3600 + start_tm.tm_min * 60 + start_tm.tm_sec);

        // 打印代码
        outtextxy(xxxxx);

        // 读取指令的代码们
        balabalabal;
    }
}

有的同学可能会问:为什么需要小时和分钟呢?读取秒不就完了?

一旦我们玩游戏的时候,跨越了分钟,时钟的秒就会变为0,我们的时间就会乱。比如我们是在1点1分1秒玩的,当我们玩到了2分0秒的时候,我们看倒计时的公式,tm_sec那一部分就会跳回0,导致倒计时的时间反而又增加了60s。同理,跨小时玩游戏的时候也有这个问题。半夜玩游戏的时候还需要加入tm_day才能解决同样的问题,但是课设的话就没这个必要了。

(2)写法二:main函数里面写while,while循环调用play函数

同样的思路,不过我们的代码就需要小小的改变了,因为对于start变量,我们只需要读取一次本地时间

// 这只是一段示范的代码,只是为了展示核心思路,仅供参考

int main(void)
{
    initgraph();
    xxxxxx;
    // 这里的指针定义最好挨着while
    time_t start;
    time_t current;
    time_t* Pcurrent;
    // 重点来了!!在进入循环之前记录我们的start本地时间
    time(&start);
    struct tm start_tm;
    localtime_s(&start_tm, &start);
    int a = (current_tm.tm_hour * 3600 + current_tm.tm_min * 60 + current_tm.tm_sec)
    while(1)
    {
    // 循环调用play函数
    play(a, Pcurrent,传参传参.....);
    xxxxxx;
    }
    xxxx;
}

void play(int a,time_t* current,传参传参.....)
{
    // 更新current
    time(current);
    // 计算倒计时
    struct tm current_tm;
    localtime_s(¤t_tm, current);
    // 倒计时为90秒
    int now = 90 - a + (start_tm.tm_hour * 3600 + start_tm.tm_min * 60 + start_tm.tm_sec);

    // 打印代码
    outtextxy(xxxxx);
    

    // 读取指令的代码们
    balabalabal;
   
}

有部分同学的游戏是多地图的,比如我的就是。我的play函数会传入一张地图的参数,只能玩一张地图,如果进入下一张,还得重新调用play,这时候我们的时间计入的策略也会有稍微的改进:

下面的代码是一个思路,大家的写代码逻辑都不一样,我只能提供一个小参考,希望能对大家有帮助。

// 假设我们的地图用一个数组存储,叫Map[10]
// main函数里面调用play的时候,可以这么写


// 这里已经定义好start 和 current了
for(int i = 0; i < 10; i++)
{
    time(&start);
    struct tm start_tm;
    localtime_s(&start_tm, &start);    
    int a = (current_tm.tm_hour * 3600 + current_tm.tm_min * 60 + current_tm.tm_sec)
    play(Map[i], a, Pcurrent);
}
三.暂停的思路和实现 1.问题

相信很多同学在写暂停的时候会出现这么一个问题:

我设置好了游戏的暂停 *** 作,进入游戏点击暂停了,倒计时也的确停止了。但是一旦恢复了游戏的游玩,发现时间直接减少了好多。这是为什么呢?

2.追根溯源

如果我们从暂停的一瞬间开始计时,然后恢复游玩的时候停止计时,那么我们就会发现,倒计时一下子减少的时间,和我们计时的时间完全一致。

仔细想想我们的代码,你就会发现问题了(这里只是诸多问我的同学们的代码中最常见的书写方法,只是一个示范):

while(1)
{
    // current更新区
    // 倒计时计算和绘制区
    if(暂停 *** 作)
        // 暂停系统,并且卡住本次循环,触发某些条件再进行循环
    
    其他代码balabala
}

发现问题了么?我们虽然暂停了游戏的一切 *** 作,但是我们电脑的本地时间可依然在流动,所以显然这种暂停方式是不可行的。

3.解决办法

很简单!用我们倒计时的思路再写一个函数就行!

void play(xxx){
    
    int pauseTime = 0;
    int* pnt = &pauseTime;
    // 获取暂停时间
    while(1)
    {
        // current更新区
        // 倒计时计算和绘制区  做出更改!!!!!!
        int now = 90 - (current_tm.tm_hour * 3600 + current_tm.tm_min * 60 + current_tm.tm_sec) + (start_tm.tm_hour * 3600 + start_tm.tm_min * 60 + start_tm.tm_sec) + (*pnt);
        if(暂停 *** 作)
        // 暂停系统,并且卡住本次循环,触发某些条件再进行循环
        {
            time_t pause;
            time(&pause);
            system("pause");
            // 提示用户按任意键恢复游戏的 *** 作
            // 调用时间函数,返回暂停的时候流失的时间,加到now_time上;
            getPauseTime(pause,pnt);
        }
            
        其他代码balabala
    }
}

void getPauseTime(time_t start, int* pnt)
{
    struct tm start_tm;	
    localtime_s(&star_tm, &start);
    int sum_start = 3600 * start_tm.tm_hour + 60 * start_tm.tm_min + start_tm.tm_sec;

    time_t current;
    time(¤t_time);
    struct tm current_tm;
    localtime_s(¤t_tm, ¤t);
    int sum_current = 3600 * current_tm.tm_hour + 60 * current_tm.tm_min + current_tm.tm_sec;
    (*pnt) =  (*pnt) + sum_current - sum_start_time;
}

我比较笨,这是我想出来的一个解决办法,就是利用system pause实现游戏的伪暂停,然后解除system pause之后用一个函数记录下暂停经过的时间,加在倒计时计算上,就ok了。

到这里,本文就到达尾声啦!希望本文章能帮助到大家!

特别鸣谢:

我的祖国

CSDN各位大佬的小教程帮助我完成了课设

C语言课设课及指导老师

河海大学童老师的网课

和我讨论的同学们,尤其是L同学提供的帮助

我的b站UID:23415007

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/755750.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-30
下一篇 2022-04-30

发表评论

登录后才能评论

评论列表(0条)

保存