53017


自分なりに実装したのですがほんとは間違って言うであるやり方をしてる点がありましてそこをほんとはこう書いたほうがいいみたいなことが知りたくて質問をしました。  
１ static int player_xみたいなやり方はほんはまずいのかと  
２ //各オブジェクト宣言 の部分はどうすればいいのか知りたい。  
それと将来性のあるちゃんとしたコードを書くためににはどうすればいいのか知りたい

[code]

    #include "DxLib.h"
    #include "math.h"
    #include <string>
    using namespace std;
    static int key[256];
    static int Color = GetColor(255, 255, 255);
    static int player_x = 0;//プレイヤーのX座標
    static int player_y = 0;//プレイヤーのY座標
    
    //キー入力関数
    int KeyBord_Get(int keycode)
    {
    
        char tmpkey[256];
        GetHitKeyStateAll(tmpkey);
        for (int i = 0; i < 256; i++)
        {
            if (tmpkey[i] != 0)
            {
                key[i]++;
            }
            else
            {
                key[i] = 0;
            }
    
        }
    
        return key[keycode];
    }
    
    
    //ショットクラス
    class Shot
    {
    
        int width;
        int height;
    
        int gh;
    
    public:
        bool life;
    
        int x;
        int y;
        void Initialize(int xx,int yy,int ww,int hh,const char *ch)//初期化
        {
            x = xx;
            y = yy;
            width = ww;
            height = hh;
            life = false;
            gh = LoadGraph(ch);//画像読み込み
    
        }
    
        void Update()//計算
        {
            //確認用デバック
            DrawFormatString(0, 0, Color, "test");
    
            if (life == true)
            {
                y = y - 4;
    
                if (y < -10)
                {
                    life = false;
                }
            }
    
            Draw();
    
        }
    
        void Draw()//描画
        {
            DrawGraph(x, y, gh, true);
    
        }
    
    };
    
    
    //ショット管理クラス
    class Player_Shot_Manager
    {
    private:
    
    #define shot_max 50
        int x;
        int y;
        bool state;
        int count;
        //Shot shot;
        Shot shot[shot_max];
    
    public:
    
        //初期化
        void Initilize()
        {
            state = false;
            count = 0;
    
            for (int i = 0; i < shot_max; i++)
            {
                //弾画像を読み込み
    
                shot[i].Initialize(-50, -50, 14, 3, "resources/Player_Shot.png");
    
            }
    
    
        }
    
        //更新
        void Update()
        {
            if (KeyBord_Get(KEY_INPUT_Z) >= 1)
            {
                if (count % 10 == 0)
                {
                    state = true;
                    if (state = true)
                    {
                        for (int i = 0; i < shot_max; i++)
                        {
                            if (shot[i].life == false)
                            {
                                shot[i].life = true;
                                shot[i].x = player_x;
                                shot[i].y = player_y;
    
                                break;
                            }
    
                        }
                    }
                }
                else
                {
                    state = false;
                }
            }
            else {
                state = true;
            }
    
            for (int i = 0; i < shot_max; i++)
            {
    
                shot[i].Update();
    
            }
    
            count++;
    
        }
    
    
        //描画
        void Draw()
        {
    
        }
    
    
    };
    
    
    
    //プレイヤークラス
    class Player_Control
    {
    
    private:
    
        int gh;
    
    
        int width;
        int height;
    
        bool flag;
    
    
    public:
        int x;
        int y;
        Player_Control()
        {
    
        }
    
        void Draw()
        {
            DrawGraph(x, y, gh, true);
            //DrawGraph(x,y - 3,gh,true);
    
    
        }
    
        void Update()
        {
            player_x = x;
            player_y = y;
            if (KeyBord_Get(KEY_INPUT_UP) >= 1)
            {
                y = y - 2;
            }
            if (KeyBord_Get(KEY_INPUT_RIGHT) >= 1)
            {
                x = x + 2;
            }
            if (KeyBord_Get(KEY_INPUT_LEFT) >= 1)
            {
                x = x - 2;
            }
            if (KeyBord_Get(KEY_INPUT_DOWN) >= 1)
            {
                y = y + 2;
            }
    
    
    
        }
    
        void Initialize()
        {
            gh = LoadGraph("resources/Player.png");
            //DrawFormatString(0,0,Color,"aaaaa");
            x = 200;
            y = 200;
    
            width = 45;
            height = 45;
    
        }
    
    };
    
    //各オブジェクト宣言
    Player_Shot_Manager shot;
    Player_Control player;
    
    //初期化
    void Game_Initialize()
    {
        shot.Initilize();
        player.Initialize();
    }
    //計算
    void Game_Update()
    {
        shot.Update();
        player.Update();
    
    }
    //描画
    void Game_Draw()
    {
        //Player_Shot_Manager.Draw();
        player.Draw();
    
    }
    
    int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
        ChangeWindowMode(TRUE);
        if (DxLib_Init() == -1) { return -1; }
    
    
        Game_Initialize();
        //int x = LoadGraph("resources/Player_Shot.png");
        while (ClearDrawScreen() == 0 && SetDrawScreen(DX_SCREEN_BACK) == 0 && ProcessMessage() == 0)
        {
    
            Game_Update();
    
    
    
            Game_Draw();
    
            //DrawGraph(100,100,x,true);
    
    
    
    
            ScreenFlip();
            if (CheckHitKey(KEY_INPUT_ESCAPE) == 1) { break; }
        }
        return 0;
    }
    
