一开始想着是通过构造函数来定义小球类,但是发现ES6的class关键字更高级和简便,但这只是简单的运用,如果有什么需要改进的地方或者不足,欢迎大家指出扶正。

首先,我们先定义一个父容器。

<div id="box"></div>

其次,就是给父容器设置定位及其它样式

#box {width: 700px;height: 500px;margin: 100px auto 0;border: 1px solid #FF0000;position: relative;}

最后就是js部分了,这里分为几块,因为是小练习,所以我并没有模块化。

首先,我们定义两个方法,生成随机数和随机色。

//随机数function randomNum(x, y) {let num = Math.floor(Math.random() * (y - x + 1) + x)if (Math.abs(num) > 2) {return num} else {return randomNum(x, y)}}//随机色function randomColor() {let r = randomNum(0, 255)let g = randomNum(0, 255)let b = randomNum(0, 255)return `rgb(${r},${g},${b})`}

其次,定义小球类。

//共同属性:大小,颜色、位置、圆球、速度//共同行为:移动、碰撞(collision)class Ball {constructor(size, color, ballLeft, ballTop, speedX, speedY) {this.size = sizethis.color = colorthis.ballLeft = ballLeftthis.ballTop = ballTopthis.speedX = speedXthis.speedY = speedYthis.r = size / 2}ck = () => {this.domBox = document.createElement("div")this.domBox.style.width = this.size + "px"this.domBox.style.height = this.size + "px"this.domBox.style.borderRadius = "100%"this.domBox.style.backgroundColor = this.colorthis.domBox.style.position = "absolute"box.appendChild(this.domBox)}move = () => {let timer = setInterval(() => {this.domBox.style.left = this.ballLeft + "px"this.domBox.style.top = this.ballTop + "px"this.ballLeft += this.speedXthis.ballTop += this.speedYif (this.ballLeft >= 700 - this.size) {this.speedX = -Math.abs(this.speedX)}if (this.ballLeft <= 0) {this.speedX = Math.abs(this.speedX)}if (this.ballTop >= 500 - this.size) {this.speedY = -Math.abs(this.speedY)}if (this.ballTop <= 0) {this.speedY = Math.abs(this.speedY)}}, 10);}go = function() {this.ck()this.move()}}

然后就是让小球动起来了。

