HTML5实现碰撞小球

合集下载

javascript实现10个球随机运动、碰撞实例详解

javascript实现10个球随机运动、碰撞实例详解

javascript实现10个球随机运动、碰撞实例详解本⽂实例讲述了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; //调⽤函数产⽣的时间idself.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) {//假设碰撞后球会按原⽅向继续做⼀定的运动,将其定义为运动Avar angle=Math.atan2(dy,dx);//当刚好相碰,即dist=misDist时,tx=ballb.x, ty=ballb.ytx=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,给每个函数添加相应的功能、最后⽤按钮点击事件调⽤函数,仅此⽽已。

HTML5重力感应小球冲撞动画实现教程

HTML5重力感应小球冲撞动画实现教程

HTML5重⼒感应⼩球冲撞动画实现教程今天我们来分享⼀款很酷的HTML5重⼒感应动画教程,这款动画可以让你甩动页⾯中的⼩球,⼩球的⼤⼩都不同,并且⿏标点击空⽩区域时⼜可以⽣成⼀定数量的⼩球。

当我们甩动⼩球时,各个⼩球之间就会发⽣互相碰撞的效果,并且在运动过程中模拟了重⼒感应的物理效果。

你可以在DEMO演⽰中来尝试⼀下。

你也可以在这⾥查看接下来我们来分析⼀下这款超酷的HTML5重⼒动画实现的思路及源码,主要由HTML代码和Javascript代码组成。

HTML代码:<div id="canvas"></div>还是很简单,HTML仅仅是列出了⼀个canvas容器,今后我们将在这⾥⽣成⼀些列canvas元素,这些⼩球就在canvas中运动。

另外由于该动画利⽤了box2d的js脚本库,所以在页⾯上你也需要引⽤它:<script src="box2d.js"></script>接下来是Javascript代码,在canvas上动态创建⼤⼩和样式不⼀的⼩球,并发⽣碰撞效果。

