167 lines
4.4 KiB
C
167 lines
4.4 KiB
C
#include <windows.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <stdio.h>
|
|
|
|
#define WINDOW_WIDTH 800
|
|
#define WINDOW_HEIGHT 600
|
|
#define PLAYER_WIDTH 60
|
|
#define PLAYER_HEIGHT 20
|
|
#define ENEMY_WIDTH 40
|
|
#define ENEMY_HEIGHT 20
|
|
#define BULLET_WIDTH 5
|
|
#define BULLET_HEIGHT 10
|
|
|
|
// 游戏状态
|
|
int playerX = WINDOW_WIDTH / 2; // 玩家位置
|
|
int bulletX = -1, bulletY = -1; // 子弹位置,初始不可见
|
|
int enemyX, enemyY; // 敌机位置
|
|
int score = 0; // 得分
|
|
BOOL bulletVisible = FALSE;
|
|
|
|
// 初始化敌机位置
|
|
void InitEnemy() {
|
|
enemyX = rand() % (WINDOW_WIDTH - ENEMY_WIDTH);
|
|
enemyY = 0;
|
|
}
|
|
|
|
// 碰撞检测
|
|
BOOL CheckCollision() {
|
|
return bulletX >= enemyX && bulletX <= enemyX + ENEMY_WIDTH &&
|
|
bulletY >= enemyY && bulletY <= enemyY + ENEMY_HEIGHT;
|
|
}
|
|
|
|
// 绘制游戏内容
|
|
void DrawGame(HDC hdc) {
|
|
// 清空背景
|
|
RECT rect;
|
|
rect.left = 0;
|
|
rect.top = 0;
|
|
rect.right = WINDOW_WIDTH;
|
|
rect.bottom = WINDOW_HEIGHT;
|
|
FillRect(hdc, &rect, (HBRUSH)(COLOR_WINDOW + 1));
|
|
|
|
// 绘制玩家飞船
|
|
Rectangle(hdc, playerX, WINDOW_HEIGHT - PLAYER_HEIGHT - 10,
|
|
playerX + PLAYER_WIDTH, WINDOW_HEIGHT - 10);
|
|
|
|
// 绘制子弹
|
|
if (bulletVisible) {
|
|
Rectangle(hdc, bulletX, bulletY, bulletX + BULLET_WIDTH, bulletY + BULLET_HEIGHT);
|
|
}
|
|
|
|
// 绘制敌机
|
|
Rectangle(hdc, enemyX, enemyY, enemyX + ENEMY_WIDTH, enemyY + ENEMY_HEIGHT);
|
|
|
|
// 显示分数
|
|
char scoreText[32];
|
|
sprintf(scoreText, "Score: %d", score);
|
|
TextOut(hdc, 10, 10, scoreText, strlen(scoreText));
|
|
}
|
|
|
|
// 处理窗口消息
|
|
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
|
static HDC hdc;
|
|
static PAINTSTRUCT ps;
|
|
|
|
switch (uMsg) {
|
|
case WM_CREATE:
|
|
srand((unsigned int)time(NULL)); // 随机种子
|
|
InitEnemy();
|
|
SetTimer(hwnd, 1, 30, NULL); // 设置游戏刷新定时器
|
|
return 0;
|
|
|
|
case WM_TIMER:
|
|
// 更新子弹位置
|
|
if (bulletVisible) {
|
|
bulletY -= 10;
|
|
if (bulletY < 0) {
|
|
bulletVisible = FALSE;
|
|
}
|
|
}
|
|
|
|
// 更新敌机位置
|
|
enemyY += 5;
|
|
if (enemyY > WINDOW_HEIGHT) {
|
|
InitEnemy(); // 重新初始化敌机位置
|
|
}
|
|
|
|
// 检测碰撞
|
|
if (bulletVisible && CheckCollision()) {
|
|
score += 10;
|
|
bulletVisible = FALSE;
|
|
InitEnemy(); // 击中后重新生成敌机
|
|
}
|
|
|
|
InvalidateRect(hwnd, NULL, FALSE); // 触发重绘
|
|
return 0;
|
|
|
|
case WM_KEYDOWN:
|
|
// 控制玩家飞船移动
|
|
if (wParam == VK_LEFT && playerX > 0) {
|
|
playerX -= 10;
|
|
} else if (wParam == VK_RIGHT && playerX < WINDOW_WIDTH - PLAYER_WIDTH) {
|
|
playerX += 10;
|
|
} else if (wParam == VK_SPACE && !bulletVisible) {
|
|
// 发射子弹
|
|
bulletVisible = TRUE;
|
|
bulletX = playerX + PLAYER_WIDTH / 2;
|
|
bulletY = WINDOW_HEIGHT - PLAYER_HEIGHT - 20;
|
|
}
|
|
return 0;
|
|
|
|
case WM_PAINT:
|
|
hdc = BeginPaint(hwnd, &ps);
|
|
DrawGame(hdc);
|
|
EndPaint(hwnd, &ps);
|
|
return 0;
|
|
|
|
case WM_DESTROY:
|
|
PostQuitMessage(0);
|
|
return 0;
|
|
}
|
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
// WinMain 函数:程序的入口点
|
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
|
|
const char CLASS_NAME[] = "AirplaneGame";
|
|
|
|
// 注册窗口类
|
|
WNDCLASS wc = { };
|
|
wc.lpfnWndProc = WindowProc;
|
|
wc.hInstance = hInstance;
|
|
wc.lpszClassName = CLASS_NAME;
|
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
|
|
|
RegisterClass(&wc);
|
|
|
|
// 创建窗口
|
|
HWND hwnd = CreateWindowEx(
|
|
0,
|
|
CLASS_NAME,
|
|
"打飞机游戏",
|
|
WS_OVERLAPPEDWINDOW,
|
|
CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT,
|
|
NULL,
|
|
NULL,
|
|
hInstance,
|
|
NULL
|
|
);
|
|
|
|
if (hwnd == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
ShowWindow(hwnd, nCmdShow);
|
|
|
|
// 消息循环
|
|
MSG msg = { };
|
|
while (GetMessage(&msg, NULL, 0, 0)) {
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
return 0;
|
|
}
|