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


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
0822
greenappleobaqのオブジェクトの形を画像の不透明部分と合わせたい!19解決


greenapple

リンク

2014/8/22(Fri) 22:38:44|NO.64157

obaqでqmat命令を利用して画像を貼り付けているのですが、オブジェクトの形自体は正四角形なので画像と挙動でギャップが起きてしまいます。
画像自体も複雑な形をしているのでいちいち全部の頂点を書くのも面倒くさいです。
オブジェクトの形を画像の不透明部分と合わせる方法はありますか?
あれば、教えていただけるとありがたいです。



この記事に返信する


Flat

リンク

2014/8/23(Sat) 00:16:26|NO.64162

モデルデータをプログラムで作成する方法でやってみた。
#module
#deffunc traceinit dim cbpos, 3, 3 cbpos(0, 0) = 1 cbpos(1, 0) = 1 cbpos(2, 0) = 3 cbpos(0, 1) = 0 cbpos(2, 1) = 3 cbpos(0, 2) = 0 cbpos(1, 2) = 2 cbpos(2, 2) = 2 return #deffunc traceedge int bx, int by, int iw, int ih, array edge, \ local ck, local flag, local x, local y, local sx, local sy, local ox, local oy, local p, local tmp ck = ginfo_r, ginfo_g, ginfo_b repeat ih y = cnt repeat iw x = cnt pget x, y if (ginfo_r != ck(0)) || (ginfo_g != ck(1)) || (ginfo_b != ck(2)) { flag = 1 break } loop if flag : break loop dim tmp sx = x sy = y ox = x oy = y - 1 repeat p = cbpos(x-ox+1, y-oy+1) ox = x oy = y x = ( p & 1 ) << 1 y = ( p >> 1 ) << 1 flag = 0 repeat 8 pget x+ox-1, y+oy-1 if (ginfo_r != ck(0)) || (ginfo_g != ck(1)) || (ginfo_b != ck(2)) { break } if (x == 2) && (y != 0) : y-- : continue if (y == 2) && (x != 2) : x++ : continue if (x == 0) && (y != 2) : y++ : continue if (y == 0) && (x != 0) : x-- : continue loop x += ox - 1 y += oy - 1 tmp(cnt<<1) = x, y if (x == sx) && (y == sy) : break loop ddim edge, 2 p = 0 ox = -1.0 oy = -1.0 repeat (length(tmp) >> 1) - 1 x = tmp((cnt<<1)+2)-tmp(cnt<<1) y = tmp((cnt<<1)+3)-tmp((cnt<<1)+1) if (x != ox) || (y != oy) { //* edge(p<<1) = double(tmp(cnt<<1))/iw, double(tmp((cnt<<1)+1))/ih /*/ edge(p<<2) = double(tmp(cnt<<1))/iw, double(tmp((cnt<<1)+1))/ih, double(tmp((cnt<<1)+2))/iw, double(tmp((cnt<<1)+3))/ih //*/ ox = x oy = y p++ } loop return #global traceinit #include "obaq.as" #define TEXTURE 1 // テクスチャのバッファID #define OBJNUM 30 // サンプルで作成されるオブジェクトの数 buffer TEXTURE, 64, 64 font msgothic, 64 color 0, 0, 0 boxf color 255, 255, 255 mes "☆" celdiv TEXTURE, 64, 64, 32, 32 ddim edge, 1 color 0, 0, 0 traceedge 0, 0, 64, 64, edge // traceedge テクスチャ左端, テクスチャ上端, テクスチャ横幅, テクスチャ高さ, 配列変数 // でテクスチャの形状にあったモデルデータ(qaddmodel用)が配列変数に書き込まれます // テクスチャの透過色は現在の色(colorで設定した色)となります gsel 0 qreset qmat 0, mat_wire, 0x7F0000 qaddmodel my, edge, -1, 20, 20, 0, 20, 20 // ここで先ほど作成したedgeを指定 qgroup my, 1, 0, 2 //* // 左の//*を/*にすると輪郭が表示されます qmat my, mat_spr, TEXTURE, 0 /*/ qmat my, mat_wire, 0xFFFFFF, 0 //*/ // 以下test9.hspから持ってきたサンプル // 特別な処理は行っておりません frame = 0 obj = 0 *main qexec stick key,15+16 if key & 128 : end if key & 16 { qgetpos my, x, y, ang qblast x, y, 1 } if key & 1 : qspeed my, -0.04, 0.0, 0.0 if key & 2 : qspeed my, 0.0, -0.05, 0.0 if key & 4 : qspeed my, 0.04, 0.0, 0.0 if obj <= OBJNUM { qaddpoly i, rnd(4) + 3, 96, 24, 0.01 * rnd(628) if i >= 0 { qmat i, mat_wire, 0x00FF00 qspeed i, 0.1 * rnd(10) - 0.5, 0, 0.01 obj++ } } redraw 0 color 0, 0, 127 boxf qdraw 1 color 255, 255, 255 pos 0, 0 mes "Frame: " + frame redraw await 12 frame++ goto *main
※一部の特殊な形状ではシステムエラーが発生します。