Javascript代码:var canvas;var delta = [ 0, 0 ];var stage = [ window.screenX, window.screenY, window.innerWidth, window.innerHeight ];getBrowserDimensions();var themes = [ [ "#10222B", "#95AB63", "#BDD684", "#E2F0D6", "#F6FFE0" ],[ "#362C2A", "#732420", "#BF734C", "#FAD9A0", "#736859" ],[ "#0D1114", "#102C2E", "#695F4C", "#EBBC5E", "#FFFBB8" ],[ "#2E2F38", "#FFD63E", "#FFB54B", "#E88638", "#8A221C" ],[ "#121212", "#E6F2DA", "#C9F24B", "#4D7B85", "#23383D" ],[ "#343F40", "#736751", "#F2D7B6", "#BFAC95", "#8C3F3F" ],[ "#000000", "#2D2B2A", "#561812", "#B81111", "#FFFFFF" ],[ "#333B3A", "#B4BD51", "#543B38", "#61594D", "#B8925A" ] ];var theme;var worldAABB, world, iterations = 1, timeStep = 1 / 15;var walls = [];var wall_thickness = 200;var wallsSetted = false;var bodies, elements, text;var createMode = false;var destroyMode = false;var isMouseDown = false;var mouseJoint;var mouse = { x: 0, y: 0 };var gravity = { x: 0, y: 1 };var PI2 = Math.PI * 2;var timeOfLastTouch = 0;init();play();function init() {canvas = document.getElementById( 'canvas' );document.onmousedown = onDocumentMouseDown;document.onmouseup = onDocumentMouseUp;document.onmousemove = onDocumentMouseMove;document.ondblclick = onDocumentDoubleClick;document.addEventListener( 'touchstart', onDocumentTouchStart, false );document.addEventListener( 'touchmove', onDocumentTouchMove, false );document.addEventListener( 'touchend', onDocumentTouchEnd, false );window.addEventListener( 'deviceorientation', onWindowDeviceOrientation, false );// init box2dworldAABB = new b2AABB();worldAABB.minVertex.Set( -200, -200 );worldAABB.maxVertex.Set( window.innerWidth + 200, window.innerHeight + 200 );world = new b2World( worldAABB, new b2Vec2( 0, 0 ), true );setWalls();reset();}function play() {setInterval( loop, 1000 / 40 );}function reset() {var i;if ( bodies ) {for ( i = 0; i < bodies.length; i++ ) {var body = bodies[ i ]canvas.removeChild( body.GetUserData().element );world.DestroyBody( body );body = null;}}// color themetheme = themes[ Math.random() * themes.length >> 0 ];document.body.style[ 'backgroundColor' ] = theme[ 0 ];bodies = [];createInstructions();for( i = 0; i < 10; i++ ) {createBall();}}//function onDocumentMouseDown() {isMouseDown = true;return false;}function onDocumentMouseUp() {isMouseDown = false;return false;}function onDocumentMouseMove( event ) {mouse.x = event.clientX;mouse.y = event.clientY;}function onDocumentDoubleClick() {reset();}function onDocumentTouchStart( event ) {if( event.touches.length == 1 ) {event.preventDefault();// Faking double click for touch devicesvar now = new Date().getTime();if ( now - timeOfLastTouch < 250 ) {reset();return;}timeOfLastTouch = now;mouse.x = event.touches[ 0 ].pageX;mouse.y = event.touches[ 0 ].pageY;isMouseDown = true;}}function onDocumentTouchMove( event ) {if ( event.touches.length == 1 ) {event.preventDefault();mouse.x = event.touches[ 0 ].pageX;mouse.y = event.touches[ 0 ].pageY;}}function onDocumentTouchEnd( event ) {if ( event.touches.length == 0 ) {event.preventDefault();isMouseDown = false;}}function onWindowDeviceOrientation( event ) {if ( event.beta ) {gravity.x = Math.sin( event.gamma * Math.PI / 180 );gravity.y = Math.sin( ( Math.PI / 4 ) + event.beta * Math.PI / 180 ); }}//function createInstructions() {var size = 250;var element = document.createElement( 'div' );element.width = size;element.height = size;element.style.position = 'absolute';element.style.left = -200 + 'px';element.style.top = -200 + 'px';element.style.cursor = "default";canvas.appendChild(element);elements.push( element );var circle = document.createElement( 'canvas' );circle.width = size;circle.height = size;var graphics = circle.getContext( '2d' );graphics.fillStyle = theme[ 3 ];graphics.beginPath();graphics.arc( size * .5, size * .5, size * .5, 0, PI2, true );graphics.closePath();element.appendChild( circle );text = document.createElement( 'div' );text.onSelectStart = null;text.innerHTML = '<span style="color:' + theme[0] + ';font-size:40px;">Hello!</span><br /><br /><span style="font-size:15px;"><strong>This is how it works:</strong><br /><br />1. Drag a ball.<br />2.&nbsp;Click&nbsp;on&nbsp;the&nbsp;ba text.style.color = theme[1];text.style.position = 'absolute';text.style.left = '0px';text.style.top = '0px';text.style.fontFamily = 'Georgia';text.style.textAlign = 'center';element.appendChild(text);text.style.left = ((250 - text.clientWidth) / 2) +'px';text.style.top = ((250 - text.clientHeight) / 2) +'px';var b2body = new b2BodyDef();var circle = new b2CircleDef();circle.radius = size / 2;circle.density = 1;circle.friction = 0.3;circle.restitution = 0.3;b2body.AddShape(circle);erData = {element: element};b2body.position.Set( Math.random() * stage[2], Math.random() * -200 );b2body.linearVelocity.Set( Math.random() * 400 - 200, Math.random() * 400 - 200 );bodies.push( world.CreateBody(b2body) );}function createBall( x, y ) {var x = x || Math.random() * stage[2];var y = y || Math.random() * -200;var size = (Math.random() * 100 >> 0) + 20;var element = document.createElement("canvas");element.width = size;element.height = size;element.style.position = 'absolute';element.style.left = -200 + 'px';element.style.top = -200 + 'px';element.style.WebkitTransform = 'translateZ(0)';element.style.MozTransform = 'translateZ(0)';element.style.OTransform = 'translateZ(0)';element.style.msTransform = 'translateZ(0)';element.style.transform = 'translateZ(0)';var graphics = element.getContext("2d");var num_circles = Math.random() * 10 >> 0;for (var i = size; i > 0; i-= (size/num_circles)) {graphics.fillStyle = theme[ (Math.random() * 4 >> 0) + 1];graphics.beginPath();graphics.arc(size * .5, size * .5, i * .5, 0, PI2, true);graphics.closePath();graphics.fill();}canvas.appendChild(element);elements.push( element );var b2body = new b2BodyDef();var circle = new b2CircleDef();circle.radius = size >> 1;circle.density = 1;circle.friction = 0.3;circle.restitution = 0.3;b2body.AddShape(circle);erData = {element: element};b2body.position.Set( x, y );b2body.linearVelocity.Set( Math.random() * 400 - 200, Math.random() * 400 - 200 );bodies.push( world.CreateBody(b2body) );}//function loop() {if (getBrowserDimensions()) {setWalls();}delta[0] += (0 - delta[0]) * .5;delta[1] += (0 - delta[1]) * .5;world.m_gravity.x = gravity.x * 350 + delta[0];world.m_gravity.y = gravity.y * 350 + delta[1];mouseDrag();world.Step(timeStep, iterations);for (i = 0; i < bodies.length; i++) {var body = bodies[i];var element = elements[i];element.style.left = (body.m_position0.x - (element.width >> 1)) + 'px';element.style.top = (body.m_position0.y - (element.height >> 1)) + 'px';if (element.tagName == 'DIV') {var style = 'rotate(' + (body.m_rotation0 * 57.2957795) + 'deg) translateZ(0)';text.style.WebkitTransform = style;text.style.MozTransform = style;text.style.OTransform = style;text.style.msTransform = style;text.style.transform = style;}// .. BOX2D UTILSfunction createBox(world, x, y, width, height, fixed) {if (typeof(fixed) == 'undefined') {fixed = true;}var boxSd = new b2BoxDef();if (!fixed) {boxSd.density = 1.0;}boxSd.extents.Set(width, height);var boxBd = new b2BodyDef();boxBd.AddShape(boxSd);boxBd.position.Set(x,y);return world.CreateBody(boxBd);}function mouseDrag(){// mouse pressif (createMode) {createBall( mouse.x, mouse.y );} else if (isMouseDown && !mouseJoint) {var body = getBodyAtMouse();if (body) {var md = new b2MouseJointDef();md.body1 = world.m_groundBody;md.body2 = body;md.target.Set(mouse.x, mouse.y);md.maxForce = 30000 * body.m_mass;// md.timeStep = timeStep;mouseJoint = world.CreateJoint(md);body.WakeUp();} else {createMode = true;}}// mouse releaseif (!isMouseDown) {createMode = false;destroyMode = false;if (mouseJoint) {world.DestroyJoint(mouseJoint);mouseJoint = null;}}// mouse moveif (mouseJoint) {var p2 = new b2Vec2(mouse.x, mouse.y);mouseJoint.SetTarget(p2);}}function getBodyAtMouse() {// Make a small box.var mousePVec = new b2Vec2();mousePVec.Set(mouse.x, mouse.y);var aabb = new b2AABB();aabb.minVertex.Set(mouse.x - 1, mouse.y - 1);aabb.maxVertex.Set(mouse.x + 1, mouse.y + 1);// Query the world for overlapping shapes.var k_maxCount = 10;var shapes = new Array();var count = world.Query(aabb, shapes, k_maxCount); var body = null;for (var i = 0; i < count; ++i) {if (shapes[i].m_body.IsStatic() == false) {if ( shapes[i].TestPoint(mousePVec) ) {body = shapes[i].m_body;break;}}}return body;}function setWalls() {world.DestroyBody(walls[1]);world.DestroyBody(walls[2]);world.DestroyBody(walls[3]);walls[0] = null;walls[1] = null;walls[2] = null;walls[3] = null;}walls[0] = createBox(world, stage[2] / 2, - wall_thickness, stage[2], wall_thickness);walls[1] = createBox(world, stage[2] / 2, stage[3] + wall_thickness, stage[2], wall_thickness);walls[2] = createBox(world, - wall_thickness, stage[3] / 2, wall_thickness, stage[3]);walls[3] = createBox(world, stage[2] + wall_thickness, stage[3] / 2, wall_thickness, stage[3]);wallsSetted = true;}// BROWSER DIMENSIONSfunction getBrowserDimensions() {var changed = false;if (stage[0] != window.screenX) {delta[0] = (window.screenX - stage[0]) * 50;stage[0] = window.screenX;changed = true;}if (stage[1] != window.screenY) {delta[1] = (window.screenY - stage[1]) * 50;stage[1] = window.screenY;changed = true;}if (stage[2] != window.innerWidth) {stage[2] = window.innerWidth;changed = true;}if (stage[3] != window.innerHeight) {stage[3] = window.innerHeight;changed = true;}return changed;}上⾯mouseDrag⽅法就实现了⿏标拖拽甩动⼩球的功能,这也是该动画最重要的⽅法。

JavaScript动画实例:炸开的小球

JavaScript动画实例:炸开的小球
}
go();
</script>
</body>
</html>
在浏览器中打开包含这段HTML代码的html文件,可以看到在画布中呈现出如图1所示的动画效果。
图1炸开的小球
2
定义一个小球对象类Ball,它有6个属性:圆心坐标(x,y)、小球半径radius、填充颜色color、圆心坐标水平方向的变化量speedX、圆心坐标垂直方向的变化量speedY。
{
balls[i].move();
}
requestAnimationFrame(anim);
}
anim();
</script>
</body>
</html>
在浏览器中打开包含这段HTML代码的html文件,可以看到在画布中呈现出如图2所示的动画效果。
图2运动的彩色小球
在图2效果的基础上,添加交互式效果。可以在画布的下方通过表格的方式布置10个颜色块,鼠标单击某个颜色块,画布中对应色块填充的小球消失(从balls数组中删除对应的对象元素);若画布中没有对应色块填充的小球,则显示提示信息“无对应色块小球,无效单击!”。
ctx.fill();
}
var balls=[];
for (var i=0;i<50;i++)
{
balls[i]=new Ball();
}
function anim()
{
ctx.clearRect(0,0,canvas.width,canvas.height)
for (var i=0;i<50;i++)
function Ball()

HTML5-右脑开发项目-基础训练-小球移动con_bollMove.html

HTML5-右脑开发项目-基础训练-小球移动con_bollMove.html

HTML5-右脑开发项目-基础训练-小球移动con_bollMove.html小球移动页-con_bollMove.html:<!DOCTYPE html><html><div align="left" ><img height="50" width="50" src="../img/tubiao/1.png" border="0" title="返回上一页" style="background-repeat: no-repeat" onClick="javascript:history.back(-1);"><div style="position:absolute;z-index: 10;left: 150px;top: -20px;"><p align="center" style="font-size: 30px;color: black;font-weight:bold;">小球移动</p></div></div><head><meta charset="UTF-8"><title>专注力训练-小球移动</title><meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"> <script src="../js/jquery-1.7.2.js"></script></head><body><!--遮罩层显示--><div id="m_mask" align="center" style="top:0%; left:0%; padding:16px; border:3px solid orange; background-color:wheat;position:absolute;z-index:1002; overflow:auto; max-width: 100%;height:100%;display: block;"><div style="font-size: 30px;flood-color: black;"><p style="font-size: 35px;flood-color: red;">使用说明: </p> <br /><p>1:专注力训练-眼睛盯着小球移动,训练眼镜的速度</p><p>2:训练目标:一目十行</p><p>3:训练任务:每天练习1到2分钟。

JavaScript实例:运动的小球

JavaScript实例:运动的小球

JavaScript实例:运动的小球本篇博文通过制作一个小球运动动画的实例,来学习在HTML5的画布上实现动画制作的方法,同时理解面向对象程序设计的基本思想。

1.绘制小球先在HTML页面中设置一个画布。

<canvas id="myCanvas" width="400" height="300" style="border:3px double #996633;"> </canvas>再将小球画在canvas(画布)上面。

可编写如下的HTML代码。

<!DOCTYPE html><head><title>运动的小球(一)</title></head><body><canvas id="myCanvas" width="400" height="300" style="border:3px double #996633;"> </canvas><script type="text/javascript">var canvas = document.getElementById('myCanvas');var context = canvas.getContext('2d');var x=100, y=100,radius=25;context.beginPath();context.arc(x, y, radius, 0, Math.PI*2, true);context.closePath();context.fillStyle = "blue";context.fill();</script></body></html>其中,变量x、y、radius分别是小球的圆心坐标(x,y)和半径radius。

CSS动画实例:圆与圆的碰撞

CSS动画实例:圆与圆的碰撞
}
}
</style>
</head>
<body>
<div class="container">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
position: relative;
}
.circle
{
position: absolute;
top: 50%;
left: 50%;
width:var(--length);
height:var(--length);
transform: translate(-50%, -50%);
border: 1px solid #008b8b;
}
.four
{
width:260px;
height:Байду номын сангаас60px;
animation-delay:1.25s;
}
.five
{
width:220px;
height:220px;
animation-delay:1s;
}
.six
{
width:180px;
height:180px;
animation-delay:0.75s;
position: relative;
}

