首页 > 技术文章 > win32_吃砖块游戏

ncgds 2017-04-01 11:36 原文

// 吃砖块.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"
#include <math.h>
#include <stdio.h>
#define MAX_LOADSTRING 100
//在窗口范围内随机生成一个位置
int RandPos()
{
return rand()%501;
}
//在指定的位置绘制一个砖块
//@hdc 绘制设备句柄
//@x,y 位置
//@s 砖块大小
//@bPlayer 标记是否为玩家砖块
void DrawBrick(HDC hdc, int x, int y, int s, int bPlayer)
{
HBRUSH brush;
brush = bPlayer?CreateSolidBrush(RGB(255,0,0)):CreateSolidBrush(RGB(0,255,0));
RECT rc;
rc.top = y - s/2;
rc.left = x - s/2;
rc.bottom = y + s/2;
rc.right = x + s/2;
FillRect(hdc,&rc,brush);

DeleteObject(brush);


}

//判断两个同样大小的砖块是否在空间上重叠
int IsCollider(int x1, int y1, int x2, int y2, int s)
{
if(x1+s < x2 || x1-s > x2)
return 0;
if(y1+s < y2 || y1-s > y2)
return 0;
return 1;

}


// Global Variables:
HINSTANCE hInst;    // current instance
TCHAR szTitle[MAX_LOADSTRING];    // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];    // The title bar text

//全局变量
//调用随机位置函数,随机生成玩家砖块和其他砖块的位置
int xP = RandPos(),yP = RandPos(), xE = RandPos(), yE = RandPos();
const int size = 20;//砖块大小
int score = 0;//玩家分数

// Foward declarations of functions included in this code module:
ATOM    MyRegisterClass(HINSTANCE hInstance);
BOOL    InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;

// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_MY, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow)) 
{
return FALSE;
}

hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_MY);

// Main message loop:
while (GetMessage(&msg, NULL, 0, 0)) 
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return msg.wParam;
}

 

//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style    = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc    = (WNDPROC)WndProc;
wcex.cbClsExtra    = 0;
wcex.cbWndExtra    = 0;
wcex.hInstance    = hInstance;
wcex.hIcon    = LoadIcon(hInstance, (LPCTSTR)IDI_MY);
wcex.hCursor    = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName    = (LPCSTR)IDC_MY;
wcex.lpszClassName    = szWindowClass;
wcex.hIconSm    = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

return RegisterClassEx(&wcex);
}

//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;

hInst = hInstance; // Store instance handle in our global variable

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

if (!hWnd)
{
return FALSE;
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

return TRUE;
}

//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND    - process the application menu
// WM_PAINT    - Paint the main window
// WM_DESTROY    - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

switch (message) 
{
case WM_COMMAND:
wmId = LOWORD(wParam); 
wmEvent = HIWORD(wParam); 
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_KEYDOWN:
//让窗口变为无校,从而触发重绘消息
InvalidateRect(hWnd,NULL,TRUE);
switch(wParam)//玩家控制砖块进行上下左右移动
{
case VK_LEFT:
xP -= xP<0?0:10;
break;

case VK_RIGHT:
xP += xP>500?0:10;
break;
case VK_UP:
yP -= yP<0?0:10;
break;
case VK_DOWN:
yP += yP>500?0:10;
break;
}
if(IsCollider(xP,yP,xE,yE,size))
//如果重叠则得分并重新分配敌人位置
{
score++;
xE= RandPos(),yE = RandPos();

}
break;
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
WCHAR str[16];
swprintf(str,L"你的得分:%d",score);
TextOut(hdc,0,0,(char*)str,wcslen(str));
DrawBrick(hdc,xE,yE,size,0);
DrawBrick(hdc,xP,yP,size,1);


EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;

case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}

 

 
View Code

 

推荐阅读