greenapple

リンク

2014/8/23(Sat) 01:07:20|NO.64164

Flatさん、返信ありがとうございます。
そのソースの文字の所を画像に差し替えてみたのですが、あいにく素材は 32px*32px で分割をして使う形になっており、celputで表示させたい画像の分割IDを指定しても極端に小さくなってしまい、思った通りに動きません。
ただし、celputの指定を外すと分割された画像のsubIDが0の画像が指定されてしまいます。
どこをどのように変更すれば、分割された画像のsubIDが0以外の画像も正常に利用できるようになりますか。



Flat

リンク

2014/8/23(Sat) 01:14:32|NO.64165

celdiv TEXTURE, 64, 64, 32, 32

traceedge 0, 0, 64, 64, edge
で位置や中心点、大きさを指定しています。
各数値を書き換えてみてください。



Flat

リンク

2014/8/23(Sat) 03:09:59|NO.64168

あ、今確認したらスクリプト間違ってた。
18行目のrepeat ihをrepeat ih, byに
20行目のrepeat iwをrepeat iw, bxに
修正してください。



Flat

リンク

2014/8/23(Sat) 16:10:09|NO.64181


#module // システムエラーが発生する場合はMINPLOTやTHRESHOLDを編集してください #const THRESHOLD 1 // 頂点検出閾値(角度) #const MINPLOT 3 // 傾き計算に使用する最小の点数 // この2つは編集しないでください #const M_PIx2 M_PI * 2 #const THRESHOLDR M_PI * THRESHOLD / 180 #deffunc traceinit dim cbpos, 3, 3 cbpos(0, 0) = 1 cbpos(1, 0) = 1 cbpos(2, 0) = 3 cbpos(0, 1) = 0 cbpos(2, 1) = 3 cbpos(0, 2) = 0 cbpos(1, 2) = 2 cbpos(2, 2) = 2 return #deffunc traceedge int bx, int by, int iw, int ih, array edge, \ local ck, local flag, local x, local y, local sx, local sy, local ox, local oy, local oc, local oa, local p, local tmp ck = ginfo_r, ginfo_g, ginfo_b repeat ih, by y = cnt repeat iw, bx x = cnt pget x, y if (ginfo_r != ck(0)) || (ginfo_g != ck(1)) || (ginfo_b != ck(2)) { flag = 1 break } loop if flag : break loop dim tmp sx = x sy = y ox = x oy = y - 1 repeat p = cbpos(x-ox+1, y-oy+1) ox = x oy = y x = ( p & 1 ) << 1 y = ( p >> 1 ) << 1 flag = 0 repeat 8 pget x+ox-1, y+oy-1 if (ginfo_r != ck(0)) || (ginfo_g != ck(1)) || (ginfo_b != ck(2)) { if ((x+ox-1) >= 0) && ((y+oy-1) >= 0) && ((x+ox-1) < ginfo_sx) && ((y+oy-1) < ginfo_sy) { break } } if (x == 2) && (y != 0) : y-- : continue if (y == 2) && (x != 2) : x++ : continue if (x == 0) && (y != 2) : y++ : continue if (y == 0) && (x != 0) : x-- : continue loop x += ox - 1 y += oy - 1 tmp(cnt<<1) = x, y if (x == sx) && (y == sy) : break loop ddim edge, 2 p = 0 oa = 0.0 a = 0.0 ox = 0 oy = 0 oc = 0 repeat length(tmp) >> 1 a = atan(tmp((cnt<<1)+1)-oy, tmp(cnt<<1)-ox) if a < 0 : a += M_PIx2 if (p == 0) || ( (absf(a - oa) > THRESHOLDR) && ((cnt - oc) > MINPLOT) ) { edge(p<<1) = double(tmp(cnt<<1))/iw, double(tmp((cnt<<1)+1))/ih oc = cnt oa = a ox = tmp(cnt<<1) oy = tmp((cnt<<1)+1) p++ } loop return #global
少し修正。
先ほどのスクリプトの#module〜#globalを上のに置き換えてください。



