71616


みなさんありがとうございました！  
こちらのサイトの内容はいくらやっても理解できなかったので  
新しいサイトを参考に制作します！ありがとうございました！

<https://bituse.info/game/shot/9>  
こちらのサイトを参考にシュミレーションゲームを制作しようとしています

それで、敵を追加する項目でg_count;という拡張子が見当たらないとエラーが出てしまったでサイトをよく見ると

> まず、最初に説明しておかなければならないのは、変数g_countです。  
>  これはゲームが開始してから何ループしたのかを表す変数です。  
>  これはmain.cppでグローバル変数として定義し、define.hでextern宣言して共有できるようにしています。

と説明されていたので  
main.cpp に int g_count; と追加し  
define.h に extern int g_count; と追加したところ見たことないエラーが出てしまい色々試したのですが解決できません。  
どなたか分かる方助けてほしいです。

**追記**  
お返事のほうありがとうございます。  
またシステムの根幹から作り直そうかなと考えています。  
とりあえず今の敵が実装できないエラーを解決したいのでそこまでは終わらせようと思います。  
ソリューションをアップしたほうがいいとのことで  
<https://dotup.org/uploda/dotup.org2294152.zip.html>  
こちらに上げさせていただきました。

よろしくお願いします。

* * *

**エラーメッセージ**

[code]

    1>------ ビルド開始: プロジェクト: gamegame, 構成: Release Win32 ------
    1>back.cpp
    1>control.cpp
    1>enemy.cpp
    1>main.cpp
    1>pch.cpp
    1>player.cpp
    1>control.obj : error LNK2001: 外部シンボル "int g_count" (?g_count@@3HA) は未解決です
    1>C:\Users\rikua\source\repos\gamegame\Release\gamegame.exe : fatal error LNK1120: 1 件の未解決の外部参照
    1>プロジェクト "gamegame.vcxproj" のビルドが終了しました -- 失敗。
    ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
    
[/code]

**main.cpp**

[code]

    #include "pch.h"
    #include "control.h"
    
    
    
    //キー取得用配列
    char key[256];
    
    int g_count;
    
    // プログラムは WinMain から始まります
    int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )
    {
        ChangeWindowMode(TRUE);
    
        if( DxLib_Init() == -1 )        // ＤＸライブラリ初期化処理
        {
            return -1 ;         // エラーが起きたら直ちに終了
        }
    
    
        CONTROL *control = new CONTROL;
    
        
    
        while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll(key)==0){
            
            control->All();
            
        }
    
    
        DxLib_End() ;               // ＤＸライブラリ使用の終了処理
    
        return 0 ;              // ソフトの終了 
    }
    
[/code]

**define.h**

[code]

    #include <windows.h>
    
    //プレイヤーの歩くスピード
    #define PLAYER_SPEED 5
    
    #define MARGIN 10
    
    //メッセージボックス
    #define MSG(m) {\
        MessageBox(NULL,m,"メッセージ",MB_OK);}
    
    //extern宣言してkey配列にどこからでもアクセスできるようにする
    extern char key[256];
    extern int g_count;
        
    
    
    #pragma once
    
    #define PSHOT_NUM 20
    #define PSHOT_SPEED 14
    struct SHOT {
        bool flag;//弾が発射中かどうか
        double x;//x座標
        double y;//y座標
        int gh;//グラフィックハンドル
        int width, height;//画像の幅と高さ
    };
    
[/code]

**enemy.cpp**

[code]

    #include "pch.h"
    #include "enemy.h"
    
    ENEMY::ENEMY()
    {
        LoadDivGraph("enemy.png", 3, 1, 3, 27, 25, gh);
    
        width = 27;
        height = 25;
    
        x = 50;
        y = -50;
    
        in_time = 180;
    
        stop_time = 300;
    
        out_time = 420;
    
        count = 0;
    
        endflag = false;
    
    }
    
    
    void ENEMY::Move()
    {
        //出てきてから止まる時間までの間なら下に移動
        if (in_time < g_count && g_count < stop_time) {
            y += 2;
            //帰還時間を過ぎたら戻る。
        }
        else if (g_count > out_time) {
            y -= 2;
            if (y < -40) {
                endflag = true;
            }
        }
    }
    
    void ENEMY::Draw()
    {
        int temp;
    
        if (!endflag) {
    
            temp = count % 40 / 10;
            if (temp == 3)
                temp = 1;
    
            DrawGraph(x, y, gh[temp], TRUE);
        }
    }
    
    
    bool ENEMY::All()
    {
        Move();
    
        Draw();
    
        ++count;
    
        return endflag;
    }
    
[/code]

**enemy.h**

[code]

    #include "pch.h"
    class ENEMY {
    private:
        double x, y;
        int gh[3];
    
        int width, height;
    
        int in_time, stop_time, out_time;
    
        int count;
    
        bool endflag;
    
    public:
        bool All();
        void Move();
        void Draw();
        ENEMY();
    };
    
