それじゃあ、画像同士がぶつかったら反射する衝突判定付きアニメーションを追加していきましょう 💥🌀
目次
✅ 追加機能:画像の衝突判定(バウンド+反射)
✨ 更新ポイント:
- 各画像の 位置 (X, Y) + サイズ (Width, Height) で 矩形衝突 を検出
- 衝突したら、進行方向(DX, DY)を反転
🧠 ロジック(簡易的なAABB衝突)
bool IsColliding(MovingImage a, MovingImage b) { return !(a.X + image.Width < b.X || a.X > b.X + image.Width || a.Y + image.Height < b.Y || a.Y > b.Y + image.Height); }
🔁 OnUpdate
内に衝突チェック追加
private void OnUpdate(object sender, ElapsedEventArgs e) { // 移動 foreach (var img in images) { img.X += img.DX; img.Y += img.DY; // 端で反射 if (img.X < 0 || img.X + image.Width > 600) img.DX = -img.DX; if (img.Y < 0 || img.Y + image.Height > 400) img.DY = -img.DY; } // 衝突判定 for (int i = 0; i < images.Count; i++) { for (int j = i + 1; j < images.Count; j++) { var a = images[i]; var b = images[j]; if (IsColliding(a, b)) { // 反射(単純にお互い逆方向に跳ね返る) a.DX = -a.DX; a.DY = -a.DY; b.DX = -b.DX; b.DY = -b.DY; } } } Application.Invoke((_, __) => drawingArea.QueueDraw()); }
🔍 衝突関数を追加
private bool IsColliding(MovingImage a, MovingImage b) { return !(a.X + image.Width < b.X || a.X > b.X + image.Width || a.Y + image.Height < b.Y || a.Y > b.Y + image.Height); }
🧪 動作イメージ
- 🖱 複数クリックして画像を出現させる
- 🔁 画像が移動しながら、お互いにぶつかると「ピョンッ」と反転
- 🧲 壁にもバウンド
🔚 全体コード変更まとめ
必要なのは:
OnUpdate
に 衝突ループ追加IsColliding(...)
を定義
それだけで OK!コード本体はそのまま。
✨ 次にやってみる?
- 💥 衝突時に色や画像を変える
- 🔊 サウンドを鳴らす
- 🎮 主人公キャラだけ操作可能にする(←おすすめ)
- 🧠 複雑な物理エンジン連携(Farseer など)
やってみたい方向ある?続けて強化できるよ!
もちろん!
以下が「GTK3 + C# で、画像をクリックで追加 & 移動 & 衝突反射」するフルコードです 🎮🌀
🖼 必要な画像ファイル
icon.png
(プロジェクトディレクトリに置いてください)
小さめの画像(64×64くらい)がおすすめ。
🧾 Program.cs
(フルコード)
using Gtk; using Cairo; using Gdk; using System; using System.Collections.Generic; using System.Timers; public class AnimatedImageWindow : Window { private DrawingArea drawingArea; private Pixbuf image; private List<MovingImage> images = new List<MovingImage>(); private Timer timer; public AnimatedImageWindow() : base("GTK3 Image Collision Animation") { SetDefaultSize(600, 400); SetPosition(WindowPosition.Center); DeleteEvent += (o, args) => Application.Quit(); drawingArea = new DrawingArea(); drawingArea.AddEvents((int)EventMask.ButtonPressMask); drawingArea.Drawn += OnDraw; drawingArea.ButtonPressEvent += OnClick; Add(drawingArea); ShowAll(); // 画像読み込み image = new Pixbuf("icon.png"); // タイマーで更新 timer = new Timer(16); // 約60FPS timer.Elapsed += OnUpdate; timer.Start(); } private void OnClick(object o, ButtonPressEventArgs args) { double x = args.Event.X; double y = args.Event.Y; var rand = new Random(); double dx = rand.NextDouble() * 4 - 2; double dy = rand.NextDouble() * 4 - 2; images.Add(new MovingImage(x, y, dx, dy)); } private void OnUpdate(object sender, ElapsedEventArgs e) { foreach (var img in images) { img.X += img.DX; img.Y += img.DY; // 端でバウンド if (img.X < 0 || img.X + image.Width > 600) img.DX = -img.DX; if (img.Y < 0 || img.Y + image.Height > 400) img.DY = -img.DY; } // 衝突判定(簡易) for (int i = 0; i < images.Count; i++) { for (int j = i + 1; j < images.Count; j++) { var a = images[i]; var b = images[j]; if (IsColliding(a, b)) { // お互いに反射 double tempDX = a.DX; double tempDY = a.DY; a.DX = b.DX; a.DY = b.DY; b.DX = tempDX; b.DY = tempDY; } } } Application.Invoke((_, __) => drawingArea.QueueDraw()); } private bool IsColliding(MovingImage a, MovingImage b) { return !(a.X + image.Width < b.X || a.X > b.X + image.Width || a.Y + image.Height < b.Y || a.Y > b.Y + image.Height); } private void OnDraw(object sender, DrawnArgs args) { Context cr = args.Cr; // 背景 cr.SetSourceRGB(1, 1, 1); cr.Paint(); // 画像を描画 foreach (var img in images) { Gdk.CairoHelper.SetSourcePixbuf(cr, image, img.X, img.Y); cr.Paint(); } } public static void Main() { Application.Init(); new AnimatedImageWindow(); Application.Run(); } private class MovingImage { public double X, Y, DX, DY; public MovingImage(double x, double y, double dx, double dy) { X = x; Y = y; DX = dx; DY = dy; } } }
🛠 ビルド & 実行
GTK3 必要ライブラリ
sudo apt install libgtk-3-dev
コンパイル
mcs -pkg:gtk-sharp-3.0 -out:animated.exe Program.cs
実行
mono animated.exe
✅ 機能まとめ
- 🖱 クリックで画像を生成
- 🌀 自動で動き回る
- 💥 画像同士がぶつかったら反射(速度交換)
- 🧲 壁で跳ね返る
🔧 拡張したい?
- 🎮 キーボードで画像操作(プレイヤーキャラ)
- 💥 衝突時のアニメーション
- 🎵 サウンド追加
- 🌈 パーティクルやエフェクト
次のステップ、希望があればすぐ用意しますよ!何を追加したい?