像素草原生存
by SwiftCoder84308 lines9.2 KB
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>像素草原生存</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{background:#222;display:flex;justify-content:center;padding-top:20px}
#game{
width:800px;height:600px;background:#7ccd7c;
position:relative;overflow:hidden;border:3px solid #fff;
}
/*玩家样式*/
.player{
width:32px;height:32px;font-size:32px;
position:absolute;left:400px;top:300px;
transition:0.08s;user-select:none;
}
/*怪物通用*/
.monster{position:absolute;font-size:32px;user-select:none;}
.boss-small{font-size:36px;}
.boss-final{font-size:128px;}
/*方向按键 左下*/
.dir-box{
position:absolute;left:20px;bottom:20px;
display:grid;grid-template-columns:50px 50px 50px;gap:6px;
}
.dir-btn{
width:50px;height:50px;border-radius:50%;
background:#ffffff88;border:2px solid white;
display:grid;place-items:center;color:#000;font-weight:bold;
}
/*技能按钮 右下*/
.skill-box{position:absolute;right:20px;bottom:20px;display:flex;gap:10px}
.skill-btn{
width:60px;height:60px;border-radius:50%;
background:#fff8;border:2px solid white;
color:#000;font-size:14px;
}
/*血量、击杀数UI*/
.ui{
position:absolute;top:10px;left:10px;color:white;
font-size:18px;text-shadow:1px 1px black;
}
.night{background:#2c3e50;transition:2s}
.tree{position:absolute;font-size:28px}
</style>
</head>
<body>
<div id="game">
<div class="ui">
生命:<span id="hp">15</span>/15<br>
击杀:<span id="kill">0</span><br>
武器:<span id="weapon">木剑(2伤)</span><br>
盾牌:<span id="shield">未解锁</span>
</div>
<div class="player" id="player">😀</div>
<!--方向键布局-->
<div class="dir-box">
<div></div>
<div class="dir-btn" data-dir="up">↑</div>
<div></div>
<div class="dir-btn" data-dir="left">←</div>
<div></div>
<div class="dir-btn" data-dir="right">→</div>
<div></div>
<div class="dir-btn" data-dir="down">↓</div>
<div></div>
</div>
<!--技能按钮-->
<div class="skill-box">
<button class="skill-btn" id="dig">挖掘</button>
<button class="skill-btn" id="attack">攻击</button>
</div>
</div>
<script>
const game = document.getElementById('game');
const player = document.getElementById('player');
const hpText = document.getElementById('hp');
const killText = document.getElementById('kill');
const weaponText = document.getElementById('weapon');
const shieldText = document.getElementById('shield');
//玩家数据
let playerData = {
x:400,y:300,speed:4,hp:15,maxHp:15,
damage:2,kill:0,shield:false,
weapon:'木剑(2伤)',night:false,gameOver:false
};
let monsters = [];
let smallBossSpawned = false;
let finalBossSpawned = false;
let finalBoss = null;
//移动控制
let moveDir = {up:false,down:false,left:false,right:false};
document.querySelectorAll('.dir-btn').forEach(btn=>{
const d = btn.dataset.dir;
btn.onmousedown = ()=>moveDir[d]=true;
btn.onmouseup = ()=>moveDir[d]=false;
btn.ontouchstart = ()=>moveDir[d]=true;
btn.ontouchend = ()=>moveDir[d]=false;
});
//更新玩家位置
function movePlayer(){
if(playerData.gameOver) return;
if(moveDir.up && playerData.y>0) playerData.y -= playerData.speed;
if(moveDir.down && playerData.y<568) playerData.y += playerData.speed;
if(moveDir.left && playerData.x>0) playerData.x -= playerData.speed;
if(moveDir.right && playerData.x<768) playerData.x += playerData.speed;
player.style.left = playerData.x+'px';
player.style.top = playerData.y+'px';
requestAnimationFrame(movePlayer);
}
movePlayer();
//解锁装备判定
function checkUnlock(){
const k = playerData.kill;
if(k>=30 && !playerData.shield){
playerData.shield = true;
shieldText.textContent = '已拥有(减伤1/3)';
}
if(k>=100 && playerData.damage===2){
playerData.damage = 6;
weaponText.textContent = '钻石剑(6伤)';
}
if(k>=200 && playerData.damage===6){
playerData.damage = 8;
weaponText.textContent = '合金剑(8伤)';
}
//小蟑螂boss
if(k>=50 && !smallBossSpawned){
spawnSmallBoss();
smallBossSpawned = true;
}
//最终恶灵骑士boss
if(k>=300 && !finalBossSpawned){
spawnFinalBoss();
finalBossSpawned = true;
}
}
//生成普通怪物 夜晚才刷
function spawnMonster(){
if(playerData.gameOver || !playerData.night) return;
const types = [
{emoji:'👽',hp:6,dmg:2,name:'外星人'},
{emoji:'👻',hp:6,dmg:3,name:'幽灵'},
];
const t = types[Math.floor(Math.random()*2)];
const m = document.createElement('div');
m.className = 'monster';
m.textContent = t.emoji;
m.style.left = Math.random()*750+'px';
m.style.top = Math.random()*550+'px';
game.appendChild(m);
monsters.push({
el:m,x:parseFloat(m.style.left),y:parseFloat(m.style.top),
hp:t.hp,maxHp:t.hp,dmg:t.dmg,type:t.name
});
}
//生成蟑螂小boss
function spawnSmallBoss(){
const boss = document.createElement('div');
boss.className = 'monster boss-small';
boss.textContent = '🪳';
boss.style.left = '200px';
boss.style.top = '200px';
game.appendChild(boss);
monsters.push({
el:boss,x:200,y:200,hp:40,maxHp:40,dmg:6,type:'蟑螂Boss'
});
}
//生成最终恶灵骑士BOSS
function spawnFinalBoss(){
const boss = document.createElement('div');
boss.className = 'monster boss-final';
boss.textContent = '🏇⚔️';
boss.style.left = '350px';
boss.style.top = '200px';
game.appendChild(boss);
finalBoss = {el:boss,x:350,y:200,hp:50,maxHp:50,dmg:10};
}
//攻击按钮
document.getElementById('attack').onclick = attackMonster;
document.getElementById('attack').ontouchstart = attackMonster;
function attackMonster(){
if(playerData.gameOver) return;
const px = playerData.x, py = playerData.y;
//攻击普通怪物
for(let i=monsters.length-1;i>=0;i--){
const m = monsters[i];
const dis = Math.hypot(m.x-px,m.y-py);
if(dis<60){
m.hp -= playerData.damage;
if(m.hp<=0){
m.el.remove();
monsters.splice(i,1);
playerData.kill++;
killText.textContent = playerData.kill;
checkUnlock();
}
}
}
//攻击最终BOSS
if(finalBoss){
const dis = Math.hypot(finalBoss.x-px,finalBoss.y-py);
if(dis<130){
finalBoss.hp -= playerData.damage;
if(finalBoss.hp<=0){
alert('恭喜!击败恶灵骑士,游戏通关!');
playerData.gameOver = true;
}
}
}
}
//怪物自动追击玩家+攻击玩家
function monsterAI(){
if(playerData.gameOver) return;
const px = playerData.x, py = playerData.y;
//小怪AI
monsters.forEach(m=>{
const dx = px - m.x, dy = py - m.y;
m.x += dx>0?1.2:-1.2;
m.y += dy>0?1.2:-1.2;
m.el.style.left = m.x+'px';
m.el.style.top = m.y+'px';
//碰到玩家造成伤害
const dist = Math.hypot(m.x-px,m.y-py);
if(dist<35){
let hurt = m.dmg;
if(playerData.shield) hurt = Math.floor(hurt*2/3);
playerData.hp -= hurt;
hpText.textContent = playerData.hp;
if(playerData.hp<=0){
alert('你被怪物击败,游戏结束');
playerData.gameOver = true;
}
}
});
//最终BOSS攻击
if(finalBoss){
const dx = px-finalBoss.x, dy = py-finalBoss.y;
finalBoss.x += dx>0?0.8:-0.8;
finalBoss.y += dy>0?0.8:-0.8;
finalBoss.el.style.left = finalBoss.x+'px';
finalBoss.el.style.top = finalBoss.y+'px';
const dist = Math.hypot(finalBoss.x-px,finalBoss.y-py);
if(dist<120){
let hurt = finalBoss.dmg;
if(playerData.shield) hurt = Math.floor(hurt*2/3);
playerData.hp -= hurt;
hpText.textContent = playerData.hp;
if(playerData.hp<=0){
alert('被恶灵骑士击杀,游戏失败');
playerData.gameOver = true;
}
}
}
requestAnimationFrame(monsterAI);
}
monsterAI();
//昼夜循环:白天无怪,夜晚刷怪
setInterval(()=>{
playerData.night = !playerData.night;
if(playerData.night){
game.classList.add('night');
spawnMonster();
}else{
game.classList.remove('night');
}
},12000);
//挖掘木头(白天刷新树木)
document.getElementById('dig').onclick = ()=>{
if(playerData.gameOver) return;
if(!playerData.night){
const tree = document.createElement('div');
tree.className = 'tree';
tree.textContent = '🪵';
tree.style.left = Math.random()*750+'px';
tree.style.top = Math.random()*550+'px';
game.appendChild(tree);
}
}
//初始刷新几根木头
for(let a=0;a<8;a++){
const tree = document.createElement('div');
tree.className = 'tree';
tree.textContent = '🪵';
tree.style.left = Math.random()*750+'px';
tree.style.top = Math.random()*550+'px';
game.appendChild(tree);
}
</script>
</body>
</html>Game Source: 像素草原生存
Creator: SwiftCoder84
Libraries: none
Complexity: complex (308 lines, 9.2 KB)
The full source code is displayed above on this page.
Remix Instructions
To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: game-swiftcoder84" to link back to the original. Then publish at arcadelab.ai/publish.