(canvas)两小球碰撞后的速度问题研究

(canvas)两⼩球碰撞后的速度问题研究这两天在研究canvas碰撞先把⼩球开始运动的图拿出来参考了⼀下别的的代码,在两个⼩球碰撞处理上,我觉得不完善怎么样处理才算完善呢,当然是要⽤⾼中物理学的动量守恒了和机械能守恒了机械能守恒我其实忘了,特地百度了下⽤⾼中⽼师的话就是,联⽴,解得,PS:结果我是⽹上找的,也存在看错的可能碰撞的逻辑我来简要所以下1.当⼩球撞到墙,对应的x轴或者y轴的速度成 -1,效果是反弹2.当两个⼩球碰撞时,由上⾯的公式,我们会分别计算speedX和speedY由于动量守恒,我们再效果图中能发现,同⼀⽅向相撞,⼩球会马上获得⼀个⼤的速度,⽽打球减速并不明显最后慢慢传递,很多球都停⽌了,但是最后⼀般来说,还是有⼀个球载运动的最后⼩球还是会有重叠的情况,我再分析下。

我觉得像⼦弹打物块⼀样,接触物体的发⽣了变化,但是⼦弹还是有向前的速度,且速度⽐物块⼤两个⼩球接触的时候也是这样,球1撞到球2,但是球1的速度还是⽐2快,于是球1就叠到球2上了然后在叠的过程中,在逻辑⾥还是处于碰撞,还在发⽣能量转移。

