|
|
2018/7/13(Fri) 21:23:44|NO.84754
自分HSPは初心者で馬鹿なので、優しくお願いします(´;ω;`)あと日本語おかしいかもです。
いま、画面にiPhoneとかによくあるクルクル歯車を表示したままデータを保存したりさせたいのですが、
全くやり方がわかりません。いろんなページを調べたり、HSP命令リファレンスを見ても自分が求めているものが
見つかりませんでした...
iPhoneのような歯車は、画像を1枚1枚読み込んで表示させています。(今はrepeat命令とloop命令で補っています)
ですが、この方法だとなんか個人的には嫌なんです...。
つまり、何が言いたいのかと言うと画像を使ったアニメーションのループを維持したまま、
裏でデータのセーブなどを行う方法を聞きたいのです(´・ω・`)
※意味わからんかも知れませんが、その場合は質問してください。
意味が伝わるように出来るかどうかはわかりませんが...(´;ω;`)
|
|
2018/7/13(Fri) 22:01:38|NO.84756
gosub命令を使い、処理が終了したらreturn命令を
実行すれば良いのではないのでしょうか?
|
|
2018/7/13(Fri) 22:04:00|NO.84757
試してみます
|
|
2018/7/13(Fri) 22:06:44|NO.84759
すいません。
Gosub命令時はアニメーションが止まってしまいます(´;ω;`)
|
|
2018/7/13(Fri) 22:07:25|NO.84760
ゲームなんかでよくあるロードやセーブ中に
何らかのアニメーションを行なうような処理をしたいということですよね?
ゲーム以外でもPCの起動画面やダウンロード中にバーが少しずつ増えるのとか。
そういった処理はアニメーションと保存処理を別々のスレッドで行なう
いわゆるマルチスレッド処理が必要かと思います。
マルチスレッドはコールバック関数が必要になるので
HSPでは少し前までは無謀だったのですが、
現在はコールバック用モジュールが標準で付属しているので
それを使うと(きっと)出来るはずです。
|
|
2018/7/13(Fri) 22:48:58|NO.84761
なるほど。参考になるソースなどはありますか?(´・ω・`)
|
|
2018/7/13(Fri) 22:52:12|NO.84762
こちらのサイトのサンプルスクリプトを理解すれば実装できます。
http://chokuto.ifdef.jp/advanced/usertimer.html
*RedrawClock の処理に軽量なローディング待ちの画面を描画させて、
[重要]データ保存処理などは、軽量なレベルに分割処理にする必要があります。
(例えば100MBのbsaveを発行する場合は、512kB単位で保存するといった対応)
この処理をしないと、ローディング待ちのアニメーションがガクガクします。
(あと、サンプルの250msはアニメーションにはおそすぎるので、16msとかにしておくといいかもです。
その分高速な描画処理じゃないと、重すぎて処理が何もできなくなります)
|
|
2018/7/14(Sat) 00:51:45|NO.84764
なるほど。
今からサンプルの方を見ていろいろ試してみます。
分からないことがあったらまた聞きますね!
(その時はよろしくお願いします。)
|
|
2018/7/14(Sat) 10:16:08|NO.84766
RedrawClockのラベルにアニメーションの画像をセットしたら、何故かRuntimeErorr!!C++
というエラーが大量に発生します。何故ですか?
それから、サンプルを見て理解しようと頑張って見ましたが理解できませんでした(´・ω・`)
どうやってアニメーションを維持したまま裏で処理させるかは未だ分からないままです(;´・ω・)
|
|
2018/7/14(Sat) 12:55:52|NO.84767
サンプルソースを作ってみました。右下のウェイトサークルを容赦なく描画で潰してくるため、ランダムサークル描画のエリアを避けていますw
#uselib "user32.dll"
bgscr 1,480,1
gradf 0,0,160,1,0,$ff0000,$00ff00
gradf 160,0,160,1,0,$00ff00,$0000ff
gradf 320,0,160,1,0,$0000ff,$ff0000
buffer 2,64,64
gsel 0
#module
#deffunc rcircle int x,int y,int r
circle x-r,y-r,x+r,y+r
return
#deffunc drawCircle
count++
if(count>=48){
count-=48
}
drawing=ginfo_sel
for i,0,10
gsel 1
if(i*48+count*10>480){
pget i*48+count*10-480,0
}else{
pget i*48+count*10,0
}
r=ginfo_r
g=ginfo_g
b=ginfo_b
gsel 2
color r,g,b
rcircle 32.0+16.0*cos(M_PI*i/5),32.0+16.0*sin(M_PI*i/5),4
next
gsel drawing
return
#global
#func SetTimer "SetTimer" int,int,int,int
#func KillTimer "KillTimer" int,int
#define WM_TIMER 0x0113
#define TIMER_ID 1 ; タイマーID
gosub *RedrawClock
; メッセージ処理の登録
oncmd gosub *OnTimer, WM_TIMER
; プログラム終了時の処理の登録
onexit goto *OnQuit
; タイマーを設定(0.25秒間隔)
SetTimer hwnd, TIMER_ID, 16, 0
if stat == 0 {
dialog "タイマーの設定に失敗しました。", 1, "エラー"
end
}
repeat
color rnd(256),rnd(256),rnd(256)
rcircle rnd(640-128),rnd(480-128),rnd(64)
wait 0
loop
*OnTimer
; ====== タイマーメッセージの処理 ======
if wparam == TIMER_ID : gosub *RedrawClock
return 0
*RedrawClock
; ====== 再描画処理 ======
drawCircle
pos_x@cur=ginfo_cx
pos_y@cur=ginfo_cy
pos 640-64,480-64
gcopy 2,0,0,64,64
pos pos_x@cur,pos_y@cur
return
*OnQuit
; ====== 終了時の処理 ======
; タイマーを破棄
KillTimer hwnd, TIMER_ID
end
| |
|
2018/7/14(Sat) 13:47:18|NO.84768
わざわざサンプルソースを作っていただけるなんて!とてもありがたいです!
このソースについて質問なんですが、 circle x-r,y-r,x+r,y+r で作成した小さい円を一つだけ
にして、その一つの円をなんか、こう、Huaweiのスマホのプログレスバー(参考にして作ったアニメーションがHuaweiなのでw)
みたいにしたいのですが...
|
|
2018/7/14(Sat) 13:49:26|NO.84769
分に抜かりがあったので
Huaweiスマホのような、小さい円を加速現ありで回転させる方法はないでしょうか?
作っていただいたサンプルソースをみていろいろ試しましたが、うまくいかず、ついにはアニメーションがとまったりで...
|
|
2018/7/14(Sat) 16:14:47|NO.84771
こんにちわ
自分も最近、似たようなことで悩んでましたが
このケースだとループしなくても大丈夫そうです
100ミリ秒なり200秒なりに一回描画すると考えてはどうでしょうか
シングルCPUのマルチな実行のイメージで
(Velgailさんは16ミリ秒にしてみては?っておっしゃてますね)
やってる処理の途中、途中で
サブルーチンで時間を計測して
経過してたら描画サブルーチンを呼ぶかんじだと思います
ってVelgailさんのサンプルスクリプトまんまですね
|
|
2018/7/14(Sat) 18:37:28|NO.84773
Y_repeatさんこんにちは。
まだあまりよくわかっていませんが、
gosub命令で指定しラベルに移動して、
そこで時間を計測して、指定した時間になったらgosub命令でアニメーション専用の
ラベルに移動させるということですか?
でも、いまだよくわかっていません(;´・ω・)
そして、Velgailさんが作ってくださったソースの*RedrawClockに
アニメーション用で制作した画像をバッファーに保存し、gcopyで描画するようにしてみようと
試したのですが、画像が表示されなかったり、エラーが発生したりといろいろあってうまくいきません...
目的としては、 screen 1でウィンドウを二つ表示させ、screen 1でアニメーションを再生したまま、
データを保存(例として、テキストデータを保存など)行いたいのです。
そのために、裏でデータのセーブ中など(時間がかかる場合)にずっとウィンドウにはアニメーション(全て画像)
を繰り返しさせておきたいのです。
(screen 1に、ウィンドウメッセージとロード、セーブ時の「アニメーション(現在はrepeat3とloop命令で、repeatの繰り返し回数に達したら次の命令でセーブを行うようにしています)」を表示させています)
※日本語文がおかしいのと、意味不明なことばかり言ってるかもしれませんw
|
|
2018/7/14(Sat) 20:12:26|NO.84774
Huaweiのスマホを持っていないので違うかもしれませんが
たぶんこんな感じでしょうか?
アニメーション部分だけです。
lr = 50; // 周の半径
cr = 5; // 円の半径
arg = 270; // 初期位置(真上)
fflag = 1; // 落下フラグ
count = 0; // カウンタ(加速度)
*main
redraw 0;
color 0, 0, 0: boxf;
cx = cos(deg2rad(arg))*lr + 320;
cy = sin(deg2rad(arg))*lr + 240;
color 255, 255, 255: circle cx-cr, cy-cr, cx+cr, cy+cr, 1;
redraw 1;
await 33;
if( fflag ) {
// 上から下に移動するときは徐々に加速
count++;
if( count == 19 ): fflag = 0;
}
else {
// 下から上に移動するときは徐々に減速
count--;
if( count == 1 ): count = 0: fflag = 1;
}
arg += count;
arg \= 360;
goto *main;
|
|
2018/7/14(Sat) 21:15:32|NO.84776
こんばんわ。あらやさんのサンプルスクリプトを改造してみました
debug window表示してください
taskマクロでなんか作業してるのをイメージしてください
自分では時間計測書くの時間かかりそうではしょりました
lr = 50; // 周の半径
cr = 5; // 円の半径
arg = 270; // 初期位置(真上)
fflag = 1; // 落下フラグ
count = 0; // カウンタ(加速度)
#define task(%1) await 10 // なんかTASKしてることをイメージして下さい
*subr
while 1
task hoge
task piyo
task hogehoge
task piyopiyo
logmes "hogepiyo"
gosub *main_r
task bar
task baz
task barbar
task bazbaz
logmes "barbaz"
gosub *main_r
wend
*main_r
redraw 0;
color 0, 0, 0: boxf;
cx = cos(deg2rad(arg))*lr + 320;
cy = sin(deg2rad(arg))*lr + 240;
color 255, 255, 255: circle cx-cr, cy-cr, cx+cr, cy+cr, 1;
redraw 1;
if( fflag ) {
// 上から下に移動するときは徐々に加速
count++;
if( count == 19 ): fflag = 0;
}
else {
// 下から上に移動するときは徐々に減速
count--;
if( count == 1 ): count = 0: fflag = 1;
}
arg += count;
arg \= 360;
return
|
|
2018/7/14(Sat) 22:59:02|NO.84777
これです!
自分が求めていたものはこれです!ありがとうございます!!
あとは*subrの処理内容を変えておいたらいいだけですかね?(´・ω・`)
|
|
2018/7/14(Sat) 23:34:01|NO.84778
ヒント:
私のサンプルソースの、drawCircleは
「呼ばれるたびにモジュール内変数のcountが1増えて、48に達したら0になる」ように設計されています。
同じように、「アニメーションを数式だけで書けるように」して、
数字が1増えるたびにどこに来るかを計算すると、うまく書きやすいです。
例えば以下のように書いてしまうと、きれいに一周で速度差を定義するのが極めて困難に……
(上のサンプルソースの改変部分です。#module〜#global間の差し替えです)
#module
#define oneroll 60
#deffunc rcircle int x,int y,int r
circle x-r,y-r,x+r,y+r
return
#deffunc drawCircle
if(vartype(rad)==4){
rad=0.0
}
count++
if(count>=oneroll){
count-=oneroll
}
drawing=ginfo_sel
gsel 2
cls
setease 0.06,0.16,ease_cubic_inout|ease_loop
speed=geteasef(count,oneroll/2)
rad+=speed
rcircle 32.0+16.0*cos(rad),32.0+16.0*sin(rad),4
gsel drawing
return
#global
けれども、動きに使う角度のグラフを書くと、(ここはひらめきでもあるけど)シグモイド関数っぽい。なら、楽なシグモイド系の関数で置き換えようとする
https://ja.wikipedia.org/wiki/シグモイド関数
今回はx/√(1+x^2)を使ってみて、その振幅を-1〜1のときに0〜2πになるように係数値を調整(ease関数内)して以下の通り。
#module
#defcfunc sigmoidal double x
return x/sqrt(1.0+x*x)
#defcfunc ease double count,double max
return M_PI*2*(sigmoidal(count/(max/2)-1)+sqrt(0.5))/sqrt(2)
#deffunc rcircle int x,int y,int r
circle x-r,y-r,x+r,y+r
return
#deffunc drawCircle
#define oneroll 60
count++
if(count>=oneroll){
count-=oneroll
}
drawing=ginfo_sel
gsel 2
cls
rad=ease(count,oneroll)
rcircle 32.0+16.0*cos(rad),32.0+16.0*sin(rad),4
gsel drawing
return
#global
しかし、これを理解できるかどうかはっ……(理解できるように書いた気がしない)
| |
|
2018/7/14(Sat) 23:54:48|NO.84779
な、なるほど(そもそもソース内のコードの意味すら理解出来ていないおバカ)
モジュール内のcoumt命令についてはよく分かりました!
みなさん本当に協力して下さってありがとうございます!
Velgailさんが教えてくださったシグモイド関数のことについては、ネットで色々調べて見たりしてみます!
そして、皆さんが教えてくださったソース内のコードに関しても完全理解していませんので、理解できる所では
頑張って調べたりしようと思います。
aaaさん、あらやさん、Velgailさん、Y_repeatさん。
本当にありがとうございました!!
|
|