Files
wehub-resource-sync 426e9eeabd
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Waiting to run
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Waiting to run
Build Agent Image / build-and-push (push) Waiting to run
Chat shell gestures / Chat shell gesture + parity e2e (push) Waiting to run
Cloud Gateway Discord / Test (push) Waiting to run
Cloud Gateway Webhook / Test (push) Waiting to run
Cloud Tests / lint-and-types (push) Waiting to run
Cloud Tests / unit-tests (push) Waiting to run
Cloud Tests / integration-tests (push) Waiting to run
Cloud Tests / e2e-tests (push) Blocked by required conditions
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Apps Worker (Product 2) / Determine environment (push) Waiting to run
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Blocked by required conditions
Deploy Eliza Provisioning Worker / Determine environment (push) Waiting to run
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Blocked by required conditions
Dev Smoke / Classify changed paths (push) Waiting to run
Dev Smoke / bun run dev onboarding chat (push) Blocked by required conditions
Dev Smoke / Vite HMR dependency-level smoke (push) Blocked by required conditions
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Waiting to run
Publish @elizaos/example-code / check_npm (push) Waiting to run
Publish @elizaos/example-code / publish_npm (push) Blocked by required conditions
Publish @elizaos/plugin-elizacloud / verify_version (push) Waiting to run
Publish @elizaos/plugin-elizacloud / publish_npm (push) Blocked by required conditions
Sandbox Live Smoke / Sandbox live smoke (push) Waiting to run
Snap Build & Test / Build Snap (amd64) (push) Waiting to run
Snap Build & Test / Build Snap (arm64) (push) Waiting to run
supply-chain / sbom (push) Waiting to run
supply-chain / vulnerability-scan (push) Waiting to run
Build, Push & Deploy to Phala Cloud / build-and-push (push) Waiting to run
Test Packaging / Validate Packaging Configs (push) Waiting to run
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Waiting to run
Test Packaging / Pack & Test JS Tarballs (push) Waiting to run
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Waiting to run
UI Fixture E2E / ui-fixture-e2e (push) Waiting to run
UI Fixture E2E / fixture-e2e (push) Waiting to run
UI Story Gate / story-gate (push) Waiting to run
vault-ci / test (macos-latest) (push) Waiting to run
vault-ci / test (ubuntu-latest) (push) Waiting to run
vault-ci / test (windows-latest) (push) Waiting to run
vault-ci / app-core wiring tests (push) Waiting to run
verify-patches / verify patches/CHECKSUMS.sha256 (push) Waiting to run
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Waiting to run
Voice Benchmark Smoke / voice bench smoke summary (push) Blocked by required conditions
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Waiting to run
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Waiting to run
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Waiting to run
Test Packaging / Build & Test PyPI Package (push) Waiting to run
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:43:05 +08:00