事实证明,叠起来的球过了⼏秒就静⽌了,通常是速度⼤的⼩球,接触到速度⼩的⼤球,接触后⼩球的速度还是别⼤球快。

于是叠在⼀起,叠在⼀起后,还在进⾏能量转换,最后保持平衡,静⽌,或者⽤同样的速度运⾏。

所以出现了叠在⼀起不分开的情况当⼀个⼩球的速度够快,碰撞⼤球的时候才会出现以上情况当我把球的半径改成⼀样应该就不会发⽣了<script type="text/javascript">var canvas = document.getElementById("canvas1");var ctx = canvas.getContext("2d");//随机函数function randomNum (m,n) {return Math.floor(Math.random() * (n - m + 1) + m);}//创建⼩球类function Ball () {//随机⼩球半径this.r = randomNum(20,30);//随机颜⾊this.color = 'rgb(' + randomNum(0,255) + ',' + randomNum(0,255) + ',' + randomNum(0,255) + ')';//随机⼩球的位置this.x = randomNum(this.r,canvas.width-this.r);this.y = randomNum(this.r,canvas.height-this.r);//⼩球速度X轴1和-1;this.speedX = randomNum(2,5) * randomNum(0,1) ? 1 : -1;this.speedY = randomNum(2,5) * randomNum(0,1) ? 1 : -1;}//⼩球移动Ball.prototype.move = function () {this.x += this.speedX;this.y += this.speedY;//判断是否碰到边界//左边界if (this.x <= this.r) {this.x = this.r;//反弹this.speedX *= -1;}//右边界if (this.x >= canvas.width-this.r) {this.x = canvas.width-this.r;this.speedX *= -1;}if (this.y <= this.r) {this.y = this.r;this.speedY *= -1;}if (this.y >= canvas.height-this.r) {this.y = canvas.height-this.r;this.speedY *= -1;}}//绘制⼩球Ball.prototype.drawBall = function () {ctx.beginPath();ctx.arc(this.x,this.y,this.r,0,Math.PI*2,false);ctx.fillStyle = this.color;ctx.fill();}//创建⼩球的对象var balls = [];for (var i = 0;i < 5;i++) {var ball = new Ball();balls.push(ball);}//让⼩球移动setInterval(function () {ctx.clearRect(0,0,canvas.width,canvas.height);for (var i = 0;i < balls.length;i++) {balls[i].move();balls[i].drawBall();//移动后检测⼩球碰撞反弹for (j = 0;j < balls.length;j++) {//判断不是同⼀个球if (balls[i] == balls[j]) {continue;//不做碰撞检测}//碰撞检测if (ballCrash(balls[i],balls[j])) {/*1.物理公式动量守恒,假设每个球的质地均匀,那么⼩球的质量与半径有关2.我们⽤1⼀次⽅的算法,实际平⾯球质量和r的平⽅有关,⽴体球和r的三次⽅有关3.由动量守恒,m1*v1+m2*v2=m1*v1'+m2*v2'4.机械能守恒,平⽅我就不写了,两个⽅程联⽴*/var fzx=(balls[i].r - balls[j].r)*balls[i].speedX + 2*balls[j].r*balls[j].speedX;var fzx2=2*balls[i].r*balls[i].speedX+(balls[i].r - balls[j].r)*balls[j].speedX;var fzy=(balls[i].r - balls[j].r)*balls[i].speedY + 2*balls[j].r*balls[j].speedY;var fzy2=2*balls[i].r*balls[i].speedY+(balls[i].r - balls[j].r)*balls[j].speedY;var fm=balls[i].r + balls[j].r;balls[i].speedX=(fzx/fm);balls[i].speedY=(fzy/fm);balls[j].speedX=(fzx2/fm);balls[j].speedY=(fzy2/fm);}}}},0.1)//碰撞检测function ballCrash (ball1,ball2) {//两个⼩球之间的距离var distance = Math.sqrt(Math.pow(ball1.x - ball2.x,2) + Math.pow(ball1.y - ball2.y,2));//两球的距离⼩于两个半径的和即为碰撞if (distance <= ball1.r + ball2.r) {return true;//碰撞} else{return false;//没有碰撞}}</script>重叠的情况⽤下⾯代码可以避免,但是有时候会出别的bug<!DOCTYPE html><html><head><meta charset="UTF-8"><title>⼩球碰撞反弹</title><style type="text/css">#canvas1{border: 4px dashed black;margin: 0 auto;display: block;}</style></head><body><canvas id="canvas1" width="600" height="600"></canvas></body><script type="text/javascript">var canvas = document.getElementById("canvas1");var ctx = canvas.getContext("2d");//随机函数function randomNum (m,n) {return Math.floor(Math.random() * (n - m + 1) + m);}//创建⼩球类function Ball () {//随机⼩球半径this.r = randomNum(15,30);//随机颜⾊this.color = 'rgb(' + randomNum(0,255) + ',' + randomNum(0,255) + ',' + randomNum(0,255) + ')'; //随机⼩球的位置this.x = randomNum(this.r,canvas.width-this.r);this.y = randomNum(this.r,canvas.height-this.r);//⼩球速度X轴1和-1;this.speedX = randomNum(2,5) * randomNum(0,1) ? 1 : -1;this.speedY = randomNum(2,5) * randomNum(0,1) ? 1 : -1;}//⼩球移动Ball.prototype.move = function () {this.x += this.speedX;this.y += this.speedY;//判断是否碰到边界//左边界if (this.x <= this.r) {this.x = this.r;//反弹this.speedX *= -1;}//右边界if (this.x >= canvas.width-this.r) {this.x = canvas.width-this.r;this.speedX *= -1;}if (this.y <= this.r) {this.y = this.r;this.speedY *= -1;}if (this.y >= canvas.height-this.r) {this.y = canvas.height-this.r;this.speedY *= -1;}}//绘制⼩球Ball.prototype.drawBall = function () {ctx.beginPath();ctx.arc(this.x,this.y,this.r,0,Math.PI*2,false);ctx.fillStyle = this.color;ctx.fill();}//创建⼩球的对象for (var i = 0;i < 10;i++) {var ball = new Ball();balls.push(ball);}//让⼩球移动setInterval(function () {ctx.clearRect(0,0,canvas.width,canvas.height);for (var i = 0;i < balls.length;i++) {balls[i].move();balls[i].drawBall();//移动后检测⼩球碰撞反弹for (j = 0;j < balls.length;j++) {//判断不是同⼀个球if (balls[i] == balls[j]) {continue;//不做碰撞检测}//碰撞检测if (ballCrash(balls[i],balls[j])) {/*1.物理公式动量守恒,假设每个球的质地均匀,那么⼩球的质量与半径有关2.我们⽤1⼀次⽅的算法,实际平⾯球质量和r的平⽅有关,⽴体球和r的三次⽅有关3.由动量守恒,m1*v1+m2*v2=m1*v1'+m2*v2'4.机械能守恒,平⽅我就不写了,两个⽅程联⽴*/var fzx=(balls[i].r - balls[j].r)*balls[i].speedX + 2*balls[j].r*balls[j].speedX;var fzx2=2*balls[i].r*balls[i].speedX+(balls[i].r - balls[j].r)*balls[j].speedX;var fzy=(balls[i].r - balls[j].r)*balls[i].speedY + 2*balls[j].r*balls[j].speedY;var fzy2=2*balls[i].r*balls[i].speedY+(balls[i].r - balls[j].r)*balls[j].speedY;var fm=balls[i].r + balls[j].r;balls[i].speedX=(fzx/fm);balls[i].speedY=(fzy/fm);balls[j].speedX=(fzx2/fm);balls[j].speedY=(fzy2/fm);}}}},1)//碰撞检测function ballCrash (ball1,ball2) {//两个⼩球之间的距离var distance = Math.sqrt(Math.pow(ball1.x - ball2.x,2) + Math.pow(ball1.y - ball2.y,2));//两球的距离⼩于两个半径的和即为碰撞if (distance == ball1.r + ball2.r) {return true;//碰撞}else if( distance < ball1.r + ball2.r){if(Math.pow(ball1.speedX,2)+Math.pow(ball1.speedY,2)>Math.pow(ball2.speedX,2)+Math.pow(ball2.speedY,2)){ if(ball1.speedX>0){ball2.x=ball2.x+ball1.r + ball2.r - distance;if(ball1.speedY > 0){ball2.y=ball2.y+ball1.r + ball2.r - distance;}else{ball2.y=ball2.y-ball1.r - ball2.r + distance;}}else{ball2.x=ball2.x-ball1.r - ball2.r + distance;if(ball1.speedY > 0){ball2.y=ball2.y+ball1.r + ball2.r - distance;}else{ball2.y=ball2.y-ball1.r - ball2.r + distance;}}}else{if(ball2.speedX>0){ball1.x=ball1.x+ball1.r + ball2.r - distance;if(ball2.speedY > 0){ball1.y=ball1.y+ball1.r + ball2.r - distance;}else{ball1.y=ball1.y-ball1.r - ball2.r + distance;}}else{ball1.x=ball1.x-ball1.r - ball2.r + distance;if(ball2.speedY > 0){ball1.y=ball1.y+ball1.r + ball2.r - distance;}else{ball1.y=ball1.y-ball1.r - ball2.r + distance;}}return true;}else{return false;//没有碰撞 }}</script></html>。

