|
|
|
2011/12/27(Tue) 11:51:37|NO.43951
HSP超初心者です。ちなみに高2です。
windows 7やvistaに標準装備されている「バブル」のようなボール同士が跳ね返るスクリーンセーバーを作りたいです
難しいですかね
とりあえず、以下のように多数のボールが壁に衝突して跳ね返るスクリプトは作りました(ほぼ引用ですが‥‥)
ボール同士が跳ね返る動作をさせるには、やはりOBAQを利用しないと出来ませんか?
OBQAは理解し難くなるべく利用したくないのですが、利用するならどの辺に追加すれば良いでしょうか
screen 0,600,400,0; 画面サイズ
winx=ginfo_winx ; 現在のウィンドウ描画エリアの横幅サイズ
winy=ginfo_winy ; 現在のウィンドウ描画エリアの縦幅サイズ
randomize ; rnd関数で発生させる乱数のパターンを初期化
ballnum=50 ; ボール数
; 任意の要素を持つ配列変数
dim bx,ballnum
dim by,ballnum
dim movex,ballnum
dim movey,ballnum
bs=40 ; ボールサイズ
repeat ballnum
; 移動速度パラメータ
movex(cnt)=rnd(11); 0〜10の範囲で整数の乱数値を発生
movey(cnt)=rnd(11)
movex(cnt)-=5; -5〜5の範囲で整数の乱数値を発生
movey(cnt)-=5
; ボールが静止状態になるのを防ぐ
if (movex(cnt)=0)&(movey(cnt)=0):movex(cnt)=1 or movey(cnt)=1
; 描写初期位置
bx(cnt)=rnd(winx-bs)
by(cnt)=rnd(winy-bs)
loop
*mainlp; メインループ
redraw 0
color 255,255,255:boxf
repeat ballnum
n=cnt
gosub *ballmove
gosub *ballput
loop
redraw 1
await 2
goto *mainlp
*ballmove; ボールの移動
;x軸方向
bx(n)=bx(n)+movex(n)
if bx(n)<0:bx(n)=0:movex(n)=0-movex(n);左壁に当たった時符号反転し反対へ移動
if bx(n)>(winx-bs):bx(n)=winx-bs:movex(n)=0-movex(n);右壁に当たった時符号反転し反対へ移動
;y軸方向
by(n)=by(n)+movey(n)
if by(n)<0:by(n)=0:movey(n)=0-movey(n);上壁に当たった時符号反転し反対へ移動
if by(n)>(winy-bs):by(n)=winy-bs:movey(n)=0-movey(n);下壁に当たった時符号反転し反対へ移動
return
*ballput; ボールの描写
color 0,0,0
circle bx(n),by(n),bx(n)+bs,by(n)+bs,0
return
| |
|
2011/12/27(Tue) 18:03:20|NO.43958
*ballmoveの中で2つのボールの中心間の距離を調べてそれがボールの直径よりも小さかったら
衝突していると判断するとか。
衝突していることがわかったらあとはx軸と衝突している時と同じように動かす方向を変えるだけ。
|
|
2011/12/27(Tue) 23:13:23|NO.43959
初心者さんのスクリプトに追加する方法は分からないのですが、参考までに、OBAQを利用した一例です(ほとんどサンプルからの引用ですが)。
OBAQはHSPとは別の内部座標を持っていたり、いろいろ勝手が違って戸惑いますよね。
#include "obaq.as"
; [ESC]で終了します
randomize ; 乱数の初期化
screen 0,640,480 ; ウィンドウ初期化
qreset ; OBAQの初期化
qgravity 0,0 ; 重力なし
qborder -80,-60,80,60
cenx=320/4:ceny=240/4
user4 = 0.0
user5 = 0.0
user6 = 0.0
ballnum=10
repeat 100
if ballnum=0 : break
qaddpoly ball, 16, cenx+rnd(60)-30,ceny+rnd(100)-50,0,10,10 ; 多角形を追加
if ball>=0 : ballnum-- ; 追加に成功したか確認のため
qweight ball, 0.3, 1200.0
user4 = 0.01 * rnd(10)
user5 = 0.01 * rnd(10)
user6 = 0.01 * rnd(10)
quser2 ball, user4, user5, user6 ; 実数型パラメータの保存領域
qspeed ball,user4,user5,user6, 1 ; 初期の向きとスピードをセット
loop
*main
; メインループ
redraw 0 ; 画面の更新を開始
cls 2
stick key,15 ; キーの取得
if key&128 : end ; [ESC]キーで終了
qexec ; OBAQによるオブジェクトの更新
qdraw ; オブジェクトの描画
redraw 1 ; 画面の更新を終了
await 12 ; 一定時間待つ
goto *main
|
|
2011/12/27(Tue) 23:19:39|NO.43960
失礼、この行は不用でした。
quser2 ball, user4, user5, user6 ; 実数型パラメータの保存領域
ほかにもいろいろ無駄がありそうですが…
あくまで一例と言う事でお目こぼしをお願いします。
|
|
2011/12/28(Wed) 20:35:26|NO.43972
; ball_mul.hsp 沢山のボールを動かす
screen 0,640,480,0
ax=ginfo_winx:ay=ginfo_winy
randomize
ballnum=50
dim bx,ballnum
dim by,ballnum
dim dx,ballnum
dim dy,ballnum
dim ballh,ballnum
dim balls,ballnum
dim ballv,ballnum
dim bs,ballnum
bs_low=10 ; 最小ボールサイズ
repeat ballnum
; ボールの発生
; HSV 色指定
ballh(cnt)=rnd(192)
balls(cnt)=rnd(256)
ballv(cnt)=rnd(256)
; 移動パラメータ
dx(cnt)=rnd(11)
dy(cnt)=rnd(11)
dx(cnt)-=5:dy(cnt)-=5
if (dx(cnt)=0)&&(dy(cnt)=0):dx(cnt)=1
; 位置
bx(cnt)=rnd(ax-bs(cnt))
by(cnt)=rnd(ay-bs(cnt))
; サイズ
bs(cnt)=bs_low+rnd(100)
loop
; メインループ
*mainlp
redraw 0
color 0,0,0:boxf
repeat ballnum
n=cnt
gosub *ballmove
gosub *ballput
loop
redraw 1
await 2
goto *mainlp
; ボールの移動
*ballmove
bx(n)=bx(n)+dx(n)
if bx(n)<0:bx(n)=0:dx(n)=0-dx(n)
if bx(n)>(ax-bs(n)):bx(n)=ax-bs(n):dx(n)=0-dx(n)
by(n)=by(n)+dy(n)
if by(n)<0:by(n)=0:dy(n)=0-dy(n)
if by(n)>(ay-bs(n)):by(n)=ay-bs(n):dy(n)=0-dy(n)
return
; ボールの表示
*ballput
h=ballh(n)
s=balls(n)
v=ballv(n)
hsvcolor h,s,v
circle bx(n),by(n),bx(n)+bs(n),by(n)+bs(n),1
return
| |
|
2011/12/28(Wed) 20:54:09|NO.43974
皆さんご丁寧にありがとうございます。
参考にさせていただきます。
|
|