我正在尝试创建一个计时器,以显示在游戏的右上角,该计时器从99%下降到0%,每秒下降1%,并且计数器在屏幕上刷新。 ps(我是编码的新手,如果这是一个愚蠢的问题,对不起)
我尝试使用一个简单的倒计时循环,但它会一次减少所有计数,并且不会将计数器另存为变量,因此我可以在屏幕上的特定位置打印它
void battery_life(){
int w, h;
get_screen_size(&w, &h);
int y=99;
while (y !=0)
y--;
draw_int (2*w/3+5,h-h+2,y);
draw_char(2*w/3+7,h-h+2,'%');
}
我希望当我运行此计数器时,它每秒每秒-1%,但它只是一次倒数并显示0%
答案 0 :(得分:1)
这是一个相当广泛的问题,但是这里有几种通用方法,都需要:
这是两种不同的方法:
游戏循环
由于您正在设计游戏,因此您可能会拥有某种game loop,即:
while (!ending)
{
process_input();
update_state();
draw();
}
您的update_state
和draw
函数应具有不同的职责,类似于:
static int current_percentage = 100;
void update_state(void)
{
// keep the time of last update
static timestamp last_update_time = 0;
// decrease 'current_percentage' when needed
timestamp now = get_current_game_time();
if (seconds_elapsed(now, last_update_time) >= 1)
{
last_update_time = now;
current_percentage--;
}
}
void draw(void)
{
// just handle the drawing
draw_percentage(current_percentage);
}
多线程
反之,如果您使用多个线程,则可能会采用完全不同的方法:
static atomic_int current_percentage = 100;
void decrease_percentage(void)
{
atomic_fetch_sub(¤t_percentage, 1);
}
void draw(void)
{
// just handle the drawing
int percentage = atomic_load(¤t_percentage);
draw_percentage(percentage);
}
// no game loop - we will need to configure function callbacks
// for different events
void on_game_start(void)
{
// one thread should update the timer
call_periodically(1000 /* period in ms */, decrease_percentage /* what to call */);
// this should run at max possible fps
call_when_idle(draw /* what to call when idle */);
}
后一种方法略短一些,尽管主要原因是因为在配置回调的函数中隐藏了许多功能。前一种方法更容易推论,并且没有多线程代码引起的问题(死锁,竞争条件-请注意使用atomic_int
来确保原子更新),这就是为什么在以下情况下首选游戏循环的原因可能。
如果您的游戏需要利用多个内核,那么您将需要涉及某种线程,这带来了额外的复杂性。第二种方法的实现也将取决于您的平台,因为计时器不是C标准的一部分。
最后,如果您使用的是游戏引擎/框架(libgdx,Unity),则可能仅需实现update
和draw
回调,而框架将负责调用这些函数在需要的时候。
答案 1 :(得分:0)
while循环中缺少括号,因此一开始就行不通!
您确实需要实现一个计时器,以便您可以实际知道什么时候过去了,因为代码的操作速度可能会有所不同,并且绝对会在您进行任何更改时确定。 您如何执行此操作完全取决于您正在编写的系统,并且您没有提供足够的信息来帮助我们。 大多数情况下,运行C的硬件都有硬件计时器和您需要定位的特定寄存器。
答案 2 :(得分:0)
几件事:
也许更好的方法是编写一个具有static int y = 99
的函数,并且每次调用它时,绘制电池文本并将y
减小1(静态或多或少意味着该值为记得在通话之间)。
然后,在您的主游戏循环中,您可以检查是否已过去一秒钟,如果已过,请执行该功能。
答案 3 :(得分:-1)
如果您使用统一,则可以简单地使用协程来每秒倒数百分比。
void countDown()
{
int percent = 99;
StartCoroutine(CountDownToZero(percent));
}
IEnumerator CountDownToZero(int percentage)
{
WaitForSeconds wait1sec = new WaitForSeconds(1f);
while(percentage > 0)
{
percentText.text = percentage.ToString()+"%";
yield return wait1sec;
percentage= percentage- 1;
}
percentText.text = "0%";
}
对于其他引擎,它们还提供了计划程序以计划功能的执行。