greenapple

リンク

2014/8/24(Sun) 00:06:18|NO.64186

Flatさん訂正ありがとうございます。
訂正した後、実行させたら大きさは直りました…大きさは…
その代わりに、というか正常の大きさに戻ったこそ気づいたのですが左上1/4が180°回転して表示するようになりました。
これはどのように対処すれば良いのでしょうか。



Flat

リンク

2014/8/24(Sun) 00:14:00|NO.64187

うーん、ちょっとソースコード見せてもらわないと分からないです><



greenapple

リンク

2014/8/24(Sun) 00:27:05|NO.64188

ソースはほとんど変わってないです
本当に文字を画像に差し替えただけです

#define cxs 32.0 ; cxs = 画像を縦に分割する長さ #define cys 32.0 ; cys = 画像を横に分割する長さ #module // システムエラーが発生する場合はMINPLOTやTHRESHOLDを編集してください #const THRESHOLD 1 // 頂点検出閾値(角度) #const MINPLOT 3 // 傾き計算に使用する最小の点数 // この2つは編集しないでください #const M_PIx2 M_PI * 2 #const THRESHOLDR M_PI * THRESHOLD / 180 #deffunc traceinit dim cbpos, 3, 3 cbpos(0, 0) = 1 cbpos(1, 0) = 1 cbpos(2, 0) = 3 cbpos(0, 1) = 0 cbpos(2, 1) = 3 cbpos(0, 2) = 0 cbpos(1, 2) = 2 cbpos(2, 2) = 2 return #deffunc traceedge int bx, int by, int iw, int ih, array edge, \ local ck, local flag, local x, local y, local sx, local sy, local ox, local oy, local oc, local oa, local p, local tmp ck = ginfo_r, ginfo_g, ginfo_b repeat ih, by y = cnt repeat iw, bx x = cnt pget x, y if (ginfo_r != ck(0)) || (ginfo_g != ck(1)) || (ginfo_b != ck(2)) { flag = 1 break } loop if flag : break loop dim tmp sx = x sy = y ox = x oy = y - 1 repeat p = cbpos(x-ox+1, y-oy+1) ox = x oy = y x = ( p & 1 ) << 1 y = ( p >> 1 ) << 1 flag = 0 repeat 8 pget x+ox-1, y+oy-1 if (ginfo_r != ck(0)) || (ginfo_g != ck(1)) || (ginfo_b != ck(2)) { if ((x+ox-1) >= 0) && ((y+oy-1) >= 0) && ((x+ox-1) < ginfo_sx) && ((y+oy-1) < ginfo_sy) { break } } if (x == 2) && (y != 0) : y-- : continue if (y == 2) && (x != 2) : x++ : continue if (x == 0) && (y != 2) : y++ : continue if (y == 0) && (x != 0) : x-- : continue loop x += ox - 1 y += oy - 1 tmp(cnt<<1) = x, y if (x == sx) && (y == sy) : break loop ddim edge, 2 p = 0 oa = 0.0 a = 0.0 ox = 0 oy = 0 oc = 0 repeat length(tmp) >> 1 a = atan(tmp((cnt<<1)+1)-oy, tmp(cnt<<1)-ox) if a < 0 : a += M_PIx2 if (p == 0) || ( (absf(a - oa) > THRESHOLDR) && ((cnt - oc) > MINPLOT) ) { edge(p<<1) = double(tmp(cnt<<1))/iw, double(tmp((cnt<<1)+1))/ih oc = cnt oa = a ox = tmp(cnt<<1) oy = tmp((cnt<<1)+1) p++ } loop return #global traceinit #include "obaq.as" #define TEXTURE 1 // テクスチャのバッファID #define OBJNUM 30 // サンプルで作成されるオブジェクトの数 buffer TEXTURE, 32, 32 ,16 ,16 ddim edge, 1 color 0, 0, 0 //画像を読み込み celload "images\\image.bmp",1 ; 32px * 32px の素材を1枚にまとめた画像 celdiv 1,cxs,cys,cxs/2,cys/2 celput 1,2 traceedge 0, 0, 32, 32, edge // traceedge テクスチャ左端, テクスチャ上端, テクスチャ横幅, テクスチャ高さ, 配列変数 // でテクスチャの形状にあったモデルデータ(qaddmodel用)が配列変数に書き込まれます // テクスチャの透過色は現在の色(colorで設定した色)となります gsel 0 qreset qmat 0, mat_wire, 0x7F0000 qaddmodel my, edge, -1, 20, 20, 0, 20, 20 // ここで先ほど作成したedgeを指定 qgroup my, 1, 0, 2 //* // 左の//*を/*にすると輪郭が表示されます qmat my, mat_spr, TEXTURE, 0 /*/ qmat my, mat_wire, 0xFFFFFF, 0 //*/ // 以下test9.hspから持ってきたサンプル // 特別な処理は行っておりません frame = 0 obj = 0 *main qexec stick key,15+16 if key & 128 : end if key & 16 { qgetpos my, x, y, ang qblast x, y, 1 } if key & 1 : qspeed my, -0.04, 0.0, 0.0 if key & 2 : qspeed my, 0.0, -0.05, 0.0 if key & 4 : qspeed my, 0.04, 0.0, 0.0 if obj <= OBJNUM { qaddpoly i, rnd(4) + 3, 96, 24, 0.01 * rnd(628) if i >= 0 { qmat i, mat_wire, 0x00FF00 qspeed i, 0.1 * rnd(10) - 0.5, 0, 0.01 obj++ } } redraw 0 color 0, 0, 127 boxf qdraw 1 color 255, 255, 255 pos 0, 0 mes "Frame: " + frame redraw await 12 frame++ goto *main



