🎮ArcadeLab

表情血量对战小游戏

by ShadowPanther96
218 lines6.1 KB
▶ Play
先说重点:
我没办法直接凭空产出一条可以点开玩的游戏链接!
链接需要把游戏代码上传到网络服务器托管,我没有外网服务器可以直接帮你部署。
 
两种最简单方案(选其一)
 
方案1|本地双击直接玩(不用网络,最省事)
 
我把完整游戏代码发给你:
 
1. 电脑新建文本文档
2. 粘贴全部代码
3. 文件另存为  game.html ,保存类型:所有文件
✅ 保存后双击文件直接游玩,相当于本地小游戏。
 
方案2|做成在线链接(别人也能点开)
 
你拿到代码后,打开这个免费网站:
https://arcadelab.ai/publish
 
1. 粘贴完整游戏代码
2. 填写游戏名字,点发布
3. 立刻生成一条公开链接,发给任何人点开就能玩,无需注册账号
 
你想要的【对战小游戏完整代码】我现在直接发你,复制好就能部署:
 
html
  
<!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">
<title>表情血量对战小游戏</title>
<style>
*{margin:0;padding:0;box-sizing:border-box;font-family:system-ui;touch-action:none;}
body{overflow:hidden;}
#game{width:100vw;height:100vh;background:#73c95c;position:relative;}
.role{position:absolute;font-size:40px;transform:translate(-50%,-50%);text-align:center;pointer-events:none;}
.hp-text{font-size:16px;color:#000;font-weight:bold;}
.item{position:absolute;font-size:35px;transform:translate(-50%,-50%);pointer-events:none;}
.joystick-area{width:120px;height:120px;background:rgba(255,255,255,0.35);border-radius:50%;position:fixed;bottom:30px;}
#moveJoy{left:30px;}
#atkJoy{right:30px;}
.stick{width:50px;height:50px;background:#333;color:#fff;border-radius:50%;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:grid;place-items:center;font-size:14px;}
#failMask{display:none;position:fixed;inset:0;background:rgba(0,0,0,0.75);z-index:999;align-items:center;justify-content:center;flex-direction:column;}
.apaz-text{font-size:70px;color:red;font-weight:bold;}
.restart-btn{margin-top:30px;padding:12px 30px;font-size:20px;cursor:pointer;}
</style>
</head>
<body>
<div id="game">
<div class="joystick-area" id="moveJoy"><div class="stick"></div></div>
<div class="joystick-area" id="atkJoy"><div class="stick">攻击</div></div>
<div id="failMask">
<div class="apaz-text">游戏结束</div>
<button class="restart-btn" onclick="restartGame()">重新开始</button>
</div>
</div>

<script>
const game = document.getElementById("game");
const moveJoy = document.getElementById("moveJoy");
const atkJoy = document.getElementById("atkJoy");
const moveStick = moveJoy.querySelector(".stick");
const atkStick = atkJoy.querySelector(".stick");
const failMask = document.getElementById("failMask");

//玩家
const player = {
  x: window.innerWidth/2,
  y: window.innerHeight/2,
  hp:100,
  speed:4,
  el:null
}
//敌人
const enemy = {
  x: 150,
  y:150,
  hp:100,
  speed:2.2,
  el:null
}

//创建角色元素
function createRole(obj,emoji){
  let div = document.createElement("div");
  div.className = "role";
  div.innerHTML = `${emoji}<div class="hp-text">HP:${obj.hp}</div>`;
  game.appendChild(div);
  obj.el = div;
}
createRole(player,"😊");
createRole(enemy,"👹");

//更新位置和血量显示
function updateUI(){
  player.el.style.left = player.x+"px";
  player.el.style.top = player.y+"px";
  player.el.innerHTML = `😊<div class="hp-text">HP:${player.hp}</div>`;

  enemy.el.style.left = enemy.x+"px";
  enemy.el.style.top = enemy.y+"px";
  enemy.el.innerHTML = `👹<div class="hp-text">HP:${enemy.hp}</div>`;
}
updateUI();

//摇杆控制
let moveVec={x:0,y:0};
let isAttack=false;

//移动摇杆
function setupJoy(area,stick,callback){
  const centerX = area.offsetWidth/2;
  const centerY = area.offsetHeight/2;
  function moveHandle(e){
    e.preventDefault();
    let touch = e.touches?e.touches[0]:e;
    let rect = area.getBoundingClientRect();
    let px = touch.clientX - rect.left;
    let py = touch.clientY - rect.top;
    let dx = px-centerX;
    let dy = py-centerY;
    let dist = Math.hypot(dx,dy);
    let maxR = centerX;
    if(dist>maxR){
      dx = dx/dist*maxR;
      dy = dy/dist*maxR;
    }
    stick.style.left = centerX+dx+"px";
    stick.style.top = centerY+dy+"px";
    callback(dx/maxR, dy/maxR);
  }
  function reset(){
    stick.style.left = "50%";
    stick.style.top = "50%";
    callback(0,0);
  }
  area.addEventListener("touchmove",moveHandle);
  area.addEventListener("mousemove",moveHandle);
  area.addEventListener("touchend",reset);
  area.addEventListener("mouseup",reset);
}
setupJoy(moveJoy,moveStick,(x,y)=>{
  moveVec.x=x;
  moveVec.y=y;
})
setupJoy(atkJoy,atkStick,()=>{isAttack=true;})

//敌人AI追击
function enemyAI(){
  let dx = player.x - enemy.x;
  let dy = player.y - enemy.y;
  let dist = Math.hypot(dx,dy);
  if(dist>30){
    enemy.x += dx/dist*enemy.speed;
    enemy.y += dy/dist*enemy.speed;
  }
  //敌人碰到玩家持续扣血
  if(dist<45){
    player.hp-=0.15;
  }
}

//攻击判定
function attackCheck(){
  if(!isAttack)return;
  isAttack=false;
  let dist = Math.hypot(player.x-enemy.x, player.y-enemy.y);
  if(dist<90){
    enemy.hp -=12;
  }
}

//边界限制
function limitPos(obj){
  obj.x = Math.max(30, Math.min(window.innerWidth-30, obj.x));
  obj.y = Math.max(30, Math.min(window.innerHeight-30, obj.y));
}

//游戏循环
function loop(){
  player.x += moveVec.x*player.speed;
  player.y += moveVec.y*player.speed;
  limitPos(player);
  enemyAI();
  limitPos(enemy);
  attackCheck();
  updateUI();

  //判断结束
  if(player.hp<=0||enemy.hp<=0){
    failMask.style.display="flex";
    return;
  }
  requestAnimationFrame(loop);
}
loop();

//重启
function restartGame(){
  player.hp=100;
  enemy.hp=100;
  player.x=window.innerWidth/2;
  player.y=window.innerHeight/2;
  enemy.x=150;enemy.y=150;
  failMask.style.display="none";
  loop();
}

window.addEventListener("resize",()=>updateUI());
</script>
</body>
</html>
 
 
复制全部代码,直接粘贴到 arcadeLab 网站就能生成分享链接。
如果你不会操作,我一步步教你!

Game Source: 表情血量对战小游戏

Creator: ShadowPanther96

Libraries: none

Complexity: complex (218 lines, 6.1 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-shadowpanther96-ms2vaepl" to link back to the original. Then publish at arcadelab.ai/publish.