HTML5实现碰撞小球

<html><head><title>MyWeb</title><script>var ctx;var r=10;var x=200;var y=200;var tevent;var spx;//水平运动速度var spy;//垂直运动速度function init(){ctx=document.getElementById("canvas").getContext("2d");ctx.lineWidth=10;ctx.strokeRect(0,0,400,400);}function drawBall(){clearBall();checkBall();ctx.fillStyle="rgb(255,0,0)";ctx.beginPath();ctx.arc(x,y,r,0,2*Math.PI,true);ctx.fill();}function checkBall()//检查小球位置,如果超出边界,则贴近边界,运动速度反向{x+=spx;y+=spy;if(x<10){spx*=-1;x=10;}if(x>390){spx*=-1;x=390;}if(y<10){spy*=-1;y=10;}if(y>390){spy*=-1;y=390;}}function clearBall(){ctx.fillStyle="rgb(255,255,255)";ctx.fillRect(5,5,390,390);}function runBall(){spx=Number(document.f.xsp.value);spy=Number(document.f.ysp.value);tevent=setInterval("drawBall();",50);//设置每50毫秒执行drawBall }function stopBall(){clearInterval(tevent);//清除定时器clearBall();x=200;y=200;ctx.fillStyle="rgb(255,0,0)";ctx.beginPath();ctx.arc(x,y,r,0,2*Math.PI,true);ctx.fill();}</script></head><body onload="init();"><canvas id="canvas"width="400"height="400"></canvas><form name="f">水平速度:<input name="xsp"value="10"/>垂直速度:<input name="ysp"value="13"/></form><button onclick="runBall();">开始</button><button onclick="stopBall();">停止</button></body></html>。

