javascript实现10个球随机运动、碰撞实例详解_javascript技巧
本文实例讲述了javascript实现10个球随机运动、碰撞的方法。分享给大家供大家参考。具体如下:
学了一段时间的javascript了,做过一些小案例,目前最有难度的就是10个小球随机碰撞效果,这不,把它上上来与大家分享一下,相信不少和我一样的菜鸟在开始上手编程时都会有不少的困惑,希望它能给一些人带来帮助。
效果要求:10个小球在页面随机移动,碰到窗口边界或其他小球都会反弹
思路:
1、10个小球是10个div;
2、碰窗口反弹,定义vx vy为小球的移动变量,以及一个弹力变量bounce(负值),小球碰窗口边界时,vx vy分别乘以bounce,则改变了小球移动方向
3、小球相碰反弹,说简单点,当两个小球的圆心距变量dist小于其最小值(半径之和)则改变球的移动方向,实现反弹
好了,代码如下:
html和js是分开的文件哟
test.html文件如下:
<html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <style type="text/css"> body { margin:0; padding:0; text-align: center; } #screen { width: 800px; height: 640px; position: relative; background: #ccccff;margin: 0 auto;vertical-align: bottom} #inner { position: absolute; left:0px; top:0px; width:100%; height:100%; } #screen p {color:white;font:bold 14px;} .one { background-image:url('bubble.png'); background-position: -66px -58px; } .two { background-image:url('bubble.png'); background-position: -66px -126px;} .three { background-image:url('bubble.png'); background-position: -66px -194px; } .four { background-image:url('bubble.png'); background-position: -66px -263px; } .five { background-image:url('bubble.png'); background-position: -66px -331px; } .six { background-image:url('bubble.png'); background-position: -66px -399px; } .seven { background-image:url('bubble.png'); background-position: -66px -194px; } .eight { background-image:url('bubble.png'); background-position: -66px -263px; } .nine { background-image:url('bubble.png'); background-position: -66px -331px; } .ten{ background-image:url('bubble.png'); background-position: -66px -399px; } </style> </head> <body> <div id="screen" > <p>hi test it!</p> <div id="inner"></div> </div> <input type="button" id="start" value="start" > <input type="button" id="stop" value="stop"> <br><br><br> <script type="text/javascript" src="test.js"></script> </body> </html>
test.js文件如下:
var getFlag=function (id) { return document.getElementByIdx_x(id); //获取元素引用 } var extend=function(des, src) { for (p in src) { des[p]=src[p]; } return des; } var clss=['one','two','three','four','five','six','seven','eight','nine','ten']; var Ball=function (diameter,classn) { var ball=document.createElement_x("div"); ball.className=classn; with(ball.style) { width=height=diameter+'px';position='absolute'; } return ball; } var Screen=function (cid,config) { //先创建类的属性 var self=this; if (!(self instanceof Screen)) { return new Screen(cid,config) } config=extend(Screen.Config, config) //configj是extend类的实例 self.container=getFlag(cid); //窗口对象 self.ballsnum=config.ballsnum; self.diameter=56; //球的直径 self.radius=self.diameter/2; self.spring=config.spring; //球相碰后的反弹力 self.bounce=config.bounce; //球碰到窗口边界后的反弹力 self.gravity=config.gravity; //球的重力 self.balls=[]; //把创建的球置于该数组变量 self.timer=null; //调用函数产生的时间id self.L_bound=0; //container的边界 self.R_bound=self.container.clientWidth; self.T_bound=0; self.B_bound=self.container.clientHeight; }; Screen.Config={ //为属性赋初值 ballsnum:10, spring:0.8, bounce:-0.9, gravity:0.05 }; Screen.prototype={ initialize:function () { var self=this; self.createBalls(); self.timer=setInterval(function (){self.hitBalls()}, 30) }, createBalls:function () { var self=this, num=self.ballsnum; var frag=document.createDocumentFragment(); //创建文档碎片,避免多次刷新 for (i=0;i<num;i++) { var ball=new Ball(self.diameter,clss[ Math.floor(Math.random()* num )]); ball.diameter=self.diameter; ball.radius=self.radius; ball.style.left=(Math.random()*self.R_bound)+'px'; //球的初始位置, ball.style.top=(Math.random()*self.B_bound)+'px'; ball.vx=Math.random() * 6 -3; ball.vy=Math.random() * 6 -3; frag.appendChild(ball); self.balls[i]=ball; } self.container.appendChild(frag); }, hitBalls:function () { var self=this, num=self.ballsnum,balls=self.balls; for (i=0;i<num-1;i++) { var ball1=self.balls[i]; ball1.x=ball1.offsetLeft+ball1.radius; //小球圆心坐标 ball1.y=ball1.offsetTop+ball1.radius; for (j=i+1;j<num;j++) { var ball2=self.balls[j]; ball2.x=ball2.offsetLeft+ball2.radius; ball2.y=ball2.offsetTop+ball2.radius; dx=ball2.x-ball1.x; //两小球圆心距对应的两条直角边 dy=ball2.y-ball1.y; var dist=Math.sqrt(dx*dx + dy*dy); //两直角边求圆心距 var misDist=ball1.radius+ball2.radius; //圆心距最小值 if(dist < misDist) { //假设碰撞后球会按原方向继续做一定的运动,将其定义为运动A var angle=Math.atan2(dy,dx); //当刚好相碰,即dist=misDist时,tx=ballb.x, ty=ballb.y tx=balla.x+Math.cos(angle) * misDist; ty=balla.y+Math.sin(angle) * misDist; //产生运动A后,tx > ballb.x, ty > ballb.y,所以用ax、ay记录的是运动A的值 ax=(tx-ballb.x) * self.spring; ay=(ty-ballb.y) * self.spring; //一个球减去ax、ay,另一个加上它,则实现反弹 balla.vx-=ax; balla.vy-=ay; ballb.vx+=ax; ballb.vy+=ay; } } } for (i=0;i<num;i++) { self.moveBalls(balls[i]); } }, moveBalls:function (ball) { var self=this; ball.vy+=self.gravity; ball.style.left=(ball.offsetLeft+ball.vx)+'px'; ball.style.top=(ball.offsetTop+ball.vy)+'px'; //判断球与窗口边界相碰,把变量名简化一下 var L=self.L_bound, R=self.R_bound, T=self.T_bound, B=self.B_bound, BC=self.bounce; if (ball.offsetLeft < L) { ball.style.left=L; ball.vx*=BC; } else if (ball.offsetLeft + ball.diameter > R) { ball.style.left=(R-ball.diameter)+'px'; ball.vx*=BC; } else if (ball.offsetTop < T) { ball.style.top=T; ball.vy*=BC; } if (ball.offsetTop + ball.diameter > B) { ball.style.top=(B-ball.diameter)+'px'; ball.vy*=BC; } } } window.onload=function() { var sc=null; getFlag('start').onclick=function () { document.getElementByIdx_x("inner").innerHTML=''; sc=new Screen('inner',{ballsnum:10, spring:0.8, bounce:-0.9, gravity:0.05}); sc.initialize(); } getFlag('stop').onclick=function() { clearInterval(sc.timer); } }
测试后的效果还是很不错的,各位也许会觉得代码挺长,但是其思路还是蛮清晰的:
首先创建Screen类,并在Screen的构造函数中给出了球移动、碰撞所需的各种属性变量,如ballsnum、spring、bounce、gravity等等
然后用原型prototype给出相应的函数,如创建球,createBalls,球碰撞hitBalls,球移动moveBalls,给每个函数添加相应的功能、
最后用按钮点击事件调用函数,仅此而已。
希望本文所述对大家的javascript程序设计有所帮助。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

JavaScript中的HTTP状态码获取方法简介:在进行前端开发中,我们常常需要处理与后端接口的交互,而HTTP状态码就是其中非常重要的一部分。了解和获取HTTP状态码有助于我们更好地处理接口返回的数据。本文将介绍使用JavaScript获取HTTP状态码的方法,并提供具体代码示例。一、什么是HTTP状态码HTTP状态码是指当浏览器向服务器发起请求时,服务

用法:在JavaScript中,insertBefore()方法用于在DOM树中插入一个新的节点。这个方法需要两个参数:要插入的新节点和参考节点(即新节点将要被插入的位置的节点)。
