サンプルプログラム集
① キー入力でキャラクターを動かす
#include <DrawPad.hpp>
void DrawMain()
{
int x = 0, y = 0;
while (true) {
if (CheckKey(Key::Left)) { x -= 3; }
if (CheckKey(Key::Right)) { x += 3; }
if (CheckKey(Key::Up)) { y += 3; } // Yは上がプラス!
if (CheckKey(Key::Down)) { y -= 3; }
StartBatch();
Clear(Color::Black);
DrawEmoji("🚀", x, y, 64, 64);
EndBatch();
}
}
② ボールの反射(はね返り)
#include <DrawPad.hpp>
void DrawMain()
{
double x = 0, y = 0;
double vx = 4, vy = 3; // 1フレームあたりの移動量
while (true) {
x += vx;
y += vy;
if (x < -380 || x > 379) { vx = -vx; } // 左右の壁
if (y < -280 || y > 279) { vy = -vy; } // 上下の壁
StartBatch();
Clear(Color::MidnightBlue);
FillCircle((int)x, (int)y, 20, Color::Orange);
EndBatch();
}
}
💡 この例の
vx・
vy は「1フレームあたりの移動量」なので、フレームレートが変わると速さも変わります。
どのマシンでも同じ速さにしたいときは、
GetDeltaTime を使って
x += 240.0 * GetDeltaTime(); のように「1秒あたりの移動量」で書きます。
③ マウスでお絵かき
#include <DrawPad.hpp>
void DrawMain()
{
Clear(Color::White);
while (true) {
if (CheckMouse()) { // 左ボタンを押している間
FillCircle(GetMouseX(), GetMouseY(), 5, Color::Black);
}
UpdateFrame(); // 画面・入力の更新(終了操作もここで効く。FAQ参照)
}
}
④ 効果音つきのカウントゲーム
#include <DrawPad.hpp>
void DrawMain()
{
LoadAsset("coin.mp3"); // ★ 音は最初に1回だけ読み込む
int score = 0;
char buf[64];
while (true) {
if (CheckKeyDown(Key::Space)) { // 押した「瞬間」だけ true
score++;
PlaySound("coin.mp3");
}
StartBatch();
Clear(Color::DarkSlateBlue);
snprintf(buf, sizeof(buf), "SCORE: %d", score);
DrawTextAtCenter(48, buf, 0, 0, Color::Gold);
DrawTextAtCenter("Press SPACE", 0, -100, Color::White);
EndBatch();
}
}
⑤ スプライトシートで歩行アニメーション
#include <DrawPad.hpp>
// walk.png : 32x32 のコマが横に4枚並んだ画像(Assetsフォルダーに置く)
void DrawMain()
{
while (true) {
int frame = (int)(GetTime() * 8) % 4; // 1秒間に8コマ進む
StartBatch();
Clear(Color::ForestGreen);
DrawSprite("walk.png", 32, 32, frame, 0, 0, 0, 96, 96); // 3倍に拡大表示
EndBatch();
}
}
図形の描画
色はすべて 0xRRGGBB 形式の整数、Color::Red などの色定数、または ColorRGB() / ColorHSV() などの色作成関数で指定します。
座標は画面中央が原点です。
Clear🔰 初級
void Clear(int color);
画面全体を指定した色で塗りつぶします。アニメーションでは毎フレームの最初に呼んで、前のフレームを消します。
| 引数 | 説明 |
| color | 塗りつぶす色(0xRRGGBB または Color:: 定数) |
Clear(Color::SkyBlue); // 空色で塗りつぶす
Clear(0x336699); // 数値での指定もOK
⚠ Clear() には SetAlpha / SetBlendMode の効果はかかりません(常に不透明で塗りつぶします)。
DrawPoint🔰 初級
void DrawPoint(int x, int y, int color);
void DrawPoint(const vec2<int>& pos, int color);
指定した座標に1ピクセルの点を描画します。画面の範囲外を指定した場合は何も起きません。
// 点を散りばめて星空を作る
for (int i = 0; i < 200; i++) {
DrawPoint(RandomInt(-400, 399), RandomInt(-300, 299), Color::White);
}
DrawLine🔰 初級
void DrawLine(int x1, int y1, int x2, int y2, int color, int thickness = 1);
void DrawLine(const vec2<int>& p1, const vec2<int>& p2, int color, int thickness = 1);
2点を結ぶ直線を描画します。
| 引数 | 説明 |
| x1, y1 | 始点の座標 |
| x2, y2 | 終点の座標 |
| color | 描画色 |
| thickness | 線の太さ(省略時 1) |
DrawLine(-400, 0, 399, 0, Color::Gray); // 横軸
DrawLine(0, -300, 0, 299, Color::Gray); // 縦軸
DrawLine(-100, -100, 100, 100, Color::Red, 5); // 太さ5の斜め線
DrawRect🔰 初級
void DrawRect(int x, int y, int width, int height, int color, int thickness = 1);
void DrawRect(const vec2<int>& pos, const vec2<int>& size, int color, int thickness = 1);
void DrawRect(const rect<int>& r, int color, int thickness = 1);
四角形の輪郭線を描画します。(x, y) は角の座標(中心ではありません)。
width はプラスで右方向、height はプラスで上方向に伸びます。
| 引数 | 説明 |
| x, y | 始点(角)の座標 |
| width | 横の大きさ(マイナスなら左方向へ) |
| height | 縦の大きさ(マイナスなら下方向へ) |
| color | 描画色 |
| thickness | 線の太さ(省略時 1) |
DrawRect(-100, -50, 200, 100, Color::Lime, 3); // 中央に200×100の枠
⚠ 円や画像は「中心」を指定しますが、四角形だけは「角」を指定します。中央に置きたいときは
DrawRect(cx - w/2, cy - h/2, w, h, color) のように半分ずらしてください。
FillRect🔰 初級
void FillRect(int x, int y, int width, int height, int color);
void FillRect(const vec2<int>& pos, const vec2<int>& size, int color);
void FillRect(const rect<int>& r, int color);
四角形を塗りつぶします。座標の指定方法は DrawRect と同じです。
FillRect(-400, -300, 800, 60, Color::SaddleBrown); // 画面下端に地面を描く
DrawRoundRect🔰 初級
void DrawRoundRect(int x, int y, int width, int height, int radius, int color, int thickness = 1);
void DrawRoundRect(const vec2<int>& pos, const vec2<int>& size, int radius, int color, int thickness = 1);
void DrawRoundRect(const rect<int>& r, int radius, int color, int thickness = 1);
角が丸い四角形の輪郭線を描画します。radius は角丸の半径です。座標の指定方法は DrawRect と同じです。
DrawRoundRect(-120, -50, 240, 100, 16, Color::White, 3);
FillRoundRect🔰 初級
void FillRoundRect(int x, int y, int width, int height, int radius, int color);
void FillRoundRect(const vec2<int>& pos, const vec2<int>& size, int radius, int color);
void FillRoundRect(const rect<int>& r, int radius, int color);
角が丸い四角形を塗りつぶします。座標の指定方法は DrawRect と同じです。
FillRoundRect(-150, -60, 300, 120, 20, Color::SteelBlue);
DrawTriangle🔰 初級
void DrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color, int thickness = 1);
void DrawTriangle(const vec2<int>& p1, const vec2<int>& p2, const vec2<int>& p3, int color, int thickness = 1);
3点を結ぶ三角形の輪郭線を描画します。
| 引数 | 説明 |
| x1〜y3 | 3つの頂点の座標 |
| color | 描画色 |
| thickness | 線の太さ(省略時 1) |
FillTriangle🔰 初級
void FillTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color);
void FillTriangle(const vec2<int>& p1, const vec2<int>& p2, const vec2<int>& p3, int color);
3点を結ぶ三角形を塗りつぶします。
// 山を描く
FillTriangle(-200, -100, 0, 150, 200, -100, Color::ForestGreen);
DrawPolygon⭐ 中級
void DrawPolygon(const vec2<int> points[], int count, int color, int thickness = 1);
void DrawPolygon(const std::vector<vec2<int>>& points, int color, int thickness = 1);
任意の頂点数の多角形の輪郭線を描画します。頂点は順番に結ばれ、最後の頂点と最初の頂点も自動的に結ばれます。
| 引数 | 説明 |
| points | 頂点の配列またはvector(中心 (0,0) 基準) |
| count | 頂点数(配列版のみ) |
| color | 描画色 |
| thickness | 線の太さ(省略時 1) |
// 配列版(固定頂点数)
vec2<int> star[] = { {0,100}, {25,35}, {95,30}, {40,-15}, {60,-90},
{0,-50}, {-60,-90}, {-40,-15}, {-95,30}, {-25,35} };
DrawPolygon(star, 10, Color::Gold, 2);
// vector版(動的に頂点を組み立てる)
std::vector<vec2<int>> pts = { {-100,0}, {0,150}, {100,0} };
DrawPolygon(pts, Color::Cyan);
FillPolygon⭐ 中級
void FillPolygon(const vec2<int> points[], int count, int color);
void FillPolygon(const std::vector<vec2<int>>& points, int color);
任意の頂点数の多角形を塗りつぶします。頂点の並び順(時計回り/反時計回り)はどちらでも自動修正されます。
| 引数 | 説明 |
| points | 頂点の配列またはvector(中心 (0,0) 基準) |
| count | 頂点数(配列版のみ) |
| color | 描画色 |
// 五角形
vec2<int> pentagon[5];
for (int i = 0; i < 5; i++) {
double a = M_PI / 2 + i * 2 * M_PI / 5;
pentagon[i] = { (int)(100 * cos(a)), (int)(100 * sin(a)) };
}
FillPolygon(pentagon, 5, Color::MediumPurple);
凸多角形・凹多角形のどちらにも対応しています。自己交差するパスは正しく描画されない場合があります。
DrawCircle(円)🔰 初級
void DrawCircle(int cx, int cy, int radius, int color, int thickness = 1);
void DrawCircle(const vec2<int>& center, int radius, int color, int thickness = 1);
中心と半径を指定して、円の輪郭線を描画します。
| 引数 | 説明 |
| cx, cy | 中心の座標 |
| radius | 半径(ピクセル) |
| color | 描画色 |
| thickness | 線の太さ(省略時 1) |
DrawCircle(0, 0, 150, Color::DeepPink, 4);
FillCircle(円)🔰 初級
void FillCircle(int cx, int cy, int radius, int color);
void FillCircle(const vec2<int>& center, int radius, int color);
中心と半径を指定して、円を塗りつぶします。ボールやキャラクターを描く定番の関数です。
FillCircle(0, 100, 40, Color::Yellow); // 顔
FillCircle(-15, 110, 5, Color::Black); // 左目
FillCircle( 15, 110, 5, Color::Black); // 右目
DrawArc(円弧)⭐ 中級
void DrawArc(int cx, int cy, int radius, int color,
double startAngleRad, double endAngleRad, int thickness = 1);
void DrawArc(const vec2<int>& center, int radius, int color,
double startAngleRad, double endAngleRad, int thickness = 1);
開始角度と終了角度をラジアンで指定して、円弧(円の一部)を描画します。
角度0は右方向(+X方向)で、反時計回りに進みます。
| 引数 | 説明 |
| cx, cy | 中心の座標 |
| radius | 半径 |
| color | 描画色 |
| startAngleRad | 開始角度(ラジアン) |
| endAngleRad | 終了角度(ラジアン) |
| thickness | 線の太さ(省略時 1) |
#include <cmath>
DrawArc(0, 0, 100, Color::Cyan, 0.0, M_PI / 2); // 第1象限の90度分の弧
⚠ 角度は内部で -π〜+π の範囲に変換されます(例: 0〜5/2π → 0〜1/2π と同じ扱い)。
開始角度と終了角度が同じ値のときは何も描画されません。
FillArc(扇形)⭐ 中級
void FillArc(int cx, int cy, int radius, int color,
double startAngleRad, double endAngleRad);
void FillArc(const vec2<int>& center, int radius, int color,
double startAngleRad, double endAngleRad);
開始角度と終了角度をラジアンで指定して、中心から円弧の両端を結んだ扇形を塗りつぶします。円グラフや残り時間ゲージに使えます。
#include <cmath>
// 残り時間を扇形で表示(残り75%の例)
double rate = 0.75;
FillArc(0, 0, 80, Color::Tomato, 0.0, 2 * M_PI * rate);
⚠ 開始角度と終了角度が同じ値のときは何も描画されません。円全体を塗りつぶしたいときは FillCircle() を使います。
DrawEllipse🔰 初級
void DrawEllipse(int cx, int cy, int radius_x, int radius_y, int color, int thickness = 1);
void DrawEllipse(const vec2<int>& center, const vec2<int>& radius, int color, int thickness = 1);
中心と縦横それぞれの半径を指定して、楕円の輪郭線を描画します。
| 引数 | 説明 |
| cx, cy | 中心の座標 |
| radius_x | X方向(横)の半径 |
| radius_y | Y方向(縦)の半径 |
FillEllipse🔰 初級
void FillEllipse(int cx, int cy, int radius_x, int radius_y, int color);
void FillEllipse(const vec2<int>& center, const vec2<int>& radius, int color);
楕円を塗りつぶします。キャラクターの足元の影などに便利です。
FillEllipse(0, -80, 50, 12, Color::DarkGray); // 影
DrawEmoji("🐱", 0, -40, 80, 80); // その上にキャラ
GetColor⭐ 中級
int GetColor(int x, int y);
int GetColor(const vec2<int>& pos);
画面上の指定した座標のピクセルの色を取得します。「色を調べて当たり判定をする」といった使い方ができます。
戻り値: 0xRRGGBB 形式の色。画面の範囲外を指定すると 0(黒と同じ値)。
// マウス位置の色を調べる
int c = GetColor(GetMouseX(), GetMouseY());
if (c == Color::Red) {
DrawText("RED!", 0, 250, Color::White);
}
画像とスプライト
画像ファイルはプロジェクトの Assets フォルダーに入れておきます。PNG・JPEG など、macOS が読める形式に対応しています。
読み込みは自動で行われ、2回目以降はキャッシュされるので高速です。
DrawImage⭐ 中級
void DrawImage(const char *imageFileName, int cx, int cy,
double angle = 0.0, bool flipX = false, int color = Color::White);
void DrawImage(const char *imageFileName, int cx, int cy, int width, int height,
double angle = 0.0, bool flipX = false, int color = Color::White);
// vec2版: DrawImage(file, pos, ...) / DrawImage(file, pos, size, ...)
Assets フォルダー内の画像を、指定した座標を中心として描画します。
サイズを指定しない場合は画像の元の大きさで描画されます。
| 引数 | 説明 |
| imageFileName | Assets フォルダー内のファイル名(例: "player.png") |
| cx, cy | 描画の中心座標 |
| width, height | 描画サイズ(ピクセル)。指定すると拡大縮小される |
| angle | 回転角度(ラジアン)。反時計回りが正。省略時 0 |
| flipX | true で左右反転。省略時 false |
| color | 色合い(ティント)。省略時は白(= 元の色のまま)。Color::Red などを指定すると画像にその色がかかる |
DrawImage("player.png", 0, 0); // 等倍で中央に
DrawImage("player.png", 100, 50, 64, 64); // 64×64に拡縮
DrawImage("player.png", 0, 0, 64, 64, GetTime()); // くるくる回転
DrawImage("player.png", 0, 0, 64, 64, 0, true); // 左右反転(左向き→右向き)
DrawImage("player.png", 0, 0, 64, 64, 0, false, Color::Red); // 赤くする(ダメージ表現)
⚠ ファイルが見つからないときは、エラーを表示してプログラムを終了します。ファイル名と置き場所(Assets フォルダー)を確認してください。
なお画像は LoadAsset なしでも初回描画時に自動で読み込まれますが、LoadAsset で先読みしておくと初回描画のひっかかりがなくなります。
DrawSprite⭐ 中級
void DrawSprite(const char *imageFileName, int frameWidth, int frameHeight,
int column, int row, int cx, int cy,
double angle = 0.0, bool flipX = false, int color = Color::White);
void DrawSprite(const char *imageFileName, int frameWidth, int frameHeight,
int column, int row, int cx, int cy, int width, int height,
double angle = 0.0, bool flipX = false, int color = Color::White);
// vec2版: DrawSprite(file, frameSize, frame, pos, ...) など
1枚の画像にコマが並んだ「スプライトシート」から、1コマを切り出して描画します。
切り出し位置は画像の左上を起点に (column × frameWidth, row × frameHeight) です。
| 引数 | 説明 |
| imageFileName | スプライトシート画像のファイル名 |
| frameWidth / frameHeight | 1コマの幅・高さ(ピクセル) |
| column / row | 切り出すコマの列・行(0始まり) |
| cx, cy | 描画の中心座標 |
| width, height | 描画サイズ(省略時はコマの等倍) |
| angle / flipX / color | DrawImage と同じ |
// 32×32のコマが横4枚並んだ walk.png をアニメーション
int frame = (int)(GetTime() * 8) % 4;
DrawSprite("walk.png", 32, 32, frame, 0, 0, 0);
文字と絵文字
DrawText🔰 初級
void DrawText(const char *str, int x, int y, int color);
void DrawText(int fontSize, const char *str, int x, int y, int color);
void DrawText(const char *str, const vec2<int>& pos, int color);
void DrawText(int fontSize, const char *str, const vec2<int>& pos, int color);
指定した座標に文字列を描画します。(x, y) は文字列の左下(ベースライン左端)の位置です。
フォントサイズを省略すると 18 ポイントになります。等幅フォントで描画されます。
| 引数 | 説明 |
| fontSize | フォントサイズ(ポイント)。省略時 18 |
| str | 描画する文字列 |
| x, y | 描画位置(文字列の左下あたり) |
| color | 描画色 |
DrawText("Hello!", -380, 260, Color::White); // 画面左上に
DrawText(36, "BIG TEXT", -150, 0, Color::Yellow); // 大きな文字
// 数値を表示したいときは snprintf で文字列にする
char buf[64];
snprintf(buf, sizeof(buf), "SCORE: %d", 1200);
DrawText(buf, -380, 220, Color::White);
DrawTextAtCenter🔰 初級
void DrawTextAtCenter(const char *str, int cx, int cy, int color, double angle = 0.0);
void DrawTextAtCenter(int fontSize, const char *str, int cx, int cy, int color, double angle = 0.0);
void DrawTextAtCenter(const char *str, const vec2<int>& pos, int color, double angle = 0.0);
void DrawTextAtCenter(int fontSize, const char *str, const vec2<int>& pos, int color, double angle = 0.0);
指定した座標が文字列の中心になるように描画します。タイトルやメッセージを画面中央に出すときに便利です。
回転角度(ラジアン)も指定できます。angle は反時計回りが正です。
DrawTextAtCenter(64, "GAME OVER", 0, 50, Color::Red);
DrawTextAtCenter("Press SPACE to retry", 0, -50, Color::White);
DrawEmoji🔰 初級
void DrawEmoji(const char *emojiStr, int x, int y,
double angle = 0.0, bool flipX = false);
void DrawEmoji(const char *emojiStr, int x, int y, int width, int height,
double angle = 0.0, bool flipX = false);
void DrawEmoji(const char *emojiStr, const vec2<int>& pos,
double angle = 0.0, bool flipX = false);
void DrawEmoji(const char *emojiStr, const vec2<int>& pos, const vec2<int>& size,
double angle = 0.0, bool flipX = false);
絵文字を描画します。画像ファイルを用意しなくてもキャラクターが作れる、DrawPad の楽しい機能です。
絵文字は "🎈" のように文字列で渡します。
| 引数 | 説明 |
| emojiStr | 描画する絵文字 |
| x, y | 描画の中心座標 |
| width, height | 描画サイズ。省略すると約128ポイント相当のかなり大きいサイズになるので、ふつうはサイズ指定版を使う |
| angle | 回転角度(ラジアン)。反時計回りが正。省略時 0 |
| flipX | true で左右反転。省略時 false |
DrawEmoji("🎈", 0, 100, 48, 48); // 48×48の風船
DrawEmoji("🐟", x, y, 64, 64, 0.0, true); // 左右反転した魚
DrawEmoji("⭐", 0, 0, 80, 80, GetTime() * 2); // 回る星
💡 一度描画した絵文字はキャッシュされるので、2回目以降は高速に描画されます。
サイズを毎フレーム少しずつ変えるアニメーション(拡大縮小演出など)でも、内部で適切にキャッシュが共有されるため、安心して使えます。
GetTextSize⭐ 中級
vec2<int> GetTextSize(const char *str);
vec2<int> GetTextSize(int fontSize, const char *str);
文字列を描画したときの幅と高さを返します。フォントサイズを省略すると 18 になります。
右寄せ・中央揃え・吹き出しの幅合わせなど、テキストのレイアウトに使います。
戻り値: 幅と高さの入った vec2<int>(.x が幅、.y が高さ)
// 右端に右寄せで描画する
vec2<int> sz = GetTextSize("Score: 999");
DrawText("Score: 999", 399 - sz.x, 290, Color::White);
// フォントサイズを指定する場合
vec2<int> sz2 = GetTextSize(32, "GAME OVER");
GetEmojiSize⭐ 中級
vec2<int> GetEmojiSize(const char *emojiStr);
絵文字をサイズ無指定(128ポイント相当)で描画したときの幅と高さを取得します。
戻り値: 幅と高さの入った vec2<int>(.x が幅、.y が高さ)
数学ユーティリティ
値を範囲内に収めたり、なめらかに補間したりする関数と、座標や範囲をまとめて扱うためのテンプレート構造体です。多くの描画・入力関数には、
個別の int x, int y 版に加えてこれらを受け取るオーバーロードが用意されています。
範囲と補間の関数🔰 初級
int Sign(int value);
int Sign(double value);
double Clamp(double value, double min, double max);
int Clamp(int value, int min, int max);
double Clamp01(double value);
double Lerp(double a, double b, double t);
int LerpInt(int a, int b, double t);
double InverseLerp(double a, double b, double value);
double Map(double value,
double inMin, double inMax,
double outMin, double outMax);
double MapClamped(double value,
double inMin, double inMax,
double outMin, double outMax);
double SmoothStep(double a, double b, double t);
double EaseIn(double t);
double EaseOut(double t);
double EaseInOut(double t);
double EaseInQuad(double t);
double EaseOutQuad(double t);
double EaseInOutQuad(double t);
double MoveTowards(double current, double target, double maxDelta);
double Repeat(double value, double length);
double PingPong(double value, double length);
double DegToRad(double degrees);
double RadToDeg(double radians);
double NormalizeAngleDeg(double angle);
double NormalizeAngleRad(double angle);
Clamp は値を範囲内に収めます。Lerp は2つの値の間を補間し、Map はある範囲の値を別の範囲へ変換します。MoveTowards や Repeat は、一定速度の移動やくり返しアニメーションに便利です。
| 関数 | 用途 |
Clamp | 値を min 以上 max 以下に収める |
Clamp01 | 値を 0.0 以上 1.0 以下に収める |
Lerp | t=0.0 で a、t=1.0 で b になる線形補間 |
LerpInt | 整数版の線形補間。結果は四捨五入される |
InverseLerp | 値が範囲内のどの割合にあるかを求める |
Map | 入力範囲の値を出力範囲へ変換する |
MapClamped | 入力値を範囲内に収めてから変換する |
SmoothStep | 0.0〜1.0の t を使ってなめらかに補間する |
EaseIn | ゆっくり始まってだんだん速くなる割合を返す |
EaseOut | 速く始まってだんだんゆっくり止まる割合を返す |
EaseInOut | 始まりと終わりがゆっくりになる割合を返す |
EaseInQuad / EaseOutQuad / EaseInOutQuad | 2次関数を使ったイージング。EaseIn などの基本形と同じ |
Sign | 負なら -1、0なら 0、正なら 1 を返す |
MoveTowards | 現在値を目標値へ、1回あたり最大 maxDelta だけ近づける |
Repeat | 値を 0.0 以上 length 未満の範囲で繰り返す |
PingPong | 0.0 → length → 0.0 を往復する値を作る |
DegToRad / RadToDeg | 度数法とラジアンを変換する |
NormalizeAngleDeg | 角度を 0.0 以上 360.0 未満に収める |
NormalizeAngleRad | 角度を 0.0 以上 2π 未満に収める |
double t = Clamp01(GetMouseX() / 600.0);
double x = Lerp(-250.0, 250.0, EaseInOut(t));
double size = MapClamped(GetMouseY(), -200.0, 200.0, 20.0, 100.0);
double y = PingPong(GetTime() * 120.0, 180.0) - 90.0;
FillCircle(x, y, size, Color::DeepSkyBlue);
InverseLerp と Map は範囲外の値もそのまま割合として扱います。0.0〜1.0に収めたい場合は Clamp01 または MapClamped を使います。
vec2<T>🚀 上級
template <typename T> struct vec2 {
T x, y;
vec2(); // (0, 0)
vec2(T x, T y);
// 演算子: + - * / += -= *= /= == != (* と / はスカラー値と)
void Add(const vec2<T>& v); // 加算(+= と同じ)
vec2<T> Center() const; // (x/2, y/2)
T Dot(const vec2<T>& v) const; // 内積
T Cross(const vec2<T>& v) const; // 外積(2Dなのでスカラー)
double Length() const; // ベクトルの長さ
double LengthSquared() const; // 長さの2乗(高速・比較用)
double Distance(const vec2<T>& v) const; // 2点間の距離
double DistanceSquared(const vec2<T>& v) const; // 距離の2乗
vec2<double> Normalized() const; // 長さ1に正規化したベクトル
};
2次元ベクトル。座標・速度・大きさなどを1つの変数で扱えます。vec2<int> や vec2<double> のように型を指定して使います。
vec2<double> pos(0, 0);
vec2<double> vel(3, 2);
pos += vel; // 位置を速度ぶん進める
// プレイヤーとの距離で当たり判定
if (pos.Distance(playerPos) < 30.0) { hit(); }
// マウスの方向へ速度100で進む
vec2<double> dir = (vec2<double>(GetMousePos()) - pos).Normalized();
pos += dir * (100.0 * GetDeltaTime());
⚠ / 演算子は0で割ろうとすると例外(std::runtime_error)を投げます。
rect<T>🚀 上級
template <typename T> struct rect {
T x, y, width, height;
rect();
rect(T x, T y, T width, T height);
rect(const vec2<U>& pos, const vec2<U>& size);
static rect<T> FromEdges(T left, T top, T right, T bottom);
bool Intersects(const rect<T>& other) const; // 重なっているか
};
矩形(四角形の範囲)。Intersects() で矩形同士の重なり判定ができるので、簡単な当たり判定に使えます。
DrawRect / FillRect にそのまま渡せます。
rect<int> player(x - 16, y - 16, 32, 32);
rect<int> enemy(ex - 20, ey - 20, 40, 40);
if (player.Intersects(enemy)) {
DrawTextAtCenter(48, "HIT!", 0, 0, Color::Red);
}
FillRect(player, Color::Aqua); // rect をそのまま描画にも使える