1 var Physics = new Class({
\r
4 onComplete: Class.empty,
\r
5 onStart: Class.empty,
\r
16 initialize: function(element, container, options){
\r
17 this.setOptions(options);
\r
18 this.element = $(element);
\r
19 this.container = $(container);
\r
20 this.velocity = {'x': 0, 'y': 0};
\r
22 this.oldPosition = {};
\r
23 this.oldVelocity = {};
\r
24 this.position.x = this.oldPosition.x = this.element.getStyle('left').toInt();
\r
25 this.position.y = this.oldPosition.y = this.element.getStyle('top').toInt();
\r
26 this.blockers = $$(this.options.blockers);
\r
29 this.oldPosition.x = this.position.x;
\r
30 this.oldPosition.y = this.position.y;
\r
31 this.fireEvent('onStep');
\r
32 this.velocity.y += this.options.gravity;
\r
33 this.position.x += this.velocity.x;
\r
34 this.position.y += this.velocity.y;
\r
35 var onGround = false;
\r
38 element.width = this.element.offsetWidth;
\r
39 element.height = this.element.offsetHeight;
\r
40 element.top = this.position.y;
\r
41 element.left = this.position.x;
\r
42 element.right = element.left + element.width;
\r
43 element.bottom = element.top + element.height;
\r
44 container.width = this.container.offsetWidth;
\r
45 container.height = this.container.offsetHeight;
\r
46 this.blockers.each(function(blocker){
\r
47 var collision = false;
\r
49 block.left = blocker.getStyle('left').toInt();
\r
50 block.right = block.left + blocker.offsetWidth;
\r
51 block.top = blocker.getStyle('top').toInt();
\r
52 block.bottom = block.top + blocker.offsetHeight;
\r
53 if (element.right > block.left && element.left < block.right && element.bottom > block.top && element.top < block.bottom){ //collision area
\r
54 if (element.top < block.top && this.velocity.y > 0){ //touches top part of the blocker
\r
55 this.position.y = block.top - element.height;
\r
56 this.velocity.y *= -this.options.restitution;
\r
57 if (!this.options.airFriction) this.velocity.x *= this.options.friction;
\r
59 blocker.fireEvent('collisionTop', this.element);
\r
61 } else if (element.bottom > block.bottom && this.velocity.y < 0){ //touches bottom part of the blocker
\r
62 this.position.y = block.bottom;
\r
63 this.velocity.y *= -this.options.restitution;
\r
65 blocker.fireEvent('collisionBottom', this.element);
\r
66 } else if (element.left < block.left && this.velocity.x > 0){ //touches left part of the blocker
\r
67 this.position.x = block.left - element.width;
\r
68 this.velocity.x *= -this.options.restitution;
\r
70 blocker.fireEvent('collisionLeft');
\r
71 } else if (element.right > block.right && this.velocity.x < 0){ //touches right part of the blocker
\r
72 this.position.x = block.right;
\r
73 this.velocity.x *= -this.options.restitution;
\r
75 blocker.fireEvent('collisionRight', this.element);
\r
78 if (collision) blocker.fireEvent('collision', this.element);
\r
80 if (this.position.y + element.height > container.height){ //touches bottom
\r
81 this.position.y = container.height - element.height;
\r
82 this.velocity.y *= -this.options.restitution;
\r
83 if (!this.options.airFriction) this.velocity.x *= this.options.friction;
\r
85 this.container.fireEvent('collisionBottom', this.element);
\r
88 this.onGround = true;
\r
89 this.element.fireEvent('ground');
\r
91 this.element.fireEvent('air');
\r
92 this.onGround = false;
\r
94 if (this.position.y < 0){ //touches top
\r
95 this.position.y = 0;
\r
96 this.velocity.y *= -this.options.restitution;
\r
101 if (this.position.x + element.width > container.width){ //touches right
\r
102 this.position.x = container.width - element.width;
\r
103 this.velocity.x *= -this.options.restitution;
\r
104 this.onRight = true;
\r
106 this.onRight = false;
\r
108 if (this.position.x < 0){ //touches left
\r
109 this.position.x = 0;
\r
110 this.velocity.x *= -this.options.restitution;
\r
111 this.onLeft = true;
\r
113 this.onLeft = false;
\r
115 if (this.options.airFriction){
\r
116 this.velocity.y *= this.options.friction;
\r
117 this.velocity.x *= this.options.friction;
\r
119 this.element.setStyles({
\r
120 'left': this.position.x,
\r
121 'top': this.position.y
\r
126 this.fireEvent('onStart');
\r
127 this.timer = this.step.periodical(Math.round(1000/this.options.fps), this);
\r
131 force: function(velx, vely){
\r
132 this.position.x = this.element.getStyle('left').toInt();
\r
133 this.position.y = this.element.getStyle('top').toInt();
\r
134 this.velocity.x += velx;
\r
135 this.velocity.y += vely;
\r
139 this.timer = $clear(this.timer);
\r
140 this.fireEvent('onComplete');
\r
145 Physics.implement(new Events);
\r
146 Physics.implement(new Options);