|
|
2013/7/31(Wed) 23:21:54|NO.56013
hspdfixでスプライトを一旦オフスクリーンに描画する方法が知りたいです。
一旦大きな別画面にスプライトとマップを描きこんだあと表示する分だけ切り取る形でのスクロールを行いたいのですが、
スプライトをオフスクリーンに書き込む方法が分からず困っています。
自機の動きに合わせてスプライトを反対側に動かす形でのスクロールも試してみましたが、
動く前の自機の位置に向けて移動するように命令したスプライト(自機に向けて発射された弾)が別の地点に到達してしまったりと、うまくいきませんでした。
どちらかだけでも解決できればいいので、情報があったらぜひ下さい。
|
|
2013/7/31(Wed) 23:57:24|NO.56016
ここでいうオフスクリーンとは「es_buffer」で確保した裏画面、という解釈でよいですか?
スプライトは通常のコピーとは描画系統が別で、
DLL側で直接画面に書き込むことで高速化を図っている(と思われる)ので、
たぶん質問のようなやりかたは出来ないと思います。
いったんマップとキャラを重ね合わせたいのであれば、
スプライトを使用せずに通常の透過コピー(es_copy)でバッファに描画するように、
組み直す必要があると思います。
>動く前の自機の位置に向けて移動するように命令したスプライト(自機に向けて発射された弾)が
>別の地点に到達してしまったりと、うまくいきませんでした。
これはコピーの仕方というよりはキャラクターの座標管理の問題のような気がします。
|
|
2013/8/1(Thu) 12:23:55|NO.56019
>スプライトは通常のコピーとは描画系統が別で、
分かりやすくありがとうございます。参考になります。
>これはコピーの仕方というよりはキャラクターの座標管理の問題のような気がします。
きっとそうでしょう。しかし、原因を考えてみても分かりませんでした。
es_aimで移動を設定したスプライトをes_posすると何か不都合が発生するのでしょうか。
スクリプトはイメージとしては下記の通りなのですが、一体何が悪いのか。
;初期化----------------------------------------------------
#include "hspdxfix.as"
#include "hsp3util.as"
es_ini 1000,1000,360:es_screen 640,480,32,,1,1
screen 0,640,480,0
if stat : dialog"HSPDXFIX : DirectXの初期化に失敗":end
*start
gsel 0:mmstop:es_cls:es_draw:es_sync:wait 100
;----------------------------------------------------------
;******************
buffer 1:buffer 2:buffer 3
color $FF,$FF,0
mes"人・敵"
es_buffer 1,2,$FFFFFF
;転送失敗時
if stat=1 {
es_bye
dialog "転送に失敗しました。",1,"Error"
end
}
;キャラクタ登録
es_size 16,20,80,0
es_pat 0,0,0,0
es_size 2,2,100,0
es_pat 1,23,7,0
es_size 16,20,90,0
es_pat 3,32,0,0
;MAP設定
mapsize_x=1280:mapsize_y=480
buffer 5,mapsize_x,mapsize_y
gsel 5
cls 4
color 255,255,255
mx=0:my=0
*map_draw
pos mx*16,464
mes mx
if mx<160:mx+=1:goto *map_draw
es_buffer 5,2,$FFFFFF;window5に送る
;ステージ前初期化
chara_x=32:chara_y=448;自機座標の初期値設定
chara_wx=chara_x:chara_wy=chara_y
window_x=0:window_y=0
;----------敵配置----------
dim enemy_sdelay,99
enemy_sdelay=25,50
enemy_bbullet_no=300
benemy_no=201
es_set 200,432,292,3,0;432,236,3,0
es_set 201,432,236,3,0
;メインルーチン-------------------------------------
repeat
;移動関係
getkey a0,38:getkey a1,37:getkey a2,39
if a1=1{
chara_x-=3
if chara_x>312:if chara_x<mapsize_x-328:gosub *scroll_enemy_left:gosub *scroll_enemybullet_left
}
if a2=1{
chara_x+=3
if chara_x>312:if chara_x<mapsize_x-328:gosub *scroll_enemy_right:gosub *scroll_enemybullet_right
}
if chara_x<=0:chara_x=0
if chara_x>=mapsize_x-16:chara_x=mapsize_x-16
if chara_y<=0:chara_y=0
;-----------敵処理-----------
gosub *enemy_shot
;----------escキーで終了-----------
getkey b,27
if b=1:es_bye:end
;------------描画ステップ------------
chara_wx=chara_x:chara_wy=chara_y;chara_x=キャラマップ座標 chara_wx=キャラ画面座標
window_x=chara_x-312;マップ切り取り開始位置座標調整
if window_x<0:window_x=0
if window_x>mapsize_x-640:window_x=mapsize_x-640
if chara_wx>312{
if chara_wx>mapsize_x-328{
chara_wx-=mapsize_x:chara_wx+=640
}
else:chara_wx=312
}
gsel 0
es_cls;画面クリア
es_copy 5,window_x,window_y,640,480;ID5のwindowから画面全てコピー(マップ想定)
es_set 0,chara_wx,chara_wy,0,0;自機スプライト描画準備
es_draw
es_sync 16
;------------------------------------
await 0
loop
;----------サブルーチン----------
;-----------敵弾発射処理-------------
*enemy_shot
enemy_n=benemy_no
if enemy_n<200:return
*enemy_shot_loop
es_get enemy_f,enemy_n,0
if enemy_f=0:if enemy_n>200{
if enemy_n=benemy_no:benemy_no-=1
enemy_n-=1:goto *enemy_shot_loop
}
else :return
enemy_sdelay(enemy_n-200)-=1;敵機弾ディレイ値を減らす
if enemy_sdelay(enemy_n-200)>0:if enemy_n>200{enemy_n-=1:goto *enemy_shot_loop}
else :return
enemy_sdelay(enemy_n-200)=10;ディレイリセット
es_new enemy_bullet_no,300;空スプライトナンバー取得(No.300以降で検索)
if enemy_bullet_no>enemy_bbullet_no{
enemy_bbullet_no=enemy_bullet_no;最大Noを記録しておく
}
es_get enemy_bullet_x,enemy_n,3
es_get enemy_bullet_y,enemy_n,5
es_set enemy_bullet_no,enemy_bullet_x+8,enemy_bullet_y+8,1,0;弾セット
es_aim enemy_bullet_no,chara_wx+8,chara_wy+8,200;弾移動
if enemy_n>200:enemy_n-=1:goto *enemy_shot_loop
return
;-----------------------------------
;----------敵スクロール----------
*scroll_enemy_left
enemy_scroll_n=benemy_no
if enemy_n<200:return
*scroll_enemy_left_loop
es_get enemy_scroll_f,enemy_scroll_n,0;fにn番のスプライトのフラグnoを代入
if enemy_scroll_f!0{;n番のフラグが立っている場合は(n番のスプライトが生きていれば)
es_get enemy_scroll_x,enemy_scroll_n,3;xにn番のスプライトのx座標を代入
es_get enemy_scroll_y,enemy_scroll_n,5;yにn番のスプライトのy座標を代入
es_pos enemy_scroll_n,enemy_scroll_x+3,enemy_scroll_y;該当スプライトをx方向に3ずらす
}
else:if enemy_scroll_n=benemy_no:benemy_no-=1
if enemy_scroll_n>200:enemy_scroll_n-=1:goto *scroll_enemy_left_loop;最大noから開始して最低noまでチェックしてなかったらloop
return
*scroll_enemy_right
enemy_scroll_n=benemy_no
if enemy_n<200:return
*scroll_enemy_right_loop
es_get enemy_scroll_f,enemy_scroll_n,0;fにn番のスプライトのフラグnoを代入
if enemy_scroll_f!0{;n番のフラグが立っている場合は(n番のスプライトが生きていれば)
es_get enemy_scroll_x,enemy_scroll_n,3;xにn番のスプライトのx座標を代入
es_get enemy_scroll_y,enemy_scroll_n,5;yにn番のスプライトのy座標を代入
es_pos enemy_scroll_n,enemy_scroll_x-3,enemy_scroll_y;該当スプライトをxの逆に3ずらす
}
else:if enemy_scroll_n=benemy_no:benemy_no-=1
if enemy_scroll_n>200:enemy_scroll_n-=1:goto *scroll_enemy_right_loop;最大noから開始して最低noまでチェックしてなかったらloop
return
;----------敵弾スクロール----------
*scroll_enemybullet_left
enemy_scroll_bullet_n=enemy_bbullet_no
if enemy_scroll_bullet_n<300:return
*scroll_enemybullet_left_loop
es_get enemy_scroll_bullet_f,enemy_scroll_bullet_n,0;fにn番のスプライトのフラグnoを代入
if enemy_scroll_bullet_f!0{;n番のフラグが立っている場合は(n番のスプライトが生きていれば)
es_get enemy_scroll_bullet_x,enemy_scroll_bullet_n,3;xにn番のスプライトのx座標を代入
es_get enemy_scroll_bullet_y,enemy_scroll_bullet_n,5;yにn番のスプライトのy座標を代入
es_pos enemy_scroll_bullet_n,enemy_scroll_bullet_x+3,enemy_scroll_bullet_y;該当スプライトをx方向に3ずらす
}
else:if enemy_scroll_bullet_n=enemy_bbullet_no:enemy_bbullet_no-=1
if enemy_scroll_bullet_n>300:enemy_scroll_bullet_n-=1:goto *scroll_enemybullet_left_loop;最大noから開始して最低noまでチェックしてなかったらloop
return
*scroll_enemybullet_right
enemy_scroll_bullet_n=enemy_bbullet_no
if enemy_scroll_bullet_n<300:return
*scroll_enemybullet_right_loop
es_get enemy_scroll_bullet_f,enemy_scroll_bullet_n,0;fにn番のスプライトのフラグnoを代入
if enemy_scroll_bullet_f!0{;n番のフラグが立っている場合は(n番のスプライトが生きていれば)
es_get enemy_scroll_bullet_x,enemy_scroll_bullet_n,3;xにn番のスプライトのx座標を代入
es_get enemy_scroll_bullet_y,enemy_scroll_bullet_n,5;yにn番のスプライトのy座標を代入
es_pos enemy_scroll_bullet_n,enemy_scroll_bullet_x-3,enemy_scroll_bullet_y;該当スプライトをxの逆に3ずらす
}
else:if enemy_scroll_bullet_n=enemy_bbullet_no:enemy_bbullet_no-=1
if enemy_scroll_bullet_n>300:enemy_scroll_bullet_n-=1:goto *scroll_enemybullet_right_loop;最大noから開始して最低noまでチェックしてなかったらloop
return
;-------------------------------------
| |
|
2013/8/1(Thu) 19:40:56|NO.56025
>es_aimで移動を設定したスプライトをes_posすると何か不都合が発生するのでしょうか。
es_aimは%で1フレームの移動量を指定できるようにしてるので
内部では固定小数点が使われてる
それをes_posで座標を指定してしまうと、小数部分が0でクリアされてしまうため
動きがおかしくなる
> es_get enemy_scroll_bullet_x,enemy_scroll_bullet_n,3;xにn番のスプライトのx座標を代入
これは整数部のみ取り出してるが
設定も同じ事が出来る
es_setp enemy_scroll_bullet_n,3,enemy_scroll_bullet_x-3
これで小数部はクリアせずに座標を設定できる
因みにスプライトのX座標を取得するのに3を指定してるのを2にすると小数部が取得できる(Yは4)
後、es_screen にDirect3Dを使う設定してるのに
他の命令が使用しない指定をしてるため物凄く重くなってる
自分の環境でNO.56019のスクリプトはCPU使用率45%(2コアなので実質90%)
全てDirect3D使用の指定をした場合0%になる
;初期化----------------------------------------------------
#include "hspdxfix.as"
#include "hsp3util.as"
es_ini 1000,1000,360:es_screen 640,480,32,,1,1
screen 0,640,480,0
if stat : dialog"HSPDXFIX : DirectXの初期化に失敗":end
*start
gsel 0:mmstop:es_cls:es_draw:es_sync:wait 100
;----------------------------------------------------------
;******************
buffer 1:buffer 2:buffer 3
color $FF,$FF,0
mes"人・敵"
es_buffer 1,2,$FFFFFF,,1
;転送失敗時
if stat=1 {
es_bye
dialog "転送に失敗しました。",1,"Error"
end
}
;キャラクタ登録
es_size 16,20,80,0
es_pat 0,0,0,0
es_size 2,2,100,0
es_pat 1,23,7,0
es_size 16,20,90,0
es_pat 3,32,0,0
;MAP設定
mapsize_x=1280:mapsize_y=480
buffer 5,mapsize_x,mapsize_y
gsel 5
cls 4
color 255,255,255
mx=0:my=0
*map_draw
pos mx*16,464
mes mx
if mx<160:mx+=1:goto *map_draw
es_buffer 5,2,$FFFFFF,,1;window5に送る
;ステージ前初期化
chara_x=32:chara_y=448;自機座標の初期値設定
chara_wx=chara_x:chara_wy=chara_y
window_x=0:window_y=0
;----------敵配置----------
dim enemy_sdelay,99
enemy_sdelay=25,50
enemy_bbullet_no=300
benemy_no=201
es_set 200,432,292,3,1;432,236,3,0
es_set 201,432,236,3,1
;メインルーチン-------------------------------------
repeat
;移動関係
getkey a0,38:getkey a1,37:getkey a2,39
chara_speedx=a2*3-a1*3
if chara_speedx {
chara_x+chara_speedx
if chara_x>312:if chara_x<mapsize_x-328:gosub *scroll_enemy:gosub *scroll_enemybullet
}
if chara_x<=0:chara_x=0
if chara_x>=mapsize_x-16:chara_x=mapsize_x-16
if chara_y<=0:chara_y=0
;-----------敵処理-----------
gosub *enemy_shot
;----------escキーで終了-----------
getkey b,27
if b=1:es_bye:end
;------------描画ステップ------------
chara_wx=chara_x:chara_wy=chara_y;chara_x=キャラマップ座標 chara_wx=キャラ画面座標
window_x=chara_x-312;マップ切り取り開始位置座標調整
if window_x<0:window_x=0
if window_x>mapsize_x-640:window_x=mapsize_x-640
if chara_wx>312{
if chara_wx>mapsize_x-328{
chara_wx-=mapsize_x:chara_wx+=640
}
else:chara_wx=312
}
gsel 0
;es_cls;画面クリア
es_excopy 5,window_x,window_y,640,480;ID5のwindowから画面全てコピー(マップ想定)
es_set 0,chara_wx,chara_wy,0,1;自機スプライト描画準備
es_draw
es_sync 16
;------------------------------------
await 0
loop
;----------サブルーチン----------
;-----------敵弾発射処理-------------
*enemy_shot
enemy_n=benemy_no
if enemy_n<200:return
*enemy_shot_loop
es_get enemy_f,enemy_n,0
if enemy_f=0:if enemy_n>200{
if enemy_n=benemy_no:benemy_no-=1
enemy_n-=1:goto *enemy_shot_loop
}
else :return
enemy_sdelay(enemy_n-200)-=1;敵機弾ディレイ値を減らす
if enemy_sdelay(enemy_n-200)>0:if enemy_n>200{enemy_n-=1:goto *enemy_shot_loop}
else :return
enemy_sdelay(enemy_n-200)=10;ディレイリセット
es_new enemy_bullet_no,300;空スプライトナンバー取得(No.300以降で検索)
if enemy_bullet_no>enemy_bbullet_no{
enemy_bbullet_no=enemy_bullet_no;最大Noを記録しておく
}
es_get enemy_bullet_x,enemy_n,3
es_get enemy_bullet_y,enemy_n,5
es_set enemy_bullet_no,enemy_bullet_x+8,enemy_bullet_y+8,1,1;弾セット
es_aim enemy_bullet_no,chara_wx+8,chara_wy+8,200;弾移動
if enemy_n>200:enemy_n-=1:goto *enemy_shot_loop
return
;-----------------------------------
;----------敵スクロール----------
*scroll_enemy
enemy_scroll_n=benemy_no
if enemy_n<200:return
*scroll_enemy_loop
es_get enemy_scroll_f,enemy_scroll_n,0;fにn番のスプライトのフラグnoを代入
if enemy_scroll_f!0{;n番のフラグが立っている場合は(n番のスプライトが生きていれば)
es_get enemy_scroll_x,enemy_scroll_n,3;xにn番のスプライトのx座標を代入
es_setp enemy_scroll_n,3,enemy_scroll_x-chara_speedx;該当スプライトをx方向にchara_speed分ずらす
}
else:if enemy_scroll_n=benemy_no:benemy_no-=1
if enemy_scroll_n>200:enemy_scroll_n-=1:goto *scroll_enemy_loop;最大noから開始して最低noまでチェックしてなかったらloop
return
;----------敵弾スクロール----------
*scroll_enemybullet
enemy_scroll_bullet_n=enemy_bbullet_no
if enemy_scroll_bullet_n<300:return
*scroll_enemybullet_loop
es_get enemy_scroll_bullet_f,enemy_scroll_bullet_n,0;fにn番のスプライトのフラグnoを代入
if enemy_scroll_bullet_f!0{;n番のフラグが立っている場合は(n番のスプライトが生きていれば)
es_get enemy_scroll_bullet_x,enemy_scroll_bullet_n,3;xにn番のスプライトのx座標を代入
es_setp enemy_scroll_bullet_n,3,enemy_scroll_bullet_x-chara_speedx;該当スプライトをx方向にchara_speed分ずらす
}
else:if enemy_scroll_bullet_n=enemy_bbullet_no:enemy_bbullet_no-=1
if enemy_scroll_bullet_n>300:enemy_scroll_bullet_n-=1:goto *scroll_enemybullet_loop;最大noから開始して最低noまでチェックしてなかったらloop
return
全部Direct3D使用するようにして
左右のスクロールでサブルーチンの差異が移動量だけなので一緒にした
| |
|
2013/8/1(Thu) 20:53:49|NO.56027
とても分かりやすく詳細な説明をありがとうございます。
勉強不足でお手数をおかけしました!
|
|