TypePHP 编译器 https://swoole.com/aot/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

234 lines
6.3 KiB

<?php
/**
* Tetris Game - Main Logic in PHP
* Using C++ API for graphics and game state management
*/
// Windows 常量定义
const SW_SHOW = 5;
const MB_OK = 0x00000000;
const VK_LEFT = 0x25;
const VK_RIGHT = 0x27;
const VK_UP = 0x26;
const VK_DOWN = 0x28;
const VK_SPACE = 0x20;
const WM_KEYDOWN = 0x0100;
const WM_PAINT = 0x000F;
function GetMessage(array &$lpMsg, int $hWnd, int $wMsgFilterMin, int $wMsgFilterMax): int {}
function TranslateMessage(array $lpMsg): int {}
function DispatchMessage(array $lpMsg): int {}
function PeekMessage(array &$lpMsg, int $hWnd, int $wMsgFilterMin, int $wMsgFilterMax, int $wRemoveMsg): int {}
function GetTickCount(): int {}
/**
* 俄罗斯方块游戏主类
*/
class TetrisGame
{
private mixed $game;
private int $hWnd;
private int $lastDropTime;
private int $dropInterval;
public function __construct()
{
// 创建游戏实例(C++ Box 对象)
echo "正在创建游戏实例...\n";
$this->game = tetris_new();
echo "游戏实例已创建,类型: " . gettype($this->game) . "\n";
if (!is_resource($this->game) && !is_object($this->game)) {
echo "警告:game 不是有效的资源或对象类型\n";
}
$this->hWnd = 0;
$this->lastDropTime = 0;
$this->dropInterval = 500; // 初始下落间隔(毫秒)
}
/**
* 初始化游戏窗口
*/
public function initWindow(): void
{
echo "正在创建窗口...\n";
$this->hWnd = tetris_create_window("俄罗斯方块 - PHP版");
echo "窗口句柄: {$this->hWnd}\n";
if ($this->hWnd == 0) {
echo "错误:窗口创建失败!\n";
return;
}
tetris_show_window($this->hWnd, SW_SHOW);
echo "游戏窗口已创建\n";
echo "控制说明:\n";
echo " ← → : 左右移动\n";
echo " ↑ : 旋转方块\n";
echo " ↓ : 加速下落\n";
echo " 空格 : 直接落下\n";
echo "\n";
}
/**
* 游戏主循环
*/
public function run(): void
{
$msg = [];
$running = true;
echo "游戏开始!\n";
while ($running) {
// 处理 Windows 消息
while (PeekMessage($msg, $this->hWnd, 0, 0, 1)) {
if (!isset($msg['message'])) {
continue;
}
$messageType = $msg['message'];
if ($messageType == WM_KEYDOWN) {
$keyCode = isset($msg['wParam']) ? $msg['wParam'] : 0;
$this->handleKeyPress($keyCode);
}
// 检查是否收到退出消息
if ($messageType == 0x0012) { // WM_QUIT
$running = false;
break;
}
}
if (!$running) {
break;
}
// 自动下落逻辑
$currentTime = GetTickCount();
if ($currentTime - $this->lastDropTime > $this->dropInterval) {
if (!tetris_is_game_over($this->game)) {
tetris_move_down($this->game);
// 根据分数调整速度
$score = tetris_get_score($this->game);
$this->dropInterval = max(100, 500 - intdiv($score, 500) * 50);
}
$this->lastDropTime = $currentTime;
}
// 渲染游戏画面
tetris_render($this->game, $this->hWnd);
// 检查游戏结束
if (tetris_is_game_over($this->game)) {
$this->handleGameOver();
break;
}
// 控制帧率
usleep(16000); // 约 60 FPS (16ms = 16000us)
}
}
/**
* 处理键盘输入
*/
private function handleKeyPress(int $keyCode): void
{
switch ($keyCode) {
case VK_LEFT:
tetris_move_left($this->game);
break;
case VK_RIGHT:
tetris_move_right($this->game);
break;
case VK_UP:
tetris_rotate($this->game);
break;
case VK_DOWN:
tetris_move_down($this->game);
break;
case VK_SPACE:
tetris_hard_drop($this->game);
break;
}
}
/**
* 处理游戏结束
*/
private function handleGameOver(): void
{
$score = tetris_get_score($this->game);
$message = "游戏结束!\n\n最终得分: {$score}\n\n是否重新开始?";
$result = tetris_messagebox(
$this->hWnd,
$message,
"游戏结束",
MB_OK
);
if ($result == 1) { // IDOK
// 重新开始游戏
tetris_reset($this->game);
$this->lastDropTime = GetTickCount();
$this->dropInterval = 500;
echo "游戏重新开始\n";
} else {
echo "游戏退出\n";
tetris_post_quit(0);
}
}
/**
* 获取当前游戏状态
*/
public function getStatus(): array
{
return [
'score' => tetris_get_score($this->game),
'gameOver' => tetris_is_game_over($this->game),
'board' => tetris_get_board($this->game),
'currentPiece' => tetris_get_current_piece($this->game),
];
}
}
/**
* 主函数
*/
function main(): void
{
// 设置时区
date_default_timezone_set('Asia/Shanghai');
// 设置控制台编码为 UTF-8(Windows)
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
exec('chcp 65001 > nul');
}
echo "========================================\n";
echo " 俄罗斯方块 - PHP 编译器演示\n";
echo "========================================\n\n";
// 创建并运行游戏
$game = new TetrisGame();
$game->initWindow();
$game->run();
echo "\n感谢游玩!\n";
}