物置‎ > ‎

Puyopuyo拡張

ClassPuyoEx.h
#ifndef CLASSPUYOEX_H
#define CLASSPUYOEX_H

#include "ClassPuyo.h"

class CPuyoEx : public CPuyo
{
public:
  CPuyoEx();
private:
  void ShowFieldEx () ;
  void SelShowBlockEx ( int type , int x, int y );
};

#endif //CLASSPUYOEX_H

ClassPuyoEx.cpp
#include "ClassPuyoEx.h"
#include "windows.h"
#include <string.h>
#pragma warning(disable : 4996)//printfの警告を防ぐ

static HWND g_hwnd;
static HDC g_memory_dc;
static HBITMAP g_memory_bmp;
static HBRUSH g_black;
static HBRUSH g_red;
static HBRUSH g_blue;
static HBRUSH g_green;
static HBRUSH g_yellow;
static HBRUSH g_violet;

const TCHAR* APP_NAME = TEXT("WinPuyopuyo");
const int WINDOW_WIDTH  = 680;
const int WINDOW_HEIGHT = 480;
const int BDW = 20;//BLOCK_DRAW_WIDTH。ブロック描画幅

LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
  HDC hdc;
  PAINTSTRUCT ps;
  RECT rect;

  switch (msg) {
  case WM_PAINT:
    hdc = BeginPaint(hwnd , &ps);
    GetClientRect(hwnd , &rect);
    BitBlt(hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_memory_dc, 0, 0, SRCCOPY);
    EndPaint(hwnd , &ps);
    return 0;

  case WM_DESTROY:
    DeleteDC(g_memory_dc);
    DeleteObject(g_memory_bmp);
    DeleteObject(g_black);
    DeleteObject(g_red);
    DeleteObject(g_blue);
    DeleteObject(g_green);
    DeleteObject(g_violet);
    PostQuitMessage(0);
    exit(0);//コンソールも強制終了する
    return 0;
  }
  return DefWindowProc(hwnd , msg , wp , lp);
}

DWORD WINAPI ThreadFunc(LPVOID vdParam) {
  WNDCLASS wc = { CS_CLASSDC,
                  WinProc,                                //ウィンドウプロシージャ
                  0,
                  0,
                  (HINSTANCE)GetModuleHandle(NULL),
                  NULL,                                   //アイコン
                  LoadCursor( NULL, IDC_ARROW ),          //マウスカーソル
                  (HBRUSH) GetStockObject( WHITE_BRUSH ), //背景色
                  NULL,                                   //メニュー
                  APP_NAME };
  if(RegisterClass(&wc) == 0) {
    MessageBox(NULL, TEXT("RegisterClass関数が失敗しました"), APP_NAME, NULL);
    return 0 ;
  }
  g_hwnd = CreateWindow( APP_NAME,            //タイトルバーテキスト
                         APP_NAME,            //クラス名
                         WS_OVERLAPPEDWINDOW, //ウインドウスタイル
                         CW_USEDEFAULT,       //ウインドウ左上x座標
                         CW_USEDEFAULT,       //ウインドウ左上y座標
                         WINDOW_WIDTH,        //ウインドウ幅
                         WINDOW_HEIGHT,       //ウインドウ高さ
                         GetTopWindow(NULL),  //親ウインドウのハンドル
                         NULL,
                         (HINSTANCE)GetModuleHandle(NULL),
                         NULL );
  if(!g_hwnd){
    MessageBox(NULL, TEXT("CreateWindow関数が失敗しました"), APP_NAME, NULL);
    return 0;
  }

  ShowWindow(g_hwnd , SW_SHOW);
  UpdateWindow(g_hwnd);

  MSG msg;

  while (GetMessage(&msg , NULL , 0 , 0 )) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return 0;
}

