合計 昨日 今日

キー入力が反映されない

[このトピックは解決済みです]

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Name: たくや
[URL]
かけだし(1,138 ポイント)
Date: 2018年2月10日(土) 19:54
No: 1
(OFFLINE)

 キー入力が反映されない

失礼します。初めて投稿させて頂きます。今回私はVC++でDxライブラリを使用し、プレイヤー(赤い四角)を画面の中央に置き続け、、背景をを動かすことでことでスクロールを行うプログラムを作成しました。マップにおけるプレイヤーの座標(PlayerX,PlayerY)が変化するとマップにおける画面の左上の座標(PointX,PointY)が変化し、その画面左上の座標を起点としてfor文を使うことで画像を当てはめていくというような形を意識しました。また、32フレームでプレイヤーが1マス動くように考えました。しかし方向キーを入力するとスクロールが開始するはずなのですが全く変化が起きません。コンパイルは上手くいきました。なぜ動かないのかそもそもの理由が分からないので理由と解決策を教えていただけると助かります。c言語初心者ですので大変見づらいコードかもしれませんがご了承ください。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//Draw_Main.cpp
#include"DxLib.h"
#include"Player_Map.h"
#define WIDTH 21//マップの横の長さ
#define HEIGHT 16//マップの縦の長さ
#define SCREENW 640//スクリーンの横の大きさ
#define SCREENH 480//スクリーンの縦の大きさ
#define SIZE 16 //画像一つあたりの一辺の大きさ
 
 
 
static int rose[HEIGHT][WIDTH] = {
    { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4 },
{ 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 },
{ 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 },
{ 2,0,0,0,0,0,20,20,20,20,20,20,20,20,20,0,0,0,0,0,4 },
{ 2,0,0,0,0,0,20,0,0,0,0,0,0,0,20,0,0,0,0,0,4 },
{ 2,0,0,0,0,0,20,0,0,0,0,0,0,0,20,0,0,0,0,0,4 },
{ 2,0,0,0,0,0,20,0,0,0,0,0,0,0,20,0,0,0,0,0,4 },
{ 2,0,0,0,0,0,20,20,20,0,0,0,20,20,20,0,0,0,0,0,4 },
{ 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 },
{ 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 },
{ 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 },
{ 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 },
{ 2,0,0,0,0,0,0,0,0,15,6,17,0,0,0,0,0,0,0,0,4 },
{ 2,0,0,0,0,0,0,0,0,18,0,18,0,0,0,0,0,0,0,0,4 },
{ 2,0,0,0,0,0,0,0,0,19,0,19,0,0,0,0,0,0,0,0,4 },
{ 2,3,3,3,3,3,3,3,3,10,0,10,3,3,3,3,3,3,3,3,3 },
};
 
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
    DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK), ChangeWindowMode(FALSE);
    int image[8];
    int image1[72];
        int image2[24];
    int Move = 0;//プレイヤーが移動中→1、停止中→0
    int PlayerX = 2, PlayerY = 2;
    LoadDivGraph("0.png", 8, 4, 2, 16, 16, image);
    LoadDivGraph("rose.png", 72, 8, 9, 16, 16, image1);
    LoadDivGraph("garden.png", 24, 8, 3, 16, 16, image2);
 
    while (ScreenFlip() == 0 && ClearDrawScreen()==0&& ProcessMessage() == 0&&CheckHitKey(KEY_INPUT_ESCAPE)==0) {
        Player_Map(PlayerX,PlayerY,Move,image,image1,image2,rose);
    }
   
    DxLib_End();
}

コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//Player_Map.cpp
#include"DxLib.h"
#include"Draw_Map.h"
#define SIZE 16
#define WIDTH 21
#define HEIGHT 16
#define SCREENW 640
#define SCREENH 480
static int Movecounter;//プレイヤーが移動し始めてから何フレーム経過したか
static int MoveX, MoveY;//プレイヤーの進行距離
 
