HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2011
1108
ニンニクラー油(よっしーsoft)跳ね返りについて18解決


ニンニクラー油(よっしーsoft)

リンク

2011/11/8(Tue) 21:12:04|NO.42868

掲示板投稿のため、画像は●で代用しています。
避けゲーを作ろうとおもっています。
まずは、●に対する簡素な跳ね返り判定は作ることが出来ました。
そして、●を動かすことも出来ました。
しかし、●が跳ね返るとき、全て同じ方向に跳ね返ってしまいます。
意味が分らないとおもいます、↓の図を見てください
 -------------
|      |
|      |
|  ●   |
|      |
|      |
|      |
 -------------
   ↓
 -------------
|      |
|      |
|      |
|   ●  |
|      |
|      |
 -------------
   ↓
 -------------
|      |
|      |
|      |
|      |
|     ●|
|      |
 -------------
    ↓

 -------------
|      |
|      |
|      |
|   ●  |
|      |
|      |
 -------------
   ↓


 -------------
|      |
|  ●   |
|      |
|      |
|      |
|      |
 -------------
このように、同じ向きしか返してくれません。
それをこのようにしたいのです。↓
 -------------
|      |
|      |
|  ●   |
|      |
|      |
|      |
 -------------
   ↓
 -------------
|      |
|      |
|      |
|   ●  |
|      |
|      |
 -------------
   ↓
 -------------
|      |
|      |
|      |
|      |
|     ●|
|      |
 -------------
    ↓

 -------------
|      |
|      |
|      |
|      |
|      |
|    ● |
 -------------
   ↓


 -------------
|      |
|      |
|      |
|      |
|   ●  |
|      |
 -------------
なんとなく分っていただけたでしょうか・・・
●の返し方が分る方、返答お願いします。



このようなスクリプトを書きました。

SCREEN 0,480,580 RANDOMIZE X=RND(480) Y=RND(480) *a POS X,Y MES"■" WAIT 1 X=X+5 Y=Y+5 CLS IF X>480 :GOTO *b IF Y>580 :GOTO *b GOTO *a *b POS X,Y MES"■" WAIT 1 X=X-5 Y=Y-5 CLS IF X<0 :GOTO *a IF Y<0 :GOTO *a GOTO *b
回答をお待ちしています。



この記事に返信する


ニンニクラー油(よっしーsoft)

リンク

2011/11/8(Tue) 21:15:13|NO.42869

-------------
|          |
|          |
|  ●       |
|          |
|          |
|          |
 -------------
   ↓
 -------------
|          |
|          |
|          |
|   ●      |
|          |
|          |
 -------------
   ↓
 -------------
|          |
|          |
|          |
|          |
|     ●    |
|          |
 -------------
    ↓

 -------------
|          |
|          |
|          |
|   ●      |
|          |
|          |
 -------------
   ↓


 -------------
|          |
|  ●       |
|          |
|          |
|          |
|          |
 -------------

 -------------
|          |
|          |
|  ●       |
|          |
|          |
|          |
 -------------
   ↓
 -------------
|          |
|          |
|          |
|   ●      |
|          |
|          |
 -------------
   ↓
 -------------
|          |
|          |
|          |
|          |
|     ●    |
|          |
 -------------
    ↓

 -------------
|          |
|          |
|          |
|          |
|          |
|    ●     |
 -------------
   ↓


 -------------
|          |
|          |
|          |
|          |
|   ●      |
|          |
 -------------
でした。



ニンニクラー油(よっしーsoft)

リンク

2011/11/8(Tue) 21:16:19|NO.42870

-------------
|          |
|          |
|  ●       |
|          |
|          |
|          |
 -------------
   ↓
 -------------
|          |
|          |
|          |
|   ●      |
|          |
|          |
 -------------
   ↓
 -------------
|          |
|          |
|          |
|          |
|          |
|         ●|
 -------------
    ↓

 -------------
|          |
|          |
|          |
|   ●      |
|          |
|          |
 -------------
   ↓


 -------------
|          |
|  ●       |
|          |
|          |
|          |
|          |
 -------------

 -------------
|          |
|          |
|  ●       |
|          |
|          |
|          |
 -------------
   ↓
 -------------
