Skip to content

Instantly share code, notes, and snippets.

@okathira
Last active March 20, 2021 11:27
Show Gist options
  • Save okathira/e046384230b681df6b97f2fb3257b7ad to your computer and use it in GitHub Desktop.
Save okathira/e046384230b681df6b97f2fb3257b7ad to your computer and use it in GitHub Desktop.
OpenSiv3Dでレーダーロックオン https://twitter.com/okathira/status/1373152804739551233
#include <Siv3D.hpp> // OpenSiv3D v0.4.3
void Main() {
// フレームレート
constexpr std::array<int32, 6> framerates = {15, 30, 60, 120, 165, 240};
size_t index = 4;
Graphics::SetTargetFrameRateHz(framerates[index]);
Window::Resize(600, 600);
Scene::SetBackground(Palette::Black);
constexpr double TwoPi = s3d::Math::Constants::TwoPi;
constexpr double radarRange = 300;
const Vec2 center(Scene::Center());
double radarRad = 0;
double radPerSec = 1.4 * TwoPi;
bool clockWise = true;
bool lockOn = false;
bool flap = false;
double lockOnSwingRad = 15.0 / 360 * TwoPi;
double lastLockOnRad = 0;
Circle target(400, 200, 20); // ターゲットまとめたいね
Circle mouseTarget(200, 400, 20);
while (System::Update()) {
// 操作
// スペースキーが押されたら
if (KeySpace.down()) {
lockOn = !lockOn;
}
// Cキーが押されたら
if (KeyC.down() && !lockOn) {
clockWise = !clockWise;
}
// Wキーが押されたら
if (KeyW.down()) {
radPerSec += 0.1 * TwoPi;
}
// Sキーが押されたら
if (KeyS.down()) {
radPerSec -= 0.1 * TwoPi;
}
// Aキーが押されたら
if (KeyA.down()) {
lockOnSwingRad -= 5.0 / 360 * TwoPi;
}
// Dキーが押されたら
if (KeyD.down()) {
lockOnSwingRad += 5.0 / 360 * TwoPi;
}
// 設定表示
ClearPrint();
Print << (clockWise ? U"CW" : U"CCW");
Print << U"rotations per sec: " << radPerSec / TwoPi;
Print << U"lock-on: " << (lockOn ? U"Yes" : U"No");
Print << U"lock-on swing deg: " << lockOnSwingRad * 360 / TwoPi;
Print << U"last detection rad: " << lastLockOnRad;
// ロックオン処理
if (lockOn) {
Cursor::RequestStyle(CursorStyle::Cross);
if (!clockWise && (lastLockOnRad - lockOnSwingRad > radarRad) ||
clockWise && (lastLockOnRad + lockOnSwingRad < radarRad)) {
clockWise = !clockWise;
if (flap) { // 見失ったら
flap = false;
lockOn = false;
} else {
flap = true;
}
}
}
if (radPerSec < 0) radPerSec = 0;
const double radPerFrame =
(clockWise ? radPerSec : -radPerSec) * Scene::DeltaTime();
// レーダー走査線 判定用
const Quad radarSight(
center, center + radarRange * Vec2(Sin(radarRad), -Cos(radarRad)),
center + radarRange * Vec2(Sin(radarRad + radPerFrame / 2),
-Cos(radarRad + radPerFrame / 2)),
center + radarRange * Vec2(Sin(radarRad + radPerFrame),
-Cos(radarRad + radPerFrame)));
// 直前のフレームを使用
Graphics::SkipClearScreen();
Rect(0, 0, Scene::Size())
.draw(Color(Palette::Black,
(int32)(15 * 60 * Pow(Scene::DeltaTime(), 0.9)))); // 適当
// レーダー描画
Circle(center, radarRange)
.drawPie(radarRad, radPerFrame, Color(0, 255, 0, 128));
// 走査線にあたったら描画
if (target.intersects(radarSight)) {
target.draw(Color(0, 255, 0));
lastLockOnRad = radarRad;
flap = false;
}
mouseTarget.center = Cursor::Pos();
if (mouseTarget.intersects(radarSight)) {
mouseTarget.draw(Color(0, 255, 0));
lastLockOnRad = radarRad;
flap = false;
}
// 走査線の角度更新
radarRad += radPerFrame;
}
}
@okathira
Copy link
Author

更新のたびに4点打つのではなく、最初に上を向いた走査線を作っておき、更新時にレーダーの中心点で回転するのが良い?
と思ったけどScene::DeltaTime()で幅変わってた

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment