C言語レベル多分7です。ダッシュについて。
Posted: 2007年4月21日(土) 14:35
今学校っでアクションRPGを作成することになり、私は先頭システムのメインプログラマになりました。
そこで戦闘中のダッシュ判定で苦しんでいます。
DXライブラリを使いタイム関数を使い、キーを押してる時間を検出してダッシュかどうかを判定してます。
ここでの問題はPCの性能が低かったり、ゲーム中に急に処理が重たくなったりしたときに、ダッシュと歩行を
繰り返してしまうと言うことです。
アルゴリズムの考え方じたいを新しくする必要があるのは分かるのですが、新しいアルゴリズムが浮かんできません、何かヒントでもいいので指摘をお願いします。
パット関数はキーボードを入力したらそれに対して値を返す。
キーに何も入力しないとパット関数は0を返す。
アニメカウントは関数に入ってくる前に+1されてくる。
■変数key = パット関数
|▲上 = パット関数
||自キャラ座標上下 = 時キャラ座標 - 4
|+――――――
|▼
|▲下 = パット関数
||自キャラ座標上下 = 時キャラ座標 + 4
|+――――――
|▼
|
|▲右 = パット関数
||画像送り数 = ダッシュ判定関数(key)
||▲580 > 自キャラ座標左右
|||▲画像送り数 != 0
||||自キャラ左右座標=自キャラ左右座標+6
|||+――――――――――――――――――
||||自キャラ左右座標=自キャラ左右座標+3
|||▼
||+―――――――――――――――――――――――
|||▲画像送り値 != 0
||||背景ダッシュモード値 = 2;
|||+―――――――――――――――
|||▼
||▼
||柱座標左右=柱画像左右+(3+背景ダッシュモード値)
||背景座標左右=背景座標左右+(1+背景ダッシュモード)
||画像送り値=画像送り値+9
|▼
|
|▲左 = パット関数
||画像送り数 = ダッシュ判定関数(key)
||▲30 < 自キャラ座標左右
|||▲画像送り数 != 0
||||自キャラ左右座標=自キャラ左右座標-6
|||+――――――――――――――――――
||||自キャラ左右座標=自キャラ左右座標-3
|||▼
||+―――――――――――――――――――――――
|||▲画像送り値 != 0
||||背景ダッシュモード値 = 2;
|||+―――――――――――――――
|||▼
||▼
||柱座標左右=柱画像左右+(3+背景ダッシュモード値)
||背景座標左右=背景座標左右+(1+背景ダッシュモード)
||画像送り値=画像送り値+9
|▼
|
|▲前回入力キー左右 == 4 && 画像送り値 == 0
||画像送り値 = 前回入力キー左右-1
|+―――――――――――――――――――――――――――
|▼
|画像切り替え時間 = アニメカウント / 6% 自キャラアニメーションに必要な画像枚数
|出力関数 = 自キャラ座標左右・自キャラ上下・自キャラ画像配列[自キャラアニメーションに必要な画|像枚数+画像送り値]
▼
・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
DSTIMEを100と見る。
DSTIMEを190と見る。
移動モード=0は歩く 移動モード=1は走る。
移動関数から現在入力された値が来る(key)
■
|画像送り値 = 0;
|▲ループ時間>現在時間関数 && 移動モード=0 || 前回入力キー左右=key || 現在||時間関数>ダッシュ認識限界時間
||ループ時間 = 現在時間関数 + 100
||ダッシュ認識限界時間 = 現在時間関数 + 190
||移動モード = 0
||前回入力キー左右 = key
|+――――――――――――――――――――――
||ダッシュ認識限界時間 = 現在時間関数 + 100 (一度キーを話したら確実に歩くた|| めにループ時間を代入)
||移動モード = 1
||画像送り値 = 画像送り値 + 24
|▼
|
|状態を見るために、key・ループ時間・ダッシュ認識限界時間・移動モードを出力。
|移動関数に画像送り値を返す。
▼
void JicharaMove(){
//キャラムーブ
int b=0 , c=0;
int key = GetJoypadInputState(DX_INPUT_KEY_PAD1); //方向キー代入判定。
if(key & PAD_INPUT_UP) jikidata.y=jikidata.y-idouryou[4];
if(key & PAD_INPUT_DOWN) jikidata.y=jikidata.y+idouryou[4];
//ダッシュ判定
if(key & PAD_INPUT_RIGHT){ //右キーを押されたら。
b = Ds_Hantei(key); //ダッシュ判定関数
if(580>jikidata.x){ //キャラが右端にいなければ移動させる
if(b){
jikidata.x=jikidata.x+idouryou[6];
}
else{
jikidata.x=jikidata.x+idouryou[3];
}
}
else if(b)c=2; //キャラが右端にいない+ダッシュならc=2
hasira.x=hasira.x-idouryou[3+c],haikei.x=haikei.x-idouryou[1+c],b=b+9;
}
if(key & PAD_INPUT_LEFT){ //左キーを押されたら。
b = Ds_Hantei(key); //ダッシュ判定関数
if(30<jikidata.x){ //キャラが左端にいなければ移動させる。
if(b){
jikidata.x=jikidata.x-idouryou[6];
}
else{
jikidata.x=jikidata.x-idouryou[3];
}
}
else if(b)c=2; //キャラが右端にいない+ダッシュならc=2
hasira.x=hasira.x+idouryou[3+c],haikei.x=haikei.x+idouryou[1+c],b=b+6;
}
if(lr==4&&b==0)b=lr-1;//停止時の向き判別
int a = animcounter / 6 % jikidata.animpat; //キャラ画像切り替え時間
DrawGraph(jikidata.x, jikidata.y, jikidata.ghandle[a+b], TRUE);
・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
int Ds_Hantei(int key){
int b = 0;
if((D_time_l>GetNowCount() && D_mod==0)|| lr!=key || GetNowCount()>D_time_h){
D_time_l= GetNowCount()+DSTIME_L; //ループ時間代入
D_time_h= GetNowCount()+DSTIME_H; //ダッシュ判定時間限界代入
D_mod = 0;
lr = key;
}
else{
D_time_h= GetNowCount()+DSTIME_L; //ループ時間代入
D_mod = 1;
b = b + 24;
}
printfDx("%d %d %d %d\n",key,D_time_l,D_time_h,D_mod); //明細出力
return(b);
}
そこで戦闘中のダッシュ判定で苦しんでいます。
DXライブラリを使いタイム関数を使い、キーを押してる時間を検出してダッシュかどうかを判定してます。
ここでの問題はPCの性能が低かったり、ゲーム中に急に処理が重たくなったりしたときに、ダッシュと歩行を
繰り返してしまうと言うことです。
アルゴリズムの考え方じたいを新しくする必要があるのは分かるのですが、新しいアルゴリズムが浮かんできません、何かヒントでもいいので指摘をお願いします。
パット関数はキーボードを入力したらそれに対して値を返す。
キーに何も入力しないとパット関数は0を返す。
アニメカウントは関数に入ってくる前に+1されてくる。
■変数key = パット関数
|▲上 = パット関数
||自キャラ座標上下 = 時キャラ座標 - 4
|+――――――
|▼
|▲下 = パット関数
||自キャラ座標上下 = 時キャラ座標 + 4
|+――――――
|▼
|
|▲右 = パット関数
||画像送り数 = ダッシュ判定関数(key)
||▲580 > 自キャラ座標左右
|||▲画像送り数 != 0
||||自キャラ左右座標=自キャラ左右座標+6
|||+――――――――――――――――――
||||自キャラ左右座標=自キャラ左右座標+3
|||▼
||+―――――――――――――――――――――――
|||▲画像送り値 != 0
||||背景ダッシュモード値 = 2;
|||+―――――――――――――――
|||▼
||▼
||柱座標左右=柱画像左右+(3+背景ダッシュモード値)
||背景座標左右=背景座標左右+(1+背景ダッシュモード)
||画像送り値=画像送り値+9
|▼
|
|▲左 = パット関数
||画像送り数 = ダッシュ判定関数(key)
||▲30 < 自キャラ座標左右
|||▲画像送り数 != 0
||||自キャラ左右座標=自キャラ左右座標-6
|||+――――――――――――――――――
||||自キャラ左右座標=自キャラ左右座標-3
|||▼
||+―――――――――――――――――――――――
|||▲画像送り値 != 0
||||背景ダッシュモード値 = 2;
|||+―――――――――――――――
|||▼
||▼
||柱座標左右=柱画像左右+(3+背景ダッシュモード値)
||背景座標左右=背景座標左右+(1+背景ダッシュモード)
||画像送り値=画像送り値+9
|▼
|
|▲前回入力キー左右 == 4 && 画像送り値 == 0
||画像送り値 = 前回入力キー左右-1
|+―――――――――――――――――――――――――――
|▼
|画像切り替え時間 = アニメカウント / 6% 自キャラアニメーションに必要な画像枚数
|出力関数 = 自キャラ座標左右・自キャラ上下・自キャラ画像配列[自キャラアニメーションに必要な画|像枚数+画像送り値]
▼
・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
DSTIMEを100と見る。
DSTIMEを190と見る。
移動モード=0は歩く 移動モード=1は走る。
移動関数から現在入力された値が来る(key)
■
|画像送り値 = 0;
|▲ループ時間>現在時間関数 && 移動モード=0 || 前回入力キー左右=key || 現在||時間関数>ダッシュ認識限界時間
||ループ時間 = 現在時間関数 + 100
||ダッシュ認識限界時間 = 現在時間関数 + 190
||移動モード = 0
||前回入力キー左右 = key
|+――――――――――――――――――――――
||ダッシュ認識限界時間 = 現在時間関数 + 100 (一度キーを話したら確実に歩くた|| めにループ時間を代入)
||移動モード = 1
||画像送り値 = 画像送り値 + 24
|▼
|
|状態を見るために、key・ループ時間・ダッシュ認識限界時間・移動モードを出力。
|移動関数に画像送り値を返す。
▼
void JicharaMove(){
//キャラムーブ
int b=0 , c=0;
int key = GetJoypadInputState(DX_INPUT_KEY_PAD1); //方向キー代入判定。
if(key & PAD_INPUT_UP) jikidata.y=jikidata.y-idouryou[4];
if(key & PAD_INPUT_DOWN) jikidata.y=jikidata.y+idouryou[4];
//ダッシュ判定
if(key & PAD_INPUT_RIGHT){ //右キーを押されたら。
b = Ds_Hantei(key); //ダッシュ判定関数
if(580>jikidata.x){ //キャラが右端にいなければ移動させる
if(b){
jikidata.x=jikidata.x+idouryou[6];
}
else{
jikidata.x=jikidata.x+idouryou[3];
}
}
else if(b)c=2; //キャラが右端にいない+ダッシュならc=2
hasira.x=hasira.x-idouryou[3+c],haikei.x=haikei.x-idouryou[1+c],b=b+9;
}
if(key & PAD_INPUT_LEFT){ //左キーを押されたら。
b = Ds_Hantei(key); //ダッシュ判定関数
if(30<jikidata.x){ //キャラが左端にいなければ移動させる。
if(b){
jikidata.x=jikidata.x-idouryou[6];
}
else{
jikidata.x=jikidata.x-idouryou[3];
}
}
else if(b)c=2; //キャラが右端にいない+ダッシュならc=2
hasira.x=hasira.x+idouryou[3+c],haikei.x=haikei.x+idouryou[1+c],b=b+6;
}
if(lr==4&&b==0)b=lr-1;//停止時の向き判別
int a = animcounter / 6 % jikidata.animpat; //キャラ画像切り替え時間
DrawGraph(jikidata.x, jikidata.y, jikidata.ghandle[a+b], TRUE);
・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
int Ds_Hantei(int key){
int b = 0;
if((D_time_l>GetNowCount() && D_mod==0)|| lr!=key || GetNowCount()>D_time_h){
D_time_l= GetNowCount()+DSTIME_L; //ループ時間代入
D_time_h= GetNowCount()+DSTIME_H; //ダッシュ判定時間限界代入
D_mod = 0;
lr = key;
}
else{
D_time_h= GetNowCount()+DSTIME_L; //ループ時間代入
D_mod = 1;
b = b + 24;
}
printfDx("%d %d %d %d\n",key,D_time_l,D_time_h,D_mod); //明細出力
return(b);
}