玩个球
本帖最后由 马黑黑 于 2025-11-8 13:00 编辑 <br /><br /><div class="codebox" data-prev="1"><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>玩个球</title>
<style>
.parent { margin: 20px auto; padding: 10px; width: 80vw; height: 80vh; border: 1px solid gray; user-select: none; overflow: hidden; position: relative; }
.parent::before { content: '添加的球球可以在框内自由拖动'; }
.son { --bg1: #998d21; --bg2: #229dee; position: absolute; width: 100px; height: 100px; background: linear-gradient(var(--bg1), var(--bg2)); border-radius: 50%; cursor: move; display: grid; place-items: center; }
.moving { animation: escape var(--du) forwards; }
.tMid { text-align: center; }
#btnAdd { transform: translateX(100px); }
@keyframes escape {
to { left: var(--xx); top: var(--yy); }
}
</style>
</head>
<body>
<div id="pa" class="parent"></div>
<p class="tMid"><input type="button" id="btnAdd" value="添加球球" /></p>
<script>
const pa = document.getElementById('pa');
const sons = [];
let dragger = null;
let offsetX, offsetY, counter = 0;
const startDrag = (e) => {
const target = e.target.closest('.son');
if (!target) return;
dragger = target;
offsetX = e.clientX - target.offsetLeft;
offsetY = e.clientY - target.offsetTop;
e.preventDefault();
};
const doDrag = (e) => {
if (!dragger) return;
let newX = e.clientX - offsetX;
let newY = e.clientY - offsetY;
const maxX = pa.offsetWidth - dragger.offsetWidth;
const maxY = pa.offsetHeight - dragger.offsetHeight;
newX = Math.max(0, Math.min(newX, maxX));
newY = Math.max(0, Math.min(newY, maxY));
dragger.style.left = newX + 'px';
dragger.style.top = newY + 'px';
};
const stopDrag = () => dragger = null;
const endAnimation = () => {
sons.forEach(son => {
son.onanimationend = () => {
pa.removeChild(son);
const rest = document.querySelectorAll('.son');
if (rest.length < 1) {
sons.length = 0;
counter = 0;
btnAdd.disabled = false;
}
}
});
};
pa.addEventListener('touchstart', (e) => {
const touch = e.touches;
const mouseEvent = new MouseEvent('mousedown', {
clientX: touch.clientX,
clientY: touch.clientY
});
startDrag(mouseEvent);
});
document.addEventListener('touchmove', (e) => {
if (!dragger) return;
const touch = e.touches;
const mouseEvent = new MouseEvent('mousemove', {
clientX: touch.clientX,
clientY: touch.clientY
});
doDrag(mouseEvent);
e.preventDefault();
});
btnAdd.addEventListener('click', () => {
counter ++;
if (counter > 10) {
sons.forEach(son => {
son.classList.add('moving');
});
btnAdd.disabled = true;
endAnimation();
return;
}
const son = document.createElement('div');
son.innerText = counter;
son.classList.add('son');
son.style.cssText += `
left: ${Math.floor(Math.random() * (pa.offsetWidth - 100))}px;
top: ${Math.floor(Math.random() * (pa.offsetHeight - 100))}px;
--bg1: #${Math.random().toString(16).substring(2,8)};
--bg2: #${Math.random().toString(16).substring(2,8)};
--du: ${Math.random() * 4 + 2}s;
--xx: ${(Math.random() > 0.5 ? 1 : -1) * window.innerWidth}px;
--yy: ${(Math.random() > 0.5 ? 1 : -1) * window.innerHeight}px;
`;
pa.appendChild(son);
sons.push(son);
});
pa.addEventListener('mousedown', startDrag);
document.addEventListener('mousemove', doDrag);
document.addEventListener('mouseup', stopDrag);
document.addEventListener('touchend', stopDrag);
</script>
</body>
</html>
</div>
<script type="module">
import linenumber from 'https://638183.freep.cn/638183/web/js/linenumber.js';
linenumber();
</script> 玩法:点击代码框右上角“预览”按钮,进入预览模态界面,在该界面点击“添加球球”按钮,主框内会添加随机渐变颜色的球,每点击一次加一个小球。所有添加上去的小球,均可以自由地在框内拖曳。加到一定数量,球球们会跑开,跑的最慢的球球跑到安全地带之后程序重置,可以接着再玩。 实现原理:
一、拖动小球
以改变小球的位置即 left 和 top 属性值达成拖曳的目的。程序监听鼠标指针按下、移动、松开三个事件,不同的事件处理不同的业务,比如按下鼠标左键且按在任意一个小球之上,触发小球可以拖曳条件,此时若不松开按键且移动鼠标指针,小球会跟着鼠标指针走,而松开鼠标指针后小球可移动条件消失、小球不会再跟着鼠标指针走。
二、小球动画
当小球加满10个,再点击“添加球球”按钮,触发小球逃亡动画,它们会四散而去。当最后一个小球的动画运行完毕,重置数据到初始化状态,这时一切可以从头再来。
CSS设计+JS实现机制是开发类似东东的关键。不过这只是一个简单的案例,尚不具备游戏雏形状态,玩玩而已。真要开发游戏,一楼代码展现出来的思路行不通,需要复杂成百上千倍的设计。 JS代码支持移动端操作 好玩,可以添加11个球的动画{:4_174:} 马黑黑 发表于 2025-11-8 12:08
玩法:点击代码框右上角“预览”按钮,进入预览模态界面,在该界面点击“添加球球”按钮,主框内会添加随机 ...
这人的和玩游戏似的,有趣{:4_173:} 马黑黑 发表于 2025-11-8 12:20
实现原理:
一、拖动小球
这些小球的颜色好好看,每点击一下都在猜测下一个渐变的小球是什么颜色的,会落在哪里{:4_187:} 红影 发表于 2025-11-8 15:47
这些小球的颜色好好看,每点击一下都在猜测下一个渐变的小球是什么颜色的,会落在哪里
JS的随机本质上可以破解,但需要做大量的工作才能找到它的算法结果 红影 发表于 2025-11-8 15:46
这人的和玩游戏似的,有趣
不过感觉对移动端拖曳支持不理想,我在这些方面基础薄弱 马黑黑 发表于 2025-11-8 18:49
JS的随机本质上可以破解,但需要做大量的工作才能找到它的算法结果
那就不去找了,只跟着它的算法玩呗。 马黑黑 发表于 2025-11-8 18:50
不过感觉对移动端拖曳支持不理想,我在这些方面基础薄弱
移动端的拖曳有另外的语句么?你能弄好电脑上也很厉害啊{:4_187:} 这些小球以后是初中学习的内容了? 黑黑先预览效果,后面出实题操作 小辣椒 发表于 2025-11-8 21:58
黑黑先预览效果,后面出实题操作
这个只是练手玩玩,没有什么计划 小辣椒 发表于 2025-11-8 21:57
这些小球以后是初中学习的内容了?
幼儿园大班吧 红影 发表于 2025-11-8 20:46
移动端的拖曳有另外的语句么?你能弄好电脑上也很厉害啊
移动端需要另外的代码进行适配,我是放了一组适配代码,但是不好使,改天有空再研究研究,目前精力不再它那里 红影 发表于 2025-11-8 20:45
那就不去找了,只跟着它的算法玩呗。
也行,凭空猜猜也挺好玩 马黑黑 发表于 2025-11-9 12:33
这个只是练手玩玩,没有什么计划
小辣椒是纯欣赏{:4_205:} 马黑黑 发表于 2025-11-9 12:33
幼儿园大班吧
那这个幼儿园大班都是以后的高材生,基础起点就这么高{:4_170:} 小辣椒 发表于 2025-11-9 17:58
那这个幼儿园大班都是以后的高材生,基础起点就这么高
也不一定的。你看宁铂,两岁就背了30多首诗歌,是妥妥的天才,13岁入读中国科大,19岁成为讲师,可是后来并没啥成就,没到40岁就出家做和尚了。幼时聪慧不等于长大后就能成才,还是脚踏实地的好。
页:
[1]
2