bouncing objects

pgvago

Member
hello from italy (again);

can i anybody suggest an idea on how you would make an object bounce off a wall.
the antifairy in zelda is ideally what i am trying to achieve.


please move to 03:02.

i would love a suggestion on how you would tackle the problem.

thanks, pietro.
 

Gzebra

Member
use speed and direction for movement, and randomly add or subtract 90 to direction when the object collide with the wall.
 
T

Timothy

Guest
use speed and direction for movement, and randomly add or subtract 90 to direction when the object collide with the wall.
Except it's not random.

Simple solution.
If colliding on x axis, reverse hspeed.
If colliding on y axis, reverse vspeed.
 

pgvago

Member
thank you for your replies.
let me do some experiments on your suggestions and i'll get back to you.

pietro.
 
Two collision checks. One for the x axis plus hspeed, one for the y axis plus vspeed. Whichever returns the hit, reverse the appropriate variable.
 
R

Rattlejaw

Guest
You can try this. It's a very simple method.

In the object that is bouncing off walls.

CREATE EVENT
direction = (random_range(45,135));
speed = 2;

Add a collision event with your obj_wall. In that event, use the following function.

move_bounce_all(true);

The object should move around and bounce off of walls. You can change the values in the direction and speed to tweak it. If you don't want it's starting direction to be so random, you can just have direction = 45 or something like that.

Where ever you place or spawn the object in the room, it does effect it's moving pattern.
 
Last edited by a moderator:

pgvago

Member
thanks for your help.
unfortunately there isn't much literature on move_bounce_all ().

does the object bounce bounce at the same angle?

thanks, pietro.
 

Jaan

Member
Gidday.

Found this thread and it's along the lines of the problem I'm having. So... I've been through the Breakthrough tutorial and am trying to impliment multiball. A single ball works and bounces perfectly.

If I pick up the multiball powerup two extra balls are created, move upwards at the correct speed... but all balls lose the ability to bounce. All three balls will move upwards through the bricks they're meant to bounce off. Neither will they bounce off the boundaries. I'm certain the problem is with move_bounce_all() but I just can't figure it out.

  • If I comment the move_bounce_all() line then the single ball won't bounce, as expected. It moves through the bricks and gets stuck on the top boundary, same as the multiball problem.
  • If I place move_bounce_all() in the Step event the balls collide with the brick and get stuck, looking like they're very quickly vibrating.

o_powerup object code when collecting a multiball powerup:
Code:
case 9:  //Triple ball
        //Set multi ball control on
        o_multiball_control.multi = true;
      
        //Create new balls
        for (var _i = 0; _i < 2; _i++){
            instance_create_layer(o_ball.x, o_ball.y, "Ball", o_ball);
        }
        instance_destroy();
        break;
o_ball object code when colliding with a brick:
Code:
if bounce_enable{
    bounce();
} 

with other{
    //Determin powerup drop
    var _chance = random(10);
    if _chance < other.pu_chance instance_create_layer(x, y, "Powerups", o_powerup);
    //Float point value
    spawn_floating_text(value);
    instance_destroy();
}

global.player_score += o_Brick.value;
bounce() script code:
Code:
//Get direction ball came from
var _dir = direction - 180;

//If ball is overlapping the brick, bounce will be incorrect
//Move the ball back until the bounding boxes are not overlapping
while place_meeting(x, y, other){
    x += lengthdir_x(1, _dir);
    y += lengthdir_y(1, _dir);
}

//Enable bouncing
move_bounce_all(true);

//Increase speed
if speed < max_spd speed += spd_increase;
o_ball object code that is used to shoot the ball the first time, or auto set speed and direction if multiball is active:
Code:
//Control the ball when new ball
if !o_multiball_control.multi{
    //Keep ball on the bat
    if on_bat{
        x = o_player.x;
        y = o_player.bbox_top - sprite_height /2;
    }
   
    //Shoot ball
    if o_player.shoot && can_shoot{
        speed = initial_spd;
        direction = dir;
        on_bat = false;
        can_shoot = false;
    }
}

if o_multiball_control.multi{
    speed = initial_spd;
    direction = dir;
    move_bounce_all(true);
}
The move_bounce_all(true) in the o_ball code above is what causes the balls to collide with the bricks and stick.

Any help and a good explanation of how move_bounce_all() works will be much appreciated. The explanation of this function is confusing.

Cheers!
 
R

Rukiri

Guest
This is what I use:
Create:
Code:
degree = -1;
radians = -1;
spd = 2;
knockback = false;
Step:
Code:
if (knockback == true) {
   x+=cos(radians)*SPEED_TO_BOUNCE_BACK;
   y+=-sin(radians)*SPEED_TO_BOUNCE_BACK;
}
Alarm:
Code:
knockback = false;
Collision (many ways to check):
Code:
//degree = radtodeg(arctan2(wall, player, etc.y - enemy.y, enemy.x - wall, player, etc.x));
degree = arctan2(wall, player, etc.y - enemy.y, enemy.x - wall, player, etc.x) * (180 / pi);
radians = pi * degree / 180;
knockback = true;
alarm[0] = 20;
Basically you want to either get the X/Y of a Wall Tile, The Player Object, etc, and then this will push the object in a direction.

