コード:
#define _USE_MATH_DEFINES // VCで、M_PIを使うため
#include <DxLib.h>
#include <math.h>
// (x, y)を座標系の原点を中心に回転させる
void RotateXY(double *x, double *y, double angle)
{
double x_ = *x;
double y_ = *y;
double cos_ = cos(angle);
double sin_ = sin(angle);
*x = x_ * cos_ - y_ * sin_;
*y = x_ * sin_ + y_ * cos_;
}
// (x, y)を平行移動させる
void TranslateXY(double *x, double *y, double tx, double ty)
{
*x += tx;
*y += ty;
}
// 正弦波レーザー
struct SinLaser
{
double x0, y0; // 発射位置
double x, y; // 現在の位置(ただし、回転・平行移動させる前の座標)
double speed; // 速度
double angle; // 角度
double amp; // 振幅
double period; // 周期
double phase; // 位相
};
// レーザーを作成する
SinLaser MakeLaser(double x, double y, double speed, double angle, double amp, double period, double phase)
{
SinLaser laser = {x, y, 0, 0, speed, angle, amp, period, phase};
return laser;
}
// レーザーを移動させる
void MoveLaser(SinLaser *laser)
{
// 回転を考慮せずに、xを増加させ、対応するyの値を計算する
laser->x += laser->speed;
laser->y = laser->amp * sin(2 * M_PI / laser->period * laser->x + laser->phase);
}
// レーザーの実際の位置を得る
void GetLaserPos(const SinLaser *laser, double *x, double *y)
{
*x = laser->x;
*y = laser->y;
// 回転後の座標を得る
RotateXY(x, y, laser->angle);
// 発射位置に合わせて平行移動させる
TranslateXY(x, y, laser->x0, laser->y0);
}
void MoveLasers(SinLaser *laser, int n)
{
for (int i = 0 ; i < n ; ++i) {
MoveLaser(&laser[i]);
}
}
void DrawLasers(const SinLaser *laser, int n)
{
int color[2] = {GetColor(255, 0, 0), GetColor(0, 0, 255)};
for (int i = 0; i < n; ++i) {
double x, y;
GetLaserPos(&laser[i], &x, &y);
DrawCircle((int)x, (int)y, 5, color[i % 3]);
}
}
int APIENTRY _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
if (ChangeWindowMode(TRUE) != 0 || DxLib_Init() != 0) {
return -1;
}
SetDrawScreen(DX_SCREEN_BACK);
char Key[256];
// 右下(45度=π/4ラジアン)に発射される、位相だけが異なる2つのレーザーを作る
const int N = 2;
double X = 20;
double Y = 100;
double Speed = 5;
double Angle = M_PI_4;
double Amp = 30;
double Period = 4 * Amp;
SinLaser laser[N] = {
MakeLaser(X, Y, Speed, Angle, Amp, Period, 0),
MakeLaser(X, Y, Speed, Angle, Amp, Period, M_PI),
};
while (ProcessMessage() == 0 && GetHitKeyStateAll(Key) == 0 && !Key[KEY_INPUT_ESCAPE]) {
// 画面クリア
//ClearDrawScreen();
// 移動
MoveLasers(laser, N);
// 描画
DrawLasers(laser, N);
ScreenFlip();
}
DxLib_End();
return 0;
}