479 lines
14 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tetris Game</title>
<style>
body {
margin: 0;
padding: 0;
background: linear-gradient(135deg, #1e3c72, #2a5298);
font-family: 'Arial', sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
color: white;
}
.game-container {
display: flex;
gap: 20px;
align-items: flex-start;
}
.game-board {
border: 3px solid #fff;
background: #000;
box-shadow: 0 0 20px rgba(255, 255, 255, 0.3);
}
.info-panel {
background: rgba(255, 255, 255, 0.1);
padding: 20px;
border-radius: 10px;
backdrop-filter: blur(10px);
min-width: 200px;
}
.score {
font-size: 18px;
margin-bottom: 10px;
}
.next-piece {
margin-top: 20px;
}
.next-piece canvas {
border: 2px solid #fff;
background: #000;
}
.controls {
margin-top: 20px;
font-size: 14px;
line-height: 1.6;
}
.game-over {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.9);
padding: 30px;
border-radius: 10px;
text-align: center;
display: none;
}
.game-over button {
background: #4CAF50;
color: white;
border: none;
padding: 10px 20px;
font-size: 16px;
border-radius: 5px;
cursor: pointer;
margin-top: 15px;
}
.game-over button:hover {
background: #45a049;
}
</style>
</head>
<body>
<div class="game-container">
<canvas id="gameCanvas" class="game-board" width="300" height="600"></canvas>
<div class="info-panel">
<div class="score">Score: <span id="score">0</span></div>
<div class="score">Lines: <span id="lines">0</span></div>
<div class="score">Level: <span id="level">1</span></div>
<div class="next-piece">
<h3>Next:</h3>
<canvas id="nextCanvas" width="120" height="120"></canvas>
</div>
<div class="controls">
<h3>Controls:</h3>
<div>← → Move</div>
<div>↓ Soft Drop</div>
<div>↑ Rotate</div>
<div>Space Hard Drop</div>
<div>P Pause</div>
</div>
</div>
</div>
<div id="gameOver" class="game-over">
<h2>Game Over!</h2>
<div>Final Score: <span id="finalScore">0</span></div>
<button onclick="restartGame()" type="button">Play Again</button>
</div>
<script>
// Game constants
const BOARD_WIDTH = 10;
const BOARD_HEIGHT = 20;
const BLOCK_SIZE = 30;
// Game state
let board = [];
let currentPiece = null;
let nextPiece = null;
let score = 0;
let lines = 0;
let level = 1;
let dropTime = 0;
let dropInterval = 1000;
let gameRunning = true;
let paused = false;
// Canvas setup
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const nextCanvas = document.getElementById('nextCanvas');
const nextCtx = nextCanvas.getContext('2d');
// Tetris pieces (tetrominoes)
const PIECES = [
// I-piece
{
shape: [
[1, 1, 1, 1]
],
color: '#00f5ff'
},
// O-piece
{
shape: [
[1, 1],
[1, 1]
],
color: '#ffff00'
},
// T-piece
{
shape: [
[0, 1, 0],
[1, 1, 1]
],
color: '#a000f0'
},
// S-piece
{
shape: [
[0, 1, 1],
[1, 1, 0]
],
color: '#00f000'
},
// Z-piece
{
shape: [
[1, 1, 0],
[0, 1, 1]
],
color: '#f00000'
},
// J-piece
{
shape: [
[1, 0, 0],
[1, 1, 1]
],
color: '#0000f0'
},
// L-piece
{
shape: [
[0, 0, 1],
[1, 1, 1]
],
color: '#f0a000'
}
];
// Initialize game board
function initBoard() {
board = Array(BOARD_HEIGHT).fill().map(() => Array(BOARD_WIDTH).fill(0));
}
// Create a new piece
function createPiece() {
const pieceType = Math.floor(Math.random() * PIECES.length);
const piece = JSON.parse(JSON.stringify(PIECES[pieceType]));
piece.x = Math.floor(BOARD_WIDTH / 2) - Math.floor(piece.shape[0].length / 2);
piece.y = 0;
return piece;
}
// Check if piece can be placed at position
function isValidPosition(piece, dx = 0, dy = 0, rotation = null) {
const shape = rotation || piece.shape;
const newX = piece.x + dx;
const newY = piece.y + dy;
for (let y = 0; y < shape.length; y++) {
for (let x = 0; x < shape[y].length; x++) {
if (shape[y][x]) {
const boardX = newX + x;
const boardY = newY + y;
if (boardX < 0 || boardX >= BOARD_WIDTH ||
boardY >= BOARD_HEIGHT ||
(boardY >= 0 && board[boardY][boardX])) {
return false;
}
}
}
}
return true;
}
// Rotate piece 90 degrees clockwise
function rotatePiece(piece) {
const rotated = [];
const rows = piece.shape.length;
const cols = piece.shape[0].length;
for (let i = 0; i < cols; i++) {
rotated[i] = [];
for (let j = 0; j < rows; j++) {
rotated[i][j] = piece.shape[rows - 1 - j][i];
}
}
return rotated;
}
// Place piece on board
function placePiece(piece) {
for (let y = 0; y < piece.shape.length; y++) {
for (let x = 0; x < piece.shape[y].length; x++) {
if (piece.shape[y][x]) {
const boardY = piece.y + y;
const boardX = piece.x + x;
if (boardY >= 0) {
board[boardY][boardX] = piece.color;
}
}
}
}
}
// Clear completed lines
function clearLines() {
let linesCleared = 0;
for (let y = BOARD_HEIGHT - 1; y >= 0; y--) {
if (board[y].every(cell => cell !== 0)) {
board.splice(y, 1);
board.unshift(Array(BOARD_WIDTH).fill(0));
linesCleared++;
y++; // Check the same line again
}
}
if (linesCleared > 0) {
lines += linesCleared;
score += linesCleared * 100 * level;
level = Math.floor(lines / 10) + 1;
dropInterval = Math.max(50, 1000 - (level - 1) * 50);
updateUI();
}
}
// Move piece down
function dropPiece() {
if (isValidPosition(currentPiece, 0, 1)) {
currentPiece.y++;
} else {
placePiece(currentPiece);
clearLines();
currentPiece = nextPiece;
nextPiece = createPiece();
if (!isValidPosition(currentPiece)) {
gameOver();
}
}
}
// Hard drop piece
function hardDrop() {
while (isValidPosition(currentPiece, 0, 1)) {
currentPiece.y++;
score += 2;
}
dropPiece();
updateUI();
}
// Draw a block
function drawBlock(ctx, x, y, color) {
ctx.fillStyle = color;
ctx.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
ctx.strokeStyle = '#333';
ctx.lineWidth = 1;
ctx.strokeRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
}
// Draw the game board
function drawBoard() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw placed pieces
for (let y = 0; y < BOARD_HEIGHT; y++) {
for (let x = 0; x < BOARD_WIDTH; x++) {
if (board[y][x]) {
drawBlock(ctx, x, y, board[y][x]);
}
}
}
// Draw current piece
if (currentPiece) {
for (let y = 0; y < currentPiece.shape.length; y++) {
for (let x = 0; x < currentPiece.shape[y].length; x++) {
if (currentPiece.shape[y][x]) {
drawBlock(ctx, currentPiece.x + x, currentPiece.y + y, currentPiece.color);
}
}
}
}
}
// Draw next piece
function drawNextPiece() {
nextCtx.clearRect(0, 0, nextCanvas.width, nextCanvas.height);
if (nextPiece) {
const offsetX = (4 - nextPiece.shape[0].length) / 2;
const offsetY = (4 - nextPiece.shape.length) / 2;
for (let y = 0; y < nextPiece.shape.length; y++) {
for (let x = 0; x < nextPiece.shape[y].length; x++) {
if (nextPiece.shape[y][x]) {
nextCtx.fillStyle = nextPiece.color;
nextCtx.fillRect(
(offsetX + x) * 30,
(offsetY + y) * 30,
30, 30
);
nextCtx.strokeStyle = '#333';
nextCtx.strokeRect(
(offsetX + x) * 30,
(offsetY + y) * 30,
30, 30
);
}
}
}
}
}
// Update UI elements
function updateUI() {
document.getElementById('score').textContent = score;
document.getElementById('lines').textContent = lines;
document.getElementById('level').textContent = level;
}
// Game over
function gameOver() {
gameRunning = false;
document.getElementById('finalScore').textContent = score;
document.getElementById('gameOver').style.display = 'block';
}
// Restart game
function _restartGame() {
initBoard();
currentPiece = createPiece();
nextPiece = createPiece();
score = 0;
lines = 0;
level = 1;
dropTime = 0;
dropInterval = 1000;
gameRunning = true;
paused = false;
document.getElementById('gameOver').style.display = 'none';
updateUI();
}
// Handle keyboard input
document.addEventListener('keydown', (e) => {
if (!gameRunning || paused) {
if (e.code === 'KeyP') {
paused = !paused;
}
return;
}
switch (e.code) {
case 'ArrowLeft':
if (isValidPosition(currentPiece, -1, 0)) {
currentPiece.x--;
}
break;
case 'ArrowRight':
if (isValidPosition(currentPiece, 1, 0)) {
currentPiece.x++;
}
break;
case 'ArrowDown':
dropPiece();
score += 1;
updateUI();
break;
case 'ArrowUp': {
const rotated = rotatePiece(currentPiece);
if (isValidPosition(currentPiece, 0, 0, rotated)) {
currentPiece.shape = rotated;
}
break;
}
case 'Space':
e.preventDefault();
hardDrop();
break;
case 'KeyP':
paused = !paused;
break;
}
});
// Game loop
function gameLoop(timestamp) {
if (gameRunning && !paused) {
if (timestamp - dropTime > dropInterval) {
dropPiece();
dropTime = timestamp;
}
drawBoard();
drawNextPiece();
}
requestAnimationFrame(gameLoop);
}
// Initialize game
function init() {
initBoard();
currentPiece = createPiece();
nextPiece = createPiece();
updateUI();
requestAnimationFrame(gameLoop);
}
// Start the game
init();
</script>
</body>
</html>