|          |
|          |
|          |
|   ●      |
|          |
|          |
 -------------
   ↓
 -------------
|          |
|          |
|          |
|          |
|         ●|
|          |
 -------------
    ↓

 -------------
|          |
|          |
|          |
|          |
|          |
|    ●     |
 -------------
   ↓


 -------------
|          |
|          |
|          |
|          |
|   ●      |
|          |
 -------------



ニンニクラー油(よっしーsoft)

リンク

2011/11/8(Tue) 21:16:43|NO.42871

たびたび連投すみませんでした。
下の図が正しいです。



FPW

リンク

2011/11/8(Tue) 21:26:17|NO.42873

●は、右上・右下・左上・左下の4方向の動きが考えられます。
一方、貼ってくださったスクリプトでは「X+5,Y+5」の「右下」、
「X-5,Y-5」の「左上」パターンしかありません。
残り二方向、「X-5,Y+5」の「左下」、「X+5,Y-5」の「右上」
が必要です。

そうして考えていくと、今のままの、ラベルごとに方向を指定する方法は
少々効率が悪いことに気づくかと思います。



ニンニクラー油(よっしーsoft)

リンク

2011/11/8(Tue) 21:27:17|NO.42874

片方を-5、もう片方を+5にするとできました!
FPWさん、ありがとうございました



FPW

リンク

2011/11/8(Tue) 21:35:50|NO.42876

解決したみたいですが一応今後のために。

ラベルを4つ作るよりも、たとえばX,Yの変化量をDX,DYとして(X=X+DX,Y=Y+DY)、
壁にぶつかるたびにDX,DYの中身を変更していくほうが効率的です。



ひじき

リンク

2011/11/8(Tue) 22:40:19|NO.42878

FPWさんが既におっしゃられていますが、
暇だったので具体的な例を組んでみました。
既に解決しているようで、ここを見て下さるか心配ですが、
一応投稿しておきます。

;------------------------------------------------------------------------------- ; 跳ね返りサンプル ; ランダムなどを盛り込んでいない割と最小限な作りです。 ; お好きに改変してお使い下さい。 ;------------------------------------------------------------------------------- x = 320 ;初期位置X y = 240 ;初期位置Y dx = 5 ;移動量X(毎フレーム移動する量) dy = 5 ;移動量Y #if 0 ;←ここの0を1にすると移動量がランダムになります。 ; このスクリプトだと単純な4方向以外の方向にも対応しています。 ; 試してみて下さい。 randomize dx = -5 + rnd(10) dy = -5 + rnd(10) #endif ;--------------------------------------------------------------------------- ; メインループ ;--------------------------------------------------------------------------- *__main redraw 0 color 255,255,255:boxf:color ;clsよりこちらの方が高速です ;移動 x + dx y + dy ;画面外へ出たら方向転換 if(x < 0 | x > 640) { dx = dx - (dx * 2) } if(y < 0 | y > 480) { dy = dy - (dy * 2) } ;描画 pos x - 8 , y - 8 ;↑1文字のサイズが全角の場合16x16なので、 ; xとyからそれぞれ-8を引いてあげることで、 ; X,Y座標を中心として文字が描画されます。 mes "■" redraw 1 wait 1 goto *__main



ニンニクラー油(よっしーsoft)

リンク

2011/11/9(Wed) 19:17:55|NO.42892

みなさんすばらしい回答をいただきました。
今後のゲームつくりに役立てていこうとおもうので、参考に成りました。



玄冬

リンク

2011/11/10(Thu) 03:11:26|NO.42900

>ひじき様
28行目:dx = dx - (dx * 2)→dx *= -1
31行目:dy = dy - (dy * 2)→dy *= -1
で良いのでは?



ひじき

リンク

2011/11/10(Thu) 16:12:26|NO.42904

>玄冬さま
確かにそれで同じ挙動をするのですが、
推測ながらスレ主さんがプログラミングを初めたばかりだと思い、
見やすく覚えやすい記述を優先しました。

私がプログラミングを初めてすぐの頃(といっても未だに3年ほどなので初心者ですが)
>dx *= -1
こういった記述方法が分かりづらく、どういった挙動をしているのかが分からなかったためです。
私が思うに、サンプルに求められるものは、
書き方が遠回しになろうと「誰が読んでもわかる記述法」だと思うのです。

