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
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)