摸金行动 完整版-多地图+撤离点
by BraveCoder31423 lines12.5 KB
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>摸金行动 完整版-多地图+撤离点</title>
<style>
* { margin:0; padding:0; box-sizing:border-box; user-select:none; }
body { background:#1a1a1a; color:#fff; font-family:微软雅黑; overflow:hidden; }
#crosshair {
position:fixed; top:50%; left:50%;
transform:translate(-50%,-50%);
width:24px; height:24px;
border:2px solid #fff; border-radius:50%;
pointer-events:none; z-index:20;
}
#game { width:100vw; height:100vh; position:relative; background:#2b241c; }
#player {
width:40px; height:40px;
background:#5490ff; border-radius:50%;
position:absolute; transform:translate(-50%,-50%);
}
.wall {
background:#44382b; border:3px solid #6b5947;
position:absolute;
}
.safe {
width:65px; height:55px;
background:#806020; border:3px solid #ffd700;
position:absolute; border-radius:4px;
}
.birdNest {
width:45px; height:40px;
background:#614a32; border-radius:50% 50% 40% 40%;
position:absolute;
}
.trashPile {
width:50px; height:35px;
background:#524333; border-radius:6px;
position:absolute;
}
.leavePoint {
width:70px; height:60px;
background:#27ae60; border:3px solid #fff;
position:absolute; border-radius:8px;
text-align:center; line-height:60px; font-weight:bold;
}
.loot {
width:28px; height:28px;
position:absolute; border-radius:3px;
display:none;
}
.gold { background:#ffd700; }
.coin { background:#e6c200; }
.junk { background:#888; }
.poison { background:#9b2222; }
.medicine { background:#27ae60; }
.enemy {
width:36px; height:36px;
background:#c72c2c; border-radius:50%;
position:absolute;
}
.bullet {
width:6px; height:14px;
background:#ffffff; border-radius:3px;
position:absolute;
}
#ui {
position:fixed; top:15px; left:15px;
z-index:10; font-size:18px; line-height:1.6;
background:rgba(0,0,0,0.5); padding:8px 12px; border-radius:6px;
}
#tip {
position:fixed; bottom:25px; left:50%;
transform:translateX(-50%); font-size:17px;
color:#ffdd77; text-align:center;
background:rgba(0,0,0,0.4); padding:6px 15px; border-radius:20px;
z-index:10;
}
#mapTip{
position:fixed; top:15px; right:15px;
background:rgba(0,0,0,0.5); padding:8px 12px;
border-radius:6px; font-size:18px; z-index:10;
}
.overBox{
position:fixed; top:0;left:0;width:100vw;height:100vh;
background:rgba(0,0,0,0.85);z-index:30;
display:none;text-align:center;padding-top:200px;
font-size:36px;
}
</style>
</head>
<body>
<div id="crosshair"></div>
<div id="game">
<div id="player"></div>
</div>
<div id="ui">
💰 总收益:<span id="totalScore">0</span><br>
🔫 子弹:∞ 无限<br>
⚠️ 小心负面物品!
</div>
<div id="mapTip">当前地图:<span id="mapName">一号区域</span></div>
<div id="tip">WASD移动 | 鼠标左键开枪 | E键搜刮/撤离 | M键切换地图</div>
<div class="overBox" id="overBox">
<div>✅ 成功撤离!本局得分:<span id="finalScore">0</span></div>
<div style="font-size:20px;margin-top:20px">刷新页面重新开始</div>
</div>
<script>
const game = document.getElementById('game');
const player = document.getElementById('player');
const scoreDom = document.getElementById('totalScore');
const tipDom = document.getElementById('tip');
const mapNameDom = document.getElementById('mapName');
const overBox = document.getElementById('overBox');
const finalScoreDom = document.getElementById('finalScore');
let playerX = window.innerWidth / 2;
let playerY = window.innerHeight / 2;
const moveSpeed = 5;
let keys = {};
let mouseHold = false;
let totalScore = 0;
let nowMap = 1;
let safes = [];
let birdNests = [];
let trashes = [];
let leavePoints = [];
let enemies = [];
let bullets = [];
const lootTypeList = [
{ name: "金条", score: 10, className: "gold" },
{ name: "钱币", score: 5, className: "coin" },
{ name: "药品", score: 8, className: "medicine" },
{ name: "废旧杂物", score: 1, className: "junk" },
{ name: "破损毒物", score: -15, className: "poison" }
];
function clearAllObj(){
safes.forEach(item=>item.remove());
birdNests.forEach(item=>item.remove());
trashes.forEach(item=>item.remove());
leavePoints.forEach(item=>item.remove());
enemies.forEach(item=>item.remove());
document.querySelectorAll('.wall').forEach(w=>w.remove());
safes=[];birdNests=[];trashes=[];leavePoints=[];enemies=[];bullets=[];
}
function buildWall(x, y, w, h) {
let wall = document.createElement('div');
wall.className = "wall";
wall.style.left = x + "px";
wall.style.top = y + "px";
wall.style.width = w + "px";
wall.style.height = h + "px";
game.appendChild(wall);
}
function createSafe(x, y) {
let obj = document.createElement('div');
obj.className = "safe";
obj.style.left = x + "px";
obj.style.top = y + "px";
obj.dataset.open = "false";
game.appendChild(obj);
let loot = createRandomLoot(obj);
obj.loot = loot;
safes.push(obj);
}
function createBirdNest(x, y) {
let obj = document.createElement('div');
obj.className = "birdNest";
obj.style.left = x + "px";
obj.style.top = y + "px";
obj.dataset.open = "false";
game.appendChild(obj);
let loot = createRandomLoot(obj);
obj.loot = loot;
birdNests.push(obj);
}
function createTrash(x, y) {
let obj = document.createElement('div');
obj.className = "trashPile";
obj.style.left = x + "px";
obj.style.top = y + "px";
obj.dataset.open = "false";
game.appendChild(obj);
let loot = createRandomLoot(obj);
obj.loot = loot;
trashes.push(obj);
}
function createLeavePoint(x,y){
let obj = document.createElement('div');
obj.className = "leavePoint";
obj.style.left = x + "px";
obj.style.top = y + "px";
obj.innerText = "撤离点";
game.appendChild(obj);
leavePoints.push(obj);
}
function createRandomLoot(parent) {
let loot = document.createElement('div');
loot.className = "loot";
let randomIdx = Math.floor(Math.random() * lootTypeList.length);
let targetLoot = lootTypeList[randomIdx];
loot.classList.add(targetLoot.className);
loot.dataset.name = targetLoot.name;
loot.dataset.score = targetLoot.score;
loot.style.left = (parseFloat(parent.style.left) + 15) + "px";
loot.style.top = (parseFloat(parent.style.top) + 10) + "px";
loot.style.display = "none";
game.appendChild(loot);
return loot;
}
function createEnemy() {
let enemy = document.createElement('div');
enemy.className = "enemy";
let x = Math.random() * window.innerWidth;
let y = Math.random() * window.innerHeight;
enemy.style.left = x + "px";
enemy.style.top = y + "px";
game.appendChild(enemy);
enemies.push(enemy);
}
function loadMap1(){
mapNameDom.innerText = "一号区域";
buildWall(200, 0, 20, 350);
buildWall(500, 250, 20, 400);
buildWall(0, 450, window.innerWidth, 20);
createSafe(100, 120);
createSafe(620, 150);
createSafe(320, 520);
createBirdNest(260, 220);
createBirdNest(700, 380);
createTrash(150, 380);
createTrash(480, 550);
createTrash(600, 280);
createLeavePoint(window.innerWidth-120,window.innerHeight-100);
for(let i=0;i<3;i++) createEnemy();
}
function loadMap2(){
mapNameDom.innerText = "二号仓库";
buildWall(350,0,20,400);
buildWall(100,200,600,20);
buildWall(0,500,window.innerWidth,20);
createSafe(80,80);
createSafe(720,420);
createSafe(400,580);
createBirdNest(180,300);
createBirdNest(550,120);
createTrash(280,450);
createTrash(650,220);
createLeavePoint(50,window.innerHeight-100);
for(let i=0;i<4;i++) createEnemy();
}
function loadMap3(){
mapNameDom.innerText = "三号据点";
buildWall(150,100,500,20);
buildWall(150,300,500,20);
buildWall(300,0,20,window.innerHeight);
createSafe(80,180);
createSafe(750,200);
createSafe(750,400);
createBirdNest(200,450);
createBirdNest(600,120);
createTrash(100,520);
createTrash(680,500);
createLeavePoint(window.innerWidth/2-35,window.innerHeight-90);
for(let i=0;i<5;i++) createEnemy();
}
function switchMap(){
clearAllObj();
playerX = window.innerWidth/2;
playerY = window.innerHeight/2;
nowMap++;
if(nowMap>3) nowMap=1;
if(nowMap===1) loadMap1();
if(nowMap===2) loadMap2();
if(nowMap===3) loadMap3();
tipDom.innerText = "已切换地图!继续搜刮物资";
setTimeout(()=>{
tipDom.innerText = "WASD移动 | 鼠标左键开枪 | E键搜刮/撤离 | M键切换地图";
},1500);
}
function searchItem() {
let allItems = [...safes, ...birdNests, ...trashes];
let playerCenterX = playerX;
let playerCenterY = playerY;
allItems.forEach(item => {
if (item.dataset.open === "true") return;
let itemX = parseFloat(item.style.left) + 25;
let itemY = parseFloat(item.style.top) + 20;
let dist = Math.hypot(playerCenterX - itemX, playerCenterY - itemY);
if (dist < 60) {
item.dataset.open = "true";
item.loot.style.display = "block";
let lootName = item.loot.dataset.name;
let lootScore = Number(item.loot.dataset.score);
totalScore += lootScore;
scoreDom.innerText = totalScore;
if (lootScore > 0) {
tipDom.innerText = `✅ 搜到【${lootName}】,+${lootScore}分`;
} else if (lootScore < 0) {
tipDom.innerText = `❌ 捡到【${lootName}】,${lootScore}分`;
} else {
tipDom.innerText = `📦 搜到【${lootName}】,收益一般`;
}
setTimeout(() => {
item.loot.remove();
tipDom.innerText = "WASD移动 | 鼠标左键开枪 | E键搜刮/撤离 | M键切换地图";
}, 1200);
}
});
leavePoints.forEach(lp=>{
let lpX = parseFloat(lp.style.left)+35;
let lpY = parseFloat(lp.style.top)+30;
let dist = Math.hypot(playerX-lpX,playerY-lpY);
if(dist<70){
finalScoreDom.innerText = totalScore;
overBox.style.display = "block";
}
});
}
function fireBullet(e) {
let bullet = document.createElement('div');
bullet.className = "bullet";
bullet.style.left = playerX + "px";
bullet.style.top = playerY + "px";
game.appendChild(bullet);
bullets.push(bullet);
let angle = Math.atan2(e.clientY - playerY, e.clientX - playerX);
bullet.vx = Math.cos(angle) * 14;
bullet.vy = Math.sin(angle) * 14;
}
function checkCollide(a, b) {
let aRect = a.getBoundingClientRect();
let bRect = b.getBoundingClientRect();
return !(aRect.bottom < bRect.top || aRect.top > bRect.bottom ||
aRect.right < bRect.left || aRect.left > bRect.right);
}
document.addEventListener('keydown', e => {
keys[e.code] = true;
if (e.code === "KeyE") searchItem();
if (e.code === "KeyM") switchMap();
});
document.addEventListener('keyup', e => keys[e.code] = false);
document.addEventListener('mousedown', e => {
mouseHold = true;
fireBullet(e);
});
document.addEventListener('mouseup', () => mouseHold = false);
function gameLoop() {
if (keys["KeyW"] || keys["ArrowUp"]) playerY -= moveSpeed;
if (keys["KeyS"] || keys["ArrowDown"]) playerY += moveSpeed;
if (keys["KeyA"] || keys["ArrowLeft"]) playerX -= moveSpeed;
if (keys["KeyD"] || keys["ArrowRight"]) playerX += moveSpeed;
playerX = Math.max(25, Math.min(window.innerWidth - 25, playerX));
playerY = Math.max(25, Math.min(window.innerHeight - 25, playerY));
player.style.left = playerX + "px";
player.style.top = playerY + "px";
if (mouseHold) {
fireBullet(event);
}
for (let i = bullets.length - 1; i >= 0; i--) {
let b = bullets[i];
let x = parseFloat(b.style.left) + b.vx;
let y = parseFloat(b.style.top) + b.vy;
b.style.left = x + "px";
b.style.top = y + "px";
if (x < 0 || x > window.innerWidth || y < 0 || y > window.innerHeight) {
b.remove();
bullets.splice(i, 1);
continue;
}
for (let j = enemies.length - 1; j >= 0; j--) {
let en = enemies[j];
if (checkCollide(b, en)) {
en.remove();
enemies.splice(j, 1);
b.remove();
bullets.splice(i, 1);
setTimeout(createEnemy, 2500);
break;
}
}
}
requestAnimationFrame(gameLoop);
}
loadMap1();
gameLoop();
</script>
</body>
</html>
Game Source: 摸金行动 完整版-多地图+撤离点
Creator: BraveCoder31
Libraries: none
Complexity: complex (423 lines, 12.5 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-bravecoder31" to link back to the original. Then publish at arcadelab.ai/publish.