なんだか当初お返事する予定の内容より長くなってしまいましたが、
こんなところですw
もし私がとてもイレギュラーなことを言っていたらすみません。



check

リンク

2011/11/10(Thu) 16:45:24|NO.42905

こういう場合はコメントで
// 符号反転
とでも書いておけばいいんじゃないんだろうか。

dx = dx - (dx * 2)のほうが、
逆に何をしているのかつかみにくい気がするのは俺だけだろうか。
遅くなるし。


これ以上はスレの趣旨と離れるのでやめておく。



ひじき

リンク

2011/11/10(Thu) 17:50:16|NO.42906

>checkさま,ならびに玄冬さま
私が開示したサンプルに問題があることは分かりました。
以降気をつけます。ご指摘ありがとうございました。
そして玄冬さまには反論とも取れるレスをしてしまい申し訳ありませんでした。

>スレ主さま
結果的にスレを汚してしまって申し訳ありませんでした。
流れで分かる通り、私が示したサンプルを参考にすることは推奨しません。



ひらまる

リンク

2011/11/10(Thu) 18:20:54|NO.42909

同じ処理をするのにも様々な書き方があるのがプログラミングの面白さでもあり、
たまに論争に発展し、宗教論のようになってしまう面でもあると思います。
んでなんか楽しそうだったので私も書いてみました。

;乱数初期化 randomize ;スクリーン初期化 ScreenW = 500 ScreenH = 500 screen 0, ScreenW, ScreenH title "バウンドするよー" ;ボール変数宣言 MaxBallNum = 256 ; ボールの最大数 ddim MaxSize, MaxBallNum ; ボールの最大半径 ddim MinSize, MaxBallNum ; ボールの最小半径 ddim PosX, MaxBallNum ; ボールX座標 実数配列 ddim PosY, MaxBallNum ; ボールY座標 実数配列 ddim AddX, MaxBallNum ; ボールX加算 実数配列 ddim AddY, MaxBallNum ; ボールY加算 実数配列 ddim SizeX, MaxBallNum ; ボールXサイズ 実数配列 ddim SizeY, MaxBallNum ; ボールYサイズ 実数配列 dim ColorR, MaxBallNum ; ボール色赤要素 整数配列 dim ColorG, MaxBallNum ; ボール色緑要素 整数配列 dim ColorB, MaxBallNum ; ボール色青要素 整数配列 ;ボール初期化 repeat MaxBallNum MaxSize( cnt ) = 5.0 + rnd( 25 ) MinSize( cnt ) = MaxSize( cnt ) / 2 PosX( cnt ) = 1.0 * rnd( ScreenW ) PosY( cnt ) = 1.0 * rnd( ScreenH ) AddX( cnt ) = -3.2 + 0.1 * rnd( 64 ) AddY( cnt ) = 0.1 + 0.1 * rnd( 32 ) SizeX( cnt ) = MaxSize( cnt ) SizeY( cnt ) = MaxSize( cnt ) ColorR( cnt ) = rnd( 256 ) ColorG( cnt ) = rnd( 256 ) ColorB( cnt ) = rnd( 256 ) loop ;メインループ repeat ;ボール更新 repeat MaxBallNum ;表示 nowX1 = PosX( cnt ) - SizeX( cnt ) nowY1 = PosY( cnt ) - SizeY( cnt ) nowX2 = PosX( cnt ) + SizeX( cnt ) nowY2 = PosY( cnt ) + SizeY( cnt ) color ColorR( cnt ), ColorG( cnt ), ColorB( cnt ) circle nowX1, nowY1, nowX2, nowY2 ;移動 PosX( cnt ) += AddX( cnt ) PosY( cnt ) += AddY( cnt ) ;壁に隣接 if PosX( cnt ) - MaxSize( cnt ) < 0 : SizeX( cnt ) = 1.0 * PosX( cnt ) ; 左の壁に隣接 if PosY( cnt ) - MaxSize( cnt ) < 0 : SizeY( cnt ) = 1.0 * PosY( cnt ) ; 上の壁に隣接 if PosX( cnt ) + MaxSize( cnt ) > ScreenW : SizeX( cnt ) = 1.0 * ScreenW - PosX( cnt ) ; 右の壁に隣接 if PosY( cnt ) + MaxSize( cnt ) > ScreenH : SizeY( cnt ) = 1.0 * ScreenH - PosY( cnt ) ; 下の壁に隣接 ;めり込み回避 if PosX( cnt ) < MinSize( cnt ) : PosX( cnt ) = MinSize( cnt ) ; 左の壁へのめり込み回避 if PosY( cnt ) < MinSize( cnt ) : PosY( cnt ) = MinSize( cnt ) ; 上の壁へのめり込み回避 if PosX( cnt ) > ScreenW - MinSize( cnt ) : PosX( cnt ) = 1.0 * ScreenW - MinSize( cnt ) ; 右の壁へのめり込み回避 if PosY( cnt ) > ScreenH - MinSize( cnt ) : PosY( cnt ) = 1.0 * ScreenH - MinSize( cnt ) ; 下の壁へのめり込み回避 ;バウンド if SizeX( cnt ) < MinSize( cnt ) : AddX( cnt ) = AddX( cnt ) * -1 : SizeX( cnt ) = MinSize( cnt ); 横バウンド if SizeY( cnt ) < MinSize( cnt ) : AddY( cnt ) = AddY( cnt ) * -1 : SizeY( cnt ) = MinSize( cnt ); 縦バウンド loop ;画面更新 redraw 1 redraw 0 gradf 0, 0, ScreenW, ScreenH, 1, $FFFFFF, $6464FF await 1 loop



