用html5写一个打巴掌大赛
我来帮你创建一个打巴掌大赛的HTML5游戏。这个游戏使用Canvas绘制,支持点击互动
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>打巴掌大赛</title>
<style>
body {
margin: 0;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
font-family: Arial, sans-serif;
}
canvas {
border: 3px solid #fff;
border-radius: 15px;
cursor: pointer;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
background: #f0f0f0;
}
.score {
position: absolute;
top: 30px;
left: 50%;
transform: translateX(-50%);
color: white;
font-size: 24px;
font-weight: bold;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
</style>
</head>
<body>
<div class="score">打巴掌大赛</div>
<canvas id="gameCanvas" width="800" height="400"></canvas>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
let leftScore = 0;
let rightScore = 0;
let isAnimating = false;
// 左边巴掌
const leftHand = {
x: 150,
y: 200,
angle: 0,
targetAngle: 0,
isSlapping: false
};
// 右边巴掌
const rightHand = {
x: 650,
y: 200,
angle: 0,
targetAngle: 0,
isSlapping: false
};
function drawFace(x, y, size, isLeft) {
// 画脸
ctx.fillStyle = '#fdbcb4';
ctx.beginPath();
ctx.arc(x, y, size, 0, Math.PI * 2);
ctx.fill();
// 脸轮廓
ctx.strokeStyle = '#f4a28c';
ctx.lineWidth = 3;
ctx.stroke();
// 眼睛
const eyeX = isLeft ? x - 20 : x + 20;
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.arc(eyeX, y - 15, 8, 0, Math.PI * 2);
ctx.fill();
// 眼睛高光
ctx.fillStyle = '#fff';
ctx.beginPath();
ctx.arc(eyeX + 2, y - 17, 3, 0, Math.PI * 2);
ctx.fill();
// 鼻子
ctx.fillStyle = '#f4a28c';
ctx.beginPath();
ctx.arc(x, y + 5, 4, 0, Math.PI * 2);
ctx.fill();
// 嘴巴
ctx.strokeStyle = '#333';
ctx.lineWidth = 2;
ctx.beginPath();
if (isLeft && leftHand.isSlapping) {
// 被打时的表情
ctx.arc(x, y + 25, 15, 0, Math.PI, false);
} else if (!isLeft && rightHand.isSlapping) {
ctx.arc(x, y + 25, 15, 0, Math.PI, false);
} else {
ctx.arc(x, y + 25, 15, 0, Math.PI, true);
}
ctx.stroke();
// 脸颊(被打时变红)
if ((isLeft && leftHand.isSlapping) || (!isLeft && rightHand.isSlapping)) {
ctx.fillStyle = 'rgba(255, 0, 0, 0.3)';
ctx.beginPath();
ctx.arc(isLeft ? x + 35 : x - 35, y + 10, 20, 0, Math.PI * 2);
ctx.fill();
}
}
function drawHand(hand) {
ctx.save();
ctx.translate(hand.x, hand.y);
ctx.rotate(hand.angle);
// 手
ctx.fillStyle = '#fdbcb4';
ctx.beginPath();
ctx.ellipse(0, 0, 25, 35, 0, 0, Math.PI * 2);
ctx.fill();
// 手指
ctx.beginPath();
ctx.moveTo(-15, -20);
ctx.lineTo(-20, -35);
ctx.lineTo(-15, -35);
ctx.lineTo(-10, -20);
ctx.closePath();
ctx.fill();
ctx.beginPath();
ctx.moveTo(0, -25);
ctx.lineTo(-5, -40);
ctx.lineTo(0, -40);
ctx.lineTo(5, -25);
ctx.closePath();
ctx.fill();
ctx.beginPath();
ctx.moveTo(15, -20);
ctx.lineTo(10, -35);
ctx.lineTo(15, -35);
ctx.lineTo(20, -20);
ctx.closePath();
ctx.fill();
// 手腕
ctx.strokeStyle = '#fdbcb4';
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(0, 25);
ctx.lineTo(0, 50);
ctx.stroke();
ctx.restore();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 画脸
drawFace(200, 150, 60, true); // 左脸
drawFace(600, 150, 60, false); // 右脸
// 画手
drawHand(leftHand);
drawHand(rightHand);
// 画分数
ctx.fillStyle = '#333';
ctx.font = 'bold 24px Arial';
ctx.fillText(`分数: ${leftScore}`, 50, 50);
ctx.fillText(`分数: ${rightScore}`, 600, 50);
// 动画
if (leftHand.isSlapping && leftHand.angle < leftHand.targetAngle) {
leftHand.angle += 0.1;
if (leftHand.angle >= Math.PI / 3) {
rightScore++;
leftHand.isSlapping = false;
leftHand.targetAngle = 0;
}
} else if (!leftHand.isSlapping && leftHand.angle > 0) {
leftHand.angle -= 0.1;
if (leftHand.angle < 0) {
leftHand.angle = 0;
}
}
if (rightHand.isSlapping && rightHand.angle > rightHand.targetAngle) {
rightHand.angle -= 0.1;
if (rightHand.angle <= -Math.PI / 3) {
leftScore++;
rightHand.isSlapping = false;
rightHand.targetAngle = 0;
}
} else if (!rightHand.isSlapping && rightHand.angle < 0) {
rightHand.angle += 0.1;
if (rightHand.angle > 0) {
rightHand.angle = 0;
}
}
requestAnimationFrame(draw);
}
// 点击事件
canvas.addEventListener('click', (e) => {
if (isAnimating) return;
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// 点击左手
if (x > 100 && x < 200 && y > 150 && y < 250) {
if (!leftHand.isSlapping) {
leftHand.isSlapping = true;
leftHand.targetAngle = Math.PI / 3;
isAnimating = true;
setTimeout(() => {
isAnimating = false;
}, 500);
}
}
// 点击右手
if (x > 600 && x < 700 && y > 150 && y < 250) {
if (!rightHand.isSlapping) {
rightHand.isSlapping = true;
rightHand.targetAngle = -Math.PI / 3;
isAnimating = true;
setTimeout(() => {
isAnimating = false;
}, 500);
}
}
});
// 开始游戏
draw();
</script>
</body>
</html>
以上是打巴掌大赛HTML5游戏的实现代码,这份代码实现了:
-
游戏界面设计
-
使用Canvas绘制整个游戏场景
-
紫色渐变背景和白色边框营造游戏氛围
-
包含分数显示区域
-
-
角色绘制
-
使用
drawFace()函数绘制卡通人脸 -
包含脸部、眼睛、鼻子、嘴巴等细节
-
被打时脸颊会变红,嘴巴会变形
-
-
交互功能
-
点击左右巴掌触发攻击动画
-
使用
requestAnimationFrame实现流畅动画 -
攻击时巴掌会旋转,模拟挥掌动作
-
-
游戏机制
-
左右巴掌分别对应不同玩家
-
成功击中对方得分
-
防止连续点击的动画锁定机制
-
-
视觉效果
-
被打时角色脸颊泛红
-
嘴巴呈现痛苦表情
-
平滑的旋转动画效果
-
使用方法:将代码保存为HTML文件,用浏览器打开即可游玩。
