<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, viewport-fit=cover">
<title>董测浩解救许子昂二代 - 超级马里奥风格</title>
<style>
* {
user-select: none;
-webkit-tap-highlight-color: transparent;
}
body {
background: linear-gradient(145deg, #0a2f3a 0%, #0a1f2a 100%);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
font-family: 'Courier New', 'Press Start 2P', 'VT323', monospace;
margin: 0;
padding: 20px;
}
/* 游戏主容器 */
.game-container {
background: #000;
border-radius: 32px;
box-shadow: 0 20px 35px rgba(0,0,0,0.5), inset 0 1px 4px rgba(255,255,255,0.2);
padding: 12px;
}
canvas {
display: block;
margin: 0 auto;
border-radius: 20px;
box-shadow: 0 0 0 4px #f3b33d, 0 0 0 8px #d48d2b;
cursor: pointer;
}
/* UI 面板 */
.game-ui {
margin-top: 16px;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 12px;
background: #2b1e0fcc;
backdrop-filter: blur(10px);
padding: 8px 18px;
border-radius: 60px;
color: #f7e05e;
text-shadow: 2px 2px 0 #7a3e0a;
font-weight: bold;
}
.stats {
display: flex;
gap: 24px;
background: #1f1306;
padding: 6px 20px;
border-radius: 40px;
font-size: 1.1rem;
}
.skills {
display: flex;
gap: 20px;
}
.skill-btn {
background: #3c2a1f;
border: 2px solid #e0b03b;
padding: 6px 15px;
border-radius: 30px;
color: #ffdd99;
font-weight: bold;
cursor: pointer;
transition: 0.1s linear;
box-shadow: 0 3px 0 #6b3f00;
font-family: monospace;
}
.skill-btn:active {
transform: translateY(2px);
box-shadow: none;
}
.skill-cd {
font-size: 0.7rem;
margin-left: 6px;
background: #000000aa;
padding: 2px 6px;
border-radius: 20px;
}
button {
background: #e09d32;
border: none;
font-family: monospace;
font-weight: bold;
padding: 6px 14px;
border-radius: 30px;
cursor: pointer;
transition: 0.1s;
color: #2c1a07;
box-shadow: 0 2px 0 #714a19;
}
button:active {
transform: translateY(2px);
box-shadow: none;
}
.modal {
display: none;
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0,0,0,0.8);
justify-content: center;
align-items: center;
z-index: 1000;
font-family: monospace;
}
.modal-content {
background: #fef0cf;
border-radius: 48px;
padding: 24px;
width: 280px;
text-align: center;
border: 6px solid #ffb347;
box-shadow: 0 10px 25px black;
}
.modal-content input {
margin: 10px 0;
padding: 8px;
width: 80%;
font-size: 1rem;
}
.close {
margin-top: 16px;
background: #c97e2a;
padding: 6px 12px;
border-radius: 30px;
cursor: pointer;
}
.dev-info {
font-size: 0.8rem;
text-align: left;
background: #2e241a;
padding: 12px;
border-radius: 20px;
color: #f3c26b;
}
.touch-controls {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 20px;
flex-wrap: wrap;
}
.touch-btn {
background: #000000aa;
backdrop-filter: blur(8px);
border: 2px solid gold;
color: gold;
font-size: 1.8rem;
width: 70px;
padding: 10px 0;
text-align: center;
border-radius: 60px;
font-weight: bold;
cursor: pointer;
}
@media (max-width: 800px) {
.stats { font-size: 0.8rem; gap: 12px; }
.skill-btn { padding: 4px 10px; font-size: 0.8rem;}
}
</style>
</head>
<body>
<div>
<div class="game-container">
<canvas id="gameCanvas" width="1000" height="560"></canvas>
<div class="game-ui">
<div class="stats">
<span>❤️ 血量: <span id="hpVal">5</span></span>
<span>🔫 子弹: ∞</span>
<span>🛡️ 护盾: <span id="shieldStatus">待机</span></span>
<span>🏆 关卡: <span id="levelIdx">1</span>/5</span>
</div>
<div class="skills">
<div class="skill-btn" id="skillShield">🛡️ 护盾 (<span id="shieldCdText">0</span>s)</div>
<div class="skill-btn" id="skillHeal">💚 超级回血 (<span id="healCdText">0</span>s)</div>
</div>
<button id="settingsBtn">⚙️ 设置</button>
<button id="devBtn">👾 开发者</button>
<button id="cheatBtn">🎮 内测外挂</button>
</div>
<div class="touch-controls" id="touchControls">
<div class="touch-btn" data-action="left">◀</div>
<div class="touch-btn" data-action="right">▶</div>
<div class="touch-btn" data-action="jump">⭐ 跳</div>
<div class="touch-btn" data-action="shoot">🔫 射击</div>
<div class="touch-btn" data-action="shield">🛡️ 盾</div>
<div class="touch-btn" data-action="heal">💚 回血</div>
</div>
</div>
<!-- 模态框 -->
<div id="settingsModal" class="modal">
<div class="modal-content"><h3>⚙️ 帧率设置</h3>
<button id="fps30">30 FPS</button> <button id="fps60">60 FPS</button>
<div class="close" onclick="closeModal('settingsModal')">关闭</div>
</div>
</div>
<div id="devModal" class="modal">
<div class="modal-content"><h3>👨💻 开发者</h3>
<div class="dev-info">👤 XLANGJISHI<br>📞 18762997233<br>💬 感谢你使用本游戏,本游戏在上代基础上继续增强,UI更加精致细腻,游戏中所出现的人物名称均为现实人物,已获得授权使用,基于DeepSeek,ChatGPT完成制作,建议请联系 one more。</div>
<div class="close" onclick="closeModal('devModal')">关闭</div>
</div>
</div>
<div id="cheatModal" class="modal">
<div class="modal-content"><h3>🔓 内测外挂验证</h3>
<input type="password" id="cheatPassword" placeholder="输入密码"><br>
<button id="unlockCheat">解锁</button>
<div id="cheatPanel" style="display:none; margin-top:15px;">
<label>🏃 人物速度: <input type="range" id="speedSlider" min="1.5" max="8" step="0.2" value="3.5"></label><br>
<label>✨ 无敌模式: <input type="checkbox" id="invincibleToggle"></label><br>
<label>🎚️ 选择关卡: <select id="levelSelect"><option>1</option><option>2</option><option>3</option><option>4</option><option>5</option><option>6(BOSS)</option></select><button id="applyLevel">跳关</button></label><br>
<label>⚡ 技能无CD: <input type="checkbox" id="noCdToggle"></label><br>
<label>💀 BOSS血量: <input type="range" id="bossHpSlider" min="5" max="50" value="25"> <span id="bossHpVal">25</span></label>
<div class="close" onclick="closeModal('cheatModal')">退出外挂面板</div>
</div>
</div>
</div>
<div id="storyModal" class="modal" style="display:flex;">
<div class="modal-content" style="width:340px;">
<h2>📖 序章</h2>
<p id="storyText">董测浩:喂,哪位给我打电话?<br>金文祥:就你就是许子昂的大哥是吧!我告诉你,勋章在我手中一个大鸡巴头子有本事就来找我!<br>董测浩:我操你妈看我找到你不给你打死!<br>金文祥:我就告你啊!<br>董测浩踏上了解救朋友许子昂之路...</p>
<button id="startGameBtn">🚀 开始冒险</button>
</div>
</div>
</div>
<script>
(function(){
// ---------- CANVAS ----------
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// 游戏全局状态
let gameRunning = false;
let currentLevel = 1; // 1-5普通,6为BOSS关
let levelsCompleted = 0;
let player = {
x: 80, y: 400, width: 32, height: 32, vx: 0, vy: 0, facingRight: true,
hp: 5, maxHp: 8, invincibleTimer: 0, shieldActive: false, baseSpeed: 3.5,
jumpPower: -9, grounded: false, canDoubleJump: false
};
let bullets = [];
let enemies = [];
let platforms = [];
let boss = null;
let cameraX = 0;
let score = 0;
// 技能
let shieldCd = 0, healCd = 0;
let lastShieldUse = -10, lastHealUse = -25;
// 彩蛋力量
let powerUpMode = false; // 大迫杰力量
let autoShoot = false;
let shootCooldown = 0;
let jumpPressCount = 0;
let lastJumpFrame = 0;
// 内测外挂开关
let cheatActive = false;
let cheatInvincible = false;
let cheatNoCd = false;
let cheatSpeedMul = 1.0;
let cheatBossHpBase = 25;
// 帧率控制
let targetFps = 60;
let lastTimestamp = 0;
let frameInterval = 1000/60;
let animationId = null;
// 键盘控制
const keys = { left: false, right: false, jump: false, shoot: false };
let jumpPressed = false;
let canJump = true;
// UI元素绑定
const hpSpan = document.getElementById('hpVal');
const shieldStatusSpan = document.getElementById('shieldStatus');
const levelIdxSpan = document.getElementById('levelIdx');
const shieldCdSpan = document.getElementById('shieldCdText');
const healCdSpan = document.getElementById('healCdText');
// 初始化默认平台(基础世界)
function buildLevel(level) {
platforms = [];
enemies = [];
boss = null;
// 基础地面
platforms.push({x:0, y:540, w:2000, h:20});
platforms.push({x:0, y:300, w:100, h:20});
platforms.push({x:250, y:420, w:120, h:20});
platforms.push({x:500, y:350, w:100, h:20});
platforms.push({x:750, y:280, w:80, h:20});
platforms.push({x:900, y:450, w:120, h:20});
if(level === 2){
platforms.push({x:150, y:200, w:80, h:20});
enemies.push({x:400, y:500, type:'goomba', hp:2, w:28, h:28, vx:-0.8});
enemies.push({x:700, y:250, type:'goomba', hp:2, w:28, h:28, vx:0.6});
} else if(level === 3){
enemies.push({x:300, y:500, type:'goomba', hp:2, vx:-1});
enemies.push({x:550, y:310, type:'goomba', hp:2, vx:0.9});
enemies.push({x:800, y:450, type:'goomba', hp:3, vx:-0.7});
} else if(level === 4){
enemies.push({x:200, y:490, type:'goomba', hp:3, vx:1});
enemies.push({x:600, y:330, type:'goomba', hp:3, vx:-1.2});
enemies.push({x:850, y:270, type:'goomba', hp:2, vx:0.8});
} else if(level === 5){
enemies.push({x:350, y:500, type:'goomba', hp:4, vx:1});
enemies.push({x:680, y:400, type:'goomba', hp:3, vx:-1});
enemies.push({x:950, y:280, type:'goomba', hp:3, vx:0.9});
} else if(level === 6){
// BOSS 关卡
platforms.push({x:400, y:480, w:300, h:20});
boss = { x: 650, y: 440, w: 58, h: 58, hp: cheatActive ? cheatBossHpBase : 25, maxHp: 25, type: 'jinwenxiang', attackTimer: 0, vx: 1.2 };
enemies = [];
}
// 增加通用敌人普通
if(level !==6 && level>1) for(let i=0;i<2;i++) enemies.push({x:100+Math.random()*800, y:500, type:'goomba', hp:2, w:28, h:28, vx:(Math.random()>0.5?0.7:-0.7)});
// 过关旗杆位置 (粗略)
}
function resetPlayerForLevel(){
player.x = 70;
player.y = 400;
player.vx = 0;
player.vy = 0;
player.hp = Math.min(player.maxHp, player.hp>0?player.hp:5);
player.invincibleTimer = 0;
player.shieldActive = false;
updateUI();
}
function updateUI(){
hpSpan.innerText = player.hp;
levelIdxSpan.innerText = (currentLevel===6?"BOSS":currentLevel);
let shieldTxt = player.shieldActive?"🛡️激活":"待机";
shieldStatusSpan.innerText = shieldTxt;
let shieldRem = Math.max(0, 10 - (Date.now()/1000 - lastShieldUse));
let healRem = Math.max(0, 25 - (Date.now()/1000 - lastHealUse));
if(cheatActive && cheatNoCd) { shieldCdSpan.innerText = "0"; healCdSpan.innerText = "0"; }
else { shieldCdSpan.innerText = Math.ceil(shieldRem); healCdSpan.innerText = Math.ceil(healRem); }
}
function useShield(){
if(cheatActive && cheatNoCd){ player.shieldActive = true; updateUI(); return; }
let now = Date.now()/1000;
if(now - lastShieldUse >= 10){
player.shieldActive = true;
lastShieldUse = now;
updateUI();
} else alert("护盾CD中");
}
function useHeal(){
if(cheatActive && cheatNoCd){ player.hp = player.maxHp; updateUI(); return; }
let now = Date.now()/1000;
if(now - lastHealUse >= 25){
player.hp = Math.min(player.maxHp, player.hp+4);
lastHealUse = now;
updateUI();
} else alert("回血CD中");
}
// 碰撞与物理
function applyPhysics(){
let speed = (powerUpMode?player.baseSpeed*1.7:player.baseSpeed) * (cheatActive?cheatSpeedMul:1);
if(keys.left) { player.vx = -speed; player.facingRight=false; }
if(keys.right) { player.vx = speed; player.facingRight=true; }
player.vx *= 0.92;
player.vy += 0.5;
player.y += player.vy;
player.x += player.vx;
// 平台碰撞
player.grounded = false;
for(let plat of platforms){
if(player.vy >=0 && player.y+player.height <= plat.y+15 && player.y+player.height+player.vy >= plat.y && player.x+player.width>plat.x && player.x<plat.x+plat.w){
player.y = plat.y - player.height;
player.vy = 0;
player.grounded = true;
canJump = true;
}
if(player.x+player.width>plat.x && player.x<plat.x+plat.w && player.y<plat.y+plat.h && player.y+player.height>plat.y){
// 水平推动
}
}
if(player.x<0) player.x=0;
if(player.x+player.width>2000) player.x=2000-player.width;
if(player.y>600) { player.hp=0; updateUI(); }
cameraX = Math.min(Math.max(0, player.x - canvas.width/2), 1200);
}
function shootBullet(){
if(powerUpMode && autoShoot){
if(shootCooldown<=0){
bullets.push({x:player.x+(player.facingRight?30:-10), y:player.y+12, vx:player.facingRight?12:-12, vy:0, life:true});
shootCooldown = 5;
}
} else if(!powerUpMode && shootCooldown<=0){
bullets.push({x:player.x+(player.facingRight?30:-10), y:player.y+12, vx:player.facingRight?10:-10, vy:0, life:true});
shootCooldown = 12;
}
}
function updateBullets(){
if(shootCooldown>0) shootCooldown--;
for(let i=0;i<bullets.length;i++){
bullets[i].x+=bullets[i].vx;
if(bullets[i].x>canvas.width+cameraX+100 || bullets[i].x<-100) bullets.splice(i,1);
else {
let hit = false;
for(let j=0;j<enemies.length;j++){
let e=enemies[j];
if(bullets[i].x+8>e.x && bullets[i].x<e.x+e.w && bullets[i].y+4>e.y && bullets[i].y<e.y+e.h){
e.hp-=2;
bullets.splice(i,1);
hit=true;
if(e.hp<=0) enemies.splice(j,1);
break;
}
}
if(!hit && boss && bullets[i] && bullets[i].x+8>boss.x && bullets[i].x<boss.x+boss.w && bullets[i].y+8>boss.y && bullets[i].y<boss.y+boss.h){
boss.hp -= 3;
bullets.splice(i,1);
if(boss.hp<=0) gameWin();
}
}
}
}
function updateEnemies(){
for(let e of enemies){
e.x+=e.vx;
if(e.x<50 || e.x>1900) e.vx*=-1;
// 碰撞伤害
if(!cheatInvincible && !player.shieldActive && player.invincibleTimer<=0 && Math.abs(player.x-e.x)<35 && Math.abs(player.y-e.y)<35){
player.hp -= 1;
player.invincibleTimer = 30;
player.shieldActive=false;
updateUI();
if(player.hp<=0) gameOver();
}
}
if(boss){
boss.x += boss.vx;
if(boss.x<400||boss.x>1100) boss.vx*=-1;
if(!cheatInvincible && !player.shieldActive && player.invincibleTimer<=0 && Math.abs(player.x-boss.x)<45 && Math.abs(player.y-boss.y)<50){
player.hp -= 2;
player.invincibleTimer = 30;
player.shieldActive=false;
updateUI();
if(player.hp<=0) gameOver();
}
}
if(player.invincibleTimer>0) player.invincibleTimer--;
}
// 过关判定
function checkLevelComplete(){
if(player.x>1850 && currentLevel!==6){
if(currentLevel<5){
currentLevel++;
buildLevel(currentLevel);
resetPlayerForLevel();
} else if(currentLevel===5){
currentLevel=6;
buildLevel(6);
resetPlayerForLevel();
}
updateUI();
}
if(boss && boss.hp<=0){
gameWin();
}
}
function gameOver(){
alert("游戏结束!董测浩倒下了... 重新开始?");
resetGame();
}
function gameWin(){
alert("🎉 胜利!董测浩成功解救许子昂,击败金文祥!🎉");
resetGame();
}
function resetGame(){
currentLevel=1;
player.hp=5;
player.x=70;
player.y=400;
powerUpMode=false;
autoShoot=false;
buildLevel(1);
resetPlayerForLevel();
gameRunning=true;
updateUI();
}
// 彩蛋: 跳跃10次
function triggerEasterEgg(){
if(powerUpMode) return;
powerUpMode=true;
autoShoot=true;
player.baseSpeed = 5.2;
alert("✨ 大迫杰陈浩然:小儿子董测浩,我看你那么诚心既然召唤了我,那我就勉为其难的给你大迫杰力量!跑得更快,自动枪,护盾无限释放!✨");
}
// 渲染图形 (马里奥风格)
function draw(){
ctx.fillStyle = '#6bc9ff';
ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.fillStyle='#5b9240';
for(let plat of platforms) ctx.fillRect(plat.x-cameraX, plat.y, plat.w, plat.h);
// 主角
ctx.fillStyle = '#e34234';
ctx.shadowBlur=0;
ctx.fillRect(player.x-cameraX, player.y, player.width, player.height);
ctx.fillStyle='#ffcc88';
ctx.fillRect(player.x-cameraX+8, player.y-8, 16, 12);
if(player.shieldActive){ ctx.beginPath(); ctx.arc(player.x-cameraX+16,player.y+16,24,0,Math.PI*2); ctx.fillStyle='#44aaffaa'; ctx.fill();}
// 枪
ctx.fillStyle='#444';
ctx.fillRect(player.x-cameraX+(player.facingRight?28:-10), player.y+12, 14, 6);
// 敌人
for(let e of enemies){
ctx.fillStyle='#9b4b2e';
ctx.fillRect(e.x-cameraX, e.y, e.w, e.h);
ctx.fillStyle='#000';
ctx.fillRect(e.x-cameraX+5,e.y+5,6,6);
}
if(boss){
ctx.fillStyle='#b53b1a';
ctx.fillRect(boss.x-cameraX, boss.y, boss.w, boss.h);
ctx.fillStyle='#ffd966';
ctx.font='bold 12px monospace';
ctx.fillText(`金文祥 ${boss.hp}/${boss.maxHp}`, boss.x-cameraX, boss.y-6);
}
for(let b of bullets) { ctx.fillStyle='gold'; ctx.fillRect(b.x-cameraX, b.y, 8, 5); }
ctx.fillStyle='white';
ctx.font='bold 18px "Press Start 2P"';
ctx.fillText(`★ ${powerUpMode?"大迫杰力量!":"普通"}`, 20, 50);
}
// 游戏循环逻辑
function gameUpdate(){
if(!gameRunning) return;
applyPhysics();
if(keys.shoot && (autoShoot || shootCooldown<=0)) shootBullet();
updateBullets();
updateEnemies();
checkLevelComplete();
if(player.hp<=0) gameOver();
updateUI();
}
function drawLoop(){
draw();
}
let lastFrameTime = 0;
function frameHandler(now){
if(!gameRunning){ draw(); requestAnimationFrame(frameHandler); return; }
if(now - lastFrameTime >= frameInterval){
gameUpdate();
drawLoop();
lastFrameTime = now;
}
animationId = requestAnimationFrame(frameHandler);
}
// 输入监听
function initControls(){
window.addEventListener('keydown', (e)=>{
let k=e.key;
if(k==='ArrowLeft') keys.left=true;
if(k==='ArrowRight') keys.right=true;
if(k==='ArrowUp' || k===' '){
if(!jumpPressed && player.grounded){ player.vy = player.jumpPower; player.grounded=false; jumpPressed=true;
jumpPressCount++; if(jumpPressCount>=10 && !powerUpMode) triggerEasterEgg();
setTimeout(()=>jumpPressCount=0, 3000);
}
}
if(k==='z'||k==='x') keys.shoot=true;
if(k==='c') useShield();
if(k==='v') useHeal();
});
window.addEventListener('keyup', (e)=>{
if(e.key==='ArrowLeft') keys.left=false;
if(e.key==='ArrowRight') keys.right=false;
if(e.key==='ArrowUp'||e.key===' ') jumpPressed=false;
if(e.key==='z'||e.key==='x') keys.shoot=false;
});
document.querySelectorAll('.touch-btn').forEach(btn=>{
let act=btn.dataset.action;
btn.addEventListener('touchstart',(e)=>{ e.preventDefault(); if(act==='left') keys.left=true; if(act==='right') keys.right=true; if(act==='jump' && player.grounded){ player.vy=player.jumpPower; player.grounded=false; jumpPressCount++; if(jumpPressCount>=10 && !powerUpMode) triggerEasterEgg(); } if(act==='shoot') keys.shoot=true; if(act==='shield') useShield(); if(act==='heal') useHeal(); });
btn.addEventListener('touchend',()=>{ if(act==='left') keys.left=false; if(act==='right') keys.right=false; if(act==='shoot') keys.shoot=false; });
btn.addEventListener('mousedown',()=>{ if(act==='left') keys.left=true; if(act==='right') keys.right=true; if(act==='jump' && player.grounded){ player.vy=player.jumpPower; player.grounded=false; jumpPressCount++; if(jumpPressCount>=10 && !powerUpMode) triggerEasterEgg(); } if(act==='shoot') keys.shoot=true; if(act==='shield') useShield(); if(act==='heal') useHeal(); });
btn.addEventListener('mouseup',()=>{ if(act==='left') keys.left=false; if(act==='right') keys.right=false; if(act==='shoot') keys.shoot=false; });
});
}
// 设置帧率
document.getElementById('fps30').onclick=()=>{ targetFps=30; frameInterval=1000/30; closeModal('settingsModal'); };
document.getElementById('fps60').onclick=()=>{ targetFps=60; frameInterval=1000/60; closeModal('settingsModal'); };
document.getElementById('settingsBtn').onclick=()=>document.getElementById('settingsModal').style.display='flex';
document.getElementById('devBtn').onclick=()=>document.getElementById('devModal').style.display='flex';
document.getElementById('cheatBtn').onclick=()=>document.getElementById('cheatModal').style.display='flex';
document.getElementById('unlockCheat').onclick=()=>{
let pwd=document.getElementById('cheatPassword').value;
if(pwd==='9178'){
cheatActive=true;
document.getElementById('cheatPanel').style.display='block';
alert('恭喜你解锁游戏内测,内测版本2.36,已通过审核');
} else alert('密码错误');
};
document.getElementById('speedSlider').oninput=(e)=>{ cheatSpeedMul=parseFloat(e.target.value); };
document.getElementById('invincibleToggle').onchange=(e)=>{ cheatInvincible=e.target.checked; };
document.getElementById('noCdToggle').onchange=(e)=>{ cheatNoCd=e.target.checked; };
document.getElementById('bossHpSlider').oninput=(e)=>{ cheatBossHpBase=parseInt(e.target.value); document.getElementById('bossHpVal').innerText=cheatBossHpBase; if(boss) boss.hp=cheatBossHpBase; };
document.getElementById('applyLevel').onclick=()=>{
let lvl=parseInt(document.getElementById('levelSelect').value);
currentLevel = lvl===6?6:lvl;
buildLevel(currentLevel);
resetPlayerForLevel();
closeModal('cheatModal');
};
function closeModal(id){ document.getElementById(id).style.display='none'; }
window.closeModal=closeModal;
document.getElementById('startGameBtn').onclick=()=>{
document.getElementById('storyModal').style.display='none';
gameRunning=true;
buildLevel(1);
resetPlayerForLevel();
animationId = requestAnimationFrame(frameHandler);
};
initControls();
buildLevel(1);
updateUI();
// 预启动渲染
draw();
})();
</script>
</body>
</html>
index.html
style.css
index.js
md
README.md
index.html