ニンニクラー油(よっしーsoft)

リンク

2011/11/10(Thu) 18:33:20|NO.42910

ひらまるさんすごい!
早速scrに変換しますw



玄冬

リンク

2011/11/10(Thu) 22:56:52|NO.42921

>ひじきさま
>>dx *= -1
>こういった記述方法が分かりづらく、どういった挙動をしているのかが分からなかったためです。
>私が思うに、サンプルに求められるものは、
>書き方が遠回しになろうと「誰が読んでもわかる記述法」だと思うのです。

激しく同意
a += 3 ;a = a + 3
b *= -1 ;b = b * -1
c++ ;c += 1 | c = c + 1
とか、初心者のころは大嫌いでした。

ただ、私が言いたかったのは「書き方」というより
元の変数からその2倍の数を引くよりも
-1をかけるという「考え方」の方が
わかりやすい気がするということでした。

「誰が読んでもわかる記述法」だと↓のようになるのでしょうか。
28行目:dx = dx - (dx * 2)→dx = -1 * dx
31行目:dy = dy - (dy * 2)→dy = -1 * dy

>ひらまるさま
>同じ処理をするのにも様々な書き方があるのがプログラミングの面白さでもあり、
>たまに論争に発展し、宗教論のようになってしまう面でもあると思います
それも同意

極座標&多次元配列信者の私は動かすだけなら

#enum X = 0 ;X #enum Y ;Y #enum A ;角度 #enum R ;スピード(ドット/ループ) #const SIZE 10;サイズ(半径) randomize ddim a_BALL,4; a_BALL(パラメータ, 個体数) a_BALL = 320.0, 240.0, double(rnd(360)), 15.0 + rnd(5) *main color $FF,$FF,$FF : boxf gosub *sub_move gosub *sub_draw gosub *sub_check redraw 1 await 20 redraw 2 goto *main stop *sub_move ;移動 a_BALL(X) += cos(deg2rad(a_BALL(A))) * a_BALL(R) ;r×cosθ a_BALL(Y) += sin(deg2rad(a_BALL(A))) * a_BALL(R) ;r×sinθ return *sub_draw ;描画 color : circle a_BALL(X) - SIZE, a_BALL(Y) - SIZE, a_BALL(X) + SIZE, a_BALL(Y) + SIZE return *sub_check ;衝突判定 if a_BALL(X) <= SIZE | 640 - SIZE <= a_BALL(X) : a_BALL(A) = 180.0 - a_BALL(A) ;180°−θ(水平反転) if a_BALL(Y) <= SIZE | 480 - SIZE <= a_BALL(Y) : a_BALL(A) *= -1.0 ;−θ  (垂直反転) return
としますね。
↓遊んでみました。

