|
|
2014/4/22(Tue) 10:47:21|NO.61621
ネットゲーム等でスキルのクールタイムを視覚的に把握しやすいタイマーを
自作したいと考えてHSPに行き当たったのですが、初めての作成のため
思い通りの物にならなかったので、ご教示願いたいです。
例えばF1キーを押下した時に、体力ゲージのようなバーを
キャラの近くなど任意の場所に表示させ、時間経過とともに
バーが減少していき、3秒後には消えるといったスクリプトを作りたいです。
実行時はウィンドウを消し、ゲージのみを常に最前面に表示させ、
バーの減少中に再度F1を押しても初期化&再実行されないようにしたいです。
(一度F1を押したらきっちり時間が経過した後、再使用が出来るようにしたい)
可能であればF2やF3といった別の設定時間のバーも
同時に実行させることが出来れば完璧なのですが…。
拙い説明で申し訳ないのですが、どうか宜しくお願い致します。
|
|
2014/4/22(Tue) 14:59:08|NO.61622
上の質問文ではゲーム内部でタイマーを作りたいのか
ゲームとは独立したタイマーのみを作りたいのかがよく分かりません。
また、前者だと仮定しても『実行時はウィンドウを消し』のウィンドウが
何を指しているのか不明です(メニューやステータスの事?)
これらは説明してもらうとして
希望の動作をするものを作成する為には
・時間を計る
・タイマーの状態を管理する
の二つの処理が最低限必要です。
時間計測については、実時間とゲーム内時間があるので
実時間を計測するならgettimeやd3timer等を使いますが
ゲーム内時間(フレーム単位やターン等)の場合は
自分でカウンターを用意して計測する事になります。
タイマーの管理については、タイマーが使用中かどうかを調べて
使用中なら使用しているタイマー毎の時間計測に応じたゲージの表示を行い
未使用ならタイマー処理を行わずに次の処理へ進む
といった行程になります。
以下はキャラクター毎にタイマーを設定して表示するサンプル。
(F1〜F3キーでタイマー起動)
#include "d3m.hsp"
#const TIMER_SIZE 48 ; タイマーゲージの長さ
#const TIMER_DIV 1000 * TIMER_SIZE / 3000 ; タイマーサイズ計算用定数
#const CHR_MAX 3 ; キャラクター(タイマー)数
dim cx, CHR_MAX ; キャラクターX座標
cy = 100, 200, 300 ; キャラクターY座標
cx_mov = 1, 1, 1 ; キャラクター移動量
dim timer_flg, CHR_MAX
dim timer_base, CHR_MAX
dim f_key, CHR_MAX ; ファンクションキー入力用変数
*main
redraw 0
color 0, 0, 0 : boxf
t_cnt = d3timer() ; PC起動からの時間を取得(ミリ秒)
repeat CHR_MAX
mov_rate = 1 ; キャラクター移動量倍率
getkey f_key(cnt), 112 + cnt ; ファンクションキー入力判定
if f_key(cnt) = 1 {
if timer_flg(cnt) = 0 { ; タイマー未使用ならフラグを立ててタイマー起動
timer_flg(cnt) = TIMER_SIZE ; タイマー起動中フラグ(タイマーの長さと併用)
timer_base(cnt) = t_cnt ; タイマーが起動した時間
}
}
color 255, 255, 255
pos cx(cnt), cy(cnt) : mes "●" ; キャラ表示
if timer_flg(cnt) > 0 { ; タイマー起動中ならタイマーゲージを表示
color 255, 0, 0
; 3秒(3000ミリ秒)をタイマーのサイズ(48ドット)に換算してゲージを表示
timer_flg(cnt) = limit((3000-(t_cnt-timer_base(cnt)))*TIMER_DIV/1000, 0, 48)
boxf cx(cnt)-16, cy(cnt)-4, cx(cnt)+timer_flg(cnt)-16, cy(cnt)+4
mov_rate = 2 ; タイマー使用中なら移動量2倍
}
cx(cnt) + cx_mov(cnt) * mov_rate ; キャラ移動計算
if (cx(cnt)<0) or (cx(cnt)>624) : cx_mov(cnt) * -1 ; キャラが端に来たら方向反転
pos 0, 16*cnt : mes "" + timer_flg(cnt)
loop
redraw 1
await 16
goto *main
| |
|
2014/4/22(Tue) 15:47:38|NO.61623
質問を見直したら、時間別のタイマーとの事でしたね(汗)
まぁ一つできればあとは応用という事でご勘弁を。
#include "d3m.hsp"
#const TIMER_SIZE 48 ; タイマーゲージの長さ
TIME_MAX(0) = 3000, 5000, 10000 ; タイマー毎の時間
TIMER_DIV(0) = 1000 * TIMER_SIZE / TIME_MAX(0) ; タイマーサイズ計算用定数
TIMER_DIV(1) = 1000 * TIMER_SIZE / TIME_MAX(1) ;
TIMER_DIV(2) = 1000 * TIMER_SIZE / TIME_MAX(2) ;
cx = 0 ; キャラクターX座標
cy = 200 ; キャラクターY座標
cx_mov = 2 ; キャラクター移動量
dim timer_flg, 3
dim timer_base, 3
dim f_key, 3 ; ファンクションキー入力用変数
timer_cr = 255, 0, 0 ; タイマーの色R
timer_cg = 0, 255, 0 ; タイマーの色G
timer_cb = 0, 0, 255 ; タイマーの色B
timer_posy = 180, 190, 200 ; タイマー毎のY座標
*main
redraw 0
color 0, 0, 0 : boxf
color 255, 255, 255
pos cx(cnt), cy(cnt) : mes "●" ; キャラ表示
t_cnt = d3timer() ; PC起動からの時間を取得(ミリ秒)
repeat 3
getkey f_key(cnt), 112 + cnt ; ファンクションキー入力判定
if f_key(cnt) = 1 {
if timer_flg(cnt) = 0 { ; タイマー未使用ならフラグを立ててタイマー起動
timer_flg(cnt) = TIMER_SIZE ; タイマー起動中フラグ(タイマーの長さと併用)
timer_base(cnt) = t_cnt ; タイマーが起動した時間
}
}
color 255, 255, 255
if timer_flg(cnt) > 0 { ; タイマー起動中ならタイマーゲージを表示
color timer_cr(cnt), timer_cg(cnt), timer_cb(cnt)
; タイマー毎の残り時間をタイマーのサイズ(48ドット)に換算してゲージを表示
timer_flg(cnt) = limit((TIME_MAX(cnt)-(t_cnt-timer_base(cnt)))*TIMER_DIV(cnt)/1000, 0, 48)
boxf cx-16, timer_posy(cnt), cx+timer_flg(cnt)-16, timer_posy(cnt)+8
}
pos 0, 16*cnt : mes "" + timer_flg(cnt)
loop
cx(cnt) + cx_mov(cnt) ; キャラ移動計算
if (cx(cnt)<0) or (cx(cnt)>624) : cx_mov(cnt) * -1 ; キャラが端に来たら方向反転
redraw 1
await 16
goto *main
| |
|
2014/4/22(Tue) 17:42:23|NO.61624
ありさん、ご回答頂きまして有難うござます。
教えて頂いた内容は、やりたい事に非常に近くて感動しました。
作りたいものは、ゲームとは独立したタイマーです。
私の説明が不十分でご迷惑をお掛けし、申し訳ありません。
更にはゲーム画面内のキャラを追従する必要はなく、
座標を指定し表示させているだけで問題ありません。
その際に、全画面表示されているプレイ中のゲーム画面より手前に
常にタイマーを表示させ、タイマーをクリックしてしまってもゲーム操作に支障なく
尚且つ視覚的に邪魔になるバー以外の余分な部分を透明化したいのです。
他の質問にあったサンプルで、希望に近い動作をするものが有りましたので
貼り付けてみます。しかしウィンドウと一緒にタイマーのバーも透明になる様で
何とかならないものかと…。
下記のサンプルであれば、常に手前に表示されている上にクリックしても
その向こう側を操作できます。あとこのサンプルは半透明ですが、
実際にはバー以外透明にしたいです。これでイメージが伝われば良いのですが。
#uselib "user32.dll"
#func SetWindowLong "SetWindowLongA" int,int,int;ウィンドウの透明化・半透明化・不透明化_用↓
#func SetLayeredWindowAttributes "SetLayeredWindowAttributes" int,int,int,int
#const LWA_COLORKEY 1 ;透明色を指定
#const LWA_ALPHA 2 ;アルファー値を指定
#const GWL_EXSTYLE -20 ;拡張ウィンドウスタイル
#const WS_EX_LAYERED $00080000 ;透明なウィンドウ属性
#const WS_EX_TRANSPARENT $00000020
screen 0,400,200
gsel 0,2
SetWindowLong hwnd,-20,WS_EX_LAYERED|WS_EX_TRANSPARENT
SetLayeredWindowAttributes hwnd,0,128,LWA_ALPHA
mes "表示される内容は透明にしたくないです"
|
|
2014/4/23(Wed) 14:28:37|NO.61633
/*ご参考(こう言う事?)*/
#uselib "user32.dll"
#func SetWindowLong "SetWindowLongA" int,int,int ;ウィンドウの透明化・半透明化・不透明化_用↓
#func SetLayeredWindowAttributes "SetLayeredWindowAttributes" int,int,int,int
#const LWA_COLORKEY 1 ;透明色を指定
#const LWA_ALPHA 2 ;アルファー値を指定
#const GWL_EXSTYLE -20 ;拡張ウィンドウスタイル
#const WS_EX_LAYERED $00080000 ;透明なウィンドウ属性
#const WS_EX_TRANSPARENT $00000020
screen 0,400,200
gsel 0,2
SetWindowLong hwnd,-20,WS_EX_LAYERED ;|WS_EX_TRANSPARENT
;SetLayeredWindowAttributes hwnd,0,128,LWA_ALPHA
SetLayeredWindowAttributes hwnd,255,0,LWA_COLORKEY ;
color 255 :boxf
color 0
mes "表示される内容は透明にしたくないです"
|
|
2014/4/23(Wed) 15:06:30|NO.61634
こんな方法もありますよ。
#include "gdi32.as"
#include "user32.as"
#include "winmm.as"
timeGetTime
start=stat-(stat&0x80000000)
repeat
timeGetTime
time=((stat-(stat&0x80000000))-start)
minv=time/1000
hunv=minv/60
tx=strf("%d:%d:%d:%d",hunv/60,hunv\60,minv\60,time\1000)
// デスクトップに直接描画する
getdc 0:htdc=stat
textout htdc,200,200,varptr(tx),strlen(tx)
ReleaseDC 0,htdc
await 30
loop
|
|
2014/4/23(Wed) 22:42:17|NO.61638
fortunehillさん汐さん、ご回答頂きましてありがとうございます。
汐さんのタイマーは、タイマーを作る理屈がよく分かって
大変勉強になりました。まだ全部理解できていませんが
色々調べながらものにしたいと思います。
fortunehillさんの例を参考にさせて頂き、ありさんの分と継ぎ接ぎし、
見た目と動作は自分が思い描いていたものが出来ました。
ただいまいち理屈も分から無いままにごちゃ混ぜにしたので
動作はしているのですが、使用して大丈夫か心配です。
F1〜F3キーではなく、メインキーボード1〜3を押下した時に動作するよう
変更しました。どなたか確認して頂けるようでしたらお願いできませんでしょうか。
#uselib "user32.dll"
#func SetWindowLong "SetWindowLongA" int,int,int ;ウィンドウの透明化・半透明化・不透明化_用↓
#func SetLayeredWindowAttributes "SetLayeredWindowAttributes" int,int,int,int
#const LWA_COLORKEY 1 ;透明色を指定
#const LWA_ALPHA 2 ;アルファー値を指定
#const GWL_EXSTYLE -20 ;拡張ウィンドウスタイル
#const WS_EX_LAYERED $00080000 ;透明なウィンドウ属性
#const WS_EX_TRANSPARENT $00000020
#include "d3m.hsp"
#const TIMER_SIZE 100 ; タイマーゲージの長さ
TIME_MAX(0) = 3000, 5000, 10000 ; タイマー毎の時間
TIMER_DIV(0) = 1000 * TIMER_SIZE / TIME_MAX(0) ; タイマーサイズ計算用定数
TIMER_DIV(1) = 1000 * TIMER_SIZE / TIME_MAX(1) ;
TIMER_DIV(2) = 1000 * TIMER_SIZE / TIME_MAX(2) ;
dim timer_flg, 3
dim timer_base, 3
dim f_key, 3 ; ファンクションキー入力用変数
timer_cr = 255, 0, 0 ; タイマーの色R
timer_cg = 0, 255, 0 ; タイマーの色G
timer_cb = 0, 0, 255 ; タイマーの色B
timer_posy = 5, 20, 35 ; タイマー毎のY座標
// 枠のないウィンドウを作成
bgscr 0, 130, 50
gsel 0,2
*main
redraw 0
SetWindowLong hwnd,-20,WS_EX_LAYERED ;|WS_EX_TRANSPARENT
SetLayeredWindowAttributes hwnd,0,128,LWA_ALPHA
SetLayeredWindowAttributes hwnd,0,0,LWA_COLORKEY ;
color 0, 0, 0 : boxf
color 255, 255, 255
t_cnt = d3timer() ; PC起動からの時間を取得(ミリ秒)
repeat 3
getkey f_key(cnt), 49 + cnt ; ファンクションキー入力判定
if f_key(cnt) = 1 {
if timer_flg(cnt) = 0 { ; タイマー未使用ならフラグを立ててタイマー起動
timer_flg(cnt) = TIMER_SIZE ; タイマー起動中フラグ(タイマーの長さと併用)
timer_base(cnt) = t_cnt ; タイマーが起動した時間
}
}
color 255, 255, 255
if timer_flg(cnt) > 0 { ; タイマー起動中ならタイマーゲージを表示
color timer_cr(cnt), timer_cg(cnt), timer_cb(cnt)
; タイマー毎の残り時間をタイマーのサイズ(48ドット)に換算してゲージを表示
timer_flg(cnt) = limit((TIME_MAX(cnt)-(t_cnt-timer_base(cnt)))*TIMER_DIV(cnt)/1000, 0, 100)
boxf cx+20, timer_posy(cnt), cx+timer_flg(cnt)+20, timer_posy(cnt)+8
}
pos 0, 16*cnt : mes "" + timer_flg(cnt)
loop
redraw 1
await 16
goto *main
| |
|
2014/4/23(Wed) 23:32:08|NO.61640
>SetWindowLong hwnd,-20,WS_EX_LAYERED ;|WS_EX_TRANSPARENT
>SetLayeredWindowAttributes hwnd,0,128,LWA_ALPHA
>SetLayeredWindowAttributes hwnd,0,0,LWA_COLORKEY ;
この3行はメインループから外して
>bgscr 0, 130, 50
の下あたりに入れた方が良い
|
|
2014/4/24(Thu) 23:20:28|NO.61672
暇人さん、アドバイスありがとうございました。
早速そのようにしてみます。
今回ご回答くださった皆様、本当にありがとうございました!
興味でちゃったので色々作ってみたいと思います。
|
|