双人森林逃亡|收集苹果通关版
by ApexOtter23147 lines4.9 KB
<!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">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>双人森林逃亡|收集苹果通关版</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{background:#1a2f1a;overflow:hidden;touch-action:none}
canvas{display:block;margin:auto;background:#2d4b2d}
.joystick-area-left{position:fixed;bottom:20px;left:20px;width:120px;height:120px}
.joystick-area-right{position:fixed;bottom:20px;right:20px;width:120px;height:120px}
.joystick-base{width:120px;height:120px;border-radius:50%;background:rgba(255,255,255,0.2);position:relative}
.joystick-knob{width:45px;height:45px;border-radius:50%;background:rgba(255,255,255,0.5);position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}
.tip{position:fixed;top:10px;left:0;width:100%;text-align:center;color:#fff;font-size:14px}
</style>
</head>
<body>
<div class="tip">收集10个苹果解锁终点旗帜|双人摇杆操控</div>
<canvas id="game"></canvas>
<div class="joystick-area-left">
<div class="joystick-base">
<div class="joystick-knob" id="knob1"></div>
</div>
</div>
<div class="joystick-area-right">
<div class="joystick-base">
<div class="joystick-knob" id="knob2"></div>
</div>
</div>
<script>
const canvas = document.getElementById('game')
const ctx = canvas.getContext('2d')
const MAP_W = 1600
const MAP_H = 1600
let camera = {x:0,y:0}
let gameState = {
appleCount:0,
targetApple:10,
freezeTimer:0,
freezeDuration:120,
flagSpawned:false,
win:false
}
let flag = {x:MAP_W/2, y:MAP_H/2, w:40, h:50}
let apples = []
for(let i=0;i<10;i++){
apples.push({
x: 80 + Math.random()*(MAP_W-160),
y: 80 + Math.random()*(MAP_H-160),
r:14,
collected:false
})
}
function resize(){
canvas.width = window.innerWidth
canvas.height = window.innerHeight
}
resize()
window.addEventListener('resize',resize)
const p1 = {x:200,y:200,w:30,h:30,hp:10,maxHp:10,color:'#42f590',vx:0,vy:0,speed:4,alive:true}
const p2 = {x:300,y:200,w:30,h:30,hp:10,maxHp:10,color:'#4298f5',vx:0,vy:0,speed:4,alive:true}
const enemy = {x:800,y:800,w:40,h:40,speed:2.2,color:'#9944ff',cd:0}
const knob1 = document.getElementById('knob1')
const base1 = document.querySelector('.joystick-area-left .joystick-base')
let joy1={dx:0,dy:0,active:false}
base1.addEventListener('touchstart',e=>{joy1.active=true;e.preventDefault()})
window.addEventListener('touchmove',e=>{
if(!joy1.active) return
const rect = base1.getBoundingClientRect()
const cx = rect.left+rect.width/2
const cy = rect.top+rect.height/2
let tx = e.touches[0].clientX - cx
let ty = e.touches[0].clientY - cy
const dist = Math.hypot(tx,ty)
const maxR = 40
if(dist>maxR){tx=tx/dist*maxR;ty=ty/dist*maxR}
knob1.style.transform = `translate(calc(-50% + ${tx}px),calc(-50% + ${ty}px))`
joy1.dx = tx/maxR
joy1.dy = ty/maxR
})
window.addEventListener('touchend',()=>{
joy1.active=false;joy1.dx=0;joy1.dy=0
knob1.style.transform = 'translate(-50%,-50%)'
})
const knob2 = document.getElementById('knob2')
const base2 = document.querySelector('.joystick-area-right .joystick-base')
let joy2={dx:0,dy:0,active:false}
base2.addEventListener('touchstart',e=>{joy2.active=true;e.preventDefault()})
window.addEventListener('touchmove',e=>{
if(!joy2.active) return
const rect = base2.getBoundingClientRect()
const cx = rect.left+rect.width/2
const cy = rect.top+rect.height/2
let tx = e.touches[0].clientX - cx
let ty = e.touches[0].clientY - cy
const dist = Math.hypot(tx,ty)
const maxR = 40
if(dist>maxR){tx=tx/dist*maxR;ty=ty/dist*maxR}
knob2.style.transform = `translate(calc(-50% + ${tx}px),calc(-50% + ${ty}px))`
joy2.dx = tx/maxR
joy2.dy = ty/maxR
})
window.addEventListener('touchend',()=>{
joy2.active=false;joy2.dx=0;joy2.dy=0
knob2.style.transform = 'translate(-50%,-50%)'
})
function rectCollide(a,b){
return a.x < b.x+b.w && a.x+a.w>b.x && a.y < b.y+b.h && a.y+a.h>b.y
}
function circleRect(apple,player){
let px = Math.max(player.x, Math.min(apple.x, player.x+player.w))
let py = Math.max(player.y, Math.min(apple.y, player.y+player.h))
return Math.hypot(apple.x-px, apple.y-py) < apple.r
}
function drawHp(player,top){
const barW = 120,barH=14
ctx.fillStyle='#333'
ctx.fillRect(20,top,barW,barH)
ctx.fillStyle='#f33'
ctx.fillRect(20,top,barW*(player.hp/player.maxHp),barH)
ctx.strokeStyle='#fff'
ctx.strokeRect(20,top,barW,barH)
}
function getAlivePlayers(){
let arr=[]
if(p1.alive)arr.push(p1)
if(p2.alive)arr.push(p2)
return arr
}
function loop(){
ctx.fillStyle='#2d4b2d'
ctx.fillRect(0,0,canvas.width,canvas.height)
const alive = getAlivePlayers()
apples.forEach(apple=>{
if(!apple.collected){
Game Source: 双人森林逃亡|收集苹果通关版
Creator: ApexOtter23
Libraries: none
Complexity: moderate (147 lines, 4.9 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-apexotter23" to link back to the original. Then publish at arcadelab.ai/publish.