乒乓球以一个向量运动,碰到障碍后反弹以一个新的向量运动,如下图:
要实现回弹只需要求出向量v1,把向量v0取反,再旋转(a+b)度就可以得到向量v1.
向量取反:
var v:vec2 = new Vec2(10,10); v.x = -v.x; v.y = -v.y; //或者 v=v.mul(-1);
坐标旋转:
var v:Vec2 = new Vec2(10,10); v.rotate(Math.PI);//以弧度为单位 //rotate方法的实现 public function rotate(angle:Number):void{ var cos:Number = Math.cos (angle); var sin:Number = Math.sin (angle); x = x * cos - y * sin;; y = x * sin + y * cos; }
例子代码:
package { import flash.display.MovieClip; import nape.callbacks.CbType; import nape.callbacks.InteractionType; import nape.callbacks.PreCallback; import nape.callbacks.PreFlag; import nape.callbacks.PreListener; import nape.dynamics.CollisionArbiter; import nape.geom.Vec2; import nape.phys.Body; import nape.shape.Circle; /** * ... * @author kingBook * 2015-02-01 21:18 */ public class Main extends BaseMain { public function Main() { super({gravity:{x:0,y:0}}); } private var _circle:Body; private var _circleCbType:CbType=new CbType(); private var _view:MovieClip; override protected function createBodies():void { _circle = new Body(); _circle.shapes.add(new Circle(25)); _circle.position.setxy(100,100); _circle.space=_space; _circle.velocity.setxy(500,700);//随意设置一个运动向量 _circle.cbTypes.add(_circleCbType); _view = new Circle_view();//库中的 Circle_view this.addChild(_view); //侦听与边缘碰撞 _space.listeners.add(new PreListener(InteractionType.COLLISION,_circleCbType,CbType.ANY_BODY,hitHandler)); } private function hitHandler(cb:PreCallback):PreFlag{ var colArb:CollisionArbiter=cb.arbiter.collisionArbiter; var normal:Vec2 = colArb.normal; var vel:Vec2 = _circle.velocity.copy(); vel = vel.mul(-1);//取反 vel.rotate(2*(normal.angle-vel.angle));//旋转2倍法线度与反向运动向量角的差 _circle.velocity.set(vel);//重新设置向量 return PreFlag.ACCEPT; } override protected function stepAfter():void{ //同步外观 _view.x = _circle.position.x; _view.y = _circle.position.y; _view.rotation = _circle.rotation*57.3; } } }
效果:
源码下载:
http://yunpan.cn/cVU69GkaYFyKH 访问密码 8515