#4
by みけCAT » 4年前
Ouxiy さんが書きました: ↑4年前
質問1に関しては
配列idou[3][3]の1の位置をplayerX、playerYとしたいです。
playerX、playerYに1の位置を入れたい、ということでしょうか?
以下のコードは、配列から1を探し、その位置をplayerXおよびplayerYに入れます。
コード:
// 探す対象の配列
int idou[3][3] = {
{0, 0, 0 },
{0, 1, 0 },
{0, 0, 0 }
};
// 結果を入れる変数
int playerX = -1, playerY = -1;
// 配列から1を探し、結果を入れる (1が複数ある場合、最後に見つかったものの座標が入る)
for (int y = 0; y < static_cast<int>(sizeof(idou) / sizeof(*idou)); y++) {
for (int x = 0; x < static_cast<int>(sizeof(*idou) / sizeof(**idou)); x++) {
if (idou[y][x] == 1) {
playerX = x;
playerY = y;
}
}
}
もしくは、1の位置が[1][1]だとわかっているのであれば、素直に
コード:
playerX = 1;
playerY = 1;
でいいのではないでしょうか?
Ouxiy さんが書きました: ↑4年前
コード:
例えば、
int idou[3][3] = {
{0, 0, 0 },
{0, 1, 0 },
{0, 0, 0 }
};
右に移動させたいときにplayerX+1により、
int idou[3][3] = {
{0, 0, 0 },
{0, 0, 1 },
{0, 0, 0 }
};と書くことで右への一マス移動を可能にしたいです。(すべての場合を書いて9マス移動を可能にしたいです。)
Ouxiy さんが書きました: ↑4年前
最初の投稿のマスに関して
例えば、真ん中の1はキャラとして周りの1は壁とします。
コード:
int idou[5][5] = {
{1,1,1,1,1 },
{1,0,0,0,1 },
{1,0,1,0,1 },
{1,0,0,0,1 },
{1,1,1,1,1 },
};
右に移動させたいときにplayerX(プレイヤーの位置(座標))+1により、
コード:
int idou[5][5] = {
{1,1,1,1,1 },
{1,0,0,0,1 },
{1,0,0,1,1 },
{1,0,0,0,1 },
{1,1,1,1,1 },
};
と書くことで右への一マス移動を可能にしたいです。(すべての場合を書いて9マス移動を可能にしたいです。)
「すべての場合を書いて」という条件に当てはまるかはよくわかりませんが、
playerXでプレイヤーの座標を取得できるようにしつつ、
playerX+1のような書き方でプレイヤーの位置を移動できるようにしてみました。
(このコードでは前提が違うので、この回答の前半のようなplayerXやplayerYへの座標の代入はできません)
コード:
#include "DxLib.h"
// 0 : #1のコードにある3x3の配列を使用する
// 1 : #3のコードにある5x5の配列を使用する
// 2 : 配列の縦と横の要素数が違ってもきちんと動くことのテスト
#define MODE 1
template<typename T>
struct NonZeroJudger {
bool operator()(const T& target) const {
return target != 0;
}
};
// 配列操作用クラス
template<typename T, int rows, int cols, class cancelCondition = NonZeroJudger<T> >
class ArrayController {
T (*array)[cols];
int x, y;
cancelCondition j;
public:
template <int x_mul, int y_mul>
class AddSubController {
ArrayController<T, rows, cols, cancelCondition>* controller;
public:
AddSubController(ArrayController<T, rows, cols, cancelCondition>* c) : controller(c) {}
void operator+(int d) {
if (controller) controller->moveTarget(d * x_mul, d * y_mul);
}
void operator-(int d) {
if (controller) controller->moveTarget(-d * x_mul, -d * y_mul);
}
operator int() const {
return controller->getX() * x_mul + controller->getY() * y_mul;
}
};
typedef AddSubController<1, 0> xController;
typedef AddSubController<0, 1> yController;
ArrayController(T (*array_)[cols], int x_ = -1, int y_ = -1) : array(array_), x(x_), y(y_) {}
// 操作対象の座標を設定する
void setTarget(int x_, int y_) {
if (x_ < 0 || cols <= x_ || y_ < 0 || rows <= y_) return;
x = x_;
y = y_;
}
// 操作対象を動かす (指定した量移動したマスの値と入れ替える)
void moveTarget(int dx, int dy) {
// 移動先を求める
int nx = x + dx;
int ny = y + dy;
// 移動先が範囲外なら、キャンセルする
if (nx < 0 || cols <= nx || ny < 0 || rows <= ny) return;
// 移動先が移動できないマス(デフォルトでは非0)なら、キャンセルする
if (j(array[ny][nx])) return;
// 移動を行う
T temp = array[y][x];
array[y][x] = array[ny][nx];
array[ny][nx] = temp;
x = nx;
y = ny;
}
// 座標を取得する
int getX(void) const {
return x;
}
int getY(void) const {
return y;
}
// 加減算演算子で操作する用のオブジェクトを取得する
xController getXController(void) {
return xController(this);
}
yController getYController(void) {
return yController(this);
}
};
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);
if (DxLib_Init() == -1) // DXライブラリ初期化処理
{
return -1; // エラーが起きたら直ちに終了
}
SetDrawScreen(DX_SCREEN_BACK);
#if MODE == 0
//1. 3x3マスの2次元配列
int idou[3][3] = {
{0, 0, 0 },
{0, 1, 0 },
{0, 0, 0 }
};
#elif MODE == 1
int idou[5][5] = {
{1,1,1,1,1 },
{1,0,0,0,1 },
{1,0,1,0,1 },
{1,0,0,0,1 },
{1,1,1,1,1 },
};
#elif MODE == 2
int idou[7][10] = {
{1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,0},
{1,1,1,0,1,1,1,1,1,1},
{0,0,1,0,0,1,0,0,0,1},
{1,0,1,1,0,1,0,1,0,1},
{1,0,0,0,0,0,0,1,0,1},
{1,1,1,1,1,1,1,1,0,1}
};
#else
#error invalid MODE
#endif
// 座標操作用オブジェクト
const int idouHeight = sizeof(idou) / sizeof(*idou);
const int idouWidth = sizeof(*idou) / sizeof(**idou);
ArrayController<int, idouHeight, idouWidth> controller(idou);
ArrayController<int, idouHeight, idouWidth>::xController playerX = controller.getXController();
ArrayController<int, idouHeight, idouWidth>::yController playerY = controller.getYController();
// 初期座標を登録する
#if MODE == 0
controller.setTarget(1, 1);
#elif MODE == 1
controller.setTarget(2, 2);
#elif MODE == 2
controller.setTarget(1, 0);
#endif
while (ScreenFlip() == 0 && ProcessMessage() == 0 && gpUpdateKey() == 0) {
if (Key[KEY_INPUT_RIGHT] == 1) {
playerX + 1;
}
if (Key[KEY_INPUT_UP] == 1) {
playerY - 1;
}
if (Key[KEY_INPUT_LEFT] == 1) {
playerX - 1;
}
if (Key[KEY_INPUT_DOWN] == 1) {
playerY + 1;
}
// 画面をクリア
ClearDrawScreen();
// 座標を描画
DrawFormatString(10, 10, GetColor(255, 255, 255), "(%d, %d)",
static_cast<int>(playerX), static_cast<int>(playerY));
// idouの状態を描画
for (int y = 0; y < idouHeight; y++) {
for (int x = 0; x < idouWidth; x++) {
DrawFormatString(10 + x * 50, 100 + y * 30, GetColor(255, 255, 255), "%d", idou[y][x]);
}
}
}
DxLib_End(); // DXライブラリ使用の終了処理
return 0; // ソフトの終了
}
[quote=Ouxiy post_id=154071 time=1565969871 user_id=2888]
質問1に関しては
配列idou[3][3]の1の位置をplayerX、playerYとしたいです。
[/quote]
playerX、playerYに1の位置を入れたい、ということでしょうか?
以下のコードは、配列から1を探し、その位置をplayerXおよびplayerYに入れます。
[code]
// 探す対象の配列
int idou[3][3] = {
{0, 0, 0 },
{0, 1, 0 },
{0, 0, 0 }
};
// 結果を入れる変数
int playerX = -1, playerY = -1;
// 配列から1を探し、結果を入れる (1が複数ある場合、最後に見つかったものの座標が入る)
for (int y = 0; y < static_cast<int>(sizeof(idou) / sizeof(*idou)); y++) {
for (int x = 0; x < static_cast<int>(sizeof(*idou) / sizeof(**idou)); x++) {
if (idou[y][x] == 1) {
playerX = x;
playerY = y;
}
}
}
[/code]
もしくは、1の位置が[1][1]だとわかっているのであれば、素直に
[code]
playerX = 1;
playerY = 1;
[/code]
でいいのではないでしょうか?
[quote=Ouxiy post_id=154070 time=1565969125 user_id=2888]
[code]例えば、
int idou[3][3] = {
{0, 0, 0 },
{0, 1, 0 },
{0, 0, 0 }
};
右に移動させたいときにplayerX+1により、
int idou[3][3] = {
{0, 0, 0 },
{0, 0, 1 },
{0, 0, 0 }
};と書くことで右への一マス移動を可能にしたいです。(すべての場合を書いて9マス移動を可能にしたいです。)[/code]
[/quote]
[quote=Ouxiy post_id=154072 time=1565971314 user_id=2888]
最初の投稿のマスに関して
例えば、真ん中の1はキャラとして周りの1は壁とします。
[code]int idou[5][5] = {
{1,1,1,1,1 },
{1,0,0,0,1 },
{1,0,1,0,1 },
{1,0,0,0,1 },
{1,1,1,1,1 },
};[/code]
右に移動させたいときにplayerX(プレイヤーの位置(座標))+1により、
[code]int idou[5][5] = {
{1,1,1,1,1 },
{1,0,0,0,1 },
{1,0,0,1,1 },
{1,0,0,0,1 },
{1,1,1,1,1 },
};[/code]と書くことで右への一マス移動を可能にしたいです。(すべての場合を書いて9マス移動を可能にしたいです。)
[/quote]
「すべての場合を書いて」という条件に当てはまるかはよくわかりませんが、
playerXでプレイヤーの座標を取得できるようにしつつ、
playerX+1のような書き方でプレイヤーの位置を移動できるようにしてみました。
(このコードでは前提が違うので、この回答の前半のようなplayerXやplayerYへの座標の代入はできません)
[code]
#include "DxLib.h"
// 0 : #1のコードにある3x3の配列を使用する
// 1 : #3のコードにある5x5の配列を使用する
// 2 : 配列の縦と横の要素数が違ってもきちんと動くことのテスト
#define MODE 1
template<typename T>
struct NonZeroJudger {
bool operator()(const T& target) const {
return target != 0;
}
};
// 配列操作用クラス
template<typename T, int rows, int cols, class cancelCondition = NonZeroJudger<T> >
class ArrayController {
T (*array)[cols];
int x, y;
cancelCondition j;
public:
template <int x_mul, int y_mul>
class AddSubController {
ArrayController<T, rows, cols, cancelCondition>* controller;
public:
AddSubController(ArrayController<T, rows, cols, cancelCondition>* c) : controller(c) {}
void operator+(int d) {
if (controller) controller->moveTarget(d * x_mul, d * y_mul);
}
void operator-(int d) {
if (controller) controller->moveTarget(-d * x_mul, -d * y_mul);
}
operator int() const {
return controller->getX() * x_mul + controller->getY() * y_mul;
}
};
typedef AddSubController<1, 0> xController;
typedef AddSubController<0, 1> yController;
ArrayController(T (*array_)[cols], int x_ = -1, int y_ = -1) : array(array_), x(x_), y(y_) {}
// 操作対象の座標を設定する
void setTarget(int x_, int y_) {
if (x_ < 0 || cols <= x_ || y_ < 0 || rows <= y_) return;
x = x_;
y = y_;
}
// 操作対象を動かす (指定した量移動したマスの値と入れ替える)
void moveTarget(int dx, int dy) {
// 移動先を求める
int nx = x + dx;
int ny = y + dy;
// 移動先が範囲外なら、キャンセルする
if (nx < 0 || cols <= nx || ny < 0 || rows <= ny) return;
// 移動先が移動できないマス(デフォルトでは非0)なら、キャンセルする
if (j(array[ny][nx])) return;
// 移動を行う
T temp = array[y][x];
array[y][x] = array[ny][nx];
array[ny][nx] = temp;
x = nx;
y = ny;
}
// 座標を取得する
int getX(void) const {
return x;
}
int getY(void) const {
return y;
}
// 加減算演算子で操作する用のオブジェクトを取得する
xController getXController(void) {
return xController(this);
}
yController getYController(void) {
return yController(this);
}
};
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);
if (DxLib_Init() == -1) // DXライブラリ初期化処理
{
return -1; // エラーが起きたら直ちに終了
}
SetDrawScreen(DX_SCREEN_BACK);
#if MODE == 0
//1. 3x3マスの2次元配列
int idou[3][3] = {
{0, 0, 0 },
{0, 1, 0 },
{0, 0, 0 }
};
#elif MODE == 1
int idou[5][5] = {
{1,1,1,1,1 },
{1,0,0,0,1 },
{1,0,1,0,1 },
{1,0,0,0,1 },
{1,1,1,1,1 },
};
#elif MODE == 2
int idou[7][10] = {
{1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,0},
{1,1,1,0,1,1,1,1,1,1},
{0,0,1,0,0,1,0,0,0,1},
{1,0,1,1,0,1,0,1,0,1},
{1,0,0,0,0,0,0,1,0,1},
{1,1,1,1,1,1,1,1,0,1}
};
#else
#error invalid MODE
#endif
// 座標操作用オブジェクト
const int idouHeight = sizeof(idou) / sizeof(*idou);
const int idouWidth = sizeof(*idou) / sizeof(**idou);
ArrayController<int, idouHeight, idouWidth> controller(idou);
ArrayController<int, idouHeight, idouWidth>::xController playerX = controller.getXController();
ArrayController<int, idouHeight, idouWidth>::yController playerY = controller.getYController();
// 初期座標を登録する
#if MODE == 0
controller.setTarget(1, 1);
#elif MODE == 1
controller.setTarget(2, 2);
#elif MODE == 2
controller.setTarget(1, 0);
#endif
while (ScreenFlip() == 0 && ProcessMessage() == 0 && gpUpdateKey() == 0) {
if (Key[KEY_INPUT_RIGHT] == 1) {
playerX + 1;
}
if (Key[KEY_INPUT_UP] == 1) {
playerY - 1;
}
if (Key[KEY_INPUT_LEFT] == 1) {
playerX - 1;
}
if (Key[KEY_INPUT_DOWN] == 1) {
playerY + 1;
}
// 画面をクリア
ClearDrawScreen();
// 座標を描画
DrawFormatString(10, 10, GetColor(255, 255, 255), "(%d, %d)",
static_cast<int>(playerX), static_cast<int>(playerY));
// idouの状態を描画
for (int y = 0; y < idouHeight; y++) {
for (int x = 0; x < idouWidth; x++) {
DrawFormatString(10 + x * 50, 100 + y * 30, GetColor(255, 255, 255), "%d", idou[y][x]);
}
}
}
DxLib_End(); // DXライブラリ使用の終了処理
return 0; // ソフトの終了
}
[/code]