import $ from 'jquery'; import { Msg } from 'blockly/core'; import { PageBase, HTMLTemplate, StatusBarsManager, Workspace } from 'mixly'; import '../language/loader'; import STATUS_BAR_GAME_TEMPLATE from '../templates/html/statusbar-game.html'; export default class StatusBarGame extends PageBase { static { HTMLTemplate.add( 'html/statusbar/statusbar-game.html', new HTMLTemplate(STATUS_BAR_GAME_TEMPLATE) ); this.init = function () { StatusBarsManager.typesRegistry.register(['game'], StatusBarGame); const mainWorkspace = Workspace.getMain(); const statusBarsManager = mainWorkspace.getStatusBarsManager(); statusBarsManager.add({ type: 'game', id: 'game', name: Msg.PYTHON_PYODIDE_GAME, title: Msg.PYTHON_PYODIDE_GAME }); statusBarsManager.changeTo('output'); return statusBarsManager.get('game'); } } #$startBtn_ = null; #$pauseBtn_ = null; #$randomBtn_ = null; #$resetBtn_ = null; #$generation_ = null; #$grid_ = null; #GRID_SIZE_ = 10; #SPEED_ = 500; #grid_ = []; #isRunning_ = false; #generation_ = 0; #intervalId_ = null; constructor() { super(); const $content = $(HTMLTemplate.get('html/statusbar/statusbar-game.html').render({ epoch: Msg.PYTHON_PYODIDE_GAME_EPOCH, start: Msg.PYTHON_PYODIDE_GAME_START, pause: Msg.PYTHON_PYODIDE_GAME_PAUSE, random: Msg.PYTHON_PYODIDE_GAME_RANDOM, reset: Msg.PYTHON_PYODIDE_GAME_RESET })); this.setContent($content); this.#$startBtn_ = $content.find('.start-btn'); this.#$pauseBtn_ = $content.find('.pause-btn'); this.#$randomBtn_ = $content.find('.random-btn'); this.#$resetBtn_ = $content.find('.reset-btn'); this.#$generation_ = $content.find('.generation'); this.#$grid_ = $content.find('.grid'); this.#addEventListeners_(); } #addEventListeners_() { this.#$startBtn_.click(() => this.startGame()); this.#$pauseBtn_.click(() => this.pauseGame()); this.#$randomBtn_.click(() => this.randomInitialize()); this.#$resetBtn_.click(() => this.resetGame()); } // 初始化网格 initializeGrid() { this.#$grid_.empty(); this.#grid_ = []; for (let i = 0; i < this.#GRID_SIZE_; i++) { this.#grid_[i] = []; for (let j = 0; j < this.#GRID_SIZE_; j++) { this.#grid_[i][j] = 0; // 0表示死亡,1表示存活 const cell = document.createElement('div'); cell.className = 'cell'; cell.dataset.row = i; cell.dataset.col = j; cell.addEventListener('click', () => this.toggleCell(i, j)); this.#$grid_.append(cell); } } this.updateGridDisplay(); } // 切换细胞状态 toggleCell(row, col) { if (!this.#isRunning_) { this.#grid_[row][col] = this.#grid_[row][col] === 0 ? 1 : 0; this.updateGridDisplay(); } } // 更新网格显示 updateGridDisplay() { const $cells = this.#$grid_.children('.cell'); for (let i = 0; i < $cells.length; i++) { const cell = $cells[i]; const row = parseInt(cell.dataset.row); const col = parseInt(cell.dataset.col); if (this.#grid_[row][col] === 1) { cell.classList.add('alive'); } else { cell.classList.remove('alive'); } } } // 计算下一代 nextGeneration() { const newGrid = []; for (let i = 0; i < this.#GRID_SIZE_; i++) { newGrid[i] = []; for (let j = 0; j < this.#GRID_SIZE_; j++) { const neighbors = this.countNeighbors(i, j); if (this.#grid_[i][j] === 1) { // 存活细胞:周围有2-3个存活细胞则继续存活 newGrid[i][j] = (neighbors === 2 || neighbors === 3) ? 1 : 0; } else { // 死亡细胞:周围有3个存活细胞则复活 newGrid[i][j] = neighbors === 3 ? 1 : 0; } } } this.#grid_ = newGrid; this.#generation_++; this.#$generation_.text(this.#generation_); this.updateGridDisplay(); } // 计算周围存活细胞数量 countNeighbors(row, col) { let count = 0; for (let i = -1; i <= 1; i++) { for (let j = -1; j <= 1; j++) { if (i === 0 && j === 0) continue; // 跳过自身 const newRow = row + i; const newCol = col + j; // 检查边界 if (newRow >= 0 && newRow < this.#GRID_SIZE_ && newCol >= 0 && newCol < this.#GRID_SIZE_) { count += this.#grid_[newRow][newCol]; } } } return count; } // 开始游戏 startGame() { if (!this.#isRunning_) { this.#isRunning_ = true; this.#generation_ = 0; this.#$generation_.text(this.#generation_); this.#intervalId_ = setInterval(() => this.nextGeneration(), this.#SPEED_); this.updateButtons(); } } // 暂停游戏 pauseGame() { if (this.#isRunning_) { this.#isRunning_ = false; clearInterval(this.#intervalId_); this.updateButtons(); } } // 随机初始化网格 randomInitialize() { if (!this.#isRunning_) { for (let i = 0; i < this.#GRID_SIZE_; i++) { for (let j = 0; j < this.#GRID_SIZE_; j++) { // 25%的概率生成存活细胞 this.#grid_[i][j] = Math.random() < 0.25 ? 1 : 0; } } this.updateGridDisplay(); } } // 重置游戏 resetGame() { this.#isRunning_ = false; clearInterval(this.#intervalId_); this.#generation_ = 0; this.#$generation_.text(this.#generation_); this.initializeGrid(); this.updateButtons(); } // 更新按钮状态 updateButtons() { this.#$startBtn_.attr('disabled', this.#isRunning_); this.#$pauseBtn_.attr('disabled', !this.#isRunning_); this.#$randomBtn_.attr('disabled', this.#isRunning_); this.#$resetBtn_.attr('disabled', false); } init() { super.init(); this.hideCloseBtn(); this.initializeGrid(); this.updateButtons(); } onMounted() { } onUnmounted() { } resize() { } }