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


HSPTV!掲示板


未解決 解決 停止 削除要請

2013
0110
ppr当たり判定9解決


ppr

リンク

2013/1/10(Thu) 20:31:48|NO.51780


kss=100;キャラの最大数 dim kya,kss;キャラの登録 ;キャラの値を取得 kya(1)=3:kya(5)=3 kya(7)=8:kya(46)=8 *start id1=0:id2=0;2つの当たり判定を取得するため、IDは2つ用意 //当たり判定取得 repeat kss:repeat kss;キャラのIDを取得するため、kss^2のループ数になる if id1!=id2:if kya(id1)=kya(id2) :if kya(id1)!=0&kya(id2)!=0{mes ""+id1+"と"+id2+"  位置"+kya(id1)+""} id1++:loop id1=0:id2++:loop ;redraw 1:await 5:redraw 0:goto *start

dim キャラ,ID で指定した値の当たり判定を取得したいのですが、
キャラ数(kss)を増やすと^2となり、かなり重くなってしまいます。
kya(1〜kss)=値
;kya(x,y)とは異なります。
もっと効率のよい方法はないでしょうか。
*うまく説明できなくてすみません。



この記事に返信する


@key

リンク

2013/1/10(Thu) 21:29:18|NO.51785

とにかく見づらい・・・

repeat kss
  repeat kss     if id1!=id2&kya(id1)=kya(id2)&kya(id1)!=0&kya(id2)!=0{       mes ""+id1+"と"+id2+"  位置"+kya(id1)     }     id1++   loop   id1=0   id2++ loop

関係ないけどkssじゃなくてkmaxとかのほうがいいかも


それと100同士、それ以上同士の当たり判定を取るなんて当然重くなる
どんなゲームでも自機との当たり判定しかもたせず軽くしたりしている
互いに当たり判定を取るゲームなら他のことも考えて20までには抑えた方がいい


でも他に方法がないわけじゃない
隠しバッファに単色でキャラごとの当たり判定を全員分描画し、その単色を当たり判定に取るとか
それかDirectXのスプライトを使えばOSレベルで最適化されて高速化した当たり判定の取得ができる



玄冬

リンク

2013/1/10(Thu) 22:54:25|NO.51788

確認ですが「1と5」「5と1」のような
同じ組み合わせの順番違いは必要なのでしょうか?

必要ないのであれば
↓のようにすることで100^2=10000から
100C2=100*99/2*1=4950までループ回数を減らせますよ

kss=100 dim kya,kss kya(1)=3 : kya(5)=3 : kya(7)=8 : kya(46)=8 *start id1=0 : id2=0 repeat kss-1;0〜kss-1まで repeat kss-1-id1;id2+1〜kssまで id1++ if kya(id1)=kya(id2) & kya(id1)!=0 & kya(id2)!=0 {mes ""+id1+"と"+id2+"  位置"+kya(id1)+""} loop id2++ id1=id2 loop



暇人

リンク

2013/1/10(Thu) 22:59:05|NO.51790

条件によって使えたり使えなかったりするから
前提条件が全て分からないとスクリプトで効率良くはできない

NO.51780の条件だけで良いなら(同じIDは一度しか表示しないけど,入れ替えて表示すれば良いだけだが・・・)

kss=100;キャラの最大数 vmax=30//キャラの値最大 dim kya,kss;キャラの登録 ;キャラの値を取得 kya(1)=3:kya(5)=3 kya(7)=8:kya(46)=8 dim kc,vmax+1 //同じ値を持つキャラ数カウント用配列を確保 dim kid,vmax+1,kss //キャラid(kya配列の要素数)保存用 *start id1=0:id2=0;2つの当たり判定を取得するため、IDは2つ用意 //当たり判定取得 memset kc,0,(vmax+1)*4 //キャラ数カウント用配列を初期化 repeat kss if kya(cnt) { v=kya(cnt) kid(v,kc(v))=cnt //kid(キャラの値,現在の同じ値の個数)=キャラid kc(v)++ //同じ値を持つキャラをカウント } loop repeat vmax+1 if kc(cnt)>1{//2個以上同じ値だった id1=kid(cnt,0)//1個目 id2=kid(cnt,1)//2個目 mes ""+id1+"と"+id2+"  位置"+cnt+"" } loop ;redraw 1:await 5:redraw 0:goto *start
キャラが増えても増えた分ぐらいしか処理が増えない方法



