デモプレイを設定する

プログラムを起動するとデモプレイが始まります。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プロジェクトの作成

  1. プロジェクト(Miyama) のフォルダーに miyama.lib と miyama.h を格納して下さい。
    [プロジェクト][既存項目の追加] から miyama.h をプロジェクトに追加します。
    [プロジェクト][プロパティ][リンカ][入力] で miyama.lib と dxguid.lib を追加して下さい。
  2. Miyama.cpp の先頭に次のコードを追加して下さい。
    *App が「三山くずしゲーム」の Class で、AUDIO が「音楽」と「効果音」の Class です。
    DEMO はデモプレイのフラグで「0:通常、1:デモ人間 2:デモComputer」になっています。
        #include   "Miyama.h"
        #define     ID_TIMER (WM_APP + 0)
    
        Audio       AUDIO;
        Miyama     *App= NULL;          // Miyama Object Class
        LPSTR       BmpFile= { "jewel.bmp" };
        POINT       pt;                 // CLICK の位置を記録
        short       NUM;                // T[] の次の記録位置
        short       DEMO;               // Demo Mode Flag
        char        Rule[]=
        { "三個の山に石が積まれています。\n"
          "この石を私とあなたが交互に取り除きます。\n"
          "一度に一つの山からであれば、幾つでも取り除くことができます。\n"
          "最後の石を取らされた方が負けです。"
        };
        
  3. InitInstance() に Dialog Box を表示するコードを追加します。
            App->hDlg = CreateDialog(hInst,MAKEINTRESOURCE(IDD_DIALOG1),
                                     App->hParent,(DLGPROC)MyDlgProc);
            if (App->hDlg == NULL)   return FALSE;
    
            ShowWindow(App->hDlg,SW_SHOW);       //Dialog を表示
            ShowWindow( hWnd, nCmdShow );
            UpdateWindow( hWnd );
            SetFocus(App->hDlg);                 //フォーカスを設定
            return TRUE;
        }
        
  4. WM_CREATE: でバックミュージックとゲーム開始の音声を鳴らします。
    DEMO を1(人間側のプレイ)にセットして、タイマ割り込みを設定します。
        char    buf[16];
        long    nVolume= 2000;	    //+20db
    
        switch( message ) 
        {
            case WM_CREATE:
                AUDIO.Load2("037_klar.mid");
                AUDIO.Play2(200);
                Sleep(3000);
                App= new Miyama(hWnd,BmpFile);
                App->Start();
                NUM=DEMO= 1;        //Start Demo Mode
                AUDIO.Load("Start.wav");
                AUDIO.SetVol(&nVolume);
                AUDIO.Play();
                Sleep(2000);
                SetTimer(hWnd,ID_TIMER,0,NULL);
                break;
        
  5. WM_LBUTTONDOWN: でマウスがクリックされた座標を調べて石を取り除きます。
    (App->down!=0 || (NUM&1)==0) はアニメーションの終了確認と手番の判定です。
    コンピュータ側のプレイは ComPlay(hWnd) で処理します。
            case WM_LBUTTONDOWN:
                if (App->down!=0 || (NUM&1)==0)  break;
                pt.x= LOWORD(lParam);
                pt.y= HIWORD(lParam);
                if (App->ManPlay(&pt)==0)
                {   MessageBox(hWnd,"エラーです","確認", MB_OK);
                    return TRUE;
                }
                AUDIO.Load("Latch.wav");
                AUDIO.Play();
                App->Log(NUM);
                // コンピュータがプレイする
                ComPlay(hWnd);
                return TRUE;
        
  6. WM_TIMER: でデモプレイと石を取り除くアニメーションを制御します。
    App->down が取り除く石の個数で、アニメーションしながら一個ずつ取り除きます。
    DEMO==0 のときは、通常のゲームモードです。
    ComPlay(hWnd) でプレイした局面をログに記録して ScrollBar を設定します。
    山の石が無くなったときはコンピュータの負けです。
    負けをカウントして次のゲームを始めます。
    DEMO==1 のときは、デモプレイで人間側の手番です。
    人間側の手番で石が無ければ、最後の石を取らされたコンピュータの負けです。
    App->DemoPlay() で人間に代わってプレイします。
    DEMO==2 のときは、デモプレイでコンピュータ側の手番です。
    コンピュータ側のプレイは ComPlay(hWnd) で処理します。
        case WM_TIMER:
            KillTimer(hWnd,ID_TIMER);
            if (App->down)
            {   //アニメーション処理
                AUDIO.Load("Poku.wav");     //石を取り除く音
                AUDIO.Play();
                App->CntDown();
                SetTimer(hWnd,ID_TIMER,500,NULL);
                return TRUE;
            }
            switch(DEMO)
            {   case 0:     //Game Mode
                    NUM= App->Log();
                    //スクロールバーの設定
                    SetScrollRange(GetDlgItem(App->hDlg,IDC_SCROLLBAR1),SB_CTL,0,NUM-1,TRUE);
                    SetScrollPos(GetDlgItem(App->hDlg,IDC_SCROLLBAR1),SB_CTL,NUM-1,TRUE);
                    if (App->Stone()==0)
                    {   AUDIO.Load("Lose.wav");
                        AUDIO.Play();
                        MessageBox(hWnd,"あなたの勝ちです","負け", MB_OK);
                        App->Lose_c++;
                        App->Start();
                        NUM= 1;
                    }
                    return TRUE;
                case 1:     //挑戦者のプレイ
                    if (App->Stone()==0)
                    {   AUDIO.Load("Lose.wav");
                        AUDIO.Play();
                        Sleep(2000);
                        App->Lose_c++;
                        App->Start();       //Next Game
                        DEMO=NUM= 1;
                        SetTimer(hWnd,ID_TIMER,0,NULL);
                        return TRUE;
                    }
                    Sleep(1500);
                    App->DemoPlay();
                    AUDIO.Load("Latch.wav");
                    AUDIO.Play();
                    DEMO= 2;                //COM にセット
                    Sleep(500);
                    SetTimer(hWnd,ID_TIMER,0,NULL);
                    return TRUE;
                case 2:     //COM のプレイ
                    ComPlay(hWnd);
                    DEMO= 1;                //挑戦者の手番
                    return TRUE;
            }
            return TRUE;
        
  7. WM_PAINT: に対戦成績と山の石を描画するコードを記述します。
        char    buf[16];
    
        case WM_PAINT:
            hdc = BeginPaint (hWnd, &ps);
            // TODO: この位置に描画用のコードを追加してください...
            wsprintf(buf,"%d",App->Win_c);
            SetDlgItemText(App->hDlg,IDC_WIN,buf);
            wsprintf(buf,"%d",App->Lose_c);
            SetDlgItemText(App->hDlg,IDC_LOSE,buf);
            App->Disp(hdc);
            EndPaint( hWnd, &ps );
            break;
        
  8. WM_DESTROY: で Object を開放して下さい。
        case WM_DESTROY:
            AUDIO.Stop2();
            if (App) { delete(App);  App= NULL; }
            PostQuitMessage( 0 );
            break;
        
  9. DialogBox の CALLBACK 関数 MyDlgProc() です。
        //★ DialogBox の CALLBACK 関数
        LRESULT CALLBACK MyDlgProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
        {
            switch(msg)
            {   case WM_COMMAND:
                    switch(LOWORD(wp))
                    {   case IDC_END:       //終了  
                            PostMessage(hWnd,WM_CLOSE,0,0L);
                            return TRUE;
                        case IDC_RULE:      //説明
                            MessageBox(NULL,Rule,"Miyama",MB_OK);
                            break;
                        case IDC_START:     //開始
                            KillTimer(App->hParent,ID_TIMER);
                            App->down=App->Win_c=App->Lose_c= 0;
                            DEMO= 0;
                            App->Start();
                            NUM= 1;
                            break;
                    }
                    break;
                case WM_HSCROLL:
                    switch(LOWORD(wp))
                    {   case SB_LINELEFT:   NUM--;     break;
                        case SB_LINERIGHT:  NUM++;     break;
                        case SB_PAGELEFT:   NUM-= 5;   break;
                        case SB_PAGERIGHT:  NUM+= 5;   break;
                        case SB_THUMBTRACK: NUM= (int)(HIWORD(wp)); break;
                    }
                    if (NUM<=0)          NUM= 1;
                    if (NUM>=App->CNT)   NUM= App->CNT;
                    App->Saigen(NUM);
                    SetScrollPos(GetDlgItem(App->hDlg,IDC_SCROLLBAR1),SB_CTL,NUM-1,TRUE);
                    break;
                case WM_CLOSE:
                    EndDialog(hWnd,TRUE);
                    PostQuitMessage(0);
                    break;
            }
            return FALSE;
        }
        
  10. コンピュータがプレイする ComPlay() 関数です。
    App->Play() でコンピュータがプレイします。
    コンピュータの手番で石が無いときは、最後の石を取らされた人間側の負けです。
        //★ Computer Play
        LRESULT ComPlay(HWND hwnd)
        {
            if (App->Stone())
            {   App->Play();
                SetTimer(hwnd,ID_TIMER,400,NULL);   //アニメ速度
                return TRUE;
            }
            //One Game End
            AUDIO.Load("Win.wav");
            AUDIO.Play();
            Sleep(2000);
            if (DEMO)           //DEMO Mode Next Game
            {   App->Win_c++;
                App->Start();
                NUM=DEMO= 1;
                SetTimer(hwnd,ID_TIMER,0,NULL);
                return TRUE;
            }
            if (MessageBox(hwnd,"私の勝ちです(次 | 待った)","勝ち", MB_OKCANCEL | MB_ICONQUESTION)==IDOK)
            {   App->Win_c++;
                App->Start();
                NUM= 1;
            }
            else    App->Saigen(NUM);
            return  TRUE;
        }
        
  11. プロジェクトの設定は 勝敗判定とゲームの繰り返し を参照して下さい。
    Dialog Box の設定は Dialog Box を表示する を参照して下さい。
    プログラムを起動するとデモプレイが始まります。
    ゲームを始めるときは「開始」ボタンをクリックして下さい。

[Next Chapter ↓] Client 同士が対戦する「三山くずしゲーム」
[Previous Chapter ↑] 「音楽」と「効果音」を鳴らす

超初心者のプログラム入門(Win32API C++)