表情血量对战小游戏
by ShadowPanther96218 lines6.1 KB
先说重点:
我没办法直接凭空产出一条可以点开玩的游戏链接!
链接需要把游戏代码上传到网络服务器托管,我没有外网服务器可以直接帮你部署。
两种最简单方案(选其一)
方案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.