Untitled Game
by SparkShark50354 lines11.9 KB
<!DOCTYPE html>
<html lang="zh-HK">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
超级复杂枪战大作
<style>
*{margin:0;padding:0;box-sizing:border-box;font-family:system-ui,sans-serif}
html,body{width:100%;height:100%;overflow:hidden}
canvas{display:block;touch-action:none}
#ui{position:fixed;inset:0;color:#fff;user-select:none}
/* 主菜单 */
.mainMenu{position:absolute;inset:0;background:rgba(0,0,0,0.35);display:flex;flex-direction:column;align-items:flex-end;justify-content:flex-end;padding:30px;gap:14px}
.btn{width:170px;height:64px;font-size:20px;border:none;border-radius:12px;background:#2578ed;color:#fff}
/* 全屏幕弹窗面板 */
.panel{position:absolute;inset:0;background:rgba(0,0,0,0.88);display:none;flex-wrap:wrap;align-items:center;justify-content:center;gap:20px;padding:20px}
.box{width:160px;height:200px;background:#222;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:22px;border:solid 2px #444}
/* 游戏控件默认隐藏,开局先出 */
.joy{position:absolute;bottom:25px;left:25px;width:160px;height:160px;border-radius:50%;background:rgba(255,255,255,0.12);display:none}
.joyInner{width:70px;height:70px;border-radius:50%;background:rgba(255,255,255,0.35);position:absolute;left:45px;top:45px}
.shootBtn{position:absolute;bottom:35px;right:35px;width:110px;height:110px;border-radius:50%;background:rgba(220,40,40,0.6);border:none;color:#fff;font-size:22px;display:none}
.runBtn{position:absolute;bottom:160px;right:35px;width:70px;height:70px;border-radius:50%;background:rgba(40,180,220,0.5);border:none;color:#fff;display:none}
/* 主页中间角色预览 */
.previewChar{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:130px;height:130px;border-radius:14px;border:solid 2px #ffffff55}
</style>
</head>
<body>
<canvas id="c"></canvas>
<div id="ui">
<!-- 主页菜单 -->
<div class="mainMenu" id="mainMenu">
<button class="btn" onclick="openMode()">选择模式</button>
<button class="btn" onclick="startGame()">开始游戏</button>
<button class="btn" onclick="openSkin()">皮肤中心</button>
</div>
<!-- 主页中间角色 -->
<div class="previewChar" id="previewChar"></div>
<!-- 模式选择 -->
<div class="panel" id="modePanel">
<div class="box" onclick="setMode('train')">超级训练场</div>
<div class="box" onclick="setMode('stage1')">关卡一</div>
<div class="box" onclick="setMode('stage2')">关卡二</div>
<div class="box" onclick="setMode('survive')">无限生存</div>
<button class="btn" style="position:absolute;top:20px;right:20px" onclick="closeAllPanel()">返回</button>
</div>
<!-- 皮肤面板 -->
<div class="panel" id="skinPanel">
<div class="box" style="background:#fff" onclick="setSkin('#ffffff')">白色</div>
<div class="box" style="background:#000" onclick="setSkin('#000000')">黑色</div>
<div class="box" style="background:#348ede" onclick="setSkin('#348ede')">蓝色</div>
<div class="box" style="background:#ff7700" onclick="setSkin('#ff7700')">橙色</div>
<button class="btn" style="position:absolute;top:20px;right:20px" onclick="closeAllPanel()">返回</button>
</div>
<!-- 操控按键 -->
<div class="joy" id="joy"><div class="joyInner" id="joyIn"></div></div>
<button class="shootBtn" id="shootBtn">射击</button>
<button class="runBtn" id="runBtn">奔跑</button>
</div>
<script>
const c = document.getElementById("c");
const ctx = c.getContext("2d");
let W,H;
function resize(){W=innerWidth;H=innerHeight;c.width=W;c.height=H}
resize();onresize=resize;
// ========== 全新超级复杂游戏数据(100%新版) ==========
let gameState = "menu";
let gameMode = "train";
// 玩家全维度属性
let ply = {
x:0,y:0,speed:3.5,rushSpeed:6,
hp:100,maxHp:100,armor:0,helmet:0,
color:"#ffffff",angle:0,
weapon:"rifle",shootCd:0,reloadCd:0,
mag:30,maxMag:30,ammo:999,
kill:0,totalDmg:0,running:false
};
// 全新5款专业枪械数据
const WEAPON = {
pistol:{dmg:8,cd:0.28,mag:12,spread:0.08,name:"手枪"},
smg:{dmg:5,cd:0.09,mag:40,spread:0.15,name:"冲锋枪"},
shotgun:{dmg:12,cd:0.6,mag:8,spread:0.3,bulletNum:8,name:"散弹枪"},
rifle:{dmg:9,cd:0.13,mag:30,spread:0.06,name:"突击步枪"},
sniper:{dmg:48,cd:1.4,mag:5,spread:0.01,name:"狙击枪"}
};
// 游戏数组
let enemies = [];
let bullets = [];
let items = [];
let effects = [];
let poison = {r:1400,spd:0.08};
let walls = [];
// 摇杆
let joy = {active:false,dx:0,dy:0}
const joyDom = document.getElementById("joy");
const joyInDom = document.getElementById("joyIn");
// ========== UI函数 ==========
function openMode(){closeAllPanel();document.getElementById("modePanel").style.display="flex"}
function openSkin(){closeAllPanel();document.getElementById("skinPanel").style.display="flex"}
function closeAllPanel(){
document.querySelectorAll(".panel").forEach(p=>p.style.display="none");
}
function setMode(m){gameMode=m;closeAllPanel()}
function setSkin(col){ply.color=col}
// ========== 开局初始化全新复杂地图 ==========
function startGame(){
gameState="play";
closeAllPanel();
// 强制游戏横屏
screen.orientation.lock("landscape").catch(e=>{});
// 重置玩家
ply.x=W/2;ply.y=H/2;ply.hp=ply.maxHp;ply.kill=0;ply.totalDmg=0;
ply.mag=WEAPON[ply.weapon].mag;ply.shootCd=0;ply.reloadCd=0;
// 显示操控
joyDom.style.display="block";
shootBtn.style.display="block";
runBtn.style.display="block";
// 生成随机掩体障碍物
walls=[];
for(let i=0;i<12;i++){
walls.push({
x:Math.random()*1200-600+W/2,
y:Math.random()*1200-600+H/2,
w:40+Math.random()*60,
h:40+Math.random()*60
})
}
// 生成敌人
spawnEnemy();
// 重置毒圈
poison.r=1400;
}
// 生成智能AI敌人
function spawnEnemy(){
enemies=[];
let num = gameMode=="train"?3 : gameMode=="stage1"?6 : gameMode=="stage2"?10 : 18;
for(let i=0;i<num;i++){
enemies.push({
x:W/2 + (Math.random()-0.5)*900,
y:H/2 + (Math.random()-0.5)*900,
hp:70+Math.random()*40,
speed:1.2+Math.random()*1.2,
shootCd:Math.random()*2,
state:"patrol", // patrol/chase/attack/hide
dir:Math.random()*Math.PI*2
})
}
}
// ========== 射击系统(后坐力+散布) ==========
function shoot(){
if(ply.shootCd>0||ply.reloadCd>0||ply.mag<=0)return;
let w = WEAPON[ply.weapon];
ply.shootCd = w.cd;
ply.mag--;
// 后坐力偏移
let spread = (Math.random()-0.5)*w.spread;
let bulletNum = w.bulletNum||1;
for(let i=0;i<bulletNum;i++){
bullets.push({
x:ply.x,y:ply.y,
vx:Math.cos(ply.angle+spread)*14,
vy:Math.sin(ply.angle+spread)*14,
dmg:w.dmg
})
}
// 枪口火焰特效
effects.push({x:ply.x,y:ply.y,type:"fire",life:0.15})
}
// ========== 触摸摇杆操控 ==========
joyDom.addEventListener("touchstart",e=>{
joy.active=true;
})
document.addEventListener("touchmove",e=>{
if(!joy.active)return;
let t = e.touches[0];
let rect = joyDom.getBoundingClientRect();
let cx = rect.left+rect.width/2;
let cy = rect.top+rect.height/2;
joy.dx = t.clientX - cx;
joy.dy = t.clientY - cy;
let d = Math.hypot(joy.dx,joy.dy);
if(d>70){joy.dx=joy.dx/d*70;joy.dy=joy.dy/d*70}
joyInDom.style.left = 45+joy.dx+"px";
joyInDom.style.top = 45+joy.dy+"px";
})
document.addEventListener("touchend",()=>{
joy.active=false;joy.dx=0;joy.dy=0;
joyInDom.style.left="45px";joyInDom.style.top="45px";
})
shootBtn.ontouchstart=shoot;
runBtn.ontouchstart=()=>ply.running=true;
runBtn.ontouchend=()=>ply.running=false;
// ========== 主循环(超级复杂更新逻辑) ==========
function loop(){
// 草地地图底色
ctx.fillStyle="#598c56";
ctx.fillRect(0,0,W,H);
if(gameState=="menu"){
// 主页中间角色预览
ctx.fillStyle=ply.color;
ctx.fillRect(W/2-25,H/2-25,50,50);
ctx.fillStyle="#000";
ctx.beginPath();
ctx.arc(W/2-12,H/2-10,5,0,Math.PI*2);
ctx.arc(W/2+12,H/2-10,5,0,Math.PI*2);
ctx.fill();
}
if(gameState=="play"){
// 毒圈收缩
poison.r -= poison.spd;
// 毒圈伤害
let disP = Math.hypot(ply.x-W/2,ply.y-H/2);
if(disP>poison.r) ply.hp -= 0.4;
// 玩家移动
let spd = ply.running?ply.rushSpeed:ply.speed;
ply.x += joy.dx/12*spd;
ply.y += joy.dy/12*spd;
// 冷却计时
if(ply.shootCd>0)ply.shootCd-=1/60;
// 绘制掩体
ctx.fillStyle="#666";
walls.forEach(w=>ctx.fillRect(w.x,w.y,w.w,w.h));
// 更新子弹
for(let i=bullets.length-1;i>=0;i--){
let b=bullets[i];
b.x+=b.vx;b.y+=b.vy;
// 打墙消失
let hitWall = false;
walls.forEach(w=>{
if(b.x>w.x&&b.x<w.x+w.w&&b.y>w.y&&b.y<w.y+w.h)hitWall=true;
})
if(hitWall){bullets.splice(i,1);continue}
// 打敌人
enemies.forEach(e=>{
let d=Math.hypot(b.x-e.x,b.y-e.y);
if(d<28){
e.hp -= b.dmg;
ply.totalDmg += b.dmg;
effects.push({x:e.x,y:e.y,type:"hit",life:0.3})
bullets.splice(i,1);
}
})
// 出界删除
if(Math.abs(b.x-W/2)>1500||Math.abs(b.y-H/2)>1500)bullets.splice(i,1);
}
// 超级智能AI敌人逻辑
enemies.forEach(e=>{
let d = Math.hypot(e.x-ply.x,e.y-ply.y);
// 近距离追击+开枪
if(d<350){
e.state="attack";
e.x += (ply.x-e.x)/d*e.speed;
e.y += (ply.y-e.y)/d*e.speed;
e.shootCd -= 1/60;
if(e.shootCd<=0&&d<280){
e.shootCd=1.2;
let ed = Math.hypot(e.x-ply.x,e.y-ply.y);
ply.hp -= 6;
effects.push({x:ply.x,y:ply.y,type:"hit",life:0.2})
}
}else{
// 远处巡逻
e.state="patrol";
e.dir += (Math.random()-0.5)*0.05;
e.x += Math.cos(e.dir)*e.speed*0.6;
e.y += Math.sin(e.dir)*e.speed*0.6;
}
// 敌人死亡判定
if(e.hp<=0){
ply.kill++;
enemies.splice(enemies.indexOf(e),1);
}
})
// 绘制玩家
ctx.fillStyle=ply.color;
ctx.fillRect(ply.x-22,ply.y-22,44,44);
ctx.fillStyle="#000";
ctx.beginPath();
ctx.arc(ply.x-10,ply.y-10,5,0,Math.PI*2);
ctx.arc(ply.x+10,ply.y-10,5,0,Math.PI*2);
ctx.fill();
// 绘制敌人
enemies.forEach(e=>{
ctx.fillStyle="#d63031";
ctx.fillRect(e.x-22,e.y-22,44,44);
})
// 特效渲染
effects.forEach((ef,i)=>{
ef.life-=1/60;
if(ef.type=="hit"){ctx.fillStyle="#fff";ctx.fillText("击中",ef.x,ef.y-10)}
if(ef.type=="fire"){ctx.fillStyle="#ffaa00";ctx.fillRect(ef.x,ef.y,12,12)}
if(ef.life<=0)effects.splice(i,1);
})
// 绘制毒圈
ctx.strokeStyle="#ff2222";
ctx.lineWidth=4;
ctx.beginPath();
ctx.arc(W/2,H/2,poison.r,0,Math.PI*2);
ctx.stroke();
// UI血量、击杀
ctx.fillStyle="#fff";
ctx.font="bold 20px sans-serif";
ctx.fillText(`血量:${Math.floor(ply.hp)}`,20,35);
ctx.fillText(`击杀:${ply.kill}`,20,65);
ctx.fillText(`弹药:${ply.mag}`,20,95);
}
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>Game Source: Untitled Game
Creator: SparkShark50
Libraries: none
Complexity: complex (354 lines, 11.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: untitled-game-sparkshark50" to link back to the original. Then publish at arcadelab.ai/publish.