let ballArr = [],coordArr = []Array(5).fill(1).forEach(() => {let ballSize = randomNum(40, 60),ballLeft = randomNum(0, 640),ballTop = randomNum(0, 440),radius = ballSize / 2,axiosX = ballLeft + radius,axiosY = ballTop + radius,judgeCoord = () => {// 判断小球生成位置是否重叠coordArr.forEach(item => {if (Math.abs(item[0] - ballLeft) <= item[2] + radius) {ballSize = randomNum(40, 60)ballLeft = randomNum(0, 640)judgeCoord()}if (Math.abs(item[1] - ballTop) <= item[2] + radius) {ballSize = randomNum(40, 60)ballTop = randomNum(0, 440)judgeCoord()}})}judgeCoord()// 记录球的坐标及半径coordArr.push([axiosX, axiosY, radius])let ball = new Ball(ballSize, randomColor(), ballLeft, ballTop, randomNum(-6, 6), randomNum(-6, 6))ball.go()ballArr.push(ball)})

上面只是实现了小球与父容器的边缘碰撞检测,正常情况下,小球之间的相互碰撞也是需要判断的,所以我们在加个计时器判断每个小球是否碰撞

let isCrash = (obj1, obj2, ballArr) => {let mainR = obj1.r + obj2.rlet distance = Math.sqrt(Math.pow((obj1.left + obj1.r - obj2.left - obj2.r), 2) + Math.pow((obj1.top + obj1.r - obj2.top - obj2.r), 2))if (mainR >= distance) {let vx = obj1.speedXlet vy = obj1.speedYballArr[obj1.index].speedX = obj2.speedXballArr[obj2.index].speedX = vxballArr[obj1.index].speedY = obj2.speedYballArr[obj2.index].speedY = vy}return}this.setInterval(() => {let ballProArr = ballArr.map((item, index) => {return {index,left: item.ballLeft,top: item.ballTop,r: item.r,speedX: item.speedX,speedY: item.speedY}})ballProArr.forEach((item, index) => {let i = 1let judgeBalls = () => {if (index < ballProArr.length - i) {isCrash(item, ballProArr[index + i], ballArr)i++judgeBalls()}return}judgeBalls()})}, 10)

效果图:

完整代码:

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><style type="text/css">#box {width: 700px;height: 500px;margin: 100px auto 0;border: 1px solid #FF0000;position: relative;}</style></head><body><div id="box"></div></body><script type="text/javascript">//随机数function randomNum(x, y) {let num = Math.floor(Math.random() * (y - x + 1) + x)if (Math.abs(num) > 2) {return num} else {return randomNum(x, y)}}//随机色function randomColor() {let r = randomNum(0, 255)let g = randomNum(0, 255)let b = randomNum(0, 255)return `rgb(${r},${g},${b})`}//共同属性:大小,颜色、位置、圆球、速度//共同行为:移动、碰撞(collision)class Ball {constructor(size, color, ballLeft, ballTop, speedX, speedY) {this.size = sizethis.color = colorthis.ballLeft = ballLeftthis.ballTop = ballTopthis.speedX = speedXthis.speedY = speedYthis.r = size / 2}ck = () => {this.domBox = document.createElement("div")this.domBox.style.width = this.size + "px"this.domBox.style.height = this.size + "px"this.domBox.style.borderRadius = "100%"this.domBox.style.backgroundColor = this.colorthis.domBox.style.position = "absolute"box.appendChild(this.domBox)}move = () => {let timer = setInterval(() => {this.domBox.style.left = this.ballLeft + "px"this.domBox.style.top = this.ballTop + "px"this.ballLeft += this.speedXthis.ballTop += this.speedYif (this.ballLeft >= 700 - this.size) {this.speedX = -Math.abs(this.speedX)}if (this.ballLeft <= 0) {this.speedX = Math.abs(this.speedX)}if (this.ballTop >= 500 - this.size) {this.speedY = -Math.abs(this.speedY)}if (this.ballTop <= 0) {this.speedY = Math.abs(this.speedY)}}, 10);}go = function() {this.ck()this.move()}}let ballArr = [],coordArr = []Array(5).fill(1).forEach(() => {let ballSize = randomNum(40, 60),ballLeft = randomNum(0, 640),ballTop = randomNum(0, 440),radius = ballSize / 2,axiosX = ballLeft + radius,axiosY = ballTop + radius,judgeCoord = () => {// 判断小球生成位置是否重叠coordArr.forEach(item => {if (Math.abs(item[0] - ballLeft) <= item[2] + radius) {ballSize = randomNum(40, 60)ballLeft = randomNum(0, 640)judgeCoord()}if (Math.abs(item[1] - ballTop) <= item[2] + radius) {ballSize = randomNum(40, 60)ballTop = randomNum(0, 440)judgeCoord()}})}judgeCoord()// 记录球的坐标及半径coordArr.push([axiosX, axiosY, radius])let ball = new Ball(ballSize, randomColor(), ballLeft, ballTop, randomNum(-6, 6), randomNum(-6, 6))ball.go()ballArr.push(ball)})let isCrash = (obj1, obj2, ballArr) => {let mainR = obj1.r + obj2.rlet distance = Math.sqrt(Math.pow((obj1.left + obj1.r - obj2.left - obj2.r), 2) + Math.pow((obj1.top + obj1.r - obj2.top - obj2.r), 2))if (mainR >= distance) {let vx = obj1.speedXlet vy = obj1.speedYballArr[obj1.index].speedX = obj2.speedXballArr[obj2.index].speedX = vxballArr[obj1.index].speedY = obj2.speedYballArr[obj2.index].speedY = vy}return}this.setInterval(() => {let ballProArr = ballArr.map((item, index) => {return {index,left: item.ballLeft,top: item.ballTop,r: item.r,speedX: item.speedX,speedY: item.speedY}})ballProArr.forEach((item, index) => {let i = 1let judgeBalls = () => {if (index < ballProArr.length - i) {isCrash(item, ballProArr[index + i], ballArr)i++judgeBalls()}return}judgeBalls()})}, 10)</script>
</html>

父容器和某些条件是写死的,需要的同学可以自行改进。

细心的同学会发现我并没有把小球之间的碰撞行为封装在小球类中,因为我暂时还没有找到解决思路,如果你有更好的思路,欢迎与我交流,一起进步!

js通过面向对象编程思想实现小球碰撞的小练习相关推荐

  1. JS用面向对象的思想实现的购物车

    JS用面向对象的思想实现的购物车 首先先了解面向对象的编写思想. 有面向过程的编程和面向对象的编程. 面向过程:举一个经典例子:把大象放进冰箱里. 首先第一个过程是先打开冰箱,2.然后就是把大象放进去 ...

  2. CoreJava学习第五课 --- 进入第二阶段:面向对象编程思想

    面向对象编程思想 1.面向过程 ​ 从计算机执行角度出发 ,代码执行过程核心为从程序的运行过程出发,构建编程思路,例: 哥德巴赫猜想 // 面向过程1 用户输入一个数n2 验证数字的正确性2.1 正确 ...

  3. 面向对象编程思想概览(一)类和对象

    一.简介 生活中有许多技巧值得我们在程序设计中模仿和借鉴.采用类的思想可以方便地把具有相同属性和方法归为一类,从而简化编程.本讲利用生活的常见示例,浅显通俗的语言,生动地介绍了面向对象编程中类与对象的 ...

  4. python完全支持面向对象编程思想_面向对象的编程思想和Python的类,访问和属性,继承...

    本文将从访问限制,属性,继承,方法重写这几个方面继续介绍面向对象的编程思想和Python类的继承. 复制代码 一.访问权限: Python中在类的内部定义属性和方法,在类的外部是可以直接调用或进行访问 ...

  5. 面向对象编程思想概览(三)继承

    一.简介 本讲以大家耳熟能详的<西游记>中的唐僧师徒四人为例,介绍了类的继承的概念和实现方法,总结了继承的特性和优点,帮助同学们理解面向对象编程中继承的用法,进而掌握面向对象程序设计的基本 ...

  6. 面向对象编程思想 以及类与对象

    一.面向对象编程思想 众所周知,我们常见的编程思想有面向过程和面向对象两种,像我们最基础的c语言,就是一种以过程为中心的编程思想,不关注具体的事件和对象而是针对于解决问题的思路和目标,这种编程思想由于 ...

  7. 基于STM32F103移植华为LiteOS_任务挂起与恢复_面向对象编程思想之按键状态机

    华为LiteOS_任务挂起与恢复_面向对象编程思想之按键状态机 因为在做华为LiteOS任务挂起和恢复需要使用到按键去触发任务挂起和恢复动作,因为我就萌发出使用状态机这种架构做一个按键检测触发.回想已 ...

  8. 面向对象编程思想及入门知识

    这几天在调程序,所以想写写自己对"面向对象编程"的一些理解,希望对打算入门计算机编程的同志们有所帮助.之前,好几个师弟问过我,C++与C有什么区别,学习面向对象语言需要掌握哪些基础 ...

  9. 第三章面向对象编程思想

    """ 编码规范: 类名首字母应以大写字母开头 类的成员/属性: 成员属性 实例化对象的属性: self.name=name 可以被访问,也可以在类的外部被修改 私有属性 ...

最新文章

  1. ubuntu安装Android SDK,adb,fastboot
  2. 没有什么效果的html标签,你知道却不常用的HTML标签(一)
  3. 【数据库】数据库基本操作
  4. 电话订票每日开始时间(几点放票) - 北京本地宝
  5. 知识表示学习神器OpenKE:快速获取KG表示
  6. 【flink】Flink 使用IntelliJ IDEA 进行远程调试代码
  7. JavaScript实现MVVM之我就是想监测一个普通对象的变化
  8. Ubuntu技巧之xxx is not in the sudoers file解决方法
  9. CS188-Project4
  10. 燃料电池系统建模(未完待续)
  11. 高中计算机网络说课,高一信息技术说课稿
  12. LaTex下载安装详解
  13. commit 和 push 的临界点
  14. gdb、ida调试笔记
  15. 简易的共享交通系统管理系统
  16. 准备春招 CSDN博客不定期脱更 见谅
  17. android内存最小版本下载,猫和老鼠精简版下载-猫和老鼠内存最小版下载v6.6.1 安卓版-芒果手游网...
  18. 学习使用PN532来复制IC门禁卡
  19. 硅片/SOI绝缘硅片介绍,SOI圆片特点
  20. 【1024】写给最好的你-程序员

热门文章

  1. java 笛卡尔积_笛卡儿积的java实现
  2. multisim12 仿真运放结果不对问题解决
  3. AIX系统月维护查什么(一)
  4. 计算机三级微机原理,计算机三级哪个考 微机原理与应用
  5. R语言线性回归和时间序列分析北京房价影响因素可视化案例
  6. ATC代表空中交通管制。空管调解员不过是机场可用的空中交通管制塔。在这里,您可以看到不同的航班(如101航班、202航班、707航班和808航班)。假设101航班要在机场的一个特定航站楼降落。然后飞行
  7. java使用poi解析Excel文件
  8. php adodb5,常用的php ADODB使用方法集锦
  9. cesium实现给三维建筑物贴图
  10. ubuntu 安装微信wechat、截图工具flameshot、拼音输入法、todesk,百度网盘教程,亲测有效且简洁容易操作