- - PR -
四角い画像を円として認識させる
| 投稿者 | 投稿内容 | ||||
|---|---|---|---|---|---|
|
投稿日時: 2004-08-31 20:26
次のようなアプレットを作っています。
ピクセルの色情報を作り、それをMemoryImageSourceで画像にして、バブル大中小を10個ずつ作りました。バブルの境界線の色情報は、0x6fffffffにしてあります。境界線より外側は無色透明です。それを画面下に向かってボールが落ちるように、落ちたら跳ね、最後は下にたまるというところまではできました。ただし各バブルは重なってもそのままです。今度は、それぞれのバブルが互いに接触したら("四角い画像が接触"ではなく、その中の"バブルの境界線"が接触したらという意味)、跳ね合うようにしたいですが、一応自分でコードを書いてみてコンパイルもできましたが、実行すると、バブルが初めの位置から動かないままになってしまいました。overlap_0x6fffffff()というメソッドがおかしいのです。自分でもコードのみならず頭の中までもがぐちゃぐちゃになっています。最終的な完成目標としては、ぶつかり合ったら相手のバブルの力を受け継いで跳ねる、また、今は縦方向のみで動いていますが、横方向の動きも入れようと思っています。でもとりあえず今は縦方向のみでよいので、ぶつかったら反対方向に動くことをしたいです。この怪しげなoverlap_0x6fffffff()というメソッド(バブルの境界線がオーバーラップしたら、反対方向に動く)を本当に動くようにするにはどのようにしたらよいかを教えてください。
[ メッセージ編集済み 編集者: ゴールデン 編集日時 2004-08-31 21:52 ] | ||||
|
投稿日時: 2004-08-31 21:27
[url=http://www.atmarkit.co.jp/bbs/phpBB/faq-japanese.php#bbcode]codeタグ[/code]を使ってコードを見やすくしていただけるとうれしいのですが・・・。
下記のようなBubbleクラスを作って、Appletの中で全部のBubble配列を持ったほうが分かりやすくなりますよ。すべてをApplet内で処理をしようとすると分かりにくくなります。
| ||||
|
投稿日時: 2004-08-31 22:29
H2さん、お返事ありがとうございます。そうですね。変数の種類が多すぎてごちゃごちゃしているので、すっきりさせるためにクラスを作るといいですね。最終的にはそのように書き換えます。
説明不足な点を書き加えます。 ugoku()…各バブルを縦方向に動かす。 haiti_Bubble()…大中小のバブルを10個ずつ配置する。 overlap_0x6fffffff()…バブルどおしの半透明白の線が重なったら、縦反対方向に動く。 setxy()…バブルの位置情報(x,y)に合わせて、バブル内の各ピクセルの位置情報を関係付ける。 bunnkai_pixels_color_and_xy(int a)…画像として作った一辺aのバブルをピクセルに分解し、@それぞれの色情報を配列に入れ、Aそれぞれの位置情報をb_x0、b_y0(これはバブル大の場合)の配列に入れる。 make_Bubble(int a)…ピクセルの色情報を設定し、直径aのバブルが入った一辺aの画像を作る。バブルの色の境界線は0x6fffffffで、その外側は無色透明。 特にoverlap_0x6fffffff()についてよろしくお願いします。 [ メッセージ編集済み 編集者: ゴールデン 編集日時 2004-08-31 22:40 ] [ メッセージ編集済み 編集者: ゴールデン 編集日時 2004-08-31 22:53 ] | ||||
|
投稿日時: 2004-09-01 01:47
プログラムがよくわからないです。
動きは違いますが、別のプログラムを作ったのでよければ参考にしてください。 import java.awt.*; import javax.swing.*; /* * 質量同じ、半径同じ、初速同じ。初期の位置は等間隔。初速の向きのみランダム * 重力加速度なし。壁なし。完全鋼体。 */ public class BubbleFrame extends JFrame implements Runnable { Bubble[] bubbles; BubbleView view; BubbleFrame() { bubbles = new Bubble[100]; for (int i=0; i<bubbles.length; i++) { double th = Math.random() * 2.0 * Math.PI; // 0..2π double speed = 10.0; bubbles[i] = new Bubble(100*(i%10), 100*(i/10), 20, speed*Math.cos(th), speed*Math.sin(th)); } view = new BubbleView(this); getContentPane().add(view); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(640, 480); setVisible(true); new Thread(this).start(); } public void run() { for(; for (int i=0; i<bubbles.length; i++) { bubbles[i].move(0.1); } collision(); repaint(); try { Thread.sleep(100); } catch (InterruptedException e) { } } } void collision() { for (int i=0; i<bubbles.length-1; i++) { for (int j=i+1; j<bubbles.length; j++) { // 2つのバブルの距離が半径の和以下なら衝突! double dx = bubbles[i].x - bubbles[j].x; double dy = bubbles[i].y - bubbles[j].y; if (Math.sqrt(dx*dx + dy*dy) < (bubbles[i].radius + bubbles[j].radius)) { // お互いが近づいているときだけ、向きを変える。 double vdx = bubbles[i].dx - bubbles[j].dx; double vdy = bubbles[i].dy - bubbles[j].dy; if (dx*vdx+dy*vdy<0) { // 物理法則を忘れたので速度ベクトルを交換するだけ double tmpx = bubbles[i].dx; double tmpy = bubbles[i].dy; bubbles[i].dx = bubbles[j].dx; bubbles[i].dy = bubbles[j].dy; bubbles[j].dx = tmpx; bubbles[j].dy = tmpy; } } } } } public static void main(String[] args) { new BubbleFrame(); } } class Bubble { double x; double y; double radius; double dx; double dy; Bubble(double x, double y, double radius, double dx, double dy) { this.x = x; this.y = y; this.radius = radius; this.dx = dx; this.dy = dy; } void move(double dt) { x += dx * dt; y += dy * dt; } void draw(Graphics g) { g.drawOval((int)(x-radius), (int)(y-radius), (int)radius*2, (int)radius*2); } } class BubbleView extends JComponent { BubbleFrame frame; BubbleView(BubbleFrame frame) { this.frame = frame; } public void paintComponent(Graphics g) { for (int i=0; i<frame.bubbles.length; i++) { frame.bubbles[i].draw(g); } } } | ||||
|
投稿日時: 2004-09-01 10:09
forが9つもある・・・。申し訳ないのですが、これはさすがに理解しようにもできません。ここは「急がば回れ」でa-sanさんのプログラムをサンプルに分かりやすいプログラムに書きかえたほうが早いと思いますよ。
| ||||
|
投稿日時: 2004-09-01 11:16
戯れに計算してみました。
3*10*31*31*10*25*25*3*10*19*19 = 1,951,430,625,000 さすがにこれはお勧めできないです…。 | ||||
|
投稿日時: 2004-09-01 11:20
a-san,H2さんありがとうございます。
a-san、わざわざプログラムを作って頂いてありがとうございます。a-sanのプログラムを動かしてみました。だけど、円は表示されますが円が動かないままです。できればまたアドバイスを頂きたいです。でも、私の場合、ピクセルごとの色情報をMemoryImageSourceで画像にしてから、0x6fffffffの位置を知るために、PixelGrabberで、画像を分解して位置情報を得ている、ということをしているため2度手間をしてややこしくしていることに気づきました。すべてdrawOvalメソッドから位置情報を得ることができれば、ややこしい部分を省くことができることにa-sanのプログラムを見て気づきました。できるかどうか分かりませんが、今晩やってみようと思います。またよろしくお願いします。 | ||||
|
投稿日時: 2004-09-01 15:34
要するにオブジェクトどうしの衝突判定をしたいわけですよね ?
今回は円なのでa-sanが書かれているように半径と距離で計算できるので判定はラクですが、オブジェクト数が増えると判定の計算量が指数関数的に爆発します。 もっと簡便な式で近似計算をしたり、「近くにありそうなオブジェクトだけ判定する」ような工夫をすると、高速にたくさんのオブジェクトを動かせるようになると思います。 そういうときには 3D ゲームの手法を調べられるといいでしょう。 ...そこまでは必要ないのかもしれませんけれど。余談ですみません。 | ||||
