🎮ArcadeLab

双人森林逃亡|收集苹果通关版

by ChromeLion33
147 lines4.9 KB
▶ Play
<!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: ChromeLion33

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-chromelion33-ms5gvu9g" to link back to the original. Then publish at arcadelab.ai/publish.