[/code]


CC BY-SA 4.0
2019-02-24T19:11:40.063
53000
2019-02-25T06:18:35.713
2019-02-25T01:11:10.187
2238
question
c++11
dxライブラリ　将来性のあるコードの書き方が知りたい


ソースコードを精査する気になりませんが

A1. 不必要な大域変数は良くないです。提示例ではプレイヤークラス `class Player_Control` が座標を持っていますので
`player_x` 等は要らないはず。資源を二重管理するといずれ破綻するので、必要のないものは使わないようにしましょう。

A2.
逆に、必要な大域変数を使うのをためらう必要はありません。プログラムの起動から終了まで１つしかあってはならないブツなら大域変数にして問題ないですし、他の言語なら
`static class` で実装するような手もあります。途中で複数個になりうるのであれば大域変数にするのはダメ。

> 将来性のあるちゃんとしたコードを書くためには

YAGNI 論なんてのもあります。  
<https://ja.wikipedia.org/wiki/YAGNI>  
"You ain't gonna need it." とか "You Aren't Going to Need It."
とか。「今必要のないことはするな」とか「不必要な拡張性を事前に持たせても無駄」とかいう意味です。

いきなり「ちゃんとした」などと身構えずに、まずは敵や味方の動きが自分で納得のいく動作となるコードを（稚拙で良いので）書いてみましょう。そこで満足せずに「ここは二重管理になっていて美しくない」とか「ここは関数が長すぎて後から読めない」とか、直すべき場所を自分で見つけられるようになりましょう。そうすることで「ちゃんとしたコードとは何か」が身につくと思います。

オイラ的には `class Player_Control`
にプレイヤークラスなんてコメントを入れている時点で美学に反するので、クラス名を変えるとかコメントを変えるとかしたくなります。

Javadoc (Doxygen) お勧めっすよ。  
まず設計意図・実装方針をコメントの形で文章にする。  
コードを実装するのはその後。  
修正が必要になったら Javadoc の修正が先→コード修正が後。  
時間経過で忘れたころに手直しが必要になっても文章がきっちり残っていて楽。  
「仕様（設計意図）通りに、ちゃんと実装する」のにとても役立ちます。


CC BY-SA 4.0
2019-02-25T06:18:35.713
53017
2019-02-25T06:18:35.713
8589
53000
answer