キャラクターの動きがカクつく
新入りさん 2013/6/10(Mon) 02:05:18|NO.54782
repeat
color 255,255,255:boxf
stick key,15
if Key&1 : x-=5
if Key&2 : y-=5
if Key&4 : x+=5
if Key&8 : y+=5
color : font "",30 : pos x,y : mes "凸"
redraw 1
redraw 0
await 16
loop
実行すると分かるかと思うのですが、カク、カク、カク、と規則的なカクつきが発生します。
環境の違う二つのPCで実行しても、両方とも同じようにカクつきました。
await 1にして移動量を減らすのは、PCのスペックによって速度に違いが出てしまうのでやりたくないです。
なんとかこのカクつきをなくすことはできないのでしょうか?
ht. 2013/6/10(Mon) 03:01:02|NO.54784
font命令を空文字にしたときは特に重たいのでループ前に一回にしておきましょう。
またredrawの引数を逆にして更にmesを内側に入れないと意味がありませんよ。
それでもカク付くというのなら座標の加減を減らすかawaitの間隔を狭めるしかないでしょうね。
kanahiron 2013/6/10(Mon) 08:27:22|NO.54787
この問題じゃないでしょうか?
http://hsp.tv/play/pforum.php?mode=all&num=53549
ミント 2013/6/10(Mon) 09:01:47|NO.54788
「await」を「15」にしたらスムーズに動いたよ〜
っていうか16以上だとカクつくっぽい?
GrapeColor(DION) 2013/6/10(Mon) 20:47:54|NO.54794
私の環境ではスムーズに動きましたが、一応問題点を指摘しておきます。
font命令は意外と処理が重い命令なので何回も使用しないでください。
一回使用すれば、それ以降も適応されますしね。
というわけで、見易さも考慮してスクリプトを書き直してみました。
#deffunc move 5 ; 一回で動く距離を指定
font "", 30
repeat
color 255, 255, 255 : boxf
stick key, 15
if key & 1 : x -= move
if key & 2 : y -= move
if key & 4 : x += move
if key & 8 : y += move
redraw 0
color
pos x, y
mes "凸"
redraw 1
await 16
loop
kanahiron 2013/6/10(Mon) 21:00:39|NO.54798
GrapeColor(DION)さんのソースだと実行出来ません
#define を #deffunc に間違えてしまっています…
それとredrawの位置がおかしいです
repeat直後にboxfで消してますがそこをradrawで隠してないため時々ちらつきます
repeat
redraw 0
/*〜〜〜〜〜*/
redraw 1
await 16
loop
が一般的じゃないでしょうか
新入りさん 2013/6/10(Mon) 21:20:40|NO.54801
どの方の方法をとってもカクつきます・・・
kanahironさんの教えてくださったモジュールが興味深いのですが、まだ未熟なためそれを使用するには時間がかかりそうです・・・
あと一つ疑問なのですが、redrawは最初に私が書いた方法では、皆さんにはチラつきが発生するのでしょうか?
私の環境だとあの書き方で問題ありませんし、HSP講座的なところで、あの書き方をしてる人を多く見るのですが・・・
ちなみにPCはそれなりにハイスペックな部類だと思うので、処理落ちが原因でカクついているのではないかと思います
新入りさん 2013/6/10(Mon) 21:21:16|NO.54802
日本語が少しおかしかったですね。
ないかと→ないと ですね
kanahiron 2013/6/10(Mon) 21:25:52|NO.54803
新入りさんが最初に書かれたソースはチラツキは発生しませんが、書かれているように
>実行すると分かるかと思うのですが、カク、カク、カク、と規則的なカクつきが発生します。
です
自分のPCもハイスペックな部類なので処理落ちの可能性は0です
GrapeColor(DION) 2013/6/10(Mon) 21:50:52|NO.54807
ゴメン。
あまり確認せずにプログラム書いてた。
これでOKなはず。
#define move 5 ; 一回で動く距離を指定
font "", 30
repeat
stick key, 15
if key & 1 : x -= move
if key & 2 : y -= move
if key & 4 : x += move
if key & 8 : y += move
redraw 0
color 255, 255, 255 : boxf
color
pos x, y
mes "凸"
redraw 1
await 16
loop
これで駄目だったら多分かなり低スペックですよ。
新入りさん 2013/6/10(Mon) 22:24:36|NO.54810
>GrapeColor(DION)さん
変わりません・・・
重ねていいますが、低スペックではないです
この程度のプログラムではCPUを1%も使いません
なんなんでしょうね、この現象・・・
体感で0.5秒ごとにカクつきが見られるのですが、
60fpsで動かしているのだからそういうカクつきは普通は発生しないと思うんですが
やはりkanahironさんの貼った記事にあるティアリングという現象なのでしょうか
YSR 2013/6/10(Mon) 22:38:21|NO.54811
gcopyするように書き直してみた。……まあ>>NO.54787で解決なんだろうけど。
;プリプロセッサ
#define font_size 30 //表示文字のサイズ(ピクセル数)
#define speed_per_frame 5 //1フレーム毎の移動量
;各種初期化
;(表示用オブジェクトをあらかじめ描画しておく)
buffer 2
font msgothic, font_size
mes "凸"
gsel 0
position_x = 0 :position_y = 0 ;初期座標
;メインループ(約60fpsになるように指定した)
repeat
;キー入力
stick cursor_key, 15 ;1+2+4+8(4方向キー)
if cursor_key & 1 : position_x -= speed_per_frame
if cursor_key & 2 : position_y -= speed_per_frame
if cursor_key & 4 : position_x += speed_per_frame
if cursor_key & 8 : position_y += speed_per_frame
;画面描画
;(ID:2なbufferからgcopyでID:0のscreenにコピー)
redraw 0
color 255, 255, 255 : boxf
pos position_x, position_y
gcopy 2, 0, 0, font_size, font_size
redraw 1
;fps調整用にウェイトを掛ける
await 15
loop
暇人 2013/6/11(Tue) 01:56:38|NO.54818
OSがVista以上かどうかで原因が異なる
XPならティアリングが原因
キャラの位置にティアリングが発生するとカクついてるように見える
(awaitだけで待つとティアリングの位置がずれてくので定期的にカクつくように見える)
ティアリングの位置を有る程度固定するモジュール(ディスプレイのリフレッシュレートとFPSが同じ時)
//指定FPSになるようにawaitするモジュール
#module
#uselib "winmm.dll"
#cfunc _timeGetTime "timeGetTime"
#func _timeBeginPeriod "timeBeginPeriod" sptr
#func _timeEndPeriod "timeEndPeriod" sptr
#deffunc timeEndPeriod onexit //タイマー精度を戻す(終了時に自動で呼びだされる)
if tbp {_timeEndPeriod tbp}
return
//SetFps 設定するフレームレート
#deffunc SetFps double fps
if tbp=0{tbp=1 : _timeBeginPeriod tbp} //タイマー精度変更
f_tim=1000.0/fps //1フレームの時間
ms_tim=_timeGetTime() //スタート時間(d3timer()-ms_timでスタートからの時間にする)
fs_tim=0.0 //フレームスタート時間
return f_tim
//GetFps フレームレート取得する変数
#deffunc GetFps var fps
to=t
fps_cnt+
fs_tim+f_tim //1フレームの時間を足して次フレームスタート時間にする
sms=fs_tim-(_timeGetTime()-ms_tim) //次フレームスタート時間からスタートからの時間を引いてawait時間にする(結果が負数なら1フレームの時間を越えた)
if sms < 0 {fs_tim-sms} //1フレームの時間以上使用したからオーバー分をフレームスタート時間に加算
await limit(sms,0,f_tim+1) //小数点以下のawaitは出来ないから最大await時間をf_tim+1にする
t=_timeGetTime()/1000
if t ! to {fps=fps_cnt:fps_cnt=0}
return int(f_tim-sms)
#global
//使用サンプル
//FPSを設定
SetFps 60
*rep
redraw 0
color 255,255,255:boxf
if s=0:xx+10:else:xx-10
if xx<0:s=0:else:if xx>590:s=1
color:boxf xx,0,xx+50,480
stick key,15
if Key&1 : x-=5
if Key&2 : y-=5
if Key&4 : x+=5
if Key&8 : y+=5
color : font "",30 : pos x,y : mes "凸"
pos 5,5:mes"fps:"+fps+" ms:"+ms
GetFps fps //指定FPSになるようにawaitして実際のFSPを返す
ms=stat //statにGetFps抜けてからGetFps実行時までの時間をmsで返す
redraw 1
goto*rep
タイトルバーをクリックすると動作が停止するので
放したとき時間は進んでるのでティアリング位置が変る
画面内にティアリングを発生させないようにするのがNO.54787に出されてるモジュール
>kanahironさんの教えてくださったモジュールが興味深いのですが、まだ未熟なためそれを使用するには時間がかかりそうです・・・
http://hsp.tv/play/pforum.php?mode=pastwch&num=46392
に使用サンプル
一応Vista以上でも安定化に効果あるらしい・・・
新入りさん 2013/6/15(Sat) 09:09:39|NO.54904
すみません、ちょっと私情で返信が遅れました。
>YSR
駄目っぽいです・・・
一応、初歩的な方法で変えられるものは変えつくしたと思います。
>暇人さん
OSはwindows7です。
この場合はティザリングの影響なのでしょうか?
kanahiron 2013/6/15(Sat) 09:55:23|NO.54905
あ Aeroが有効か無効かでもティアリングが発生するかしないか変わるそうです(詳しく知りません)
自分の環境はAero切っています
また自分が一番最初に貼ったモジュールを使うとティアリングが発生しないことを報告しておきます
新入りさん 2013/6/15(Sat) 10:26:29|NO.54908
>この場合はティザリングの影響なのでしょうか?
ティザリングってなんやねーん
>kanahiron
Aeroは切ってます
で、有効にしてみたのですが、変わりませんでした・・・。
暇人さんのモジュールの使用例を改変して凸を動かすプログラムにしたのですが、それでも駄目っぽいです。
もしかしたら私の知識の浅さゆえに間違っているのかもしれませんが・・・。
暇人 2013/6/15(Sat) 15:24:22|NO.54911
>で、有効にしてみたのですが、変わりませんでした・・・。
Aero有無で動作は異なるので同じにはならないはずなんだが・・・
(Aero無しでXPに近い動作)
後はHSPのバージョンが最新版かどうか
NO.54818のは最新版じゃないとカクつきが酷い
他のゲーム(HSP製じゃ無いやつで、ウィンドウモードでDX8以下の)とかでも確認してみて
HSP側の問題かどうかはっきりさせた方が良いかも
新入りさん 2013/6/15(Sat) 16:48:34|NO.54912
>暇人さん
HSP3.31でした・・・。
変えてみたところ、Aeroが有効の状態ならカクつきが消えました。
ですが、Aeroを無効にすると、やはりカクつきが発生します。>NO.54818
別のゲームですか・・・ちょっと探してみます。
kanahiron 2013/6/15(Sat) 17:22:07|NO.54914
とても簡単にマシにする方法
#module
#deffunc hold60fps
a++
if a != 3{
await 17
} else {
a=0
await 16
}
return
#global
await 16 の代わりにhold60fpsと書くだけです
新入りさん 2013/6/15(Sat) 17:40:35|NO.54915
>kanahironさん
Aero無効で不規則なカクつき、Aero有効で生まれたての小鹿のようにガックガクになりました・・・
kanahiron 2013/6/15(Sat) 17:50:18|NO.54917
まじですか…
Aero無効だと上記モジュールとまでは行かないもののだいぶマシになったのですが…
暇人 2013/6/15(Sat) 18:13:48|NO.54919
>ですが、Aeroを無効にすると、やはりカクつきが発生します。>NO.54818
Aeroを無効だとXP同様ティアリングが発生する
XPと違いきちんとタイミングを計ってもOS側(グラボ?)が
書き換えタイミングを決めてしまうので意味が無い
環境によってはNO.54787のモジュールが効果あるみたいだが・・・
グラボ側の設定で遅延を無くすための設定をすれば改善するかも知れない・・・
(レンダリング前最大フレーム数ってやつらしいグラボにより呼び方も設定の仕方も違う)
>別のゲームですか・・・ちょっと探してみます。
多分他のゲームでもAeroOFFならFPS60で固定できてるゲームほど定期的にカクつくと思う
HSPとは関係なく環境の問題だろう
新入りさん 2013/6/15(Sat) 18:43:45|NO.54921
>kanahironさん
マジですね・・・。
暇人さんの言うように環境の問題でしょうか。
>暇人さん
>グラボ側の設定で遅延を無くすための設定をすれば改善するかも知れない・・・
遅延は一応最低にしてるのですがね・・・。
もう妥協するしかないかなぁ・・・。
暇人 2013/6/15(Sat) 19:40:00|NO.54924
DX9のウィンドウ作ってHSPのバッファをDX9テクスチャにコピーし
レンダリングして垂直同期取るって事も出来なくは無いが・・・
(テクスチャにコピーする処理時間が問題、ゲームの処理が軽いなら使えなくは無い)
hgimg4はウィンドウモードでも垂直同期してるみたいなので
正式版出たら使ってみるのも良いかもしれない
新入りさん 2013/6/16(Sun) 00:15:53|NO.54929
>暇人さん
そうですか・・・。
初心者なので、どちらも難しそうです・・・。
とりあえずは、現状のまま作ろうと思います。
皆さん、いろいろご教授いただきありがとうございました。
暇人 2013/6/17(Mon) 19:41:59|NO.54983
NO.54818のだとGetFpsのstatが処理時間を返さなくなってた・・・
> fs_tim+f_tim //1フレームの時間を足して次フレームスタート時間にするの上の行に
の下あたりに await 0 を入れると改善される
違いがあるか分からないがawaitの代わりにSleepにしてみる
#module
#uselib "winmm.dll"
#cfunc _timeGetTime "timeGetTime"
#func _timeBeginPeriod "timeBeginPeriod" sptr
#func _timeEndPeriod "timeEndPeriod" sptr
#uselib "KERNEL32.DLL"
#func global _Sleep "Sleep" sptr
#deffunc timeEndPeriod onexit //タイマー精度を戻す(終了時に自動で呼びだされる)
if tbp {_timeEndPeriod tbp}
return
#deffunc SetFps double fps
if tbp=0{tbp=1 : _timeBeginPeriod tbp} //タイマー精度変更
f_tim=1000.0/fps //1フレームの時間
ms_tim=_timeGetTime() //スタート時間(d3timer()-ms_timでスタートからの時間にする)
fs_tim=0.0 //フレームスタート時間
return f_tim
#deffunc GetFps var fps
to=t
fps_cnt+
fs_tim+f_tim //1フレームの時間を足して次フレームスタート時間にする
await 0//Sleepはawaitの代わりにならないので必ず何処かでawaitが必要
sms=fs_tim-(_timeGetTime()-ms_tim) //次フレームスタート時間からスタートからの時間を引いてスリープ時間にする(結果が負数なら1フレームの時間を越えた)
if sms < 0 {fs_tim-sms} //1フレームの時間以上使用したからオーバー分をフレームスタート時間に加算
_Sleep limit(sms,0,f_tim+1) //小数点以下のスリープは出来ないから最大スリープ時間をf_tim+1にする
t=_timeGetTime()/1000
if t ! to {fps=fps_cnt:fps_cnt=0}
return int(f_tim-sms)
#global
//使用サンプル
//FPSを設定
SetFps 60
*rep
redraw 0
color 255,255,255:boxf
if s=0:xx+10:else:xx-10
if xx<0:s=0:else:if xx>590:s=1
color:boxf xx,0,xx+50,480
stick key,15
if Key&1 : x-=5
if Key&2 : y-=5
if Key&4 : x+=5
if Key&8 : y+=5
color : font "",30 : pos x,y : mes "凸"
pos 5,5:mes"fps:"+fps+" ms:"+ms
GetFps fps //指定FPSになるようにawaitして実際のFpsを返す
ms=stat //statにGetFps抜けてからGetFps実行時までの時間をmsで返す
redraw 1
goto*rep
新入りさん 2013/6/17(Mon) 21:08:32|NO.54992
>暇人さん
実行してみましたが、これはAeroOFF用ですかね・・・?
自分の環境だとAeroONでガクガクになります。
暇人 2013/7/3(Wed) 19:23:09|NO.55467
返信来てるの気付かなかった・・・
>実行してみましたが、これはAeroOFF用ですかね・・・?
どっち用と言うか
awaitとsleepで違いがあるかも知れないので試しに書いてみた