[/code]

**control.cpp**

[code]

    #include "pch.h"
    #include "control.h"
    
    
    CONTROL::CONTROL()
    {
        //プレイヤークラスの生成
        player = new PLAYER;
    
        
    
        back = new BACK;
    
    }
    
    CONTROL::~CONTROL()
    {
        //プレイヤークラスの解放
        delete player;
    
    
        
    }
    
    void CONTROL::All()
    {
    
        //描画領域を指定
        SetDrawArea(MARGIN, MARGIN, MARGIN + 380, MARGIN + 460);
    
        back->All();
    
    
    
        player->All();
    
    
        if (enemy != NULL) {
            if (enemy->All()) {
                delete enemy;
                enemy = NULL;
            }
        }
    
        ++g_count;
    }
    
[/code]


CC BY-SA 4.0
2020-10-29T14:38:01.117
71601
2020-11-06T03:00:57.060
2020-11-06T03:00:57.060
42535
42535
question
c++ visual-studio
外部シンボルが未解決というエラーが出てしまう


> 1>control.obj : error LNK2001: 外部シンボル "int g_count" (?g_count@@3HA) は未解決です

要は、g_count を宣言して使用しているにも関わらず、どこでも定義してないってことです。  
まずエラーメッセージを調べ、内容を理解してください。  
エラーコードをGoogle検索すればすぐに情報は出てくる筈です。

[Linker Tools Error LNK2001](https://docs.microsoft.com/ja-jp/cpp/error-
messages/tool-errors/linker-tools-error-lnk2001?view=msvc-160)

英語でよく判らん、という場合はChromeの翻訳機能等や翻訳サイトを使ってください。そこそこ読める日本語になります。翻訳して説明を読んで、それでも判らんという場合は、単純に開発言語に対する理解不足です。もっと勉強してください。せめて、宣言と定義くらいは理解しましょう。  
[宣言 (declaration) と定義 (definition) の違い](https://so-
zou.jp/software/tech/programming/cpp/grammar/data-
type/declaration/definition.htm)

エラーには問題解決のための情報が入っているので、まず最低限エラーの文章をきちんと読むのと、Web検索をするくらいはやりましょう。


CC BY-SA 4.0
2020-10-30T08:40:33.793
71616
2020-10-30T08:40:33.793
41943
71601
answer


アップロードされていた`.zip`の中の`main.cpp`には`int g_count;`が追加されていませんでした。

主に`main.cpp`に`int
g_count;`を追加してビルドしたら正常に終了し、デバッグ実行でそれなりに動いているようです。(カーソルキーでキャラを動かすことが出来ています)

以下のような状況が考えられます。

  * ビルド対象では無い、例えば参照先サイトからダウンロードしてセーブしておいたフォルダの`main.cpp`を編集している。
  * Visual Studio IDE上ではなく、別のエディタ上でファイルを編集していて、しかも編集内容をファイルに反映させていない。

* * *

アップロードされていた`.zip`内のソースファイルを基に、以下のような手順で確認しました。

  1. Visual Studio Community 2019 で新しいプロジェクトの作成で C++,Windows,デスクトップ の Windowsデスクトップウィザードを選択
  2. `gamegame`というソリューション＆プロジェクト名で作成
  3. `デスクトップアプリケーション(.exe)`で`空のプロジェクト`をチェックし、OKで作成
  4. `.zip`ファイルから各`.cpp`, `.h`ファイルをコピーしてプロジェクトに追加
  5. メニューの`プロジェクト`の`NuGetパッケージの管理`の`参照`で`DxLib`で検索し、`DxLib.vc140`をインストール
  6. `.cpp`, `.h`の画像ファイル名やメッセージ文言の文字列リテラルを`_T()`マクロで囲む

* * *

  7. 上記時点でビルドすると、質問記事のように「外部シンボル "int g_count" (?g_count@@3HA) は未解決です」となる

* * *

  8. `main.cpp`に`int g_count;`が無いので、追加してビルドすると正常に終了し、出来た.exeをデバッグ実行するとウインドウ・背景イメージ・キャラが表示され、キャラをカーソルキーで動かすことが出来る


CC BY-SA 4.0
2020-10-30T09:01:13.323
71618
2020-10-30T09:01:13.323
26370
71601
answer


C++17には[インライン変数](https://cpprefjp.github.io/lang/cpp17/inline_variables.html)という機能があります。ヘッダーファイルに

[code]

    inline int g_count = 0;
    
[/code]

と（宣言ではなく）定義を書くことができます。

Visual
C++は互換のためデフォルトでC++14までしか有効化されていないため、コンパイルオプション[`/std:c++17`](https://docs.microsoft.com/en-
us/cpp/build/reference/std-specify-language-standard-
version?view=msvc-160)の指定が必要です。


CC BY-SA 4.0
2020-10-30T23:54:21.517
71628
2020-10-30T23:54:21.517
4236
71601
answer