Last active
March 20, 2021 11:27
-
-
Save okathira/e046384230b681df6b97f2fb3257b7ad to your computer and use it in GitHub Desktop.
OpenSiv3Dでレーダーロックオン https://twitter.com/okathira/status/1373152804739551233
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
更新のたびに4点打つのではなく、最初に上を向いた走査線を作っておき、更新時にレーダーの中心点で回転するのが良い?
と思ったけどScene::DeltaTime()で幅変わってた