草地小人闯关跑酷
by CosmicBear11224 lines4.8 KB🛠️ p5.js (creative coding)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body{margin:0;display:flex;justify-content:center;background:#111}
canvas{border:2px solid white}
</style>
</head>
<body>
<script>
//玩家数据
let playerX = 80;
let playerY;
let playerW = 36;
let playerH = 50;
let jumpPower = -14;
let gravity = 0.6;
let ySpeed = 0;
let isGround = false;
//游戏物体
let ghosts = [];
let coins = [];
let groundY;
let scrollSpeed = 4;
let score = 0;
let level = 1;
const maxLevel = 100;
//游戏状态:playing游戏中 / gameOver失败 / win通关100关
let gameState = "playing";
let restartBtn = {x:0,y:0,w:130,h:50};
function setup(){
createCanvas(400, 600);
groundY = height - 80;
resetGame();
}
//重置游戏函数(重新开始)
function resetGame(){
playerY = groundY - playerH;
ySpeed = 0;
ghosts = [];
coins = [];
scrollSpeed = 4;
if(gameState === "gameOver") level = 1;
gameState = "playing";
loop();
}
function draw(){
background(120,190,255);
drawGrass();
textAlign(LEFT);
fill(255);
textSize(22);
text("关卡:"+level+"/"+maxLevel,15,30);
text("分数:"+score,15,58);
if(gameState === "playing"){
playerPhysics();
spawnObstacleCoin();
updateGhosts();
updateCoins();
drawPlayer();
//本关清除所有障碍,进入下一关
if(ghosts.length === 0 && frameCount > 120){
level++;
scrollSpeed += 0.35;
if(level > maxLevel){
gameState = "win";
noLoop();
}
}
}else if(gameState === "gameOver"){
drawGameOverUI();
}else if(gameState === "win"){
drawWinUI();
}
//点击按钮重新开始
if(mouseIsPressed && checkMouseOnButton()){
resetGame();
}
}
//人物重力、跳跃逻辑
function playerPhysics(){
ySpeed += gravity;
playerY += ySpeed;
if(playerY >= groundY - playerH){
playerY = groundY - playerH;
ySpeed = 0;
isGround = true;
}else isGround = false;
if(mouseIsPressed && isGround) ySpeed = jumpPower;
}
//生成小鬼柱子、金币(柱子高度最高52,保证能跳过去)
function spawnObstacleCoin(){
if(frameCount % Math.floor(85-level*0.6) === 0){
let gh = random(32,52);
ghosts.push({x:width+20,y:groundY-gh,w:30,h:gh});
}
if(frameCount % Math.floor(95-level*0.7) === 0){
coins.push({x:width+20,y:groundY-random(65,135),size:23});
}
}
//更新小鬼障碍
function updateGhosts(){
for(let i=ghosts.length-1;i>=0;i--){
let g = ghosts[i];
g.x -= scrollSpeed;
fill(70,70,70);
rect(g.x,g.y,g.w,g.h,3);
fill(255);
ellipse(g.x+7,g.y+11,5,5);
ellipse(g.x+23,g.y+11,5,5);
if(checkRectHit(playerX,playerY,playerW,playerH,g.x,g.y,g.w,g.h)){
gameState = "gameOver";
noLoop();
}
if(g.x < -g.w) ghosts.splice(i,1);
}
}
//更新金币
function updateCoins(){
for(let i=coins.length-1;i>=0;i--){
let c = coins[i];
c.x -= scrollSpeed;
fill(255,205,0);
ellipse(c.x,c.y,c.size);
fill(210,150,0);
text("$",c.x-7,c.y+8);
if(dist(playerX+playerW/2,playerY+playerH/2,c.x,c.y)<28){
coins.splice(i,1);
score += 8;
}
if(c.x < -c.size) coins.splice(i,1);
}
}
//绘制玩家小人
function drawPlayer(){
fill(255,230,190);
rect(playerX+8,playerY,playerW-16,playerH-18,6);
ellipse(playerX+playerW/2,playerY-6,18,18);
fill(40,40,40);
rect(playerX+10,playerY+34,7,16);
rect(playerX+19,playerY+34,7,16);
}
//草地地面
function drawGrass(){
fill(75,170,40);
rect(0,groundY,width,height-groundY);
stroke(50,140,20);
strokeWeight(2);
for(let x=0;x<width;x+=12){
line(x,groundY,x+4,groundY-12);
}
noStroke();
}
//碰撞检测
function checkRectHit(x1,y1,w1,h1,x2,y2,w2,h2){
return x1<x2+w2 && x1+w1>x2 && y1<y2+h2 && y1+h1>y2;
}
//游戏结束界面
function drawGameOverUI(){
fill(0,0,0,160);
rect(0,0,width,height);
textAlign(CENTER);
fill(255,40,40);
textSize(46);
text("游戏结束",width/2,height/2-60);
//重新开始按钮
restartBtn.x = width/2 - restartBtn.w/2;
restartBtn.y = height/2;
fill(30,160,50);
rect(restartBtn.x,restartBtn.y,restartBtn.w,restartBtn.h,10);
fill(255);
textSize(24);
text("重新开始",width/2,restartBtn.y+32);
}
//通关100关界面
function drawWinUI(){
fill(0,0,0,160);
rect(0,0,width,height);
textAlign(CENTER);
fill(255,220,0);
textSize(44);
text("恭喜通关100关!",width/2,height/2-60);
restartBtn.x = width/2 - restartBtn.w/2;
restartBtn.y = height/2;
fill(30,160,50);
rect(restartBtn.x,restartBtn.y,restartBtn.w,restartBtn.h,10);
fill(255);
textSize(24);
text("重新开始",width/2,restartBtn.y+32);
}
//检测鼠标是否点按钮
function checkMouseOnButton(){
return mouseX>restartBtn.x && mouseX<restartBtn.x+restartBtn.w
&& mouseY>restartBtn.y && mouseY<restartBtn.y+restartBtn.h;
}
</script>
</body>
</html>
Game Source: 草地小人闯关跑酷
Creator: CosmicBear11
Libraries: p5
Complexity: complex (224 lines, 4.8 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-cosmicbear11-mum65fzr" to link back to the original. Then publish at arcadelab.ai/publish.