Flat

リンク

2014/8/24(Sun) 00:40:08|NO.64189

celput 1,2
の前に
buffer 2, cxs, cyx
を追加。で動くかも。

celloadやcelputに関するマニュアルも読んどいたほうがいいかもしれません。



greenapple

リンク

2014/8/24(Sun) 19:06:32|NO.64197

んー、
celput 1,2
の前に
buffer 2, cxs, cyx
という方法はシステムエラーが発生するし、celput・celloadについて調べても処置方法が浮かばない…
何が原因なのかも把握出来ないですね…



Flat

リンク

2014/8/25(Mon) 14:59:21|NO.64229

cyxじゃなくてcysだった。

あと、自分が言えたことじゃないですが、
ソースコードにコメントを書いとくのも質問時・デバッグ時には有効です。



greenapple

リンク

2014/8/26(Tue) 00:33:48|NO.64285

あっ…すみません、ありがとうございます。
そこには目が行ってませんでした。
直したら、表示上は1/4が回転する問題は解決されました。
しかし、重心は画像中央ではなくオブジェクト左上端に行ってしまい、さらにオブジェクトの形自身も画像とはかけ離れた形が生成されます。
これを直すことは可能でしょうか。
また、直せるのであればどこをどのように直せばいいのでしょうか。



Flat

リンク

2014/8/26(Tue) 00:48:11|NO.64286

とりあえず、image.bmpをアップロードしてください。



greenapple

リンク

2014/8/26(Tue) 01:07:20|NO.64290




greenapple

リンク

2014/8/26(Tue) 01:20:49|NO.64291

タイトル名が違いますが、ソースで示されているimage.bmpと同じです。



Flat

リンク

2014/8/26(Tue) 02:00:23|NO.64293


