Drop, gravity, bounce issue - AS2?

Hello!

I have a file where two objects fall from the top of the stage and bounce and then eventually stop (using gravity and hit test).

You can grab the objects (a ball and a box — each has a button symbol n the movie clip) and toss them and they bounce off each other and off the 4 sides of the stage.

The issue is when one of the objects is dropped directly on top of the other object, after it stops bouncing, it slides down until it hits the bottom of the stage (in this case, the box slides down in front of the ball, and the ball slides down in back of the box).

Is this because the gravity is pulling the object down to the bottom of the stage even though there’s another object in its way?

How can I fix this so that the objects will still bounce off each other, and when dropped directly on top of each other object will stop instead of oozing through it (sorry, this is the best way I can describe it :slight_smile: ?

I’ve attached 2 files (Fla 8 and Fla mx 2004).

-------- here is the gravity code on the first frame:


var gravity:Number = 1.2;
var restitution:Number = 0.6;
var friction:Number = 0.9;

stop();

-------- here is the code on the ball


onClipEvent(load) {
	var dragging:Boolean = false;
	var vel:Object = { x: 0, y: 0 };
	var pos:Object = { x: _x, y: _y };
	var old:Object = { x: _x, y: _y };
	var radius:Number = this._width / 2;
	var movie:Object = { width: 400, height: 300 };
}

onClipEvent(enterFrame){	
	if( !dragging ) {
		vel.y += _root.gravity;
		
		pos.x += vel.x;
		pos.y += vel.y;

		if( pos.y + radius > movie.height ) {
			pos.y = movie.height - radius;
			vel.y *= -_root.restitution;
			vel.x *= _root.friction;
		}
		
		if( pos.x + radius > movie.width ) {
			pos.x = movie.width - radius;
			vel.x *= -_root.restitution;
		}
		
		if( pos.x < radius ) {
			pos.x = radius;
			vel.x *= -_root.restitution;
		}
		
		_x = pos.x;
		_y = pos.y;
		
	} else {
		old.x = pos.x;
		old.y = pos.y;
		pos.x = _x;
		pos.y = _y;
		
		vel.x = ( pos.x - old.x ) / 2;
		vel.y = ( pos.y - old.y ) / 2;		
	}	

	
if(this.hitTest(_root.box)) {
        trace("hit");
        // ball and box are colliding, so lets reverse their movements.
        vel.x *= -1;
        vel.y *= -1;
        _root.box.vel.x*=-1;
        _root.box.vel.y*=-1;
        
        /*  these actions could be made more realistic by determining the precise
        position of the ball relative to the box during the collision, for instance,
        determine if the right side is colliding with the left side, so only reverse
        the x velocity, instead of both.  */
    }
    
    //this prevents the ball from leaving the upper extreme of the stage
    if (this._y < 0) {
            vel.y*=-1;
    }  
}

-------- here is the code on the button inside the ball (so you can drag and release the ball)


on(press){
	startDrag(this,false,16,16,384,284);
	dragging = true;
}
on(release, releaseOutside){
	stopDrag();
	dragging = false;
}

-------- here is the code on the box


onClipEvent(load) {
	var dragging:Boolean = false;
	var vel:Object = { x: 0, y: 0 };
	var pos:Object = { x: _x, y: _y };
	var old:Object = { x: _x, y: _y };
	var radius:Number = this._width / 2;
	var movie:Object = { width: 400, height: 300 };
}

onClipEvent(enterFrame){	
	if( !dragging ) {
		vel.y += _root.gravity;
		
		pos.x += vel.x;
		pos.y += vel.y;

		if( pos.y + radius > movie.height ) {
			pos.y = movie.height - radius;
			vel.y *= -_root.restitution;
			vel.x *= _root.friction;
		}
		
		if( pos.x + radius > movie.width ) {
			pos.x = movie.width - radius;
			vel.x *= -_root.restitution;
		}
		
		if( pos.x < radius ) {
			pos.x = radius;
			vel.x *= -_root.restitution;
		}
		
		_x = pos.x;
		_y = pos.y;
		
	} else {
		old.x = pos.x;
		old.y = pos.y;
		pos.x = _x;
		pos.y = _y;
		
		vel.x = ( pos.x - old.x ) / 2;
		vel.y = ( pos.y - old.y ) / 2;		
	}	
}

-------- here is the code on the button inside the box (so you can drag and release the box)


on(press){
	startDrag(this,false,16,16,384,284);
	dragging = true;
}
on(release, releaseOutside){
	stopDrag();
	dragging = false;
}

I appreciate any help anyone can give me to fix this issue, I don’t understand enough yet about how these objects are interacting to fix this — but I hope to learn from you brilliant Kirupians!) Thanks!

