ページ 1 / 1
キャラクターの移動について
Posted: 2009年1月27日(火) 21:02
by フォンクス
このサイトに載っている一定区間を歩かせるプログラムを参考に
ジョイパッドで動かせるプログラムを作成したのですが、
動いている途中で別のキーを押すと動かなくなってしまうのですが、
それがどうしても直せなかったので助けてください
typedef struct{
int Graph[16];
int PlayerID;
int hp,x,y,muki;
int Speed , Kyori;
int walkflg;
tama_t Tama;
}Player_t;
Player_t Player[4];
ソース
if(Player[0].x % 32 == 0 && Player[0].y % 32 == 0){
Player[0].walkflg = 1;//移動
if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_LEFT){
Player[0].muki = 1;//左
}else if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_UP){
Player[0].muki = 0;//上
}else if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_RIGHT){
Player[0].muki = 3;//右
}else if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_DOWN){
Player[0].muki = 2;//下
}else{
Player[0].walkflg = 0;
}
if((GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_Z)){ //方向転換
Player[0].walkflg = 0;
if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_LEFT){
Player[0].muki = 1;//左
}else if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_UP){
Player[0].muki = 0;//上
}else if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_RIGHT){
Player[0].muki = 3;//右
}else if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_DOWN){
Player[0].muki = 2;//下
}
}
}
Re:キャラクターの移動について
Posted: 2009年1月27日(火) 21:12
by kazuoni
規約通り、コードはプレタグで囲ってください。
あと字下げをしないとなかなか見づらいです。
あと、方向転換は歩いてる途中でキー入力を受け付けているのですが、
1区間歩かせたいならこの処理はNGだと思います。。
32で割れない時に違う方向に進んでしまうので。
何を実装しようとしているのか分からないので何とも言えないですが・・・
Re:キャラクターの移動について
Posted: 2009年1月27日(火) 21:26
by フォンクス
すみませんでした。今度から気をつけます。
移動と書いてある方は実際にキャラを移動させて、
方向転換はジョイパッドの6番が押されてるときに
方向だけ変えたいのです。
Re:キャラクターの移動について
Posted: 2009年1月27日(火) 21:32
by kazuoni
編集してもらえばよいのですが^^;
>方向転換はジョイパッドの6番が押されてるときに
>方向だけ変えたいのです
もし右に進んでいて元いた場所から29進み、
方向転換のif文に合致したとします。(y方向)
向きのフラグは変わりますが、
次にループで移動のif文には合致しません。
なぜならxが29進んだだけで止まっているからです。(32で割ったときに余りが出続ける)
すると歩かないフラグが立ちます。→歩きません。
Re:キャラクターの移動について
Posted: 2009年1月27日(火) 21:45
by kazuoni
ちょっと解釈違っていました。。
>すると歩かないフラグが立ちます。
は方向転換のif文に入ったときに歩かないフラグが立つのですね^^;
失礼しました。
Re:キャラクターの移動について
Posted: 2009年1月27日(火) 21:47
by フォンクス
すみません。編集しました。
Re:キャラクターの移動について
Posted: 2009年1月27日(火) 22:12
by kazuoni
今見て気がついたのですが・・・
このコードだと
「x,yともに32で割り切れるときに方向を決定し、方向変換可能」
ということなので、右向いていて、6番+左キー押されたら左を向くってことですか^^;
大変失礼しました。
このプログラムには特に問題がないと思うのですが・・・
32で割り切れない時のボタンと移動の処理はどのように書いていますか?
Re:キャラクターの移動について
Posted: 2009年1月27日(火) 22:19
by フォンクス
32で割り切れない時には入力は何もやっていません。
移動は4キャラ用にループで回しています。
Player[/url].Speedは初期値として 1 が入っています。
for(i=0;i<4;i++){
if(Player.walkflg == 1){
switch(Player.muki){
case 0://上
Player.y -= Player.Speed;
break;
case 1://左
Player.x -= Player.Speed;
break;
case 2://下
Player.y += Player.Speed;
break;
case 3://右
Player.x += Player.Speed;
break;
}
}
}
Re:キャラクターの移動について
Posted: 2009年1月27日(火) 22:47
by kazuoni
んん・・・特に問題がないように思えます・・・が・・・。
自分の家にジョイパッドがないので、ちょっと試せる環境にないので
動かすことができないのですが・・・。
とりあえず、移動中は何を押そうが、No:27839のコードには影響はしないので
他の部分でジョイパッドのボタンを押したときに
Player[0].walkflg=0になって止まっているのか確認してみてください。
もしかしたら全コードをUPしてもらったほうが早いかもしれません。
Re:キャラクターの移動について
Posted: 2009年1月28日(水) 09:16
by Dixq (管理人)
こんにちは。
何度もGetJoypadInputState(DX_INPUT_PAD1)を呼んでるのがちょっともったいないですね。
ゲームプログラミングの館40章のように、
キーの入力状態を最初に配列か構造体に入れてしまい、それを使った方が良さそうです。
また、コード全文を投稿してもらった方がわかりやすいかもしれません。
Re:キャラクターの移動について
Posted: 2009年1月29日(木) 23:14
by フォンクス
キャラクターの移動に関しては下のとおりです
ブロックの当たり判定の部分は、ブロックの描画の座標が全てY軸方向に+32にしてあるので
当たり判定の部分でずらしてます。
#include"GV.h"
/*キャラクターの向き
0:上 Y - 1
1:左 X - 1
2:下 Y + 1
3:右 X + 1
*/
int HitBlock(int x,int y,int muki,int num) //X座標 Y座標 向き キャラ番号(1P:0 2P:1 3P:2 4P:3)
{
//Map.Normal[ Y ][ X ]
switch(muki){
case 0:
switch(Map.Normal[(Player[num].y / 32) - 2][Player[num].x / 32]){
case 0:
return 0;
case 1:
return 1;
case 2:
return 2;
case 3:
return 3;
}
break;
case 1:
switch(Map.Normal[(Player[num].y / 32 ) - 1][(Player[num].x / 32) - 1]){
case 0:
return 0;
case 1:
return 1;
case 2:
return 2;
case 3:
return 3;
}
break;
case 2:
switch(Map.Normal[Player[num].y / 32][Player[num].x / 32]){
case 0:
return 0;
case 1:
return 1;
case 2:
return 2;
case 3:
return 3;
}
break;
case 3:
switch(Map.Normal[(Player[num].y / 32) -1][(Player[num].x / 32) + 1]){
case 0:
return 0;
case 1:
return 1;
case 2:
return 2;
case 3:
return 3;
}
break;
}
return 0;
}
void PlayerInput()
{
int i; //カウンター変数
//--------------------1P入力-------------------
if(Player[0].x % 32 == 0 && Player[0].y % 32 == 0){
Player[0].walkflg = 1;//移動
if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_LEFT){
Player[0].muki = 1;//左
}else if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_UP){
Player[0].muki = 0;//上
}else if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_RIGHT){
Player[0].muki = 3;//右
}else if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_DOWN){
Player[0].muki = 2;//下
}else{
Player[0].walkflg = 0;
}
if((GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_Z)){ //方向転換
Player[0].walkflg = 0;
if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_LEFT){
Player[0].muki = 1;//左
}else if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_UP){
Player[0].muki = 0;//上
}else if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_RIGHT){
Player[0].muki = 3;//右
}else if(GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_DOWN){
Player[0].muki = 2;//下
}
}
}
//---------------------------------------------
//------------------2P入力---------------------
if(Player[1].x % 32 == 0 && Player[1].y % 32 == 0){
Player[1].walkflg = 1;
if(GetJoypadInputState(DX_INPUT_PAD2) & PAD_INPUT_LEFT){
Player[1].muki = 1;
}else if(GetJoypadInputState(DX_INPUT_PAD2) & PAD_INPUT_UP){
Player[1].muki = 0;
}else if(GetJoypadInputState(DX_INPUT_PAD2) & PAD_INPUT_RIGHT){
Player[1].muki = 3;
}else if(GetJoypadInputState(DX_INPUT_PAD2) & PAD_INPUT_DOWN){
Player[1].muki = 2;
}else{
Player[1].walkflg = 0;
}
if(GetJoypadInputState(DX_INPUT_PAD2) & PAD_INPUT_Z){
if(GetJoypadInputState(DX_INPUT_PAD2) & PAD_INPUT_LEFT){
Player[1].muki = 1;//左
Player[1].walkflg = 0;
}else if(GetJoypadInputState(DX_INPUT_PAD2) & PAD_INPUT_UP){
Player[1].muki = 0;//上
Player[1].walkflg = 0;
}else if(GetJoypadInputState(DX_INPUT_PAD2) & PAD_INPUT_RIGHT){
Player[1].muki = 3;//右
Player[1].walkflg = 0;
}else if(GetJoypadInputState(DX_INPUT_PAD2) & PAD_INPUT_DOWN){
Player[1].muki = 2;//下
Player[1].walkflg = 0;
}
}
}
//--------------------------------------------
for(i=0;i<2;i++){
if(Player.walkflg == 1){
switch(HitBlock(Player.x,Player.y,Player.muki,i)){
case 1:
Player.walkflg = 0;
break;
}
}
}
for(i=0;i<2;i++){
if(Player.walkflg == 1){
switch(Player.muki){
case 0://上
Player.y -= Player.Speed;
break;
case 1://左
Player.x -= Player[i].Speed;
break;
case 2://下
Player[i].y += Player[i].Speed;
break;
case 3://右
Player[i].x += Player[i].Speed;
break;
}
}
}
return;
}
void DrawPlayer()
{
int i;
for(i=0;i<2;i++)
DrawGraph(Player[i].x,Player[i].y,Player[i].Graph[( Player[i].x % 32 + Player[i].y % 32 )/8 + Player[i].muki*4],TRUE);
}
Re:キャラクターの移動について
Posted: 2009年1月30日(金) 10:05
by non
>動いている途中で別のキーを押すと動かなくなってしまうのですが
ということは、途中でキーを押さなければ、壁まで進んで壁でとまるのでしょうか?
私、DXライブラリを使ったことがないので、素人考えですが・・・
私の考えが間違っていればご指摘ください。
for(i=0;i<2;i++){
if(Player.walkflg == 1){
switch(HitBlock(Player.x,Player.y,Player.muki,i)){
case 1:
Player.walkflg = 0;
break;
}
}
}
この部分は、壁にぶつかったら止まるためのプログラムだと思います。
しかし
if(Player[0].x % 32 == 0 && Player[0].y % 32 == 0){
の部分の外ですから、1ドット動くたびにチェックしてます。
32の倍数以外でチェックすると、その次のマップ位置をチェックすることになるので、私の考えでは
壁にぶつかる31ドット前で止まると思うのですが、違いますか?
そうすると、最初に述べたように、途中で何もキーを押さないときは、壁の1ドット前で止まるはずは
ないということになりますので、その辺いかがですか?
次にint HitBlock(int x,int y,int muki,int num)関数ですが、numを引数で渡しているのだから
xやyを渡す必要がありません。また、
また、例えば上に動くときのチェックだけど、
switch(Map.Normal[(Player[num].y / 32) - 2][Player[num].x / 32]){
なぜ、-2なのか分かりません。自分の位置と上下方向のマップと一つずれているとわかりにくいです。
さらに、管理人さんが指摘されているように、GetJoypadInputState(DX_INPUT_PAD1)はループの中で
1回だけにしないと、無駄と言うよりも、タイミングによりループの途中で値が変わることにより思わぬ
バグを生じることになります。
Re:キャラクターの移動について
Posted: 2009年1月30日(金) 10:10
by non
>switch(Map.Normal[(Player[num].y / 32) - 2][Player[num].x / 32]){
>なぜ、-2なのか分かりません。
書いてありましたね。でも、そのような設計にしなければならないことに問題があったのでは?
Re:キャラクターの移動について
Posted: 2009年1月30日(金) 12:46
by JT
私もnonさんと同意見です
Re:キャラクターの移動について
Posted: 2009年1月30日(金) 13:01
by non
>32の倍数以外でチェックすると、その次のマップ位置をチェックすることになるので、私の考えでは
>壁にぶつかる31ドット前で止まると思うのですが、違いますか?
>そうすると、最初に述べたように、途中で何もキーを押さないときは、壁の1ドット前で止まるはずは
>ないということになりますので、その辺いかがですか?
折角、JTさんから賛同を得ましたが、この説明には間違いがあったかもしれません。
+方向に座標が増えた場合は、x/32が切り捨てになるので問題ないですね。
問題があるのは-方向でしょうか?例えばxが64だったときx/32=2ですから1のマップが
進めるかチェックしますね。1ドットマイナスすると、63になるのでx/32=1となり、0の
マップのチェックになります。
Re:キャラクターの移動について
Posted: 2009年1月31日(土) 09:33
by フォンクス
入力の方を直してみました。
GetJoypadInputStateは1Pと2P用で2回呼んでるだけになりました。
2Pは同じなんで省略しました。
int i,key; //カウンター変数
//--------------------1P入力-------------------
if(Player[0].x % 32 == 0 && Player[0].y % 32 == 0){
Player[0].walkflg = 1;//移動
key = GetJoypadInputState(DX_INPUT_PAD1);
if(key & PAD_INPUT_LEFT){
Player[0].muki = 1;//左
}else if(key & PAD_INPUT_UP){
Player[0].muki = 0;//上
}else if(key & PAD_INPUT_RIGHT){
Player[0].muki = 3;//右
}else if(key & PAD_INPUT_DOWN){
Player[0].muki = 2;//下
}else{
Player[0].walkflg = 0;
}
if((key & PAD_INPUT_Z)){ //方向転換
Player[0].walkflg = 0;
if(key & PAD_INPUT_LEFT){
Player[0].muki = 1;//左
}else if(key & PAD_INPUT_UP){
Player[0].muki = 0;//上
}else if(key & PAD_INPUT_RIGHT){
Player[0].muki = 3;//右
}else if(key & PAD_INPUT_DOWN){
Player[0].muki = 2;//下
}
}
}
壁にぶつかった時に当たり判定なんですが、画像の様な
表示をさせたかったのでずらしたんですが・・・。
Re:キャラクターの移動について
Posted: 2009年1月31日(土) 10:56
by non
GetJoypadInputStateの方は、この方がいいですね。
上下のマップのずれは、本人がわかりやすいのなら、それで、いいですよ。
それより、通れないところの判定のタイミングの方はよくなりましたか?
Re:キャラクターの移動について
Posted: 2009年1月31日(土) 11:00
by フォンクス
移動の判定なんですが、壁じゃないところで動かなくなってしまう時があります。
座標を見ると、32で割り切れないところで止まっているのでそのせいだと思うんですが
壁のあたり判定を見直してます
Re:キャラクターの移動について
Posted: 2009年1月31日(土) 12:35
by non
移動判定をこの中に入れてみたらどうでしょうか?
if(Player[0].x % 32 == 0 && Player[0].y % 32 == 0){
Re:キャラクターの移動について
Posted: 2009年1月31日(土) 20:05
by フォンクス
if(Player[0].x % 32 == 0 && Player[0].y % 32 == 0){
Player[0].walkflg = 1;//移動
key[0] = GetJoypadInputState(DX_INPUT_PAD1);
if(key[0] & PAD_INPUT_LEFT){
Player[0].muki = 1;//左
}else if(key[0] & PAD_INPUT_UP){
Player[0].muki = 0;//上
}else if(key[0] & PAD_INPUT_RIGHT){
Player[0].muki = 3;//右
}else if(key[0] & PAD_INPUT_DOWN){
Player[0].muki = 2;//下
}else{
Player[0].walkflg = 0;
}
if((key[0] & PAD_INPUT_Z)){ //方向転換
Player[0].walkflg = 0;
if(key[0] & PAD_INPUT_LEFT){
Player[0].muki = 1;//左
}else if(key[0] & PAD_INPUT_UP){
Player[0].muki = 0;//上
}else if(key[0] & PAD_INPUT_RIGHT){
Player[0].muki = 3;//右
}else if(key[0] & PAD_INPUT_DOWN){
Player[0].muki = 2;//下
}
}
if(Player[0].walkflg == 1){
switch(HitBlock(0)){//壁などの当たり判定
case 1://壁があった場合
Player[0].walkflg = 0;
break;
}
}
}
この様にした所、変な場所で止まらなくなりました。
回答して下さった皆様、ありがとうございました。