Alright, so i’ve been working on some line segment vs line segment collision for awhile here now, and its only half working… the collision works vertically pretty well, but horizontally, not so well. It gets pretty glitchy moving my character into a vertical line (well, standing line), not so much with moving the character into a line that’s horizontally orientated.
I have a variable, op, meaning old point. old point is the last position that ‘main’ was in last. BUT, i can only change the X value without screwing this up, and I think that because i can’t go ahead and change the Y value, it’s the reason that i can’t do certain collision so well. I can change the Y value of op, but when i do, ‘main’ gets ‘stuck’ and if you press the arrows keys like crazy, ‘main’ will just jump out…
oh, the usage behind op is that by updating the old pos, i can compare it with the new pos, and then do some adjustment to get ‘main’ out of a line.
here’s the file, check it out:
http://www.theorangeday.com/Content/LineIntersectionWithSegs.fla
the code (for lazy people)
what you need: an object, like a box, called main, and the as3 vcam, called vcam (if you odn’t have the vcam, jsut comment out the first couple lines in the game loop):
//var lines:Array = new Array({x:5, y:0}, {x:0,y:187},{x:159.9,y:187},{x:270.9,y:241},{x:449.9,y:226},{x:522,y:198},{x:600,y:198},{x:700,y:50},{x:650,y:0},{x:5,y:0});
var lines:Array = new Array({x:4,y:284},{x:132,y:284},{x:204,y:326},{x:278,y:328},{x:341,y:312},{x:405,y:296},{x:445,y:296},{x:507,y:281},{x:536,y:163},{x:456,y:45},{x:272,y:15},{x:145,y:26},{x:118,y:18},{x:80,y:18},{x:58,y:7},{x:4,y:184},{x:4,y:284});
var col:Point = new Point(0,0);
var op:Point = new Point(main.x,main.y);
var line:Shape = new Shape();
addChild(line);
var grav:Number = 1.1;
var yspeed:Number = 0;
var canFall = true;
var currLine:int = 0;
var speed = 5;
var js = -15;
var coll = false;
var q:int = 0;
var i:int;
var keyArray:Array = new Array();
var t:int = 0;
for (i=0; i<222; i++) {
keyArray.push([i,false]);
}
stage.addEventListener(Event.ENTER_FRAME, loop);
stage.addEventListener(KeyboardEvent.KEY_UP, checkKeysUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, checkKeysDown);
line.graphics.lineStyle(1,0);
line.graphics.moveTo(lines[0].x,lines[0].y);
for (q=1; q<lines.length; q++) {
line.graphics.lineTo(lines[q].x, lines[q].y);
}
line.graphics.lineTo(lines[0].x, lines[0].y);
function loop(e:Event):void {
//txt.text = op.y.toString();
vcam.x = main.x;
vcam.y = main.y;
if (keyisdown(39)) {
op.x = main.x;
main.x += speed;
}
if (keyisdown(37)) {
op.x=main.x;
main.x-=speed;
}
if (keyisdown(38)) {
//uncomment the yspeed conditional to limit the jump
//if (yspeed==0) {
coll=false;
yspeed=js;
//}
}
/*if (op.y!=main.y+yspeed+grav) {
op.y=main.y;
trace("smae");
//t = 0;
}*/
//op.y=main.y;
yspeed+=grav;
main.y+=yspeed;
//op.y = main.y + yspeed + grav;
for (q=0; q<lines.length-1; q++) {
if (SegCollide(op,new Point(main.x,main.y),lines[q],lines[q+1])) {
coll=true;
currLine=q;
break;
}
}
if (coll) {
LineCollide();
var xs=col.x-main.x;
var ys=col.y-main.y;
trace(xs+", "+ys);
/*
//this code is usable enough. you can actually change xs and ys with
//these, vx, and vy, and it'll work almost the exact same...
var ab=Math.atan2(lines[currLine].y-lines[currLine+1].y,lines[currLine].x-lines[currLine+1].x)*180/Math.PI-180;
var ac=Math.atan2(main.y-lines[currLine].y,main.x-lines[currLine].x)*180/Math.PI;
var diff=ac-ab;
trace("ab: "+ab);
var vx = Math.sin(ab*(Math.PI/180))*yspeed*-1;
var vy = Math.cos(ab*(Math.PI/180))*yspeed*-1;
trace(vx+", "+vy);*/
main.x=col.x+xs/4;
main.y=col.y+ys/4;
coll=false;
yspeed=0;
}
}
function LineCollide():void {
var s1y=main.y-op.y;
var s1x=main.x-op.x;
var s2y=lines[currLine+1].y-lines[currLine].y;
var s2x=lines[currLine+1].x-lines[currLine].x;
var sa1yb = s1x*-(main.y);
var sa1xb = s1y*-(main.x);
var sa2yb = s2x*-(lines[currLine].y);
var sa2xb = s2y*-(lines[currLine].x);
if (s1y!=s2y&&s1x!=s2x) {
var se1x=s1y/s1x;
var se1b = (sa1xb-sa1yb)/s1x;
var se2x=s2y/s2x;
var se2b = (sa2xb-sa2yb)/s2x;
col.x = (se2b-se1b)/(se1x-se2x);
col.y = (col.x*se1x)+se1b;
if (sa1yb==0) {
col.x = -(sa1xb)/s1y;
} else if (sa1xb == 0) {
col.y = -(sa1yb)/s1x;
}
if (sa2yb==0) {
col.x = -(sa2xb)/s2y;
} else if (sa2xb == 0) {
col.y = -(sa2yb)/s2x;
}
if (s1x==0&&s2x!=0) {
col.y = (se2x*col.x)+se2b;
} else if (s2x == 0 && s1x != 0) {
col.y = (se1x*col.x)+se1b;
}
trace("2"+col);
} else {
trace("no collision, parallel");
}
}
function SegCollide(a1:Point,a2:Point,b1:Object,b2:Object):Boolean {
//----------------------------------------------------------------------
var a1yb1y,a1xb1x,a2xa1x,a2ya1y;
var crossa,crossb;
//----------------------------------------------------------------------
a1yb1y=a1.y-b1.y;
a1xb1x=a1.x-b1.x;
a2xa1x=a2.x-a1.x;
a2ya1y=a2.y-a1.y;
//----------------------------------------------------------------------
crossa = a1yb1y * ( b2.x - b1.x ) - a1xb1x * ( b2.y - b1.y );
crossb = a2xa1x * ( b2.y - b1.y ) - a2ya1y * ( b2.x - b1.x );
//----------------------------------------------------------------------
if (crossb==0) {
return false;
} else if ( Math.abs( crossa ) > Math.abs( crossb ) || crossa * crossb < 0 ) {
return false;
} else {
crossa=a1yb1y*a2xa1x-a1xb1x*a2ya1y;
if (Math.abs(crossa)>Math.abs(crossb)||crossa*crossb<0) {
return false;
}
}
//----------------------------------------------------------------------
return true;
}
function checkKeysDown(event:KeyboardEvent):void {
keyArray[event.keyCode][1]=true;
}
function checkKeysUp(event:KeyboardEvent):void {
keyArray[event.keyCode][1]=false;
}
function keyisdown(X:Number):Boolean {
return keyArray[X][1];
}