iH5高级教程:H5小游戏必学,碰撞事件

iH5高级教程:H5小游戏必学,碰撞事件推动球杆,向前滑动,撞击白球,白球向前滑动,再撞击紫球,紫球也向前滑动。

根据案例,我们来看一下这个实现的步骤。

第一步:1、选中舞台,点击工具栏下的图片工具,在舞台上画出一个矩形,添加一张背景图片,右击图片对象,重命名为背景。

2、选中舞台,点击工具栏下的图片工具,在舞台上画出一个矩形,添加一张球杆图片。

右击图片对象,重命名为球杆。

属性面板拖动类型为垂直。

3、选中舞台,点击工具栏下的图片工具,在舞台上画出一个矩形,添加一张白球图片。

右击图片对象,重命为白球。

4、选中舞台,点击工具栏下的图片工具,在舞台上画出一个矩形,添加一张紫球图片。

右击图片对象,重命名为紫球。

5、选中紫球对象,点击工具栏下的缓动工具,添加一个缓动效果。

缓动属性设置,移动距离为200,移动方向为-90,时长为1,缓动类型为五次出,自动播放为NO,触发后延时设置为空,开始前隐藏为NO。

6、选中白球对象,点击工具栏下的缓动工具,添加一个缓动效果。

缓动属性设置,移动距离为200,移动方向(顺时针)为-90,时长为1,缓动类型为五次出,自动播放为NO,触发后延时设置为空,开始前隐藏为NO。

