//header.h文件
#pragma once
#include <windows.h>
#include <stdio.h>
#define KEYDOWN(vk_code)((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
//Game.h文件
#pragma once
#include "header.h"
const int BRICKNUM = 20;
typedef struct
{
int x; //球的位置
int y;
int radius; //球的半径
int speed; //球的速度
int moveX; //每次移动的值(带正负)
int moveY; //每次移动的值
COLORREF color; //球的颜色
}BALL;
typedef struct
{
int width; //砖的宽度
int height; //砖的高度
RECT rect;
COLORREF color; //砖的颜色
bool exist;
}BRICK;
class CGame
{
private:
HWND m_hWnd;
HDC m_hdc;
RECT m_wndRect;
BALL m_Ball;
BRICK* m_pBrick;
BRICK m_Bar;
public:
CGame(HWND hWnd);
~CGame(void);
void Render();
void ClearScreen(); //清除屏幕
void DrawBrick(); //画砖块
void DrawBar(); //画挡板
void DrawBall(); //画小球
void MoveBall(); //小球移动
void TestBrickCollide(); //判断碰撞砖块
void TestBarCollide(); //判断碰撞挡板
void MoveBar(int speed); //移动挡板
};
//Game.cpp文件
#include "Game.h"
//---------------------------------------------------------
// Name: CGame
// Desc: 构造函数,初始化
//---------------------------------------------------------
CGame::CGame(HWND hWnd)
{
m_hWnd = hWnd;
m_hdc = GetDC(m_hWnd);
GetWindowRect(m_hWnd, &m_wndRect);
//初始化砖块
m_pBrick = new BRICK[BRICKNUM];
int StartX = m_wndRect.right / 5; //第一块砖块的位置
int StartY = m_wndRect.bottom / 6;
for(int i = 0; i < BRICKNUM; i++)
{
(m_pBrick + i)->width = 50;
(m_pBrick + i)->height = 25;
(m_pBrick + i)->color = RGB(255, 40, 100);
(m_pBrick + i)->rect.left = StartX +(i % 5) *(m_pBrick + i)->width;
(m_pBrick + i)->rect.top = StartY +(i / 5) *(m_pBrick + i)->height;
(m_pBrick + i)->rect.right =(m_pBrick + i)->rect.left +(m_pBrick + i)->width;
(m_pBrick + i)->rect.bottom =(m_pBrick + i)->rect.top +(m_pBrick + i)->height;
(m_pBrick + i)->exist = true;
}
//初始化挡板
m_Bar.color = RGB(0, 0, 255);
m_Bar.exist = true;
m_Bar.height = 15;
m_Bar.width = 60;
m_Bar.rect.left = m_wndRect.right / 2 - m_Bar.width / 2; //游戏开始画在//窗口中央底部
m_Bar.rect.top = m_wndRect.bottom *(8.0 / 10);
m_Bar.rect.right = m_Bar.rect.left + m_Bar.width;
m_Bar.rect.bottom = m_Bar.rect.top + m_Bar.height;
//初始化小球
m_Ball.color = RGB(0, 255, 255);
m_Ball.radius = 10;
m_Ball.x = m_Bar.rect.left + m_Bar.width / 2; //小球开始出现在挡板的正上方//中央
m_Ball.y = m_Bar.rect.top - m_Ball.radius;
m_Ball.speed = 1;
m_Ball.moveX = m_Ball.speed;
m_Ball.moveY = -m_Ball.speed;
}
//---------------------------------------------------------
// Name: ~CGame
// Desc: 析构函数
//---------------------------------------------------------
CGame::~CGame(void)
{
ReleaseDC(m_hWnd, m_hdc);
}
//---------------------------------------------------------
// Name: Render
// Desc: 游戏的渲染部分
//---------------------------------------------------------
void CGame::Render()
{
ClearScreen();
DrawBrick();
MoveBar(3);
DrawBar();
TestBrickCollide();
TestBarCollide();
MoveBall();
DrawBall();
}
//---------------------------------------------------------
// Name: DrawBrick
// Desc: 画出没被小球打中的砖块
//---------------------------------------------------------
void CGame::DrawBrick()
{
bool gamesuccess = true;
for(int i = 0; i < BRICKNUM; i++)
{
if((m_pBrick + i)->exist)
{
//画实心矩形
HBRUSH hBrush = ::CreateSolidBrush((m_pBrick + i)->color);
SelectObject(m_hdc, hBrush);
::FillRect(m_hdc, &(m_pBrick + i)->rect, hBrush);
SelectObject(m_hdc, hBrush);
DeleteObject(hBrush);
//画矩形外框
HPEN hPen = ::CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
SelectObject(m_hdc, hPen);
MoveToEx(m_hdc,(m_pBrick + i)->rect.left, (m_pBrick + i)->rect.top, NULL);
LineTo(m_hdc, (m_pBrick + i)->rect.right, (m_pBrick + i)->rect.top);
LineTo(m_hdc, (m_pBrick + i)->rect.right, (m_pBrick + i)->
rect.bottom);
LineTo(m_hdc, (m_pBrick + i)->rect.left, (m_pBrick + i)->
rect.bottom);
LineTo(m_hdc, (m_pBrick + i)->rect.left, (m_pBrick + i)->rect.top);
SelectObject(m_hdc, hPen);
DeleteObject(hPen);
gamesuccess = false;
}
}
if(gamesuccess)
{
MessageBox(m_hWnd, L"游戏成功!", L"Congratulation!", MB_OK);
exit(0);
}
}
//---------------------------------------------------------
// Name: DrawBar
// Desc: 画挡板
//---------------------------------------------------------
void CGame::DrawBar()
{
HBRUSH hBrush = CreateSolidBrush(m_Bar.color);
SelectObject(m_hdc, hBrush);
FillRect(m_hdc, &m_Bar.rect, hBrush);
SelectObject(m_hdc, hBrush);
DeleteObject(hBrush);
HPEN hPen = CreatePen(PS_SOLID, 1, RGB(255, 255, 0));
SelectObject(m_hdc, hPen);
MoveToEx(m_hdc, m_Bar.rect.left, m_Bar.rect.top, NULL);
LineTo(m_hdc, m_Bar.rect.right, m_Bar.rect.top);
LineTo(m_hdc, m_Bar.rect.right, m_Bar.rect.bottom);
LineTo(m_hdc, m_Bar.rect.left, m_Bar.rect.bottom);
LineTo(m_hdc, m_Bar.rect.left, m_Bar.rect.top);
SelectObject(m_hdc, hPen);
DeleteObject(hPen);
}
//---------------------------------------------------------
// Name: DrawBall
// Desc: 画小球
//---------------------------------------------------------
void CGame::DrawBall()
{
HBRUSH hBrush = CreateSolidBrush(m_Ball.color);
HPEN hPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 255));
SelectObject(m_hdc, hBrush);
SelectObject(m_hdc, hPen);
Ellipse(m_hdc, m_Ball.x - m_Ball.radius, m_Ball.y - m_Ball.radius, m_Ball.x + m_Ball.radius, m_Ball.y + m_Ball.radius);
SelectObject(m_hdc, hPen);
SelectObject(m_hdc, hBrush);
DeleteObject(hPen);
DeleteObject(hBrush);
}
//---------------------------------------------------------
// Name: ClearScreen
// Desc: 清屏
//---------------------------------------------------------
void CGame::ClearScreen()
{
HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0));
SelectObject(m_hdc, hBrush);
FillRect(m_hdc, &m_wndRect, hBrush);
SelectObject(m_hdc, hBrush);
DeleteObject(hBrush);
}
//---------------------------------------------------------
// Name: MoveBall
// Desc: 移动小球
//---------------------------------------------------------
void CGame::MoveBall()
{
if(m_Ball.x + m_Ball.moveX + m_Ball.radius > m_wndRect.right ||
m_Ball.x + m_Ball.moveX - m_Ball.radius < m_wndRect.left)
{
m_Ball.moveX = -m_Ball.moveX;
}
if(m_Ball.y + m_Ball.moveY - m_Ball.radius < m_wndRect.top)
{
m_Ball.moveY = -m_Ball.moveY;
}
if(m_Ball.y + m_Ball.moveY + m_Ball.radius > m_wndRect.bottom)
{
MessageBox(m_hWnd, L"游戏结束!", L"GameOver", MB_OK);
exit(0);
}
m_Ball.x += m_Ball.moveX;
m_Ball.y += m_Ball.moveY;
}
//---------------------------------------------------------
// Name: TestBrickCollide
// Desc: 测试小球是否与砖块碰撞
//---------------------------------------------------------
void CGame::TestBrickCollide()
{
POINT pt;
pt.x = m_Ball.x;
pt.y = m_Ball.y;
HRGN hrgn = ::CreateRectRgn(m_Ball.x - m_Ball.radius, m_Ball.y -
m_Ball.radius, m_Ball.x + m_Ball.radius, m_Ball.y + m_Ball.radius);
for(int i = 0; i < BRICKNUM; i++)
{
if((m_pBrick + i)->exist &&
RectInRegion(hrgn, &(m_pBrick + i)->rect))
{
if(m_Ball.x <(m_pBrick + i)->rect.left &&
m_Ball.moveX > 0)
{
(m_pBrick + i)->exist = false;
m_Ball.moveX = -m_Ball.moveX;
return;
}
if(m_Ball.x >(m_pBrick + i)->rect.right &&
m_Ball.moveX < 0)
{
(m_pBrick + i)->exist = false;
m_Ball.moveX = -m_Ball.moveX;
return;
}
if(m_Ball.y <(m_pBrick + i)->rect.top &&
m_Ball.moveY > 0)
{
(m_pBrick + i)->exist = false;
m_Ball.moveY = -m_Ball.moveY;
return;
}
if(m_Ball.y >(m_pBrick + i)->rect.bottom &&
m_Ball.moveY < 0)
{
(m_pBrick + i)->exist = false;
m_Ball.moveY = -m_Ball.moveY;
return;
}
}
}
DeleteObject(hrgn);
}
//---------------------------------------------------------
// Name: TestBarCollide
// Desc: 测试小球是否与挡板碰撞
//---------------------------------------------------------
void CGame::TestBarCollide()
{
HRGN hrgn = ::CreateRectRgn(m_Ball.x - m_Ball.radius, m_Ball.y -
m_Ball.radius, m_Ball.x + m_Ball.radius, m_Ball.y + m_Ball.radius);
if(RectInRegion(hrgn, &m_Bar.rect))
{
m_Ball.moveY = -m_Ball.moveY;
float a =(m_Ball.x - m_Bar.rect.left);
float b = a / m_Bar.width;
m_Ball.moveX =((b - 0.5) * 5);
}
DeleteObject(hrgn);
}
//---------------------------------------------------------
// Name: MoveBar
// Desc: 移动挡板
//---------------------------------------------------------
void CGame::MoveBar(int speed)
{
if(KEYDOWN(VK_LEFT))
{
if(m_Bar.rect.left - speed < m_wndRect.left)
return;
m_Bar.rect.left -= speed;
m_Bar.rect.right -= speed;
}
if(KEYDOWN(VK_RIGHT))
{
if(m_Bar.rect.right + speed > m_wndRect.right)
return;
m_Bar.rect.left += speed;
m_Bar.rect.right += speed;
}
}
//main.cpp文件
#include "header.h"
#include "Game.h"
CGame* g_pGame;
//windows 的回调函数
long FAR PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY:
PostQuitMessage(0); //向操作系统传递退出的消息,只有当窗口销毁之后,WM_QUIT才能生效结束这个进程
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostMessage(hWnd, WM_CLOSE, 0, 0); //向操作系统传递关闭窗口消息,WM_CLOSE会触发WM_DESTROY消息
break;
}
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) //缩放,如按最小化时,都由这个控制
{
MSG msg; //定义一个消息的对象
HWND hWnd; //窗口句柄
WNDCLASS wc; //定义窗口类
//创建窗口类
wc.style = CS_HREDRAW | CS_VREDRAW; //支持水平和垂直重绘
wc.lpfnWndProc = WindowProc; //相应的消息处理函数
wc.cbClsExtra = 0; //附加内存空间
wc.cbWndExtra = 0; //附加内存空间
wc.hInstance = hInstance; //窗口的实例句柄
wc.hIcon = NULL; //窗口的小图标
wc.hCursor = NULL; //窗口的鼠标形状
wc.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH);//背景颜色
wc.lpszMenuName = NULL; //窗口菜单
wc.lpszClassName = L"createwindows"; //窗口名称
RegisterClass(&wc); //注册窗口句柄
hWnd = CreateWindowEx(WS_EX_TOPMOST, L"createwindows", L"Create Window Title", WS_OVERLAPPEDWINDOW, 0, 0, 400, 300, NULL, NULL, hInstance, NULL);
if(!hWnd) //判断窗口是否建立成功
{
MessageBox(NULL, L"窗口建立失败!", L"error", NULL);
return FALSE;
}
g_pGame = new CGame(hWnd);
ShowWindow(hWnd, nCmdShow); //显示窗口
UpdateWindow(hWnd); //更新窗口,默认调用了回调函数
while(true)
{
//接受系统消息(&msg 为 MSG 类型的信息结构体,NULL 窗口句柄,0, 0 表示
//接受所有的窗口信息)
if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage(&msg); //转化信息
DispatchMessage(&msg); //分配信息到相应的消息处理
}
else
{
g_pGame->Render();
Sleep(10);
}
}
return 1;
}