Files
mixly3/boards/default_src/python_pyodide/others/statusbar-game.js

227 lines
6.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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() { }
}