7、选中白球对象,点击工具栏下的事件工具,添加一个事件。

事件的属性设置,触发对象为白球,触发条件为碰撞,对象为紫球对象,中心距离为边缘位置,距离为0,速度优化为NO,目标对象是紫球的缓动,目标动作是开始。

8、选中球杆对象,点击工具栏下的事件工具,添加一个事件。

事件的属性设置,触发对象是球杆,触发条件是碰撞,对象是白球对象,中心距离是边缘位置,距离为-30,速度优化为NO,目标对象为白球的缓动,目标动作为开始。

先行知识:事件重点工具:事件、碰撞、缓动知识点:碰撞:碰撞后触发动作,即触发对象碰撞指定的对象时。

碰撞的选项中,中心距离分为“中心碰撞”和“边缘碰撞”,“中心碰撞”是碰撞到指定对象的中心才会触发动作,“边缘碰撞”是碰撞到制定对象的边缘才会触发动作,距离的大小决定了碰撞的准确度,假如边缘碰撞,距离设置为80,还没接触到指定对象碰撞就会开始和触发动作;勾选速度优化为YES,能优化触发对象在碰撞过程中的移动速度。

绘制随机小球来回弹动java代码

Java小球碰撞代码绘制小球随机位置,随机颜色(自概念颜色)来回碰撞。

那个代码只有上下左右四个方向,因此反弹也是固定的45°角。

