巨猿进化旷野 | 猿族时代风格
by RocketDragon88340 lines10.1 KB
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>巨猿进化旷野 | 猿族时代风格</title>
<style>
*{margin:0;padding:0;box-sizing:border-box;font-family:system-ui}
body{overflow:hidden;background:#000}
#game{display:block}
#info{
position:absolute;top:10px;left:10px;color:white;
background:rgba(0,0,0,0.65);padding:12px;border-radius:8px;
min-width:280px;line-height:1.5;
z-index:10;
}
#warning{
position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
color:#ffd24d;font-size:32px;font-weight:bold;
text-shadow:0 0 10px #000,0 0 20px #000;
pointer-events:none;opacity:0;
z-index:15;
}
</style>
</head>
<body>
<canvas id="game"></canvas>
<div id="info">
<div>形态:<span id="evo">幼年巨猿</span></div>
<div>等级:<span id="lv">1</span> / 200000</div>
<div id="kingTip"></div>
<div>操作:WASD移动,触碰野怪战斗,触碰蛋吞食</div>
</div>
<div id="warning"></div>
<script>
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// 玩家数据
let player = {
x: canvas.width/2,
y: canvas.height/2,
lv: 1,
size: 28,
speed: 3.2,
evolveStage: 0,
evolveFlash: 0
};
// 进化序列【最终形态:190000级】
const evolveConfig = [
{need:0, name:"幼年巨猿", color:"#a88968", glow:"#ffd700"},
{need:30, name:"蓝焰巨猿", color:"#5a88d8", glow:"#88aaff"},
{need:80, name:"熔岩巨猿", color:"#d84a4a", glow:"#ff6600"},
{need:200, name:"雷霆巨猿", color:"#6b44d8", glow:"#aa66ff"},
{need:500, name:"山岳巨猿", color:"#8b6b4a", glow:"#d4a76a"},
{need:1000, name:"白银巨猿", color:"#d8d8d8", glow:"#ffffff"},
{need:3000, name:"黄金巨猿", color:"#ffd700", glow:"#ffec8b"},
{need:8000, name:"暗影巨猿", color:"#2e1a47", glow:"#8822ff"},
{need:20000, name:"虚空巨猿", color:"#111122", glow:"#cc44ff"},
{need:50000, name:"混沌巨猿", color:"#8b2244", glow:"#ff2266"},
{need:100000,name:"太古巨猿", color:"#102840", glow:"#22ddff"},
{need:150000,name:"洪荒巨猿", color:"#501010", glow:"#ff3333"},
{need:190000,name:"终焉创世巨猿", color:"#050010", glow:"#ffdd22"}
];
// 按键监听
const key = {};
window.addEventListener("keydown",e=>key[e.key.toLowerCase()]=true);
window.addEventListener("keyup",e=>key[e.key.toLowerCase()]=false);
let enemies = [];
let eggs = [];
let hills = [];
// 地形山坡
function spawnHill(){
return {
x: Math.random()*canvas.width,
y: Math.random()*canvas.height,
radius: 35 + Math.random()*80
}
}
// 生成野生巨猿
function spawnEnemy(){
return {
x: Math.random()*canvas.width,
y: Math.random()*canvas.height,
lv: Math.floor(Math.random()*80)+5,
size: 20,
speed:1.2 + Math.random()*1.1,
targetX:0,
targetY:0,
huntKing: false
}
}
// 生成元素蛋
function spawnEgg(){
const type = Math.floor(Math.random()*4);
let addMin,addMax,color,glow;
if(type===0){addMin=3;addMax=8;color="#cccccc";glow="#eeeeee"}
else if(type===1){addMin=10;addMax=22;color="#4298e8";glow="#82c8ff"}
else if(type===2){addMin=25;addMax=45;color="#ffbb22";glow="#ffdd77"}
else {addMin=-35;addMax=55;color="#662277";glow="#aa44dd"}
return {
x: Math.random()*canvas.width,
y: Math.random()*canvas.height,
min:addMin,max:addMax,
color,glow
}
}
// 世界初始化/重置函数
function initWorld(){
player.lv = 1;
player.x = canvas.width/2;
player.y = canvas.height/2;
enemies = [];
eggs = [];
hills = [];
for(let i=0;i<14;i++) enemies.push(spawnEnemy());
for(let i=0;i<22;i++) eggs.push(spawnEgg());
for(let i=0;i<18;i++) hills.push(spawnHill());
updateEvolve();
}
// 更新进化形态
function updateEvolve(){
let newStage = 0;
for(let i=evolveConfig.length-1;i>=0;i--){
if(player.lv >= evolveConfig[i].need){
newStage = i; break;
}
}
if(player.evolveStage !== newStage){
player.evolveFlash = 90; //进化闪光动画
}
player.evolveStage = newStage;
const cfg = evolveConfig[newStage];
document.getElementById("evo").innerText = cfg.name;
document.getElementById("lv").innerText = player.lv;
player.size = 28 + newStage*14;
}
// 获取全场最高等级
function getKingLevel(){
let maxLv = player.lv;
enemies.forEach(e=>{
if(e.lv>maxLv) maxLv = e.lv;
})
return maxLv;
}
function isPlayerKing(){
const maxLv = getKingLevel();
return player.lv === maxLv;
}
// 距离计算
function dist(a,b){
return Math.hypot(a.x-b.x,a.y-b.y);
}
initWorld();
// 游戏主循环
function loop(){
// 20万级重置判定
if(player.lv >= 200000){
alert("🎉抵达200000级!世界重置,新一轮进化开始!");
initWorld();
}
// 玩家移动控制
if(key["w"]) player.y -= player.speed;
if(key["s"]) player.y += player.speed;
if(key["a"]) player.x -= player.speed;
if(key["d"]) player.x += player.speed;
player.x = Math.max(player.size, Math.min(canvas.width-player.size, player.x));
player.y = Math.max(player.size, Math.min(canvas.height-player.size, player.y));
// 吞食蛋
for(let i=eggs.length-1;i>=0;i--){
const e = eggs[i];
if(dist(player,e) < player.size+14){
const gain = Math.floor(Math.random()*(e.max-e.min)+e.min);
player.lv += gain;
if(player.lv < 1) player.lv = 1;
eggs.splice(i,1);
eggs.push(spawnEgg());
updateEvolve();
}
}
// 野怪碰撞吞噬等级
for(let i=enemies.length-1;i>=0;i--){
const en = enemies[i];
if(dist(player,en) < player.size/2 + en.size/2){
player.lv += en.lv;
enemies.splice(i,1);
enemies.push(spawnEnemy());
updateEvolve();
}
}
// 野怪AI逻辑
const kingExists = isPlayerKing();
enemies.forEach(en=>{
if(kingExists){
en.huntKing = Math.random() < 0.35; //35%追杀王者,其余游荡
}else{
en.huntKing = false;
}
if(en.huntKing){
const dx = player.x - en.x;
const dy = player.y - en.y;
en.x += dx*0.016 * en.speed;
en.y += dy*0.016 * en.speed;
}else{
if(Math.random()<0.01){
en.targetX = Math.random()*canvas.width;
en.targetY = Math.random()*canvas.height;
}
const dx = en.targetX - en.x;
const dy = en.targetY - en.y;
en.x += dx*0.009 * en.speed;
en.y += dy*0.009 * en.speed;
}
en.x = Math.max(12,Math.min(canvas.width-12,en.x));
en.y = Math.max(12,Math.min(canvas.height-12,en.y));
})
// ============ 渲染 卡通鲜亮画风(匹配截图画质) ============
// 天空渐变背景
const skyGrad = ctx.createLinearGradient(0,0,0,canvas.height);
skyGrad.addColorStop(0,"#62b8ff");
skyGrad.addColorStop(0.4,"#a4d2ff");
skyGrad.addColorStop(1,"#88c970");
ctx.fillStyle=skyGrad;
ctx.fillRect(0,0,canvas.width,canvas.height);
// 绘制远景山坡
hills.forEach(h=>{
ctx.beginPath();
ctx.arc(h.x,h.y,h.radius,0,Math.PI*2);
const hillGrad = ctx.createRadialGradient(h.x,h.y,0,h.x,h.y,h.radius);
hillGrad.addColorStop(0,"#b2c99c");
hillGrad.addColorStop(1,"#799c62");
ctx.fillStyle = hillGrad;
ctx.fill();
})
// 绘制元素蛋 + 光晕特效
eggs.forEach(e=>{
//外层光晕
ctx.beginPath();
ctx.arc(e.x,e.y,18,0,Math.PI*2);
ctx.fillStyle = e.glow + "50";
ctx.fill();
//蛋本体
ctx.beginPath();
ctx.arc(e.x,e.y,13,0,Math.PI*2);
ctx.fillStyle = e.color;
ctx.fill();
ctx.strokeStyle="#000";
ctx.lineWidth=1.5;
ctx.stroke();
})
// 野生巨猿 + 头顶等级文字
enemies.forEach(en=>{
ctx.beginPath();
ctx.arc(en.x,en.y,en.size+5,0,Math.PI*2);
ctx.fillStyle="#11111155";
ctx.fill();
ctx.beginPath();
ctx.arc(en.x,en.y,en.size,0,Math.PI*2);
ctx.fillStyle="#333333";
ctx.fill();
ctx.strokeStyle="#000";
ctx.lineWidth=2;
ctx.stroke();
//野怪头顶等级(和截图一样彩色字体)
ctx.font = "bold 18px sans-serif";
ctx.fillStyle="#ff3333";
ctx.textAlign="center";
ctx.fillText(`Lv.${en.lv}`,en.x,en.y-en.size-8);
})
// 玩家巨猿渲染
const pCfg = evolveConfig[player.evolveStage];
//进化闪光叠加
if(player.evolveFlash>0){
player.evolveFlash--;
ctx.fillStyle=`rgba(255,255,255,${player.evolveFlash/120})`;
ctx.fillRect(0,0,canvas.width,canvas.height);
}
//外层光环
ctx.beginPath();
ctx.arc(player.x,player.y,player.size+8,0,Math.PI*2);
ctx.fillStyle = pCfg.glow + "55";
ctx.fill();
//主体巨猿
ctx.beginPath();
ctx.arc(player.x,player.y,player.size,0,Math.PI*2);
ctx.fillStyle = pCfg.color;
ctx.fill();
ctx.strokeStyle="#000";
ctx.lineWidth=3;
ctx.stroke();
//玩家头顶等级
ctx.font = "bold 22px sans-serif";
ctx.fillStyle="#ffdd22";
ctx.textAlign="center";
ctx.fillText(`Lv.${player.lv}`,player.x,player.y-player.size-12);
// 王者皇冠判定
const kingTipDom = document.getElementById("kingTip");
if(isPlayerKing()){
kingTipDom.innerText = "👑 旷野王者!所有巨猿感知你的位置";
ctx.font = `${player.size*0.85}px serif`;
ctx.fillText("👑",player.x-player.size/2.2, player.y-player.size-player.size*0.2);
}else{
kingTipDom.innerText = "";
}
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>
Game Source: 巨猿进化旷野 | 猿族时代风格
Creator: RocketDragon88
Libraries: none
Complexity: complex (340 lines, 10.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-rocketdragon88" to link back to the original. Then publish at arcadelab.ai/publish.