0

我正在微处理器上用 C 语言制作游戏。分数取决于你能活多久;分数每 3 秒增加 1。分数是一个全局声明的整数,但从函数中显示。

int score = 0;//globally declared

void draw_score(int score_d)
{
    char score_draw[99];
    sprintf(score_draw,"%d", score_d);
    draw_string(score_draw, 9, 0);
}

我正在考虑一个功能,它只是将分数增加一个并延迟它,但是没有奏效。

void score_increaser(int score)
{
    score++;
    _delay_ms( 3000 );
}

它是否需要在一个while循环中?无论如何,函数本身都会在 main 中进入一个 while 循环。

4

5 回答 5

2

C 是按值传递。

score_increaser()如您的问题所示,仅增加了传入内容的副本

要解决此问题,(主要)有两个选项:

  1. 正如score全局定义的那样,不要传入任何东西:

    void score_increaser(void) {
      score++;
      _delay_ms( 3000 );
    }
    

    score直接修改了全局。

  2. 传入地址score并在函数内部取消引用

    void score_increaser(int * pscore) {
      (*pscore)++;
      _delay_ms( 3000 );
    }
    

    像这样称呼它

    ...
    score_increaser(&score);
    ...
    

第三种更复杂的方法(假设目标平台支持信号)将

  1. 设置一个信号和一个引用处理程序,然后
  2. 设置一个计时器以每 N 秒触发一次信号。
  3. 然后,该信号由处理程序处理,处理程序依次处理
  4. 增加全局score
  5. 再次启动计时器。

这可能看起来像:

#include <signal.h> /* for signal() and sig_atomic_t */
#include <unistd.h> /* for alarm() */


#define DURATION (3) /* Increase score every 3 seconds. */

sig_atomic_t score = 0;


void set_alarm(unsigned);

void handler_alarm(int sig)
{
  ++score;
  set_alarm(DURATION);
}

void set_alarm(unsigned duration)
{
  signal(SIGALRM, handler_alarm);
  alarm(duration);
}


int main(void)
{
  set_alarm(DURATION);

  ... /* The game's codes here. */
}

后一种方法的优点是您的游戏代码不需要关心增加score. score只要程序运行,它就会每 3 秒增加一次。

于 2015-05-16T06:57:14.363 回答
1

我建议使用定时器中断。将计时器配置为 3 秒。

volatile int score = 0; //global

void Intr_Init(peripheral_t per)
{
    //Initialize the timer interrupt
}

void draw_score(int score_d)
{
    char score_draw[99];
    sprintf(score_draw,"%d", score_d);
    draw_string(score_draw, 9, 0);
}

int main(void)
{
    Intr_Init(TIMER);
    while(1)
    {
        //Code that makes your game run
        draw_score(score);
    }
}

ISR (TIMER1_COMPA_vect)
{
    //clear disable interrupt
    score++;
    //enable interrupt
}

在嵌入式中,您应该依靠计时器来获得更好的时间关键任务和准确性。延迟例程的实现方式通常是循环或向上/向下计数器。而计时器通常基于计数 SysTicks。中断的另一个主要优点是您可以让处理器一直执行其任务,而不是让它在延迟循环中阻塞。

于 2015-05-16T07:20:54.587 回答
0

score是全局值,那么如果该函数可以访问该全局空间,则不需要在函数中传递它

void score_increaser() {
score++;
_delay_ms( 3000 );
}
于 2015-05-16T07:01:18.510 回答
0

您不需要分数参数,因为它是全局声明的。

//global 
int score = 0;

void score_increaser()
{
   _delay_ms(3000);
   score++;
}

调用就像:score_increaser();应该完成工作..我建议您检查score任何其他行/功能..也许您已经重新声明它或不小心更改了值..

希望这有帮助..

于 2015-05-16T07:30:58.550 回答
0

这是处理分数的好方法。

在“开始游戏”功能中,

clear 'score' to 0
setup a timer: 
--to expire once each 3 seconds 
--enable the automatic reload feature, 
--enable the timer interrupt
--enable the timer counter

在定时器中断处理函数中

--increment 'score'
--clear the timer interrupt pending flag

在“结束游戏”功能中

disable the timer counter
disable the timer interrupt
display the 'score' value
于 2015-05-16T21:13:48.157 回答