趣味开车小游戏
by PrismGalaxy54260 lines8.3 KB
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>趣味开车小游戏</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
touch-action: none;
-webkit-tap-highlight-color: transparent;
}
body {
overflow: hidden;
font-family: "微软雅黑", sans-serif;
background: #f1f1f1;
}
/* 游戏画布 */
#gameBox {
width: 100vw;
height: 70vh;
background: linear-gradient(#87CEEB 8%, #72c247 8%);
position: relative;
overflow: hidden;
}
/* 树木样式 */
.tree {
position: absolute;
width: 48px;
height: 75px;
}
.tree-crown {
width: 48px;
height: 48px;
background: #249130;
border-radius: 50%;
box-shadow: inset -5px -5px 10px #1a6b22;
}
.tree-trunk {
width: 14px;
height: 30px;
background: #795548;
margin: 0 auto;
border-radius: 2px;
}
/* 小车 */
#car {
width: 52px;
height: 30px;
background: #e53935;
border-radius: 8px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(0deg);
box-shadow: 0 2px 6px rgba(0,0,0,0.3);
transition: transform 0.03s linear;
}
/* 车辆窗户 */
#car::before {
content: "";
position: absolute;
width: 20px;
height: 11px;
background: #bbdefb;
border-radius: 2px;
top: 4px;
left: 16px;
}
/* 震动动画 */
.shake {
animation: shake 0.2s ease-in-out;
}
@keyframes shake {
0%,100% { transform: translate(-50%, -50%) rotate(var(--angle)); }
25% { transform: translate(-45%, -50%) rotate(var(--angle)); }
75% { transform: translate(-55%, -50%) rotate(var(--angle)); }
}
/* 信息面板 */
.panel {
position: absolute;
top: 12px;
left: 50%;
transform: translateX(-50%);
background: rgba(0,0,0,0.5);
color: #fff;
padding: 6px 16px;
border-radius: 20px;
font-size: 16px;
z-index: 10;
}
/* 控制区域 */
#controlArea {
width: 100vw;
height: 30vh;
background: #f8f8f8;
display: flex;
justify-content: center;
align-items: center;
}
.keyBoard {
display: grid;
grid-template-columns: 75px 75px 75px;
grid-template-rows: 75px 75px;
gap: 15px;
}
.dirBtn {
width: 75px;
height: 75px;
font-size: 30px;
border: none;
border-radius: 50%;
background: #2196F3;
color: #fff;
box-shadow: 0 5px 0 #1565C0;
}
.dirBtn:active {
transform: translateY(3px);
box-shadow: 0 2px 0 #1565C0;
background: #1976D2;
}
.btn-up { grid-column: 2; grid-row: 1; }
.btn-left { grid-column: 1; grid-row: 2; }
.btn-down { grid-column: 2; grid-row: 2; }
.btn-right { grid-column: 3; grid-row: 2; }
</style>
</head>
<body>
<div id="gameBox">
<div class="panel">分数:<span id="score">0</span> | 连续行驶加分,撞树扣分+震动</div>
<div id="car"></div>
</div>
<div id="controlArea">
<div class="keyBoard">
<button class="dirBtn btn-up">↑</button>
<button class="dirBtn btn-left">←</button>
<button class="dirBtn btn-down">↓</button>
<button class="dirBtn btn-right">→</button>
</div>
</div>
<script>
const gameBox = document.getElementById('gameBox');
const car = document.getElementById('car');
const scoreText = document.getElementById('score');
const btns = document.querySelectorAll('.dirBtn');
// 基础参数
let carX = gameBox.clientWidth / 2;
let carY = gameBox.clientHeight / 2;
let carRotate = 0;
const speed = 5;
let score = 0;
let runTime = 0; // 连续行驶计时
const carW = 52;
const carH = 30;
let treeList = [];
// 生成树木
function initTree(num = 18) {
for(let i = 0; i < num; i++) {
const tree = document.createElement('div');
tree.className = 'tree';
tree.innerHTML = `<div class="tree-crown"></div><div class="tree-trunk"></div>`;
let x = Math.random() * (gameBox.clientWidth - 60);
let y = Math.random() * (gameBox.clientHeight - 80);
tree.style.left = x + 'px';
tree.style.top = y + 'px';
gameBox.appendChild(tree);
treeList.push({el: tree, x, y, w: 48, h: 75});
}
}
initTree();
// 更新车辆位置与样式
function renderCar() {
// 边界限制
carX = Math.max(carW/2, Math.min(carX, gameBox.clientWidth - carW/2));
carY = Math.max(carH/2, Math.min(carY, gameBox.clientHeight - carH/2));
car.style.left = carX + 'px';
car.style.top = carY + 'px';
car.style.setProperty('--angle', carRotate + 'deg');
car.style.transform = `translate(-50%, -50%) rotate(${carRotate}deg)`;
checkHit();
}
// 碰撞检测
function checkHit() {
for(let tree of treeList) {
if(
carX + carW/2 > tree.x &&
carX - carW/2 < tree.x + tree.w &&
carY + carH/2 > tree.y &&
carY - carH/2 < tree.y + tree.h
) {
// 撞树扣分+震动
score -= 8;
scoreText.innerText = score;
car.classList.add('shake');
setTimeout(()=> car.classList.remove('shake'), 200);
// 回退位置
carX -= (carRotate === 0 ? speed : carRotate === 180 ? -speed : 0);
carY -= (carRotate === 90 ? speed : carRotate === 270 ? -speed : 0);
runTime = 0; // 中断连续计分
break;
}
}
}
// 按键控制
btns.forEach(btn => {
let moveInterval = null;
btn.addEventListener('touchstart', e => {
e.preventDefault();
moveInterval = setInterval(() => {
if(btn.classList.contains('btn-up')){
carY -= speed;
carRotate = 0;
}else if(btn.classList.contains('btn-down')){
carY += speed;
carRotate = 180;
}else if(btn.classList.contains('btn-left')){
carX -= speed;
carRotate = 270;
}else if(btn.classList.contains('btn-right')){
carX += speed;
carRotate = 90;
}
renderCar();
}, 20);
});
btn.addEventListener('touchend', () => {
clearInterval(moveInterval);
});
});
// 连续行驶加分
setInterval(() => {
runTime++;
if(runTime >= 3) { // 平稳行驶3秒开始加分
score += 2;
scoreText.innerText = score;
}
}, 1000);
// 窗口适配重置
window.addEventListener('resize', () => {
carX = gameBox.clientWidth / 2;
carY = gameBox.clientHeight / 2;
renderCar();
});
</script>
</body>
</html>
.htmlGame Source: 趣味开车小游戏
Creator: PrismGalaxy54
Libraries: none
Complexity: complex (260 lines, 8.3 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-prismgalaxy54" to link back to the original. Then publish at arcadelab.ai/publish.