CPuyoEx::CPuyoEx()
{
  DWORD dwID;
  CreateThread(NULL , 0 , ThreadFunc , 0 , 0 , &dwID);

  HDC hdc;
  RECT rect;
  g_memory_dc = CreateCompatibleDC(NULL);
  GetClientRect(GetDesktopWindow() , &rect);
  hdc = GetDC(g_hwnd);
  g_memory_bmp = CreateCompatibleBitmap(hdc , rect.right , rect.bottom);
  ReleaseDC(g_hwnd , hdc);
  SelectObject(g_memory_dc , g_memory_bmp);

  g_black  = CreateSolidBrush(RGB(  0,  0,  0));
  g_red    = CreateSolidBrush(RGB(255,  0,  0));
  g_blue   = CreateSolidBrush(RGB(  0,  0,255));
  g_green  = CreateSolidBrush(RGB(  0,255,  0));
  g_yellow = CreateSolidBrush(RGB(255,255,  0));
  g_violet = CreateSolidBrush(RGB(255,  0,255));
}
void CPuyoEx::ShowFieldEx()
{
  int i , j;
  char str[256];

  Rectangle(g_memory_dc , 0 , 0 , WINDOW_WIDTH , WINDOW_HEIGHT);
  for ( i = 1 ; i < STAGE_HEIGHT ; i++ ) {
    for ( j = 0 ; j < STAGE_WIDTH ; j++ ) {
      SelShowBlockEx ( field[i][j] , j, i );
    }
    
    if ( i == 2 ) {
      SelShowBlockEx ( block_type_1 , j + 2, i ) ;
    }
     
    if ( i == 3 ) {
      SelShowBlockEx ( block_type_2 , j + 2, i ) ;
    }

    if ( i == 5 ) {
      //cout << "    連鎖" << flush ;
      TextOutA(g_memory_dc , (j+2) * BDW , i * BDW, "連鎖" , (int)strlen("連鎖"));
    }

    if ( i == 6 ) {
      //cout << "   " << count_chain << flush ;
      sprintf(str , " %d", count_chain);
      TextOutA(g_memory_dc , (j+2) * BDW , i * BDW, str , (int)strlen(str));
    }

    if ( i == 8 ) {
      //cout << "  最大連鎖" << flush ;
      TextOutA(g_memory_dc , (j+1) * BDW , i * BDW, "最大連鎖" , (int)strlen("最大連鎖"));
    }

    if ( i == 9 ) {
      //cout << "   " << max_chain << flush ;
      sprintf(str , " %d", max_chain);
      TextOutA(g_memory_dc , (j+2) * BDW , i * BDW, str , (int)strlen(str));
    }
  }

  //ウィンドウを再描画。WinProc の WM_PAINT を実行する
  InvalidateRect(g_hwnd , NULL , TRUE);
}

void CPuyoEx::SelShowBlockEx ( int type , int x, int y )
{
  HBRUSH old_brush;
  RECT rect;

  switch ( type ) {
  case WALL :
    rect.left   = x*BDW;
    rect.top    = y*BDW;
    rect.right  = x*BDW + BDW;
    rect.bottom = y*BDW + BDW;
    FillRect(g_memory_dc , &rect , g_black);
    return ;

  case BLANK :
    return ;

  case BLOCK_1 :
    old_brush = (HBRUSH)SelectObject(g_memory_dc , g_red);
    break ;

  case BLOCK_2 :
    old_brush = (HBRUSH)SelectObject(g_memory_dc , g_blue);
    break ;

  case BLOCK_3 :
    old_brush = (HBRUSH)SelectObject(g_memory_dc , g_green);
    break ;

  case BLOCK_4 :
    old_brush = (HBRUSH)SelectObject(g_memory_dc , g_yellow);
    break ;

  case BLOCK_5 :
    old_brush = (HBRUSH)SelectObject(g_memory_dc , g_violet);
    break ;

  default:
    return ;
  }
  Ellipse(g_memory_dc , x*BDW , y*BDW , x*BDW + BDW , y*BDW + BDW);
  SelectObject(g_memory_dc, old_brush);
}

ConioEx.h
#ifndef CONIOEX_H
#define CONIOEX_H

//現在のキーを取得
char _getch () ;

//キーを押された時以外は0を返す
int _kbhit () ;
 
#endif//CONIOEX_H

CoinEx.cpp
#include "ConioEx.h"
#include <windows.h>

static char g_key;

//引数でキーコードを指定し、そのキーが押されているなら true を返す
bool IsKeyDown(int key)
{
  if (GetKeyState (key) & 0x8000){
    return true;
  }
  return false;
}
//引数でキーコードを指定し、そのいずれかのキーが押されているなら true を返す
bool IsKeyDown (int key1 , int key2)
{
  if (IsKeyDown (key1) ||
      IsKeyDown (key2) ){
    return true;
  }
  return false;
}
bool IsKeyDown (int key1 , int key2 , int key3)
{
  if (IsKeyDown (key1) ||
      IsKeyDown (key2) ||
      IsKeyDown (key3) ){
    return true;
  }
  return false;
}

void GetKey ()
{
  g_key = 0;

  if(IsKeyDown('F', VK_RIGHT)) g_key = 'f';//右
  if(IsKeyDown('S', VK_LEFT))  g_key = 's';//左
  if(IsKeyDown('D', VK_DOWN))  g_key = 'd';//下
  if(IsKeyDown('T'))           g_key = 't';//一時停止
  if(IsKeyDown('Y'))           g_key = 'y';//続ける
  if(IsKeyDown('E'))           g_key = 'e';//終了
  if(IsKeyDown(VK_SPACE, VK_UP, VK_CONTROL)) g_key = ' ';//回転
}

//現在のキーを取得
char _getch ()
{
  return g_key;
}

//キーを押された時以外は0を返す
int _kbhit ()
{
  GetKey();
  if (g_key) {
    return 1;
  }
  return 0;
}