第一是概念小球(Ball类)package picture;import java.awt.Color;import java.awt.Graphics;public class Ball {private int x,y;//分清概念是左上角极点坐标仍是圆心点坐标(圆心坐标)private int rSize;//半径private Color color;private int speed;private int orientation;private BallPanel panel;//取得小球所属的面板public static final int RIGHT_DOWN=0;public static final int RIGHT_ON=1;public static final int LEFT_DOWN=2;public static final int LEFT_ON=3;public Ball(){}public Ball(int x, int y, int rSize, Color color, int speed, int orientation) {super();this.x = x;this.y = y;this.rSize = rSize;this.color = color;this.speed = speed;this.orientation = orientation;}public void draw(Graphics g){g.setColor(color);g.fillArc(x-rSize, y-rSize/*左上角定点坐标*/, 2*rSize, 2*rSize, 0, 360);}//概念小球绘画的逻辑public void move(){//小球处在不同方向时移动所改变的坐标值switch(orientation){case RIGHT_DOWN:x+=speed;y+=speed;if(x+rSize >=panel.getWidth()){this.orientation = LEFT_DOWN;}if(y+rSize >=panel.getHeight()){this.orientation = RIGHT_ON;}break;case RIGHT_ON:x+=speed;y-=speed;if(x+rSize >=panel.getWidth()){this.orientation = LEFT_ON;}if(y-rSize <= 0 ){this.orientation = RIGHT_DOWN;}break;case LEFT_DOWN:x-=speed;y+=speed;if(x-rSize <= 0 ){this.orientation = RIGHT_DOWN;}if(y+rSize <=panel.getHeight()){this.orientation = LEFT_ON;}break;case LEFT_ON:x-=speed;y-=speed;if(x-rSize <= 0 ){this.orientation = RIGHT_ON;}if(y-rSize <= 0){this.orientation = LEFT_DOWN;}break;}/*碰着边界事件处置*/}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public int getrSize() {return rSize;}public void setrSize(int rSize) { this.rSize = rSize;}public Color getColor() {return color;}public void setColor(Color color) {this.color = color;}public int getSpeed() {return speed;}public void setSpeed(int speed) {this.speed = speed;}public int getOrientation() {return orientation;}public void setOrientation(int orientation) {this.orientation = orientation;}public BallPanel getPanel() {return panel;}public void setPanel(BallPanel panel) { this.panel = panel;}}然后是小球的面板(BallPanel)package picture;import java.awt.Color;import java.awt.Graphics;import javax.swing.JPanel;public class BallPanel extends JPanel{private int x = 0,y = 0;//构造函数提早挪用startRun不适合private Ball[]balls;private Color[]cs = {Color.red,Color.blue,Color.green,Color.cyan,Color.yellow,C olor.gray,Color.orange};public BallPanel(){this.setBackground(Color.WHITE);balls = new Ball[10];for(int i = 0 ;i<balls.length;i++){balls[i] = new Ball((int)(Math.random()*800),(int)(Math.random()*600),(int)(Math.random()*20)+10,cs[(int)(Math.random()*cs.length)],(int)(Math.random()*10)+1,(int)(Math.random()*4));balls[i].setPanel(this);}}public void paint(Graphics g){super.paint(g);for(int i=0;i<balls.length;i++){balls[i].draw(g);}}public void startRun(){new Thread(){public void run(){while(true){for(int i = 0;i<balls.length;i++){balls[i].move();}repaint();//从头画屏幕try {Thread.sleep(2);//画完以后睡一会再循环} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}.start();}}那个地址我需要提示一下,ball类里面关于小球方向的操纵判定,我是能够依照不同的概念。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

<html>
<head>
<title>MyWeb</title>
<script>
var ctx;
var r=10;
var x=200;
var y=200;
var tevent;
var spx;//水平运动速度
var spy;//垂直运动速度
function init()
{
ctx=document.getElementById("canvas").getContext("2d");
ctx.lineWidth=10;
ctx.strokeRect(0,0,400,400);
}
function drawBall()
{
clearBall();
checkBall();
ctx.fillStyle="rgb(255,0,0)";
ctx.beginPath();
ctx.arc(x,y,r,0,2*Math.PI,true);
ctx.fill();
}
function checkBall()//检查小球位置,如果超出边界,则贴近边界,运动速度反向{
x+=spx;
y+=spy;
if(x<10)
{
spx*=-1;
x=10;
}
if(x>390)
{
spx*=-1;
x=390;
}
if(y<10)
{
spy*=-1;
y=10;
}
if(y>390)
{
spy*=-1;
y=390;
}
}
function clearBall()
{
ctx.fillStyle="rgb(255,255,255)";
ctx.fillRect(5,5,390,390);
}
function runBall()
{
spx=Number(document.f.xsp.value);
spy=Number(document.f.ysp.value);
tevent=setInterval("drawBall();",50);//设置每50毫秒执行drawBall }
function stopBall()
{
clearInterval(tevent);//清除定时器
clearBall();
x=200;
y=200;
ctx.fillStyle="rgb(255,0,0)";
ctx.beginPath();
ctx.arc(x,y,r,0,2*Math.PI,true);
ctx.fill();
}
</script>
</head>
<body onload="init();">
<canvas id="canvas"width="400"height="400">
</canvas>
<form name="f">
水平速度:<input name="xsp"value="10"/>
垂直速度:<input name="ysp"value="13"/>
</form>
<button onclick="runBall();">开始</button>
<button onclick="stopBall();">停止</button>
</body>
</html>。

相关文档
最新文档