|
|
2013/12/6(Fri) 00:03:24|NO.58613
HGIMGでオブジェクト作成すると、作成が新し順に前面にオブジェクトが表示されますよね。
setobjmodeなどでOBJ_LATEを設定すると、指定した対象が前面に表示されますが、もっと細かく設定することはできないでしょうか。
オブジェクトにOBJ_LATEを設定すると消すのが面倒だし、OBJ_LATEの設定を複数に行うと結局は設定しなっかた時と同じく作成が古い順に後ろに隠れてしまいます。
よろしければアドバイス頂けないでしょうか。
|
|
2013/12/9(Mon) 02:36:31|NO.58652
> グループ pos: (初期値:0,0,0)
> オブジェクトのX,Y,Z座標を指定します。
> 2Dオブジェクトの場合は、(X,Y)が座標に使用され、
> Zは優先度(0.0〜1.0)として扱われます。
2Dの優先度は廃止された
全て自前で処理するしかない(固定された優先度なら楽だが、3Dオブジェクトの間に2Dをおいたりは出来ない、複数回hgdrawすれば別だが・・・)
2Dスプライトの描画の優先度を制御するのは凄く面倒になる・・・
優先度に合わせてオブジェクトが私用するモデルを入れ替えて
それに合わせて座標や設定も同じく入れ替えて・・・
2Dスプライトオブジェクトを非表示で作って
posグループやコリジョン等をオブジェクトのを利用して
表示をhgrotateでするサンプル
#include "hgimg3.as"
hgini
texload2 dir_exe+"\\hsptv\\hsptv_img.png" ; テクスチャの登録
texid=stat
setuv 0,0,1,1
addspr spmid,1 //スプライトオブジェクトの座標やコリジョングループを利用するためモデル作成
MY_UVNO=0 //自分のデータを入れる要素数
EN_UVNO=1
dim chr_uv,6,10 //キャラ画像の位置とサイズ、判定データ
//自分
//画像の左上X、左上Y、画像サイズX、画像サイズY、判定サイズX、判定サイズY
chr_uv(0,MY_UVNO)=0,64*3,64,64,40,60
//敵
chr_uv(0,EN_UVNO )= 0,64*4,64,64,45,60
chr_uv(0,EN_UVNO+1)= 64*2,64*4,64,64,60,60
chr_uv(0,EN_UVNO+2)=64*2*2,64*4,64,64,64,64
chr_uv(0,EN_UVNO+3)=64*2*3,64*4,64,64,64,64
MY_CHRNO=0 //自分のobjIDを入れる要素数
EN_CHRNO=1 //これ以降に敵キャラのオブジェIDを入れる要素数
regobj id,spmid,OBJ_HIDE //自分のOBJID取得
obj_id(MY_CHRNO)=id //OBJIDを保存(ここに入れられたIDをソートする)
setcolscale id,chr_uv(4,MY_UVNO),chr_uv(5,MY_UVNO)
cmode=3,2,5,6,6,0
/*
α合成値 = 0〜255 : 背景とα合成(blend)を行なう gmode 3のブレンド率
α合成値 = 256〜511 : 合成を行なわない(通常時) gmode 2
α合成値 = 512〜767 : 背景と色加算(modulate)を行なう gmode 5のブレンド率
α合成値 = 768〜1023 : 背景とα値減算(substract)を行なう gmode 6のブレンド率
α合成値 = 1024〜1279 : 背景と色減算(substract2)を行なう gmode 6のブレンド率
α合成値 = 1280〜1535 : 合成を行なわない(Z無視) gmode 0
*/
setefx id,256,chr_uv(2,MY_UVNO),chr_uv(3,MY_UVNO) //efxグループをgmodeの設定値として利用
setwork id,chr_uv(0,MY_UVNO),chr_uv(1,MY_UVNO) //workグループをキャラ画像の左上の座標として使用
setcoli id,1,2
chr_max=EN_CHRNO //ソートするキャラ数
repeat 30
gosub *addchr
loop
clscolor $4444
sdim zsort,2*100,1000 //ソート済みID保存用(1IDに2バイト使用、同じ優先度に100個まで)
*main
stick k,127
if k&128 : goto *owari ; [ESC]で終了
if k&16 :gosub *addchr //スペースでキャラ追加
if k&1 :addpos obj_id(MY_CHRNO), -4, 0:
if k&4 :addpos obj_id(MY_CHRNO), 4, 0:
if k&2 :addpos obj_id(MY_CHRNO), 0, -4:
if k&8 :addpos obj_id(MY_CHRNO), 0, 4:
dim zcnt,1000 //同じ優先度の個数を記録用
//敵キャラの移動とソート
repeat chr_max-EN_CHRNO,EN_CHRNO
id=obj_id(cnt)
getdir id,dx,dy,dz
addpos id,dx,dy,dz
getposi id,px_i,py_i,pz_i
getefxi id,Alpha,Sizex,Sizey
//アニメーション処理
obj_anmtimcnt(id)++
if obj_anmtim(id)=obj_anmtimcnt(id) {
obj_anmtimcnt(id)=0
obj_anmcnt(id)=(obj_anmcnt(id)+1)\obj_anmmax(id)
getworki id,wx,wy,wz
setwork id,wx,wy,obj_anmcnt(id)*Sizex
}
if px_i<-320 {adddir id,-dx*2}//速度反転
if px_i>320 {adddir id,-dx*2}
if py_i<-240 {adddir id, ,-dy*2}
if py_i>240 {adddir id, ,-dy*2}
getcoli val,id,1
if val<0 { //自分と当たったか判定
coli_id(id)=0 //当たってない
}else{
obj_hp(id)--
coli_id(id)=1 //描画時に加算合成を重ねて描画するフラグON
if obj_hp(id)<=0{//HP0以下なら削除設定
chrdel_no(chrdel_cnt)=cnt //削除するよう素数を代入
chrdel_cnt++ //削除する数
}
}
//Y座標が下な物が後から描画されるようにソート
py_i+240+Sizey/2 //画面中央が0の座標系から上端が0の座標系にしてキャラの下部分をソートの基準にする
if py_i>0 and (py_i-Sizey)<480 {//画面内
wpoke zsort(py_i),zcnt(py_i)*2,obj_id(cnt)
zcnt(py_i)++
}
loop
//自分のキャラは別にソートして同じ優先度の最後に表示するようにする
getposi obj_id(MY_CHRNO),px_i,py_i,pz_i
getefxi id,Alpha,Sizex,Sizey
py_i+240+Sizey/2
if py_i>0 and (py_i-Sizey)<480 {//画面内
wpoke zsort(py_i),zcnt(py_i)*2,obj_id(cnt)
zcnt(py_i)++
}
hgdraw
//ソートされた物を描画
z_index=0
repeat 1000
repeat zcnt(z_index)
id=wpeek(zsort(z_index),cnt*2)
getpos id,px,py,pz
getang id,rx,ry,rz
getefxi id,Alpha,Sizex,Sizey
getworki id,wx,wy,wz
wx+wz //アニメーション
pos px+320,py+240
gmode cmode(Alpha/256),Sizex,Sizey,Alpha\256
hgrotate texid,wx,wy,rz
if coli_id(id) {
gmode 5,Sizex,Sizey,255
hgrotate texid,wx,wy,rz
}
loop
z_index++
loop
//キャラ削除実行
repeat chrdel_cnt
no=chrdel_no(cnt)-cnt
delobj obj_id(no)
chr_max--
if chr_max {
index=no*4
memcpy obj_id,obj_id,chr_max*4-index,index,index+4
}else{
break
}
loop
chrdel_cnt=0
title ""+chr_max
hgsync 16 ; 時間待ち
goto *main
*owari
end
*addchr
no=rnd(4)+EN_UVNO //キャラをランダムに選ぶ
regobj id,spmid,OBJ_HIDE
obj_id(chr_max)=id //現在のキャラ数を要素数としてオブジェIDを代入
obj_hp(id)=100 //オブジェIDを要素数としてHPを代入
obj_anmmax(id)=2
obj_anmcnt(id)=0
obj_anmtim(id)=25
obj_anmtimcnt(id)=0
setcolscale id,chr_uv(4,no),chr_uv(5,no)
setefx id,256,chr_uv(2,no),chr_uv(3,no)
setwork id,chr_uv(0,no),chr_uv(1,no)
setdir id,0.5*rnd(3),0.5*rnd(3) //移動速度設定
setcoli id,2,1
setpos id,rnd(640)-320,rnd(480)-240
chr_max++
return
これは優先度を1000段階にしてて
今回はY座標を優先度としてそのまま利用してる
> wpoke zsort(py_i),zcnt(py_i)*2,obj_id(cnt)
> zcnt(py_i)++
のpy_iの所を999にすれば一番手前に表示される
描画処理時に工夫すれば
100未満は3Dオブジェクトの奥に表示
100以上は3Dオブジェクトの手前に表示みたいにする事も可能(二回hgdraw使うけど)

