質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

Q&A

解決済

4回答

1295閲覧

右のキーを押した際に配列で移動可能か判断して、一マス右に移動できるようにしたい。

carnage0216

総合スコア194

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

0グッド

1クリップ

投稿2019/08/20 15:01

編集2019/08/22 02:48

環境

  • Windows10
  • visual studio 2019
  • DXライブラリ

行いたいこと
例えばプログラムに書いてある座標(nx,ny)=(2,2)に位置するキャラが右に動く際にnx=nx+1にnx=2を代入させて、idou[nx + 1][ny + 0] は
idou[3][2] となり、配列idou[5][5]よりidou[3][2] の座標の位置は0なので移動可能となり、キャラが描画できるというプログラムを作りたいです。
以上の説明はあくあで一例です。出来れば、以上をループのようにして、どの座標からでも右のキーを押すたびに配列idou[nx + 1][ny + 0]から右に移動可能か判断して右に一マス進むようにしたいです。

これは、自分なりに以下のようにプログラムを作りました。ですがうまく機能していません。
出来ればプログラムの原型を崩さずに右キーを押すたびに右に一マス動けるようにしたいです。

if (Key[KEY_INPUT_RIGHT] == 1) { if (idou[nx + 1][ny + 0] == idou[3][0]) {// 移動可能にして、その座標に移動する nx = nx + 1; nx == 3; idou[nx + 1][ny + 0] == idou[3][2]; playerphoto = gh[7]; }

そして、以下は全体のプログラムです。

#include "DxLib.h" int Key[256]; // キーが押されているフレーム数を格納する // キーの入力状態を更新する int gpUpdateKey() { char tmpKey[256]; // 現在のキーの入力状態を格納する GetHitKeyStateAll(tmpKey); // 全てのキーの入力状態を得る for (int i = 0; i < 256; i++) { if (tmpKey[i] != 0) { // i番のキーコードに対応するキーが押されていたら Key[i]++; // 加算 } else { // 押されていなければ Key[i] = 0; // 0にする } } return 0; } // プログラムは WinMain から始まります int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { SetGraphMode(1600, 680, 32); // ウィンドウの大きさを指定 ChangeWindowMode(TRUE); int playerphoto; int nx=2, ny =2 ; // 最初のキャラのX座をdxとY座標をdyである。配列の真ん中の0を最初の座標としたため(2,2)となる if (DxLib_Init() == -1) // DXライブラリ初期化処理 { return -1; // エラーが起きたら直ちに終了 } //1. 3x3マスの2次元配列 int idou[5][5] = { {1,1,1,1,1 }, {1,0,0,0,1 }, {1,0,0,0,1 }, {1,0,0,0,1 }, {1,1,1,1,1 }, }; //DrawGraph(dx, dy, playerphoto, FALSE); //グラフィックハンドル格納用配列 int gh[12]; LoadDivGraph("charall.png", 12, 3, 4, 49, 66, gh);//画像読み込み SetDrawScreen(DX_SCREEN_BACK); while (ScreenFlip() == 0 && ProcessMessage() == 0 && gpUpdateKey() == 0) { DrawGraph(nx, ny, gh[5], FALSE);// プレイヤーの画像を描画 // カーソルキーの右が押されている if (Key[KEY_INPUT_RIGHT] == 1) { if (Key[KEY_INPUT_RIGHT] == 1) { if (idou[nx + 1][ny + 0] == idou[3][0]) {// 移動可能にして、その座標に移動する nx = nx + 1; nx == 3; idou[nx + 1][ny + 0] == idou[3][2]; playerphoto = gh[7]; } else if (nx == 1 && idou[nx + 1] == idou[2]) { // 移動不可能 playerphoto = gh[9]; } if (Key[KEY_INPUT_LEFT] == 1) { nx = nx - 1; playerphoto = gh[2]; } if (Key[KEY_INPUT_UP] == 1) { ny = ny + 1; playerphoto = gh[4]; } if (Key[KEY_INPUT_DOWN] == 1) { ny = ny - 1; playerphoto = gh[3]; } if (nx == 0 && ny == 0) { playerphoto = gh[7]; } ScreenFlip(); // 画面をクリア ClearDrawScreen(); DrawGraph(nx, ny, playerphoto, FALSE); } } DxLib_End(); // DXライブラリ使用の終了処理 return 0; // ソフトの終了 }

編集が遅くなりました。すいません。jimbeさんのプログラムをそのまま入れてみました。ですが、思うように動きませんでした。もしかしたら組み込む場所が違ったのかもしれません。

#include "DxLib.h" int Key[256]; // キーが押されているフレーム数を格納する // キーの入力状態を更新する int gpUpdateKey() { char tmpKey[256]; // 現在のキーの入力状態を格納する GetHitKeyStateAll(tmpKey); // 全てのキーの入力状態を得る for (int i = 0; i < 256; i++) { if (tmpKey[i] != 0) { // i番のキーコードに対応するキーが押されていたら Key[i]++; // 加算 } else { // 押されていなければ Key[i] = 0; // 0にする } } return 0; } // プログラムは WinMain から始まります int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { SetGraphMode(1600, 680, 32); // ウィンドウの大きさを指定 ChangeWindowMode(TRUE); int playerphoto; int nx=2, ny =2 ; // 最初のキャラのX座をdxとY座標をdyである。配列の真ん中の0を最初の座標としたため(2,2)となる if (DxLib_Init() == -1) // DXライブラリ初期化処理 { return -1; // エラーが起きたら直ちに終了 } //1. 3x3マスの2次元配列 int idou[5][5] = { {1,1,1,1,1 }, {1,0,0,0,1 }, {1,0,0,0,1 }, {1,0,0,0,1 }, {1,1,1,1,1 }, }; //DrawGraph(dx, dy, playerphoto, FALSE); //グラフィックハンドル格納用配列 int gh[12]; LoadDivGraph("charall.png", 12, 3, 4, 49, 66, gh);//画像読み込み SetDrawScreen(DX_SCREEN_BACK); while (ScreenFlip() == 0 && ProcessMessage() == 0 && gpUpdateKey() == 0) { DrawGraph(nx, ny, gh[5], FALSE);// プレイヤーの画像を描画 // カーソルキーの右が押されている if (Key[KEY_INPUT_RIGHT] == 1) { //①if (idou[ny + 1][nx + 1]) {nx==0,}//紙を読む nx==0でidou[nx + 1]がidou[1]の時移動可能にして、その座標に移動する、nx==1でidou[nx + 1]がidou[2]の時移動不可能と //①のidou[ny + 1][nx + 1]を利用してif文で書きたいが、idou[ny + 1][nx + 1]を単体でidou[ny + 1]として使えるか? if (idou[nx + 1][ny + 0] == 0) { //移動しようとする先が空いていれば //移動可能 nx = nx + 1; //移動 playerphoto = gh[7]; } else { // 移動不可能 playerphoto = gh[9]; } if (Key[KEY_INPUT_LEFT] == 1) { nx = nx - 1; playerphoto = gh[2]; } if (Key[KEY_INPUT_UP] == 1) { ny = ny + 1; playerphoto = gh[4]; } if (Key[KEY_INPUT_DOWN] == 1) { ny = ny - 1; playerphoto = gh[3]; } if (nx == 0 && ny == 0) { playerphoto = gh[7]; } ScreenFlip(); // 画面をクリア ClearDrawScreen(); DrawGraph(nx, ny, playerphoto, FALSE); } } DxLib_End(); // DXライブラリ使用の終了処理 return 0; // ソフトの終了 }

編集
入門書を見るなりしてjimbeさんから頂いたコードを正しく使おうとやっているのですが
どうもうまくいきません。
条件文としては正しいと思うのですが
右のキーが押される&右のマスが0という条件で
写真[7]を表示するプログラムとして

if (Key[KEY_INPUT_RIGHT] == 1) { if (idou[nx + 1][ny + 0] == 0) { //移動しようとする先が空いていれば //移動可能 nx = nx + 1; //移動 playerphoto = gh[7]; } else { // 移動不可能 playerphoto = gh[9]; } } と書いたんですが、うまくいきません。

jimbeさんのプログラム正しかったです。キャラの移動を50倍してみると正しく機能していることがわかりました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

C++

1#include "DxLib.h" 2 3int Key[256]; // キーが押されているフレーム数を格納する配列 4 5int gpUpdateKey() // キーの入力状態を更新する 6{ 7 char tmpKey[256]; // 現在のキーの入力状態を格納する配列 8 GetHitKeyStateAll(tmpKey); // 全てのキーの入力状態を得る 9 for (int i = 0; i < 256; i++) { 10 if (tmpKey[i] != 0) { // i番のキーが押されていたら 11 Key[i]++; // 加算 12 } 13 else { // 押されていなければ 14 Key[i] = 0; // 0にする 15 } 16 } 17 return 0; 18} 19 20int WINAPI WinMain(HINSTANCE hi, HINSTANCE hp, LPSTR cl, int cs) 21{ 22 SetGraphMode(1600, 680, 32); // ウィンドウの大きさを指定 23 ChangeWindowMode(TRUE); // 全画面ではなくウインドウを使用 24 if (DxLib_Init() == -1) return -1; // DXライブラリ初期化処理 25 SetDrawScreen(DX_SCREEN_BACK); // 裏画面を使用する設定 26 27 int idou[5][5] = { 28 { 1, 1, 1, 1, 1 }, 29 { 1, 0, 0, 0, 1 }, 30 { 1, 0, 0, 0, 1 }, 31 { 1, 0, 0, 0, 1 }, 32 { 1, 1, 1, 1, 1 }, 33 }; 34 int nx = 2, ny = 2; // プレイヤーの初期位置 35 int move = 0; // 移動状態 36 37 int gh[12]; //グラフィックハンドル格納用配列 38 // 5:正面、7:右向き、2:左向き、4:上向き、3:下向き、9:移動不可 39 LoadDivGraph("charall.png", 12, 3, 4, 49, 66, gh); //画像読み込み 40 int playerphoto = gh[5]; 41 42 while (ProcessMessage() == 0) { 43 gpUpdateKey(); // キーの入力状態を取得 44 if (Key[KEY_INPUT_RIGHT] == 1) { // カーソルキーの右が押されている 45 move = 1; 46 if (idou[nx + 1][ny] == 0) { //移動先が空いていれば 47 nx = nx + 1; playerphoto = gh[7]; // 右向き 48 } 49 else { 50 playerphoto = gh[9]; // 移動不可能 51 } 52 } 53 if (Key[KEY_INPUT_LEFT] == 1) { 54 move = 1; 55 if (idou[nx - 1][ny] == 0) { //移動先が空いていれば 56 nx = nx - 1; playerphoto = gh[2]; // 左向き 57 } 58 else { 59 playerphoto = gh[9]; // 移動不可能 60 } 61 } 62 if (Key[KEY_INPUT_UP] == 1) { 63 move = 1; 64 if (idou[nx][ny - 1] == 0) { //移動先が空いていれば 65 ny = ny - 1; playerphoto = gh[4]; // 上向き 66 } 67 else { 68 playerphoto = gh[9]; // 移動不可能 69 } 70 } 71 if (Key[KEY_INPUT_DOWN] == 1) { 72 move = 1; 73 if (idou[nx][ny + 1] == 0) { //移動先が空いていれば 74 ny = ny + 1; playerphoto = gh[3]; // 下向き 75 } 76 else { 77 playerphoto = gh[9]; // 移動不可能 78 } 79 } 80 81 ClearDrawScreen(); // 裏画面をクリア 82 if (move > 0 && ++move == 20) { 83 move = 0; playerphoto = gh[5]; // 移動終了 84 } 85 int x = nx * 60 + 100, y = ny * 80 + 100; // 表示位置に変換 86 DrawGraph(x, y, playerphoto, FALSE); // プレイヤーを裏画面に描画 87 ScreenFlip(); // 裏画面を表画面に反映 88 } 89 90 DxLib_End(); // DXライブラリ使用の終了処理 91 return 0; // ソフトの終了 92}

プレイヤーを描画する前に壁を描画してもよいでしょう。

C++

1 for (int i = 0; i < 5; i++) { 2 for (int j = 0; j < 5; j++) { 3 if (idou[i][j] == 1) { 4 int x = j * 60 + 100, y = i * 80 + 100; 5 DrawGraph(x, y, gh[11], FALSE); // 壁を裏画面に描画 6 } 7 } 8 } 9 int x = nx * 60 + 100, y = ny * 80 + 100; // 表示位置に変換 10 DrawGraph(x, y, playerphoto, FALSE); // プレイヤーを裏画面に描画

投稿2019/08/22 11:03

編集2019/08/22 12:11
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

0

私だったらこんな感じに分けますね

c++

1int dx = 0, dy = 0; 2int nextphoto; // intなのかは知らんがplayerphotoと同じ型 3 4// キー判定部分 5if (Key[KEY_INPUT_RIGHT] == 1) 6{ 7 // カーソルキーの右が押されている 8 dx = 1; 9 nextphoto = gh[7]; 10} else if(Key[KEY_INPUT_LEFT] == 1) 11{ 12 // カーソルキーの左が押されている 13 dx = -1; 14} 15// 省略 16 17// 実際の判定および移動部分 18if ( 19 (dx != 0 || dy != 0) && 20 nx + dx >= 0 && nx + dx < 5 && 21 ny + dy >= 0 && ny + dy < 5 && 22 idou[nx+dx][ny+dy] == 0 23 ) 24{ 25 nx += dx; 26 ny += dy; 27 playerphoto = nextphoto; 28}

投稿2019/08/21 21:02

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

carnage0216

2019/08/22 00:31

いつもどうもありがとうございます。
guest

0

ベストアンサー

ご説明が無茶苦茶です.
右移動部分だけですが

c

1 if(idou[nx + 1][ny + 0] == 0) { //移動しようとする先が空いていれば 2 //移動可能 3 nx = nx + 1; //移動 4 playerphoto = gh[7]; 5 } 6 else { 7 // 移動不可能 8 playerphoto = gh[9]; 9 }

これだけです.

投稿2019/08/20 17:53

編集2019/08/21 11:33
jimbe

総合スコア12646

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2019/08/20 19:45

× idou[nx + 1][ny + 0] == 0 〇 idou[(nx+1) + 1][ny + 1] == 0 // 目的地(x+1,y)にそれぞれ+1のゲタ ですねー
fana

2019/08/21 04:32

・「Java」になってます.コードのところ. ・+1のゲタは要らないような? ・idou[こっちがxで][こっちがy]なことに関してはOKなのか否か謎
episteme

2019/08/21 10:36

- 移動可能領域の左上隅を(1,1)とするならゲタは要らんすね。 - Cでは(メモリ・レイアウト上は) idou[y][x] ですしねー
jimbe

2019/08/21 11:47

>「Java」になってます 間違えました. ご指摘ありがとうございます. > 目的地(x+1,y)にそれぞれ+1のゲタ 何故でしょうか.
episteme

2019/08/21 11:51

再度: -移動可能領域の左上隅を(1,1)とするならゲタは要らんすね。
carnage0216

2019/08/21 19:22

お二方、解答ありがとうございます。 jimbeさんのプログラムを使ったものを載せさせて頂きます。
carnage0216

2019/08/22 04:03

どうもありがとうございました。
guest

0

配列要素を見て移動の可否を決めることに関しては既に存在する他の方の回答で十分に思いますが,
2次元配列のindexに関して不安に思うので指摘(?)しておきます.

例えば

int A[2][3] = { { 0, 2, 0 }, { 10, 0, 0 } };

という配列があるとき,値が2の要素はA[0][1]で,値が10の要素がA[1][0]です.
2次元的な並びで示せば

A[0][0], A[0][1], A[0][2]
A[1][0], A[1][1], A[1][2]

という感じです.
indexは
A[下に行くほどこっちが増える][右に行くほどこっちが増える]
というルール.

あなたのコードの【配列idou[][]に用いるindex】と【座標値(nx,ny)を考えている座標系(軸の向き)】との対応関係が
あなたの意図した関係になっているか?に関しても確認されると良いのではないかと思います.

投稿2019/08/21 04:47

編集2019/08/21 04:51
fana

総合スコア11656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問