So you only want to push it for 1-2 seconds use a timer variable, set delta time and then timer += 1 * delta and then you can set if timer>= 2 { knockback = false; } and you're good to go.

If you are using tile collisions you setup wall collisions for knockback and normal collision maps "so the enemy can't move past". If using sprite/object collisions use if place_meeting(x, y, wall) { // math for bounce back here } You can add an offset of 2 or 3 pixels and then check the players direction to adjust the offset but you don't need to write the bounceback 4 times just the offset part so like.

Code:
with (player) {
if place_meeting(x-1, y, player) || place_meeting(x+1, y, player) || place_meeting(x, y-1, player) || place_meeting(x, y+1, player) {
// bounceback code
}
}
with walls if place_meeting(x, y, wall) { // bounce code } is fine.

Also so the enemy doesn't bounce off the walls while just moving around make sure knockback is true so that it only happens IF it was originally knocked back by the player.

I do not use built invariables, I like making my code reusable say if I were to go to another game engine, than it's simply just copy and place
 
Last edited:
R

Rattlejaw

Guest
thanks for your help.
unfortunately there isn't much literature on move_bounce_all ().

does the object bounce bounce at the same angle?

thanks, pietro.
I know this is old, so you probably don't need this info anymore, but I found a much better way to do it. The way I showed you before locks it in the same pattern, which is not what you were looking for. Instead of using move_bounce_all() in a collision event with the wall, use move_bounce_solid() in the step event. Then in your obj_solid, tick on the solid box. It's really that simple.

In the create event do something like
speed = 2; // or any speed you want
direction = random(360); // or any direction you want

in the step event do

move_bounce_solid(true)

Don't forget to have the solid box ticked on in your obj_solid and delete the other lines of code like move_bounce_all() if you still have that in your object.
 
Last edited by a moderator:

Jeddakya

Member
Hi! :D
Jeddakya here

Re: GM2

i'm not following no tutorial (i'm a total non-conformist). dreaming this up as i go. just for the fun of it.

move_bounce_all - move and bounce obj off any n all objects
move_bounce_solid - move and bounce obj off solid objects only
move_contact_solid - move obj until obj hits a solid object; stops dead.

in my ball's step event is one line. move_contact_solid(direction, global.ballspeed)
my wall's "ball collision" event (because walls effect the ball) is also one line:
with(other) move_bounce_solid(true);

i've added a line to the wall's "ball collision" event to output a line of text "ball hit wall" (not draw_text, but i create a "message" object that displays the output). this message will sometimes display up to four times when the ball hits the wall! but not consitently. sometimes "ball hit wall" appears once, twice, three times, or even not at all (and no, it's not the msg object's fault)! the ball bounces, for sure. but will appear to "stick" to the wall for a frame or three (likely the same number of frames as the number of times the msg "ball hit wall" appears) and then continues its expected movement. it's an utterly baffling issue. all objects are set to solid. there are six objects: four "walls", a "paddle" and a ball. i'm not doing bricks until this "sticking" issue goes away.

strangely, this is not happening when the paddle and ball collide. well, it did, but for a different reason. the paddle is now coded differently. its movement is attached to the mouse, which required some thinking to get the ball to stop sticking to the paddle. turns out, i was allowing the mouse movement to move the paddle into the ball's position (overlapping the two) by just setting paddle's X to mouse_x lol. so, instead, i move the paddle one pixel at a time toward the mouse's X position (checking for ball collisions along the way) per step, bounce the ball away (if collision, of course), and continue moving until the paddle reaches mouse_x. convoluted, but it solved that problem. but...walls don't move! so ... i'm kinda stuck, if you'll pardon the pun.

i've tried many things to prevent this "stickyness", but to no avail.

after the move_contact_solid(direction, global.ballspeed) line in the ball's step event, i've added things like move_bounce_solid(true) and removed move_bounce_solid(true) from the wall's "ball collision" event. that worked, too! but, the ball still sticks to walls for a frame or three. even tried using move_outside_solid(direction-180,global.ballspeed), but that didn't seem to make a lick of a difference! i've even tried using the step end event! did if (x == xprevious and y == yprevious) and output'd another message "ball is stuck". that message will appear lots!

i've removed bouncing all together, to allow the ball to just stop when it hits a solid object. the ball goes inside the wall! <blink><blink><blink>

i think i have a fundamental knowledge gap. if i draw a box around the ball from another object's draw event, the box appears to be a frame behind or ahead - i can't tell. it's the correct size though :)

so i'm at a loss. no idea how to fix this, let alone diagnose the issue.

any ideas or help would be most appreciated
 
Top