<!DOCTYPE html>
<html lang=”zh-CN”>
<head>
<meta charset=”utf-8″>
<meta name=”viewport” content=”width=device-width,initial-scale=1,user-scalable=no”>
<title>沙漠恐龙跑酷</title>
<style>
*{margin:0;padding:0;overflow:hidden;touch-action:none}
body{background:#f7e8c8}
#game{width:100vw;height:100vh;position:fixed;top:0;left:0;z-index:-1;}
#ui{
position:fixed;top:20px;left:20px;right:20px;
display:flex;justify-content:space-between;
font:bold 26px system-ui;color:#444
}
#hearts{
font-size:30px;color:red;
}
#restart{
position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);
width:70px;height:70px;
background:#333;color:#fff;
border-radius:50%;
display:none;
justify-content:center;align-items:center;
font:bold 30px system-ui;
border:none;box-shadow:0 0 10px #0003
}
</style>
</head>
<body>
<div id=”ui”>
<div id=”hearts”>❤️❤️❤️</div>
<div>最高分: <span id=”best”>0</span></div>
<div>分数: <span id=”score”>0</span></div>
</div>
<button id=”restart” onclick=”restart()”>↻</button>
<canvas id=”game”></canvas>
<script>
const canvas=document.getElementById(‘game’);
const ctx=canvas.getContext(‘2d’);
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
const audio = new Audio(‘https://cdn.pixabay.com/download/audio/2025/03/11/audio_95371d47e9.mp3’);
audio.loop = true;
audio.volume = 0.3;
let best=localStorage.getItem(‘dinoBest’)||0;
document.getElementById(‘best’).innerText=best;
// 屏幕正中间
const centerY = canvas.height / 2;
const groundY = centerY;
let dino={
x: canvas.width/2 – 16,
y: groundY – 40,
w:32,h:40,vy:0,gravity:0.7,isJumping:false
};
let cacti=[];
let score=0;
let lives=3;
let gameOver=false;
let speed=4.5;
let animationId;
let jumpStart=0;
let invincibleTime = 0;
function updateHearts(){
let h=”;
for(let i=0;i<lives;i++)h+=’❤️’;
document.getElementById(‘hearts’).innerText=h;
}
window.addEventListener(‘resize’,()=>{
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
const centerY = canvas.height / 2;
const groundY = centerY;
dino.y = groundY – 40;
dino.x = canvas.width/2 – 16;
});
function drawBackground(){
const grad = ctx.createLinearGradient(0,0,0,canvas.height);
grad.addColorStop(0,’#f9eabe’);
grad.addColorStop(1,’#e6c88e’);
ctx.fillStyle=grad;
ctx.fillRect(0,0,canvas.width,canvas.height);
}
function drawDino(){
ctx.fillStyle= invincibleTime>0 ? ‘#88cfff’ : ‘#2a2a2a’;
ctx.fillRect(dino.x,dino.y,dino.w,dino.h);
ctx.fillStyle=’#4a4a4a’;
ctx.fillRect(dino.x+6,dino.y+9,8,6);
ctx.fillStyle=’#f5f5f5′;
ctx.fillRect(dino.x+22,dino.y+6,4,4);
}
function updateDino(){
if(dino.isJumping){
dino.vy+=dino.gravity;
dino.y+=dino.vy;
if(dino.y >= groundY – 40){
dino.y = groundY – 40;
dino.isJumping=false;
dino.vy=0;
}
}
}
canvas.addEventListener(‘touchstart’,()=>{jumpStart=Date.now();audio.play();});
canvas.addEventListener(‘touchend’,doJump);
document.addEventListener(‘keydown’,e=>{if(e.code==’Space’&&!jumpStart){jumpStart=Date.now();audio.play();}});
document.addEventListener(‘keyup’,e=>{if(e.code==’Space’)doJump();});
function doJump(){
if(dino.isJumping||gameOver)return;
const hold=Date.now()-jumpStart;
const power=hold<150 ? -11 : hold<300 ? -16 : -20;
dino.isJumping=true;
dino.vy=power;
jumpStart=0;
}
function spawnCactus(){
if(Math.random()<0.014 && !gameOver){
const w=18+Math.random()*8;
const h=35+Math.random()*15;
cacti.push({
x:canvas.width,
y: groundY – h,
w,h
});
}
}
function drawCacti(){
ctx.fillStyle=’#2d7c2d’;
cacti.forEach((c,i)=>{
if(!gameOver)c.x-=speed;
ctx.fillRect(c.x,c.y,c.w,c.h);
ctx.fillStyle=’#1f5a1f’;
ctx.fillRect(c.x+c.w-6,c.y,6,c.h);
if(c.x+c.w<0) cacti.splice(i,1);
if(invincibleTime>0) return;
if(dino.x < c.x+c.w && dino.x+dino.w > c.x &&
dino.y < c.y+c.h && dino.y+dino.h > c.y){
lives–;
updateHearts();
if(lives<=0){
gameOver=true;
audio.pause();
if(score>best){
best=Math.floor(score);
localStorage.setItem(‘dinoBest’,best);
document.getElementById(‘best’).innerText=best;
}
document.getElementById(‘restart’).style.display=’flex’;
}else{
invincibleTime = 180;
}
}
});
}
function drawGround(){
ctx.fillStyle=’#555′;
ctx.fillRect(0, groundY, canvas.width, 3);
}
function drawScore(){
if(!gameOver){
score+=0.15;
speed=Math.min(9, 4.5 + score/180);
}
document.getElementById(‘score’).innerText=Math.floor(score);
}
function loop(){
if(invincibleTime>0) invincibleTime–;
ctx.clearRect(0,0,canvas.width,canvas.height);
drawBackground();
drawGround();
drawDino();
updateDino();
spawnCactus();
drawCacti();
drawScore();
if(!gameOver) animationId=requestAnimationFrame(loop);
}
function restart(){
cancelAnimationFrame(animationId);
gameOver=false;
cacti=[];
score=0;
lives=3;
updateHearts();
speed=4.5;
dino.y = groundY – 40;
dino.x = canvas.width/2 – 16;
dino.isJumping=false;
dino.vy=0;
jumpStart=0;
invincibleTime=0;
document.getElementById(‘restart’).style.display=’none’;
audio.currentTime=0;
audio.play();
loop();
}
updateHearts();
loop();
</script>
</body>
</html>

暂无评论内容