Arduboyで狙い撃つぜ!(atan2テーブルの作り方) その1

ロックオン・ストラトスのように狙い撃ちたい。



atan2関数で狙い撃てました。

f:id:raohu69:20180506132818p:plain

f:id:raohu69:20180506132826p:plain

#include <Arduboy2.h>

Arduboy2 arduboy;

#define BOSS_SHOT   10

typedef struct CharaData {
  float x, y;
  float vx, vy;
  int life;
};

CharaData player;

CharaData boss;
CharaData bossShot[BOSS_SHOT];

uint16_t counter;

void setup()
{
  arduboy.begin();
  arduboy.setFrameRate(60);
  arduboy.clear();

  player.x = 20;
  player.y = 64 / 2;
  boss.x = 128 / 2;
  boss.y = 64 / 2;
}

void loop()
{
  if (!arduboy.nextFrame()) return;
  arduboy.clear();

  // プレイヤ(長方形)
  if (arduboy.pressed(LEFT_BUTTON)) {
    player.x -= 1.f;
  } else if (arduboy.pressed(RIGHT_BUTTON)) {
    player.x += 1.f;
  }
  if (arduboy.pressed(UP_BUTTON)) {
    player.y -= 1.f;
  } else if (arduboy.pressed(DOWN_BUTTON)) {
    player.y += 1.f;
  }
  arduboy.fillRect(player.x - 8.f, player.y - 4.f, 16, 8);

  // ボス(三角形)
  arduboy.drawTriangle(boss.x, boss.y - 8.f, boss.x - 8.f, boss.y + 8.f, boss.x + 8.f, boss.y + 8.f);

  // 弾の作成
  if (++counter % 10 == 0) {
    for (int8_t i = 0; i < BOSS_SHOT; ++i) {
      CharaData *p = &bossShot[i];
      if (p->life == 0) {
        p->life = 1;
        p->x = boss.x;
        p->y = boss.y + 2.f;

        // プレイヤの方向を求める
        float r = atan2f(player.y - p->y, player.x - p->x);

        // 弾の移動方向を求める
        p->vx = cosf(r);
        p->vy = sinf(r);

        break;
      }
    }    
  }

  // 弾の表示
  for (int16_t i = 0; i < BOSS_SHOT; ++i) {
    CharaData *p = &bossShot[i];
    if (p->life > 0) {
      p->x += p->vx;
      p->y += p->vy;

      if (p->x < 0.f || 128.f < p->x || p->y < 0.f || 64.f < p->y)
        p->life = 0;

      arduboy.fillCircle(p->x, p->y, 2);
    }
  }

  arduboy.display();
}