| |
|
2013/12/9(Mon) 07:30:23|NO.58654
あれ?
HGIMG3の話じゃない?
でもHGIMGじゃOBJ_LATEは設定できないから
やっぱりHGIMG3か・・・
|
|
2013/12/9(Mon) 21:19:20|NO.58663
あ、一部ちょっと間違い
二つ目の
> wpoke zsort(py_i),zcnt(py_i)*2,obj_id(cnt)
はobj_id(cnt)じゃ無くてobj_id(MY_CHRNO)だった
repeat〜loop内じゃないからcntは0でMY_CHRNOも0だから動作に支障は出なかった・・・
|
|
2013/12/12(Thu) 22:52:01|NO.58693
はい!HGIMG3の話です。
ありがとうございました!
|
|
2013/12/13(Fri) 02:32:59|NO.58700
どうせなのでモジュール化してみた
#include "hgimg3.as"
//必ず#include "hgimg3.as"の後に配置
#module "mod_hgEmuSpr"
/*---追加される命令とマクロ
EmuSpr_init EmuSprを使用する前の初期化命令
EmuSpr_expand EmuSprを使用する時の特定の同じ優先度に許されるオブジェクト数を増やすマクロ
addEmuSpr EmuSpr用のaddspr
regobjEmuSpr EmuSpr用のregobj
addzsort EmuSpr用のIDソートマクロ
hgdrawEmuSpr EmuSpr用の描画命令
*/
//[ EmuSpr_init zmax, zlinemax ] EmuSprを使用する前の初期化命令
// zmax = 優先度の段階数(省略時1000)
// zlinemax = 同じ優先度に許されるオブジェクト数(省略時100)
//使用メモリサイズ=zmax*zlinemax*2
//zmaxは段階数なのでaddzsortに指定できるのは最大zmax-1になる
#deffunc EmuSpr_init int zmax,int zlinemax
if zmax<=0 {_zmax=1000}else{_zmax=zmax}
_zlast=_zmax-1
if zlinemax<=0 {_zlinemax=100}else{_zlinemax=zlinemax}
sdim zsort,2*_zlinemax,_zmax //ソート済みID保存用(1IDに2バイト使用、同じ優先度にzlinemax個まで)
dim zcnt,_zmax //同じ優先度の個数を記録用
cmode=3,2,5,6,6,0
hsx=ginfo_sx/2
hsy=ginfo_sy/2
return
//[ EmuSpr_expand %1, %2 ] EmuSprを使用する時の特定の同じ優先度に許されるオブジェクト数を増やす
// %1 = 特定の優先度
// %2x = 同じ優先度に許されるオブジェクト数
#define global EmuSpr_expand(%1,%2) memexpand zsort@mod_hgEmuSpr(%1),(%2)*2
//[ addEmuSpr spmid, mode, lx, uy, rx, dy, texid ] EmuSpr用のaddspr
//使い方は通常の addspr と同じ(但しパラメータの省略不可)
#define global addEmuSpr(%1,%2,%3,%4,%5,%6,%7) _addEmuSpr %1,%2,%3,%4,%5,%6,%7
#deffunc _addEmuSpr var spmid,int mode,int lx,int uy,int rx,int dy,int texid
addspr spmid,0,0,0,1,1 //スプライトオブジェクトの座標やコリジョングループを利用するためモデル作成
//何故か通常モデルに設定されてるデータを引き出す命令が一切ないので自前で保存
_lx(spmid)=lx
_rx(spmid)=rx
_uy(spmid)=uy
_dy(spmid)=dy
_ssx(spmid)=rx-lx //コピー元サイズ
_ssy(spmid)=dy-uy
_alpha(spmid)=1280*(mode=0)+256*mode
_texid(spmid)=texid
return
//[ regobjEmuSpr oid, mid, obj_mode, ev ] EmuSpr用のregobj
//使い方は通常の regobj と同じ
//α値とコピー元サイズにefxグループを使用します
//α値だけ変更したい場合は
//selefx id :objset1 0,α値
//みたいにすると良い(eventでefxグループを変えたときはやっかいですが・・・)
#define global regobjEmuSpr(%1,%2,%3=0,%4=-1) _regobjEmuSpr %1,%2,%3,%4
#deffunc _regobjEmuSpr var oid,int mid,int obj_mode,int ev
regobj oid,mid,OBJ_HIDE | obj_mode,ev//自分のOBJID取得
/*
α合成値 = 0〜255 : gmode 3のブレンド率
α合成値 = 256〜511 : gmode 2
α合成値 = 512〜767 : gmode 5のブレンド率
α合成値 = 768〜1023 : gmode 6のブレンド率
α合成値 = 1024〜1279 : gmode 6のブレンド率
α合成値 = 1280〜1535 : gmode 0 (addEmuSprの透明色抜きなし指定時もこれ)
*/
setefx oid,_alpha(mid),_ssx(mid),_ssy(mid) //efxグループをgmodeの設定値として利用
return
//[ addzsort %1, %2 ] EmuSpr用のIDソートマクロ
// %1 = ソートするEmuSprオブジェID
// %2 = 優先度(省略時zmax-1)
//優先度は大きい程後から(手前に)描画
#define global addzsort(%1,%2=_zlast@mod_hgEmuSpr) wpoke zsort@mod_hgEmuSpr(%2),zcnt@mod_hgEmuSpr(%2)*2,%1:zcnt@mod_hgEmuSpr(%2)++
//[ hgdrawEmuSpr z_start, z_end ] EmuSpr用の描画命令
// z_start = 描画開始する優先度(省略時0)
// z_end = 描画終了する優先度段階数(省略時zmax)
//z_startが10でz_endに100を指定した場合優先度10〜99までの90段階を描画
//z_startが100でz_endを省略又は0以下を指定した場合優先度100〜終わりまで描画
#deffunc hgdrawEmuSpr int z_start,int z_end
if z_end<=0 {_z_end=_zmax-z_start}else{_z_end=z_end-z_start}
z_index=z_start
if _z_end > z_start {
repeat _z_end
repeat zcnt(z_index)
id=wpeek(zsort(z_index),cnt*2)
objexist id
if stat=0 {
getpos id,px,py,pz
getang id,rx,ry,rz
getscale id,scx,scy,scz
getefxi id,Alpha,Sizex,Sizey
getobjmodel m_id,id
getworki id,u,v,wz_i //workグループをUVアニメーション用のオフセットとして使用
u+_lx(m_id) //Xアニメーション
v+_uy(m_id) //Yアニメーション
pos px+hsx,py+hsy
if Alpha<$600 {
gmode cmode(Alpha/256),Sizex,Sizey,Alpha\256
hgrotate _texid(m_id),u,v,rz,scx*Sizex,scy*Sizey
}else{
gmode cmode((Alpha\$5ff)/256),Sizex,Sizey,Alpha\256
hgrotate _texid(m_id),u,v,rz,scx*Sizex,scy*Sizey
gmode 5,Sizex,Sizey,255
hgrotate _texid(m_id),u,v,rz,scx*Sizex,scy*Sizey
setefx id,Alpha\$5ff,Sizex,Sizey
}
}
loop
z_index++
loop
}
return
//[ event_emuspruv ev, ix, iy ] EmuSpr用のevent_uv
//使い方は通常の event_uv と同じ
//UVアニメーション用にworkグループ使用します
#deffunc event_emuspruv int ev,int ix,int iy
event_setwork ev,ix, iy,0.0
return
#undef hgsync
//hgsync実行時にzcntをクリアするためにhgsyncを置換え
#define global hgsync(%1=0) memset zcnt@mod_hgEmuSpr,0,_zmax@mod_hgEmuSpr*4,0:hgsync@hsp %1
#global
//モジュールここまで
hgini
zmax=600
//EmuSprを使えるように初期化
EmuSpr_init zmax //必ずhginiの後に実行
texload2 dir_exe+"\\hsptv\\hsptv_img.png" ; テクスチャの登録
texid=stat
MY_UVNO=0 //自分のモデル用データを入れる要素数(モデルIDを入れる要素数にもなる)
EN_UVNO=1
EX_UVNO=EN_UVNO+4
dim chr_uv,6,1 //キャラ画像の位置とサイズ、判定データ
//自分
//テクスチャの左上X座標、左上Y座標、テクスチャの右下X座標、右下Y座標、判定サイズX、判定サイズY
chr_uv(0,MY_UVNO)=0,64*3,64,64*4,40,60
//敵
chr_uv(0,EN_UVNO )= 0,64*4, 64,64*5,45,60
chr_uv(0,EN_UVNO+1)=64*2,64*4,64*3,64*5,60,60
chr_uv(0,EN_UVNO+2)=64*4,64*4,64*5,64*5,64,64
chr_uv(0,EN_UVNO+3)=64*6,64*4,64*7,64*5,64,64
//その他のキャラ
chr_uv(0,EX_UVNO )= 0,64*5, 64,64*6,64,64
repeat length(chr_uv)
addEmuSpr spmid(cnt),1,chr_uv(0,cnt),chr_uv(1,cnt),chr_uv(2,cnt),chr_uv(3,cnt),texid //EmuSpr用スプライトモデルを作成
modelcols spmid(cnt),chr_uv(4,cnt),chr_uv(5,cnt)//モデルの判定サイズ設定
loop
newevent ev ; 横2コマアニメーション用イベント
event_emuspruv ev,0
event_wait ev,25
event_emuspruv ev,64,0
event_wait ev,25
event_jump ev,0
//自分を配置
regobjEmuSpr myobj_id,spmid(MY_UVNO),0 ,ev//自分のOBJID取得
setcoli myobj_id,1,2
//敵を配置
repeat 30
gosub *addchr
loop
regobjEmuSpr exobj_id(0),spmid(EX_UVNO)//その他のオブジェクト
setpos exobj_id(0),-100,0,0 //Z座標を優先度として設定
regobjEmuSpr exobj_id(1),spmid(EX_UVNO)
setpos exobj_id(1),100,0,zmax-1//Z座標を優先度として設定
setwork exobj_id(1),64
clscolor $4444
setborder -320,-240,-1000,1 //スプライト座標用のボーダー範囲設定
setborder 320,240,1000,2
*main
stick k,127
if k&128 : goto *owari ; [ESC]で終了
if k&16 :gosub *addchr //スペースでキャラ追加
if k&1 :addpos myobj_id, -4, 0:
if k&4 :addpos myobj_id, 4, 0:
if k&2 :addpos myobj_id, 0, -4,-4:
if k&8 :addpos myobj_id, 0, 4,4:
//敵キャラの移動とソート
findobj 0,2 //敵をコリジョングループ2にしてるので2を検索
sortmax=0
repeat
nextobj id
if id<0{break}
getposi id,px_i,py_i,pz_i
getefxi id,Alpha,Sizex,Sizey
getscale id,scx,scy,scz
getcoli val,id,1.0
if val>=0 { //自分と当たったか判定
obj_hp(id)--
addefx id,$600 //α値を$600 以上にすると加算合成もされる(疑似フラッシュ)描画後に元に戻される
}
if obj_hp(id)>0 {
//Y座標が大きい物が後から描画されるようにソート
py_i+240+Sizey/2 //画面中央が0の座標系から上端が0の座標系にしてキャラの下部分をソートの基準にする
if py_i>0 and (py_i-Sizey)<480 {//画面内
addzsort id,py_i
sortmax++ //個数表示に数えてるだけで本来は必要ない
}
}else{//HP0以下なので削除
delobj id
}
loop
//自分のキャラは別にソートして同じ優先度の最後に表示するようにする
getposi myobj_id,px_i,py_i,pz_i
getefxi myobj_id,Alpha,Sizex,Sizey
py_i+240+Sizey/2
if py_i>0 and (py_i-Sizey)<480 {//画面内
addzsort myobj_id,py_i
sortmax++ //個数表示に数えてるだけで本来は必要ない
}
//その他のオブジェクトを追加ソート
repeat 2
getposi exobj_id(cnt),px_i,py_i,pz_i
addzsort exobj_id(cnt),pz_i //z座標を優先度として利用
sortmax++ //個数表示に数えてるだけで本来は必要ない
loop
hgdraw
//addzsortされたオブジェクトを全て描画
hgdrawEmuSpr //直接描画なのでhgdrawとhgsyncの間に実行(hgdraw 2 でクリアだけしてhgdrawEmuSpr後にhgdraw 4 みたいな事は出来る)
title ""+sortmax
hgsync 16 ; 時間待ち
goto *main
*owari
end
*addchr
no=rnd(4)+EN_UVNO //emusprモデルをランダムに選ぶ
regobjEmuSpr id,spmid(no),OBJ_MOVE | OBJ_FLIP | OBJ_BORDER ,ev //自動移動とボーダー反転を指定
obj_hp(id)=100 //オブジェIDを要素数としてHPを代入
setdir id,0.5*rnd(3),0.5*rnd(3),0.0 //移動速度設定
setcoli id,2,1
setpos id,rnd(640)-320,rnd(480)-240,0.0
return
NO.58652のはオブジェクトの出現順を保存することを考えてobj_idと言う配列を使ったけど
今回は無くしてコリジョングループ検索でやってみた(作ってるものによっては出現順の優先度も必要になる)
このモジュールはある程度通常の2Dスプライトを使ってるのと変らない使い方ができるようにしてみた
但し幾つか制限がある
workグループをUVアニメーションで使用
efxグループのy,zを描画元のサイズとして使い、xも通常のスプライトのαとは多少異なる
regobjEmuSprのモード値で以下のは対応していない
OBJ_HIDE //これはデフォルトで指定されてる(非表示にしたければaddzsortしなければ良い)
OBJ_LATE
OBJ_FIRST
OBJ_EMITTER
通常の2Dスプライトより重い(自分の環境だと2倍以上、500枚描画で1msが2.5msぐらいになる)

| |
|
2013/12/14(Sat) 01:14:35|NO.58719
>但し幾つか制限がある
まだあった
自動移動やeventはhgdrawで処理されるので、今回みたいにY座標を優先度にしてる場合は
表示は移動後になるのでhgdraw前にaddzsortすると、優先度が違ってしまう(両方動いてる場合目立たないだろうけど)
優先度をY座標依存にして自動移動やeventで移動させたい場合はhgdraw後にaddzsortした方が良いかも
あと、制限と言うか違い
通常の2Dスプライトのテクスチャ右下座標は実際の座標-1を指定する必要があるが
EmuSprは普通に指定
|
|
2013/12/26(Thu) 20:18:50|NO.58890
ありがとうございました。
|
|