static int Key;//キーの入力状態
static int ScrollX, ScrollY;//マップがどのくらいスクロールするか
void Player_Map(int PlayerX,int PlayerY,int Move,int *image,int *image1,int *image2,int rose[][21]) {
   
    int Xnum = SCREENW / SIZE;
    int Ynum = SCREENH / SIZE;
    if (Move == 0) {                                                       //キー入力
        Key=GetJoypadInputState(DX_INPUT_KEY_PAD1);
   
    if (Key&PAD_INPUT_RIGHT){
        Move = 1;
        MoveX = 1;
        MoveY = 0;
    }
    if (Key & PAD_INPUT_LEFT) {
        Move = 1;
        MoveX = -1;
        MoveY = 0;
    }
    if (Key & PAD_INPUT_UP) {
        Move = 1;
        MoveX = 0;
        MoveY = -1;
    }
    if (Key & PAD_INPUT_DOWN) {
        Move = 1;
        MoveX = 0;
        MoveY = 1;
    }
    if (Move == 1) {
        if (rose[PlayerY + MoveY][PlayerX + MoveX] != 0) {
            Move = 0;
        }                                           //マップの0以外のところにはプレイヤーは侵入できない
        else {
            Movecounter = 0;
        }
    }
        ScrollX = 0;
        ScrollY = 0;
    }
        if (Move == 1) {
            Movecounter++;//キーを一回押してから何フレーム経過したか
            if (Movecounter == 32) {
                ScrollX = 0;
                ScrollY = 0;
                Movecounter = 0;
                Move = 0;
                PlayerX += MoveX;//32フレーム経過するとプレイヤーの座標が変化
                PlayerY += MoveY;
 
            }else{
                ScrollX = -MoveX * SIZE*Movecounter / 32;//プレイヤーが1マス動くのに32フレームかかる
                ScrollY = -MoveY * SIZE*Movecounter / 32;
            }
        }
        Draw_Map(ScrollX, ScrollY, PlayerX, PlayerY, rose, image, image1, image2);
        DrawBox(Xnum/2*SIZE,Ynum/2*SIZE,(Xnum/2+1)*SIZE,(Ynum/2+1)*SIZE,GetColor(255,0,0),TRUE);//プレイヤーは常に画面の中心にいる
}

コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//Draw_Map.cpp
#include<DxLib.h>
 
#define WIDTH 21
#define HEIGHT 16
#define SCREENW 640
#define SCREENH 480
#define SIZE 16
 
 
 
static int Xnum, Ynum;//画面上に映ることのできる縦横各一列における画像総数
static int PointX, PointY;//マップの左上端を原点と考えたときの画面左上端の座標
 
 
static int i, j;
 
void Draw_Map(int ScrollX,int ScrollY,int PlayerX,int PlayerY,int rose[][21],int *image,int *image1,int *image2) {
    Xnum = SCREENW / SIZE;
    Ynum = SCREENH / SIZE;
 
    PointX = PlayerX - Xnum / 2;
    PointY = PlayerY - Ynum / 2;
 
    for (i = 0; i < Ynum; i++) {
        for (j = 0; j < Xnum; j++) {
            if (j + PointX < 0 || i + PointY < 0 || j + PointX >= WIDTH || i + PointY >= HEIGHT) {//画面内のマップのみを描写するように限定する
                continue;                                                                        
            }
            if (rose[i + PointY][j + PointX] == 0) {
                DrawGraph(j*SIZE + ScrollX, i*SIZE + ScrollY , image[0], TRUE);//
            }                                                                  
            if (rose[i + PointY][j + PointX] == 1) {
                DrawGraph(j *SIZE + ScrollX , i*SIZE + ScrollY , image1[0], TRUE);
            }
            if (rose[i + PointY][j + PointX] == 2) {
                DrawGraph(j*SIZE + ScrollX , i*SIZE+ ScrollY , image1[1], TRUE);
            }
            if (rose[i + PointY][j + PointX] == 3) {
                DrawGraph(j*SIZE + ScrollX , i *SIZE + ScrollY , image1[2], TRUE);
            }
            if (rose[i + PointY][j + PointX] == 4) {
                DrawGraph(j*SIZE + ScrollX , i*SIZE + ScrollY , image1[3], TRUE);
            }
            if (rose[i + PointY][j + PointX] == 6) {
                DrawGraph(j*SIZE + ScrollX , i*SIZE + ScrollY , image1[25], TRUE);
            }
            if (rose[i + PointY][j + PointX] == 10) {
                DrawGraph(j *SIZE + ScrollX , i*SIZE + ScrollY , image1[64], TRUE);
            }
            if (rose[i + PointY][j + PointX] == 15) {
                DrawGraph(j *SIZE + ScrollX , i *SIZE + ScrollY , image1[24], TRUE);
            }
            if (rose[i + PointY][j + PointX] == 17) {
                DrawGraph(j *SIZE + ScrollX , i*SIZE + ScrollY , image1[26], TRUE);
            }
            if (rose[i + PointY][j + PointX] == 18) {
                DrawGraph(j *SIZE + ScrollX , i *SIZE + ScrollY , image1[48], TRUE);
            }
            if (rose[i + PointY][j + PointX] == 19) {
                DrawGraph(j*SIZE + ScrollX , i*SIZE + ScrollY , image1[56], TRUE);
            }
            if (rose[i + PointY][j + PointX] == 20) {
                DrawGraph(j*SIZE + ScrollX , i *SIZE + ScrollY , image2[11], TRUE);
            }
        }
    }
 
}

