<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./style.css">
<title>快乐母鸡</title>
</head>
<body>
<main>
<div class="container"></div>
<div id="counter">000</div>
</main>
<script src="./index.js"></script>
</body>
</html>
index.html
style.css
index.js
现在支持上传本地图片了!
body {
background-color: skyblue;
overflow: hidden;
}
main {
position: relative;
}
#counter {
position: absolute;
right: 0.5rem;
top: 0.25rem;
padding: 0.5rem 1rem;
font-size: 2rem;
font-family: Consolas, 'Cambria Math', sans-serif;
background-color: rgba(128, 128, 128, 0.3);
border-radius: 2rem;
}
.egg {
width: 32px;
height: 32px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'%3E%3Cpath fill='%23ffc294' d='M53.6 29.8C51.1 11.8 39.7 2 32 2s-19.1 9.8-21.6 27.8C8 47.8 15.9 62 32 62s24-14.2 21.6-32.2'/%3E%3Cpath fill='%23d3976e' d='M53.6 29.8c-2-14.2-9.5-23.3-16.4-26.5c4.7 4.7 8.9 12.1 10.2 22.1c2.5 18-5.4 32.2-21.6 32.2c-3.5 0-6.6-.7-9.2-1.9c3.7 4 8.9 6.3 15.4 6.3c16.1 0 24-14.2 21.6-32.2' opacity='0.33'/%3E%3C/svg%3E");
}
.hen {
width: 96px;
height: 96px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'%3E%3Cpath fill='%23f29a2e' d='M7.6 20.4c1.8 2.9 3.8 3.3 5.2 1.6c2.2-2.6-.2-5.9-2.8-6.8c-4.3-1.7-8 3.1-8 3.1s4.1-.4 5.6 2.1'/%3E%3Cpath fill='%23e1eaf2' d='M42.8 10.2c-7.7 4.5-1.3 15.3-15.2 18.2l14.8 7.3c3 5.2 11.3 5.6 11.3 5.6s2.1-6.2.4-10.8c4.6 0 7.8-2.8 7.8-2.8s-2.6-9.2-10.5-9.2c7.8-3.2 9.2-9.8 9.2-9.8s-6.9-4.8-17.8 1.5'/%3E%3Cpath fill='%23f4bc58' d='M35.7 62H21.4c0-1.2 8.4-1.4 8.8-9.4c1.3 8.9 5.5 8.2 5.5 9.4'/%3E%3Cg fill='%23d1dce6'%3E%3Cpath d='M49.4 30.6c0 11.5-9.4 23.3-21 23.3s-21-11.8-21-23.3c0-7.7 16.6-2.3 21-2.3c11.6-.1 21-9.3 21 2.3'/%3E%3Cpath d='M36.4 49.2c0 2.3-3.3 7.3-6.2 7.3S24 53.1 24 50.8s12.4-2.7 12.4-1.6'/%3E%3C/g%3E%3Cpath fill='%23e1eaf2' d='M6.5 26.3c0 3 .6 11.7.6 11.7l2.7-3.4l3.2 3.8l.7-5.3l4.9 3.5l-.9-5.2l5.9.6l-2.7-3.2l4.1-2.7s-5 1.1-4.9-2s2.6-11.9-.5-13.2C13.9 8.8 6.5 13.6 6.5 26.3'/%3E%3Cg fill='%233e4347'%3E%3Cellipse cx='6.5' cy='16.1' rx='.7' ry='.3'/%3E%3Ccircle cx='11.5' cy='16.7' r='1.5'/%3E%3C/g%3E%3Cg fill='%23e24b4b'%3E%3Cpath d='M7.8 23.6c0 3.2-2.1.9-2.1.9c-.7 0-3.6 2.2-2.6-1.5c1.3-4.8 6.3-8 6.3-8s-1.6 2.8-1.6 8.6'/%3E%3Cpath d='M20.8 10.6V9.4c-.2-2.5 3.4-3.5 3-4.8c-.6-1.7-5.3-.6-7.6 3.1q-.45.6-.6 1.5c-.1-.4-.2-.8-.4-1.2c-1.1-2.3 2.2-4.4 1.2-5.5c-1.3-1.5-5.2 1.1-6.1 5.4c-.2.9-.2 1.8.1 2.7c-.1-.1-.2-.2-.3-.2c-1.7-1.3 0-4-1.2-4.6c-1.8-.8-3.4 2.8-2.5 6.3c.6 2 2.8 4.1 4.6 2.4c.6-.5 2-1.3 2.8-1.6c.6-.2 2.2-.1 3.2.6c.9.6 1.6 1.8 2.9 1.8c5.7.2 8.8-5.3 6.7-6.5c-1.1-.8-2.8 1.2-5.8 1.8'/%3E%3C/g%3E%3Cpath fill='%23e1eaf2' d='M42.5 43.9c-.9-2.2-3.5-3.4-3.5-3.4c2.7-1.4 4.3-4.4 4.3-4.4c-1.4-.6-6.8-1-6.8-1c1.2-1.2 2.2-2.9 2.2-2.9s-6.2-1.5-11.4 1.3c-6.8 3.8-4.8 12.8 2.9 13.8c8.5 1.1 12.3-3.4 12.3-3.4'/%3E%3C/svg%3E");
transition-property: left, top;
transition-duration: 1s;
transition-timing-function: ease-in-out;
}
.egg,
.hen {
background-size: contain;
background-repeat: no-repeat;
position: absolute;
}
// 常量配置区
const PERIOD = 2000; // ms
const LAY_EGG_DELAY = 1200; // ms
const GAME_LENGTH = 120 * 1000;
const PROB = (cnt) => 0.1 + 0.9 / cnt;
const DIGITS = 3;
const EGG_X_OFFSET = 64;
const EGG_Y_OFFSET = 72;
const HATCH_X_OFFSET = -16;
const HATCH_Y_OFFSET = -16;
const HEN_SIZE = 96;
const container = document.querySelector('.container');
let counter = 0;
let running = true;
const intervalHandles = [];
function setCounter(newValue) {
counter = newValue;
document.querySelector("#counter").textContent = counter.toString().padStart(DIGITS, '0');
}
function createHen(x, y) {
const hen = document.createElement("div");
hen.classList.add('hen');
container.append(hen);
hen.style.left = `${x}px`;
hen.style.top = `${y}px`;
setCounter(counter + 1);
const intervalHandle = setInterval(() => moveHen(hen), PERIOD);
intervalHandles.push(intervalHandle);
}
function moveHen(hen) {
const x = randomX();
const y = randomY();
hen.style.left = `${x}px`;
hen.style.top = `${y}px`;
if (Math.random() < PROB(counter)) {
setTimeout(() => layEgg(x + EGG_X_OFFSET, y + EGG_Y_OFFSET), LAY_EGG_DELAY);
}
}
function layEgg(x, y) {
if (!running) {
return;
}
const egg = document.createElement("div");
egg.classList.add('egg');
container.appendChild(egg);
egg.style.left = `${x}px`;
egg.style.top = `${y}px`;
egg.addEventListener('click', hatchEgg);
}
function hatchEgg(event) {
if (!running) {
return;
}
event.target.remove();
createHen(event.clientX + HATCH_X_OFFSET, event.clientY + HATCH_Y_OFFSET);
}
function init() {
createHen(randomX(), randomY());
setTimeout(shutDown, GAME_LENGTH);
}
function shutDown() {
running = false;
const counterElement = document.querySelector("#counter");
counterElement.style.color = "green";
for (const intervalHandle of intervalHandles) {
clearInterval(intervalHandle);
}
}
function randomX() {
return Math.random() * (document.documentElement.clientWidth - HEN_SIZE);
}
function randomY() {
return Math.random() * (document.documentElement.clientHeight - HEN_SIZE);
}
init();
预览