#define cxs 32.0 ; cxs = 画像を縦に分割する長さ #define cys 32.0 ; cys = 画像を横に分割する長さ #module // システムエラーが発生する場合はMINPLOTやTHRESHOLDを編集してください #const THRESHOLD 1 // 頂点検出閾値(角度) #const MINPLOT 3 // 傾き計算に使用する最小の点数 // この2つは編集しないでください #const M_PIx2 M_PI * 2 #const THRESHOLDR M_PI * THRESHOLD / 180 #deffunc traceinit dim cbpos, 3, 3 cbpos(0, 0) = 1 cbpos(1, 0) = 1 cbpos(2, 0) = 3 cbpos(0, 1) = 0 cbpos(2, 1) = 3 cbpos(0, 2) = 0 cbpos(1, 2) = 2 cbpos(2, 2) = 2 return #deffunc traceedge int bx, int by, int iw, int ih, int cx, int cy, array edge, array info, \ local ck, local flag, local x, local y, local sx, local sy, local ox, local oy, local oc, local oa, local p, local tmp, local lx, local ly, local gx, local gy ck = ginfo_r, ginfo_g, ginfo_b repeat ih, by y = cnt repeat iw, bx x = cnt pget x, y if (ginfo_r != ck(0)) || (ginfo_g != ck(1)) || (ginfo_b != ck(2)) { flag = 1 break } loop if flag : break loop dim tmp sx = x : sy = y ox = x : oy = y - 1 lx = iw : ly = ih gx = 0 : gy = 0 repeat p = cbpos(x-ox+1, y-oy+1) ox = x oy = y x = ( p & 1 ) << 1 y = ( p >> 1 ) << 1 flag = 0 repeat 8 pget x+ox-1, y+oy-1 if (ginfo_r != ck(0)) || (ginfo_g != ck(1)) || (ginfo_b != ck(2)) { if ((x+ox-1) >= 0) && ((y+oy-1) >= 0) && ((x+ox-1) < ginfo_sx) && ((y+oy-1) < ginfo_sy) { break } } if (x == 2) && (y != 0) : y-- : continue if (y == 2) && (x != 2) : x++ : continue if (x == 0) && (y != 2) : y++ : continue if (y == 0) && (x != 0) : x-- : continue loop x += ox - 1 y += oy - 1 tmp(cnt<<1) = x, y if gx < x : gx = x if gy < y : gy = y if lx > x : lx = x if ly > y : ly = y pset x, y if (x == sx) && (y == sy) : break loop ddim info, 4 info = 2.0*lx, 2.0*ly, double(iw)/(gx-lx), double(ih)/(gy-ly) ddim edge, 2 p = 0 oa = 0.0 a = 0.0 ox = 0 oy = 0 oc = 0 repeat length(tmp) >> 1 a = atan(tmp((cnt<<1)+1)-oy, tmp(cnt<<1)-ox) if a < 0 : a += M_PIx2 if (p == 0) || ( (absf(a - oa) > THRESHOLDR) && ((cnt - oc) > MINPLOT) ) { edge(p<<1) = double(tmp(cnt<<1)-cx)/iw, double(tmp((cnt<<1)+1)-cy)/ih oc = cnt oa = a ox = tmp(cnt<<1) oy = tmp((cnt<<1)+1) p++ } loop return #global traceinit #include "obaq.as" #define TEXTURE 1 // テクスチャのバッファID #define OBJNUM 30 // サンプルで作成されるオブジェクトの数 buffer TEXTURE, 32, 32 ,16 ,16 ddim edge, 1 color 0, 0, 0 //画像を読み込み celload "images\\image.bmp",1 ; 32px * 32px の素材を1枚にまとめた画像 celdiv 1,cxs,cys,cxs/2,cys/2 buffer 2, cxs, cys pos cxs/2, cys/2 // celput用の位置指定を追加 celput 1, 2 traceedge 0, 0, 32, 32, 16, 16, edge, info // traceedge テクスチャ左端, テクスチャ上端, テクスチャ横幅, テクスチャ高さ, 中心位置X, 中心位置Y, 頂点情報配列変数, 画像情報配列変数 // でテクスチャの形状にあったモデルデータ(qaddmodel用)が頂点情報配列変数に書き込まれます // 画像情報配列変数にはテクスチャの形状にあったデータ(qmat2用)が書き込まれます // テクスチャの透過色は現在の色(colorで設定した色)となります gsel 0 qreset qmat 0, mat_wire, 0x7F0000 qaddmodel my, edge, -1, 20, 20, 0, 20, 20 // ここで先ほど作成したedgeを指定 qgroup my, 1, 0, 2 //* // 左の//*を/*にすると輪郭が表示されます qmat my, mat_spr, TEXTURE, 2 qmat2 my, info(0), info(1), info(2), info(3) // これを追加 /*/ qmat my, mat_wire, 0xFFFFFF, 0 //*/
更に更に差し替え。



greenapple

リンク

2014/8/26(Tue) 02:18:26|NO.64294

ありがとうございます。
Flatさんにはただただ感謝です。
これで、一つの塊として存在する画像は正常に動くようになりました。
ただ、画像の下段に目を通すとわかるんですが、 32px * 32px の中で2つの塊として存在するものがありますよね。
これを、2つの塊としてちゃんと認識させることも可能でしょうか。



Flat

リンク

2014/8/26(Tue) 02:32:36|NO.64295

残念ながら、それはちょっと難しいです。
真ん中1pxを透明色以外でつないじゃうというごまかしの方法ならありますが、
ちゃんとやろうとするとすこしスクリプトが複雑になっちゃいますので…



greenapple

リンク

2014/8/26(Tue) 10:22:15|NO.64301

分かりました。
Flatさん本当に、ありがとうございました。



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