c - 在 C 中的乒乓球中平滑 Racket 运动

标签 c embedded arm keil pong

我正在为嵌入式 ARM 微 Controller 编写乒乓球游戏(该板是 Keil MCBSTM32C,适合任何感兴趣的人),目前我正在尝试实现 AI。基本功能相当简单,因为我只是将玩家 2 Controller 的位置映射到球的位置。然而,这显然并不理想,因为我希望 AI 犯错以便玩家获胜。

因此,我尝试在 AI Action 中实现随机误差量。然而,AI 桨现在在屏幕上“抖动”很多,抖动量大于错误量。我想明白为什么会发生这种情况(这是因为每次重新绘制 Racket 时随机难度偏移量都会发生变化),但我不完全确定如何解决它。我试着让它朝球的方向移动,而不是直接映射到球上,但这似乎没什么帮助。

绘制玩家桨的代码是:

void draw_player2(enum pMode mode) {
    int adcValue; 
    static int lastValue = 0;
    int direction;
    switch (mode)
  {
  default:  
                break;
    case DUAL:      
                adcValue = (ADC1->DR & 0x0FFF) >> 4;    /* AD value (8 bit) */
                if (lastValue != adcValue) {
                    thisGame.p2.y = (unsigned int) adcValue * (HEIGHT-BAR_H)/256;
                    LCDupdatePaddle(thisGame.p2);
                    lastValue = adcValue;
                }
                break;
    case AI:        
                direction = thisGame.ball.y-lastValue;
                adcValue = thisGame.ball.y;     /* AD value (8 bit) */
                if (lastValue != adcValue) {
                    thisGame.p2.y = (lastValue + direction + selectDiffMod()) * (HEIGHT-BAR_H)/256;
                    LCDupdatePaddle(thisGame.p2);
                    lastValue = adcValue;
                }
                break;
    }        
}

(HEIGHT=240 和 BAR_H=48,顺便说一句)

selectDiffMod() 的代码是:

int selectDiffMod() {
    int r;
    if(thisGame.delay == T_SLOW) {
        r = rand() % 100;
    }
    if(thisGame.delay == T_MEDIUM) {
        r = rand() % 50;
    }
    if(thisGame.delay == T_FAST) {
        r = rand() % 20;
    }
    return r;
}

我目前的想法是减少生成难度修改器/偏移量的频率,但我不确定这是否真的能解决问题,我想知道是否有人有更好的解决方案?

最佳答案

我会通过为玩家 2 的桨分配一个它可以移动的速度来做到这一点。在低难度下它会移动得更慢。可以根据需要在此之上添加较小的随机波动。它看起来像(未经测试,根据需要修改以适用于您的特定情况):

int get_new_value_ai (const int currentValue, const int ballY)
{
    int direction;
    int speed = 2;
    int newValue;

        //basic sign calc: -1, 0, 1
    direction = (currentValue < ballY) - (ballY < currentValue); 

        //Adjust speeds as needed
    if (thisGame.delay == T_SLOW) 
        speed = 1;
    else if (thisGame.delay == T_MEDIUM) 
        speed = 2;
    else if (thisGame.delay == T_FAST) 
        speed = 3;

    if (abs(currentValue - ballY) < speed) //Prevent overshooting
        newValue =  ballY;
    else
        newValue =  currentValue + direction * speed;

    newValue += (rand() % 3) - 2; //Random mod of -1, 0, +1

    return newValue;
}

并将其命名为:

thisGame.p2.y = get_new_value_ai(thisGame.p2.y, thisGame.ball.y);

除此之外,您还可以通过在桨改变方向时引入加速度/动量来使其变得更加复杂。

关于c - 在 C 中的乒乓球中平滑 Racket 运动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26641703/

相关文章:

c++ - 流式文件增量编码/解码

在 Windows 系统上未检测到 Cygwin shell

c - 在使用链表实现Stack的过程中出现Segmentation错误

在 C 中使用 for 循环创建链表并赋值

c - NTRIPClient 更新 nmea

c - 标签作为内联汇编宏中的值

linux-kernel - buildroot 中的内核 defconfig(arm 目标)

python - 用 Python 和 C 编写的 2 个进程之间进行通信的数据结构和文件类型

c - STM32F769I-DISCO 上的 1s 定时器

c - 是什么让 SPI 比 I2C 协议(protocol)更快