can't figure out why the ball object falls right through line[2] while it bounces off all the others. I have two classes below; a main class that creates the lines along with some collision and motion code for the ball, and a class for the ball. I included a comment above the line in the main class which pertains to the line that doesn't interact. When the program runs, it bounces off of all the lines with some distance based collision code - but passes right through one of the lines- the line created in the array at line[2]
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;
public class MultiAngleBounce extends Sprite
{
private var ball:Ball;
private var lines:Array;
private var numLines:uint = 6;
private var gravity:Number = 0.3;
private var bounce:Number = -0.6;
public function MultiAngleBounce()
{
init();
}
private function init():void
{
ball = new Ball(20);
addChild(ball);
ball.x = 100;
ball.y = 100;
//create five lines
lines = new Array();
for(var i:uint = 0; i < numLines; i++)
{
var line:Sprite = new Sprite();
line.graphics.lineStyle(1);
line.graphics.moveTo(-50, 0);
line.graphics.lineTo(50, 0);
addChild(line);
lines.push(line);
}
lines[0].x = 100;
lines[0].y = 100;
lines[0].rotation = 30;
lines[1].x = 100;
lines[1].y = 230;
lines[1].rotation = 50;
//why does this one get ignored
lines[2].x = 250;
lines[2].y = 180;
lines[2].rotation = -30;
lines[3].x = 150;
lines[3].y = 330;
lines[3].rotation = 10;
lines[4].x = 230;
lines[4].y = 250;
lines[4].rotation = -30;
lines[5].x = 300;
lines[5].y = 350;
lines[5].rotation = -20;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void
{
//normal motion code
ball.vy += gravity;
ball.x += ball.vx;
ball.y += ball.vy;
//bounce off ceiling, floor, walls
if(ball.x + ball.radius > stage.stageWidth)
{
ball.x = stage.stageWidth - ball.radius;
ball.vx *= bounce;
}
else if(ball.x - ball.radius < 0)
{
ball.x = ball.radius;
ball.vx *= bounce;
}
if(ball.y + ball.radius > stage.stageHeight)
{
ball.y = stage.stageHeight - ball.radius
ball.vy *= bounce;
}
else if(ball.y - ball.radius < 0)
{
ball.y = ball.radius;
ball.vy *= bounce;
}
//check each line
for(var i:uint = 0; i < numLines; i++)
{
checkLine(lines[i]);
}
}
private function checkLine(line:Sprite):void
{
//get the bounding box of the line
var bounds:Rectangle = line.getBounds(this);
if(ball.x > bounds.left && ball.x < bounds.right)
{
//get angle, sine and cosine
var angle:Number = line.rotation * Math.PI / 180;
var cos:Number = Math.cos(angle);
var sin:Number = Math.sin(angle);
//get position of ball, relative to line
var x1:Number = ball.x - line.x;
var y1:Number = ball.y - line.y;
//rotate coordinates
var y2:Number = cos * y1 - sin * x1;
//rotate velocity
var vy1:Number = cos * ball.vy - sin * ball.vx;
//perform bounce with rotated values
if(y2 > -ball.height / 2 && y2 < vy1)
{
//rotate coordinates
var x2:Number = cos * x1 + sin * y1;
//rotate velocity
var vx1:Number = cos * ball.vx + sin * ball.vy;
y2 = -ball.height / 2;
vy1 *= bounce;
//rotate everything back;
x1 = cos * x2 - sin * y2;
y1 = cos * y2 + sin * x2;
ball.vx = cos * vx1 - sin * vy1;
ball.vy = cos * vy1 + sin * vx1;
ball.x = line.x + x1;
ball.y = line.y + y1;
}
}
}
}
}
package
{
import flash.display.Sprite;
public class Ball extends Sprite
{
public var radius:Number;
private var color:uint;
public var internalAngle:Number;
public var internalRadius:Number;
internal var vx:Number = 0;
internal var vy:Number = 0;
public function Ball(radius:Number = 40, color:uint = 0xff0000)
{
this.radius = radius;
this.color = color;
init();
}
public function init():void {
graphics.beginFill(color);
graphics.drawCircle(0, 0, radius);
graphics.endFill();
}
}
}
You bounds check
if(ball.x > bounds.left && ball.x < bounds.right)
is failing for the second line. The ball hasn't attained enough speed by the time it reaches lines[2] that it can get completely into the bounds rect. You can use
if(line.hitTestObject(ball))
to do collision detection instead.