Hondo311

i didn’t read all of your problem but if you want objects to bounce off each other you need to calculate angle of impact and the resulting vectors then multiply the speed of each x impact and y impact back onto the current objects

there is a nice tutorial here

ok i have to admit that the code you have there is beyond my skills but a good practise you should try to get into is put all of your code in one location a frame or all one one object if nothing else. it will make your life 20 times easier i learnt that the very hard way give it a try.

[QUOTE=JBPresents;2327120]i didn’t read all of your problem but if you want objects to bounce off each other you need to calculate angle of impact and the resulting vectors then multiply the speed of each x impact and y impact back onto the current objects

there is a nice tutorial here[/QUOTE]

Hey JBPresents,

I didn’t read all of your response but . . . HA! just kidding, I couldn’t resist that little joke :slight_smile:

Thanks for the suggestion . . . I already have the bounce part figured out and the objects bounce off each other just fine, and I’m happy with that part . . . I’ll be modifying the movie clips eventually so they have more hittest “bounce surfaces” for more realistic bounces.

My problem is when the bouncing slows and stops and one object is on top of another (stacked) that there’s the problem, and the object won’t just sit on top of the other one . . . it vibrates a little then falls down to the bottom of the stage . . . I’d like it to just sit on top of the other object after the bouncing stops . . . this is my dilemma . . . here’s a link to the .swf so you can see what i mean:

http://www.farfromclose.com/flash_tests/drop_bounce_fla8.swf

grab the ball and place it on top of the box and let go and you’ll see what I mean . . . so what do you think the issue is?


Cooldude88,
Thanks for the code placement advice . . . I know i should try to clean up the code and get it all organized more, but for now I want to get this to work :slight_smile:

Thanks,

Hondo311

ok so i took a good look at your code and the main things i noticed were you used normal variables then just called it using _root id suggest that you try using _global instead of _root and also you have
if( pos.x + radius > movie.width ) {
pos.x = movie.width - radius;
vel.x *= -_root.restitution;
}
which if im not mistaken says that if the radius of the ball plus the x position of the ball is larger than the width of the ball should that not be < if not im sorry there but maybe thats the issue?

[QUOTE=cooldude88;2327260]ok so i took a good look at your code and the main things i noticed were you used normal variables then just called it using _root id suggest that you try using _global instead of _root and also you have
if( pos.x + radius > movie.width ) {
pos.x = movie.width - radius;
vel.x *= -_root.restitution;
}
which if im not mistaken says that if the radius of the ball plus the x position of the ball is larger than the width of the ball should that not be < if not im sorry there but maybe thats the issue?[/QUOTE]

Hi cooldude88,
That didn’t seem to work. When I changed _root to _global in the example above, it made no change. When I changed > to < the ball dropped and was aligned to the left side of the stage and when I dragged it and let go, it flew off the stage to the left.

Thanks for trying . . . any other ideas? have you tried making changes in the Flash file I uploaded? For instance, should I try changing all the _root to _global? I did that to just the ball and it got all messed up.

ok at the moment i cant open the file but when you are using _global it basically becomes part of the name itself so
_global.speed
and
then using just
speed
the program will have no idea what to do with the second one but basically what _gloal does is it makes it so that no matter where the variable is you can call it regardless of where you want to use it. so im not sure what else i can suggest.

Hey Cooldude88,

I tried that, and changed all of the _root to _global . . . except I left _root.gravity alone (when I changed _root.gravity to _global.gravity the objects just hung in space and didn’t drop.

I played around with changing only some of the _root to _global, but ultimately, I’m still havign the same problem where the objects won’t stop stacked on top of each other and slide down to the bottom of the stage.

So, I’m not sure this _root to _global method is the way to go (unless I’m doing something wrong).

Try to open the file i posted earlier, change the _root to _global values and see what I mean.

Anyone else have some ideas how to fix this issue?

Thanks!

Hondo311

Any other suggestions for this?