MillkeyStars

リンク

2013/1/11(Fri) 04:44:17|NO.51798

時間つぶしに作ってみた効率版。
スクリプト自体はほとんど暇人さんと変わらないけど、比較処理だけを改造したってパターン


kss=100;キャラの最大数 dim kya,kss;キャラの登録 ;キャラの値を取得 kya(1)=3:kya(5)=3 kya(7)=8:kya(46)=8 dim Active_kya,kss //現在有効化されているキャラ用 Active_kya = 0 //有効化されているキャラ数カウント用 dim Active_temp,kss //判定用の一時格納用 dim Active_temp_id,kss //判定用の配列番号一時格納用 repeat kss if kya(cnt){ Active_kya(cnt)=1 Active_temp(Active_kya)=kya(cnt) Active_temp_id(Active_kya)=cnt Active_kya++ } loop mes "登録されているキャラ数 : "+Active_kya main_loop = Active_kya - 1 sub_loop = Active_kya - 1 repeat main_loop front_s = cnt front = Active_temp(cnt) repeat sub_loop,vv cnext = Active_temp(cnt+1) cnext_s = cnt+1 if (front = cnext ) : mes "kya("+Active_temp_id(front_s)+") - kya("+Active_temp_id(cnext_s)+") = "+front loop sub_loop-- vv++ loop



ppr

リンク

2013/1/11(Fri) 06:48:52|NO.51799

>>暇人さん MillkeyStarsさん
なるほど。MillkeyStarsさんのソースを見てわかったことなのですが、
まず、キャラが有効化されている数を確認し、それから私が作ったソースのように実行
ってことですね。
批評的な事を言ってしまうのですが、キャラの存在が増えるごとにあまり変わらない結果と
なってしまう感じがします。
しかし、30体ほどであればなんとかなりそうなので、現在のゲーム作成の参考にしていただきます。

>>玄冬 さん
ん〜。まだちょっと私には理解不全な感じです。
しかし1/2ほどまでにできることを確認しました。
私も自分のペースでじっくりと理解していくので、少々時間を下さい。
先ほどMillkeyStars等のソースを見て、1部は解決したので、この件については(とりあえず)解決とさせていただきます。

>@keyさん
画面のカラーを取得すれば当たり判定をすることができるかもしれません。
でも何かにつまずくような変な感じがするよな気が・・・



MillkeyStars

リンク

2013/1/11(Fri) 09:03:53|NO.51805

まぁ、見た目はさほど変わらないが。
これが、キャラ数1万とか10万とかになると、結構な処理の差になるんよ。

質問者さんが最初に提示したスクリプトだと、100キャラx100キャラ の処理なんだけど。
回答してくれてるみんなのスクリプトだと、必要最低限の処理しかしてない。

作れるキャラは、100体なんだけど、それを使ってるキャラのみの処理に変えると
処理の回数が大幅に削減できるのよ。

配列比較は、競馬とかの馬券って思えばいい。(「馬連オッズ」をググってね)
1-2 1-3 1-4 とかを配列番号に置き換えて考えてみると効率がいい処理をできるかも。

下記は、モジュール化してみた。

#module #deffunc array_same array _ap1,array _ap2 dim _Active_temp,length(_ap1),5 _Active_count = 0 repeat length(_ap1) if _ap1(cnt) { _Active_temp(_Active_count,0)=_ap1(cnt) _Active_temp(_Active_count,1)=cnt _Active_count++ } loop _main_loop = _Active_count - 1 _sub_loop = _main_loop _same_count = 0 id_a = 0 repeat _main_loop _main_cnt = cnt repeat _sub_loop,id_a _sub_cnt = cnt + 1 if (_Active_temp(_main_cnt,0) = _Active_temp(_sub_cnt,0)){ _ap2(_same_count,0)=_Active_temp(_main_cnt,1) _ap2(_same_count,1)=_Active_temp(_sub_cnt,1) _same_count++ } loop _sub_loop-- id_a++ loop return _same_count #global kss=100;キャラの最大数 dim kya,kss;キャラの登録 dim ret,kss,2 ;同じ値の代入用(2次元配列) ;キャラの値を取得 kya(1)=3:kya(5)=3 kya(7)=8:kya(46)=8 kya(99)=13:kya(32)=13 kya(9)=8 array_same kya,ret onaji_count = stat mes "同じ数値があった配列数 : "+onaji_count+" 個" repeat onaji_count mes "["+cnt+"] kya("+ret(cnt,0)+") ≒ kya("+ret(cnt,1)+") = "+kya(ret(cnt,0)) loop stop