#enum X = 0 ;X #enum Y ;Y #enum A ;角度 #enum R ;スピード(ドット/ループ) #enum SIZE ;サイズ(半径) randomize ddim a_BALL,5,0; a_BALL(パラメータ, 個体数) a_BALL(0,0) = 320.0, 240.0, double(rnd(360)), 15.0 + rnd(5), 10.0 + rnd(5) *main color : boxf repeat length2(a_BALL) gosub *sub_move gosub *sub_draw gosub *sub_check loop redraw 1 await 20 redraw 2 goto *main stop *sub_move ;移動 a_BALL(X, cnt) += cos(deg2rad(a_BALL(A, cnt))) * a_BALL(R, cnt) ;r×cosθ a_BALL(Y, cnt) += sin(deg2rad(a_BALL(A, cnt))) * a_BALL(R, cnt) ;r×sinθ return *sub_draw ;描画 color (cnt\12)*20, (cnt\12)*20,255: circle a_BALL(X, cnt) - a_BALL(SIZE, cnt), a_BALL(Y, cnt)-a_BALL(SIZE, cnt), a_BALL(X, cnt)+a_BALL(SIZE, cnt), a_BALL(Y, cnt) + a_BALL(SIZE, cnt) return *sub_check ;衝突判定 if a_BALL(X, cnt) <= a_BALL(SIZE, cnt) | 640 - a_BALL(SIZE, cnt) <= a_BALL(X, cnt) : a_BALL(A, cnt) = 180.0 - a_BALL(A, cnt) :v_flg++;180°−θ(水平反転) if a_BALL(Y, cnt) <= a_BALL(SIZE, cnt) | 480 - a_BALL(SIZE, cnt) <= a_BALL(Y, cnt) : a_BALL(A, cnt) *= -1.0 :v_flg++;−θ  (垂直反転) if v_flg : a_BALL(0, (length2(a_BALL)\1500)) = 320.0,240.0, double(rnd(360)), 5.0 + rnd(5), 5.0 + rnd(15) v_flg = 0 return



ひらまる

リンク

2011/11/11(Fri) 01:43:01|NO.42922

>玄冬さん
いいですねー 私も昔は多次元配列教の信者でした。上のソースでは使っていませんが、今はモジュール変数教の信者です(笑
でもLetやDivを使うには多次元配列が有利ですねー あとmemsetやmemcpyなどががっつりはまると高速ですねー
それでも私はモジュール変数教です(笑



通りすがり

リンク

2011/11/11(Fri) 14:50:14|NO.42923

マイナスとの掛け算は初学者には理解し辛い部分もあると思うので
理解しやすいという観点で考えれば恐らくもっとも簡単な記述はこうではないかと

dx = 0 - dx dy = 0 - dy



ひじき

リンク

2011/11/11(Fri) 15:57:00|NO.42924

>玄冬さま
私が反論してしまい、自らそれを訂正しておきながら
同意されるというのは複雑な状態ですが、
とにかくありがとうございます。

たしかに
>>dx - (dx * 2)
という記述はあまりにも遠回しで、
逆に分かりづらくしていました;
私が反転方法を初めて試行錯誤して見つけたとき、
この方法だったので、ついこう書いてしまいました。
よく考えてみれば、
>>dx * -1
という記述の方がスマートで分かりやすかったと思います。

ただ、私が言いたかった部分はそこではなく、
数学にはない「+=」や「-=」や「*=」を
プログラミング初心者に開示するサンプルに
含めると訳が分からなくなってしまうのではないか
というのを言いたかったのです。
が、もう伝わっているようですね。

蛇足としては、>>42906 を書いてから、
話が微妙にかみあってないことに気づいたのですが、
さらに私が1人でレスを伸ばしてしまうのもどうかと思い、
そのままにしておくつもりだったのですが、
スッキリして良かったです。
ありがとうございました。

最後に、スレ主さまや他の皆様に
私が開示したサンプル、およびそれの指摘への返答が不適切で
スレを汚してしまい申し訳ありませんでした。



ONION software Copyright 1997-2023(c) All rights reserved.