それじゃあ、画像同士がぶつかったら反射する衝突判定付きアニメーションを追加していきましょう 💥🌀
目次
✅ 追加機能:画像の衝突判定(バウンド+反射)
✨ 更新ポイント:
- 各画像の 位置 (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
✅ 機能まとめ
- 🖱 クリックで画像を生成
- 🌀 自動で動き回る
- 💥 画像同士がぶつかったら反射(速度交換)
- 🧲 壁で跳ね返る
🔧 拡張したい?
- 🎮 キーボードで画像操作(プレイヤーキャラ)
- 💥 衝突時のアニメーション
- 🎵 サウンド追加
- 🌈 パーティクルやエフェクト
次のステップ、希望があればすぐ用意しますよ!何を追加したい?