暇人

リンク

2013/1/11(Fri) 19:25:50|NO.51809

>まず、キャラが有効化されている数を確認し、それから私が作ったソースのように実行
> ってことですね。
ん?
自分のNO.51790は全然違いますよ


NO.51790のは2個以上同じで値でも2個だけしか表示しなかったのを全て表示するようにした(IDの1、2、3が同じ値だったら1と2、1と3になる2と3等は表示しない)
自分の環境ではCPU10%程度だが、殆どmes行の処理で食ってる
mes行をコメントアウトすれば1000個でも10%程度(awit 5で)

kss=100;キャラの最大数 vmax=30//キャラの値最大 dim kya,kss;キャラの登録 randomize repeat kss kya(cnt)=rnd(vmax)+1 //全て存在に設定 loop dim kc,vmax+1 //同じ値を持つキャラ数カウント用配列を確保 dim kid,vmax+1,kss //キャラid(kya配列の要素数)保存用 *start id1=0:id2=0;2つの当たり判定を取得するため、IDは2つ用意 //当たり判定取得 memset kc,0,(vmax+1)*4 //キャラ数カウント用配列を初期化 repeat kss if kya(cnt) { v=kya(cnt) kid(v,kc(v))=cnt //kid(キャラの値,現在の同じ値の個数)=キャラid kc(v)++ //同じ値を持つキャラをカウント } loop repeat vmax,1 if kc(cnt)>1{//2個以上同じ値だった(cntがキャラの値を表す) id1=kid(cnt,0) //1個目 for i,1,kc(cnt) //0は1個目なので1から id2=kid(cnt,i) //2個目から取得 mes ""+id1+"と"+id2+"  位置"+cnt+"" next } loop redraw 1:await 5:redraw 0:goto *start
キャラの値が入ってたら同じ値が入ってるグループに別けて
同じ値が入ってる数を数える

2個以上の同じ値を持つIDを取り出して表示

こんな感じの流れ

ループ回数は

キャラ数+存在キャラ数+最大値

になるからキャラ数が増える程総当りの判定より処理が軽くなる
逆にキャラ数が少なくて最大値が大きいと逆転もあるが・・・(まぁ、軽い時に少し重いなら普通影響出ないけど)



暇人

リンク

2013/1/11(Fri) 19:28:59|NO.51810

ループ回数が違ってた

>キャラ数+存在キャラ数+最大値

キャラ数+2個以上同じ値を持つキャラ数+最大値

だった・・・



暇人

リンク

2013/1/12(Sat) 19:45:39|NO.51828

NO.51809のは値の順にID取り出してたけど
今度はID順に取り出せるようにした

kss=100;キャラの最大数 vmax=30//キャラの値最大 dim kya,kss;キャラの登録 randomize repeat kss kya(cnt)=rnd(vmax)+1 //全て存在に設定 loop dim kc,vmax+1 //同じ値を持つキャラ数カウント用配列を確保 dim kid,vmax+1,kss //キャラid(kya配列の要素数)保存用 *start id1=0:id2=0;2つの当たり判定を取得するため、IDは2つ用意 //当たり判定取得 memset kc,0,(vmax+1)*4 //キャラ数カウント用配列を初期化 kvc=0 //値の種類数カウンター初期化 repeat kss if kya(cnt) { v=kya(cnt) kid(v,kc(v))=cnt //kid(キャラの値,現在の同じ値の個数)=キャラid if kc(v)=0 {//まだ同じ値は使われてない kid1(kvc)=cnt//1個目だけを保存(ID順にソートするの役目) kvc++ //値の種類数をカウント } kc(v)++ //同じ値を持つキャラをカウント } loop repeat kvc id1=kid1(cnt) //1個目 v = kya(id1) //キャラの値をvに代入 repeat kc(v)-1,1 //0は1個目なので1から(1個しかなければ-1してるのでループせずに抜ける) id2=kid(v,cnt) //2個目から取得 mes ""+id1+"と"+id2+"  位置"+v loop loop redraw 1:await 5:redraw 0:goto *start

ループ回数は

キャラ数+2個以上同じ値を持つキャラ数+値の種類数

値の種類数は使われてる値の種類
最大値30で実際に使われてるのが3,8なら種類数2となる



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