コード[C++]: 全て選択
1
2
//Draw_Map.h
void Draw_Map(int ScrollX, int ScrollY, int PlayerX, int PlayerY, int rose[][21], int *image, int *image1, int *image2);

コード[C++]: 全て選択
1
2
//Player_Map.h
void Player_Map(int PlayerX,int PlayerY,int Move,int *image, int *image1, int *image2, int rose[][21]);

Name: みけCAT
[URL]
伝説なるハッカー(693,419 ポイント)
Date: 2018年2月10日(土) 20:09
No: 2
(ONLINE)

 Re: キー入力が反映されない

関数の仮引数への変更は、関数から抜けると破棄されます。
関数内での値の変更を関数の呼び出し元に反映させるには、参照を使うといいでしょう。

サンプル
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
 
// 参照を使っておらず、変更が反映されない
void func_noref(int x) {
    x *= 2;
}
 
// 参照を使っており、変更が反映される
void func_ref(int &x) {
    x *= 2;
}
 
int main() {
    int a, b;
    a = b = 1;
    func_noref(a);
    func_ref(b);
    std::cout << "a = " << a << ", b = " << b << std::endl;
    return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Name: みけCAT
[URL]
伝説なるハッカー(693,419 ポイント)
Date: 2018年2月10日(土) 20:34
No: 3
(ONLINE)

 Re: キー入力が反映されない

Offtopic :
テスト実行用の画像を作ったので、置いておきますね。
images.zip
テスト実行用の画像
(2.56 KiB) ダウンロード数: 3 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Name: みけCAT
[URL]
伝説なるハッカー(693,419 ポイント)
Date: 2018年2月10日(土) 20:41
No: 4
(ONLINE)

 Re: キー入力が反映されない

よく見たら、全く動かない原因は仮引数への変更を保存していないからではないですね。
本当の原因は、Player_Map.cppの46行目でMovecounterを0にしていることのようです。
rose[2][2]のまわりの要素は全て0なので、Move == 1 (キー入力がある場合)なら必ずこれが実行されます。
その後インクリメントがあるのでMovecounterは1にはなりますが、ScrollXやScrollYを0でなくするためには計算式よりMovecounterの絶対値が2以上でなければいけません。
この行をコメントアウトしてコンパイル・実行すると、方向キーを押すとマップが動くことが確認できました。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Name: たくや
[URL]
かけだし(1,138 ポイント)
Date: 2018年2月10日(土) 21:19
No: 5
(OFFLINE)

 Re: キー入力が反映されない

みけCATさん、返信ありがとうございます。確かにMoveCounterが2以上でないと動かないようにはなっていますが、同じキーをずっと入力し続けた場合は46行目Movecounter=0は通らないように18行目のif文でしていると思います。したがって、MoveCounterは蓄積されると思います。おっしゃる通りに46行目のMoveCounterをコメントアウトしたとき確かにキー入力が反映されたのですが、プレイヤ-が一瞬で元の位置に戻ってしまいます。もしよろしければどのように修正されたかを見せていただけませんか。

Name: たくや
[URL]
かけだし(1,138 ポイント)
Date: 2018年2月11日(日) 00:58
No: 6
(OFFLINE)

 Re: キー入力が反映されない

[解決!]

みけCATさんがおっしゃったとおりMovecounterがおかしかったです。あと、MoveCounterをコメントアウトしたあと実行してキーを入力すると元の位置に戻るという現象ですが、Main_Map.cppでPlayer_Mapを呼び出すときにPlayerX=2,Playery=2を渡していましたが、渡す行為もループしていたために元の位置に戻っていました。アドレスを渡すことで解決しました。ありがとうございました。


Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[11人]