1. Hey! Guest! The 36th GMC Jam will take place between February 27th, 12:00 UTC - March 2nd, 12:00 UTC. Why not join in! Click here to find out more!
    Dismiss Notice

Move Outside Issue

Discussion in 'Programming' started by robproctor83, Feb 9, 2020.

  1. robproctor83

    robproctor83 Member

    Joined:
    Sep 30, 2019
    Posts:
    292
    Okay, this is a long outstanding issue that I have had in my project that I am trying to fix, but it seems like no matter what I try it has some other issue. I attached an image to help explain, but my problem is that my ammo can get stuck in the wall if the player is too close. The ammo start extended out from the player, and so I need some way to pull the ammo out of the wall.

    I have tried a number of things, but essentially what I want is for the ammo to instantly teleport to the right location. The closest I have gotten is the code below, but the problem is it only works with walls to the left/right and not up/down because it's got the x/y separated and moves x first, so if it's a y wall it will try moving it x first and that isn't what I want.

    Code:
            var _collide = instance_place(x, y, obj_Solid);
            if(move_x_sp != 0){
                var collide = instance_place(x+move_x_sp,y,obj_Solid);
                if(instance_exists(collide) && collide.solid){
                    if(_collide){
                        var _pdir = point_direction( 0, 0, sign(owner.x-x), 0);
                        move_outside_solid(_pdir, -1);
                    }
                    move_x_sp = 0;
                }
                x += move_x_sp*scr_delta(time.Global);
            }
            else{
                move_x_sp = cos(move_direction) * move_speed;
            }
    
            if(move_y_sp != 0){
                var collide = instance_place(x,y+move_y_sp,obj_Solid);
                if(instance_exists(collide) && collide.solid){
                    if(_collide){
                        var _pdir = point_direction( 0, 0, 0, sign(owner.y-y));
                        move_outside_solid(_pdir, -1);
                    }
                    move_y_sp = 0;
                }
                y += move_y_sp*scr_delta(time.Global);
            }
            else{
                move_y_sp = sin(move_direction) * move_speed;
            }
    
    I think, what I need is to do something like check and see if _collide is y positioned or x positioned and then run one of the two chunks.. But, the problem there would be walls that are diagnal, I don't think it would work there.

    Also, just to note, I have tried other things like reversing the direction towards the player, or move_outside_* over time instead of instantly, it's like no matter what I do there is some other issue.
     

    Attached Files:

  2. Nidoking

    Nidoking Member

    Joined:
    Nov 20, 2019
    Posts:
    114
    It might be easier if you spawn the bullet inside the player, where you know there won't be a solid object, then move it in the correct direction and account for collisions with walls as you go. The bullet won't actually appear until you reach the final location at the desired radius, since you do all of these calculations within the same event where you spawn the bullet.
     
  3. robproctor83

    robproctor83 Member

    Joined:
    Sep 30, 2019
    Posts:
    292
    If at all possible I'd want to avoid that. You can't tell from my example image but the player weapon circles the player 360 deg and when the player attacks the ammo spawns on the weapon rather than the player. Also some ammo is quite larger than the player and I'd run into problems still.
     
  4. Nidoking

    Nidoking Member

    Joined:
    Nov 20, 2019
    Posts:
    114
    There is literally no difference between spawning the bullet at the weapon and spawning it at the player and then moving it to the weapon, except for a bit more processing that you're going to have to do anyway.
     
  5. robproctor83

    robproctor83 Member

    Joined:
    Sep 30, 2019
    Posts:
    292
    I see what you are saying, sorry I misunderstood initially. While I think that would probably work, I don't think that would work with ammo larger than the player as it would start already on top of everything.

    My thought was to take the colliding object and the ammos owner (player) and figure out if the ammo should be spawning above or below, left or right of the colliding object. The problem I ran into there is I have up/down and left/right separate and so if it's left/right collision it works perfectly but if it's up/down it still triggers as left/right and so repositions the ammo incorrectly. I was thinking about setting up some condition to see which direction I should reposition the ammo but then that would not fix diagonal. In order for diagonal to work it seems like it would need to only move so far in a single step, like 16px let's say, so that it can move in both directions, but then are other problems with moving over time... Aghh
     
  6. Joe Ellis

    Joe Ellis Member

    Joined:
    Aug 30, 2016
    Posts:
    1,106
    If the ammo moves how you want when the player isn't next to a wall, couldn't you do a check when the ammo is first fired, where if it collides with a wall within 1 step or so, it just destroys it instantly? You could set the ammo to not visible so this wouldn't be seen, then set it to visible if it hasn't been destroyed instantly.
     
  7. robproctor83

    robproctor83 Member

    Joined:
    Sep 30, 2019
    Posts:
    292
    Joe, Thanks for your suggestion. That is what I was doing initially, but the problem with that is some of the ammo is rather large and in scenarios where the player is in a tight spot or a narrow hallway it's not always clear when the ammo will end up landing on a wall, especially considering the weapon is rotating 360 around the player extended about 16px from the sprite origin. So when the player is butted up against a wall they may be trying to place ammo right up next to the wall, but to do that they have to make sure they don't have the weapon to far into the wall area otherwise the ammo will never appear.... See what I mean?

    There has got to be some way to do this...
     
  8. robproctor83

    robproctor83 Member

    Joined:
    Sep 30, 2019
    Posts:
    292
    Alright, I have a solution that works "good enough" in that in 90% of the situations it reacts how I anticipate. On those few that didn't work exactly as I wanted they were still acceptable results. Even in tight situations and corners it seems to be working well enough, no more teleporting or flickering yay! It's not perfect though, in some corner cases or strange angles the ammo gets projected not exactly where I would want and also if the ammo can't be larger than 32px. Well, I would consider this solved, but if anyone has anymore suggestions/ideas I would love to hear them.

    Code:
            if(move_x_sp != 0){
                var collide = instance_place(x+move_x_sp,y,obj_Solid);
                if(instance_exists(collide) && collide.solid){
                    if(_collide && (owner.x > _collide.bbox_right || owner.x < _collide.bbox_left)){
                        var _cbx = (owner.x > _collide.bbox_right) ? _collide.bbox_right: _collide.bbox_left;
                        move_outside_solid(point_direction( 0, 0, sign(owner.x-_cbx), 0), 48);
                    }
                    move_x_sp = 0;
                }
                x += move_x_sp*scr_delta(time.Global);
            }
            else{
                move_x_sp = cos(move_direction) * move_speed;
            }
    
            if(move_y_sp != 0){
                var collide = instance_place(x,y+move_y_sp,obj_Solid);
                if(instance_exists(collide) && collide.solid){
                    if(_collide){
                        var _cby = (owner.y > _collide.bbox_top) ? _collide.bbox_top: _collide.bbox_bottom;
                        move_outside_solid(point_direction( 0, 0, 0, sign(owner.y-_cby)), 48);
                    }
                    move_y_sp = 0;
                }
                y += move_y_sp*scr_delta(time.Global);
            }
            else{
                move_y_sp = sin(move_direction) * move_speed;
            }
    
     
  9. robproctor83

    robproctor83 Member

    Joined:
    Sep 30, 2019
    Posts:
    292
    Okay, dangit maybe I jumped the gun there... Play testing more this morning it seems that no, there are in fact still major problems. Bah... I'll have to rethink this. Preventing the ammo from ever starting outside the walls and spawning it on top of the player is probably the right way to go about doing this, but I can't comprehend how that would work without other issues because of the size of the ammo can be quite a bit larger than the player.
     
  10. Joe Ellis

    Joe Ellis Member

    Joined:
    Aug 30, 2016
    Posts:
    1,106
    What about using a collision line from the player to where the ammo first appears:

    Code:
    ///weapon_shoot()
    
    if !collision_line(x, y, x + lengthdir_x(ammo_size, aim_dir), y + lengthdir_y(ammo_size, aim_dir), obj_solid)
    {
    //create ammo
    }
    To get "ammo_size" it would probably be the width of the sprite, or height depending which direction the original image is facing.

    Or maybe you could use collision_circle(x, y, ammo_radius, obj_solid)
     
    Last edited: Feb 11, 2020
  11. robproctor83

    robproctor83 Member

    Joined:
    Sep 30, 2019
    Posts:
    292
    Thank you Joe, but if I understand correctly what your saying would be the same as doing a normal collision check. What I am after is a way to move that object outside of the collision appropriately.
     
  12. Joe Ellis

    Joe Ellis Member

    Joined:
    Aug 30, 2016
    Posts:
    1,106
    Oh ok, in that case you could, after collision has been checked and a bullet is in collision, do a bbox check which will determine how it should bounce and also move it to contact with the wall's bbox:

    Code:
    if bbox_top < wall.bbox_bottom
    && bbox_bottom > wall.bbox_bottom
    {
    vsp = -vsp
    y = wall.bbox_bottom - (bbox_top - y)
    }
    if bbox_bottom > wall.bbox_top
    && bbox_top < wall.bbox_top
    {
    vsp = -vsp
    y = wall.bbox_top - (bbox_bottom - y)
    }
    if bbox_left < wall.bbox_right
    && bbox_right > wall.bbox_right
    {
    hsp = -hsp
    x = wall.bbox_right - (bbox_left - x)
    }
    if bbox_right > wall.bbox_left
    && bbox_left < wall.bbox_left
    {
    hsp = -hsp
    x = wall.bbox_left - (bbox_right - x)
    }
    It might be best to put that in a switch statement instead, to stop the speed being flipped twice, or use return false inside each statement.

    Does this sound like the right kind of thing?
     
    Last edited: Feb 11, 2020
  13. robproctor83

    robproctor83 Member

    Joined:
    Sep 30, 2019
    Posts:
    292
    Yes, Joe something like that may very well work, thank you! When I get home here in a bit I'll have another go at it and I think, yes, using the bbox of the collider (wall) and the ammo might be what I need.
     
    Joe Ellis likes this.
  14. robproctor83

    robproctor83 Member

    Joined:
    Sep 30, 2019
    Posts:
    292
    It bothers me how much trouble this problem has given me. I've worked and reworked this code over and over for the past couple years and I've reworked my ammo generator again to start from the player, and for collisions with a single straight wall it works how I want, but on corners it falls apart because it's colliding with multiple walls. I'm not sure how I will go about figuring out corners... Argh... This is driving me crazy, I feel like no matter what I do there is some issue with it.

    Code:
    var _start_collide = instance_place(x,y,obj_Solid);
    if(_start_collide){
        //top overlap
        if(bbox_top <= _start_collide.bbox_bottom && bbox_bottom > _start_collide.bbox_bottom){
            while(bbox_top <= _start_collide.bbox_bottom && bbox_bottom > _start_collide.bbox_bottom){
                y++;
            }
        }
        //right overlap
        if(bbox_right >= _start_collide.bbox_left && bbox_left < _start_collide.bbox_left){
            while(bbox_right >= _start_collide.bbox_left && bbox_left < _start_collide.bbox_left){
                x--
            }
        }
        //bottom overlap
        if(bbox_bottom >= _start_collide.bbox_top && bbox_top < _start_collide.bbox_top){
            while(bbox_bottom >= _start_collide.bbox_top && bbox_top < _start_collide.bbox_top){
                y--;
            }
        }
        //left overlap
        if(bbox_left <= _start_collide.bbox_right && bbox_right > _start_collide.bbox_right){
            while(bbox_left <= _start_collide.bbox_right && bbox_right > _start_collide.bbox_right){
                x++;
            }
        }
    }
    
    *edit - Okay, thinking about this for another 2 seconds I realize that obviously I should loop over all the collisions, but stil on the example image I attached how would I go about handling the collision with the wall object on the corner like that?

    *edit 2 - Okay, more thought, maybe for wall corners I can check for each bbox side and not just opposite sides... Hmm... that's going to be a hell of a complicated conditional, so much so I feel like that can't be the right way... is it?

    *EDIT 3 - OMG wait, maybe I don't need to worry about any of the bbox stuff! My ammo may be larger than my player, but it's not larger than a single gid cell (32px by 32px) SO I really only need to move the ammo to the grid cell that the player is in, not to the actual position of the player... YES that makes sense... Okay, updating now!

    *EDIT 4 - Okay... Bummer that won't work because apart from walls I also have a few other solid objects and they are not all at least 32px, some are pretty small and so the player and a solid can both occupy a single cell at the same time... damnit...
     

    Attached Files:

    Last edited: Feb 13, 2020 at 1:49 AM
  15. robproctor83

    robproctor83 Member

    Joined:
    Sep 30, 2019
    Posts:
    292
    Okay... Getting close, just about got it I think... As far as walls go, I think I have it figured out, it seems overwhelming but hey, it's working... Now, the problem I need to solve is the smaller solids, things that the ammo shouldn't spawn on but is smaller than a wall cell, some are even smaller than the player. the other problem that may arise is that the smaller solids can spawn next to a wall, so I have a feeling there will be some problems there... But for now, just walls, this seems to be working :)

    Code:
    var _bbox_top_left = collision_point(bbox_left, bbox_top, obj_Solid, false, true);
    var _bbox_top_right = collision_point(bbox_right, bbox_top, obj_Solid, false, true);
    var _bbox_bot_right = collision_point(bbox_right, bbox_bottom, obj_Solid, false, true);
    var _bbox_bot_left = collision_point(bbox_left, bbox_bottom, obj_Solid, false, true);
    
    /* STRAIGHT */
    //top
    var _ic = 0;
    if(_bbox_top_left && _bbox_top_right && !_bbox_bot_right && !_bbox_bot_left){
        while(collision_line(bbox_left, bbox_top, bbox_right, bbox_top, obj_Solid, false, false)){
            y+=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    //right
    if(!_bbox_top_left && _bbox_top_right && _bbox_bot_right && !_bbox_bot_left){
        _ic = 0;
        while(collision_line(bbox_right, bbox_top, bbox_right, bbox_bottom, obj_Solid, false, false)){
            x-=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    //bottom
    if(!_bbox_top_left && !_bbox_top_right && _bbox_bot_right && _bbox_bot_left){
        _ic = 0;
        while(collision_line(bbox_left, bbox_bottom, bbox_right, bbox_bottom, obj_Solid, false, false)){
            y-=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    //left
    if(_bbox_top_left && !_bbox_top_right && !_bbox_bot_right && _bbox_bot_left){
        _ic = 0;
        while(collision_line(bbox_left, bbox_top, bbox_left, bbox_bottom, obj_Solid, false, false)){
            x+=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    /* CORNER || INSET */
    //top left
    if((_bbox_top_left && !_bbox_top_right && !_bbox_bot_right && !_bbox_bot_left) || (_bbox_top_left && _bbox_top_right && !_bbox_bot_right && _bbox_bot_left)){
        _ic = 0;
        while(collision_line(bbox_left, bbox_top, bbox_right, bbox_top, obj_Solid, false, false) && collision_line(bbox_left, bbox_top, bbox_left, bbox_bottom, obj_Solid, false, false)){
            y+=2;
            x+=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    //top right
    if((!_bbox_top_left && _bbox_top_right && !_bbox_bot_right && !_bbox_bot_left) || (_bbox_top_left && _bbox_top_right && _bbox_bot_right && !_bbox_bot_left)){
        _ic = 0;
        while(collision_line(bbox_left, bbox_top, bbox_right, bbox_top, obj_Solid, false, false) && collision_line(bbox_right, bbox_top, bbox_right, bbox_bottom, obj_Solid, false, false)){
            y+=2;
            x-=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    //bot right
    if((!_bbox_top_left && !_bbox_top_right && _bbox_bot_right && !_bbox_bot_left) || (!_bbox_top_left && _bbox_top_right && _bbox_bot_right && _bbox_bot_left)){
        _ic = 0;
        while(collision_line(bbox_left, bbox_bottom, bbox_right, bbox_bottom, obj_Solid, false, false) && collision_line(bbox_right, bbox_top, bbox_right, bbox_bottom, obj_Solid, false, false)){
            y-=2;
            x-=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    //bot left
    if((!_bbox_top_left && !_bbox_top_right && !_bbox_bot_right && _bbox_bot_left) || (_bbox_top_left && !_bbox_top_right && _bbox_bot_right && _bbox_bot_left)){
        _ic = 0;
        while(collision_line(bbox_left, bbox_bottom, bbox_right, bbox_bottom, obj_Solid, false, false) && collision_line(bbox_left, bbox_top, bbox_left, bbox_bottom, obj_Solid, false, false)){
            y-=2;
            x+=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    
    *edit 1 - I also need to fix that +/-2 it should only be 1 at a time but for some reason when only moving 1 some other code I have that stop ammo from moving when it hits a wall is being triggered incorrectly.
     
    Last edited: Feb 13, 2020 at 3:47 PM
  16. robproctor83

    robproctor83 Member

    Joined:
    Sep 30, 2019
    Posts:
    292
    Progress! I'm very close, thank you guys for your help and suggestions because it has helped a lot. I have it working "almost" perfect, the only remaining problem is tight situations where a small solid spawn near a wall or a corner and the player positions themselves between the two and fires an ammo that is larger than the distance between the two solids. It's not a super common issue, but there are usually a handful of those positions throughout the map. As a temporary work around I am destroying the ammo if after re-positioning everything it still has a solid collision.

    I would LOVE to fix that problem if possible, so if anyone has any suggestions please, it would be much appreciated. It can be confusing for the player to nudged up in that corner attacking and then go to shoot a particular ammo that is just a few pixels too large and nothing appears... But how do I figure out how to reposition ammo in this obscure circumstance? I need to somehow figure out the closest open space, in the direction of the player, and move it there...

    Anyways, here is what I have now... I somehow still feel like I am not going about this the right way! But, I'm just not sure.
    Code:
    ///AMMO CREATE
    //Start the ammo from the player position, this will be the base position from which the ammo can spawn
    //Check each corner to see what section is overlapped
    var _bbox_top_left = collision_point(bbox_left, bbox_top, obj_Solid, false, true);
    var _bbox_top_right = collision_point(bbox_right, bbox_top, obj_Solid, false, true);
    var _bbox_bot_right = collision_point(bbox_right, bbox_bottom, obj_Solid, false, true);
    var _bbox_bot_left = collision_point(bbox_left, bbox_bottom, obj_Solid, false, true);
    
    /* STRAIGHT collisions, directly up,down,left,right*/
    //top
    var _ic = 0;
    if(_bbox_top_left && _bbox_top_right && !_bbox_bot_right && !_bbox_bot_left){
        while(collision_line(bbox_left, bbox_top, bbox_right, bbox_top, obj_Solid, false, false)){
            y+=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    //right
    if(!_bbox_top_left && _bbox_top_right && _bbox_bot_right && !_bbox_bot_left){
        _ic = 0;
        while(collision_line(bbox_right, bbox_top, bbox_right, bbox_bottom, obj_Solid, false, false)){
            x-=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    //bottom
    if(!_bbox_top_left && !_bbox_top_right && _bbox_bot_right && _bbox_bot_left){
        _ic = 0;
        while(collision_line(bbox_left, bbox_bottom, bbox_right, bbox_bottom, obj_Solid, false, false)){
            y-=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    //left
    if(_bbox_top_left && !_bbox_top_right && !_bbox_bot_right && _bbox_bot_left){
        _ic = 0;
        while(collision_line(bbox_left, bbox_top, bbox_left, bbox_bottom, obj_Solid, false, false)){
            x+=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    /* CORNER || INSET */
    //top left
    if((_bbox_top_left && !_bbox_top_right && !_bbox_bot_right && !_bbox_bot_left) || (_bbox_top_left && _bbox_top_right && !_bbox_bot_right && _bbox_bot_left)){
        _ic = 0;
        while(collision_line(bbox_left, bbox_top, bbox_right, bbox_top, obj_Solid, false, false) && collision_line(bbox_left, bbox_top, bbox_left, bbox_bottom, obj_Solid, false, false)){
            y+=2;
            x+=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    //top right
    if((!_bbox_top_left && _bbox_top_right && !_bbox_bot_right && !_bbox_bot_left) || (_bbox_top_left && _bbox_top_right && _bbox_bot_right && !_bbox_bot_left)){
        _ic = 0;
        while(collision_line(bbox_left, bbox_top, bbox_right, bbox_top, obj_Solid, false, false) && collision_line(bbox_right, bbox_top, bbox_right, bbox_bottom, obj_Solid, false, false)){
            y+=2;
            x-=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    //bot right
    if((!_bbox_top_left && !_bbox_top_right && _bbox_bot_right && !_bbox_bot_left) || (!_bbox_top_left && _bbox_top_right && _bbox_bot_right && _bbox_bot_left)){
        _ic = 0;
        while(collision_line(bbox_left, bbox_bottom, bbox_right, bbox_bottom, obj_Solid, false, false) && collision_line(bbox_right, bbox_top, bbox_right, bbox_bottom, obj_Solid, false, false)){
            y-=2;
            x-=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    //bot left
    if((!_bbox_top_left && !_bbox_top_right && !_bbox_bot_right && _bbox_bot_left) || (_bbox_top_left && !_bbox_top_right && _bbox_bot_right && _bbox_bot_left)){
        _ic = 0;
        while(collision_line(bbox_left, bbox_bottom, bbox_right, bbox_bottom, obj_Solid, false, false) && collision_line(bbox_left, bbox_top, bbox_left, bbox_bottom, obj_Solid, false, false)){
            y-=2;
            x+=2;
            _ic++;
            if(_ic > 100) break;
        }
    }
    
    //Reposition ammo to target position
    var xx = x;
    var yy = y;
    x = move_x;
    y = move_y;
    _ic = 0;
    //Step BACK from target, less collision checks hopefully
    while(instance_place(x, y, obj_Solid)){
        var _pdir = point_direction(x,y,xx,yy);
        x += lengthdir_x(1,_pdir);
        y += lengthdir_y(1,_pdir);
        _ic++;
        if(_ic > 100) break;
    }
    //One last collision to prevent player hiding behind solid and shooting
    //This happens because of stepping back from target
    //One extra collision, may still be cheaper than moving forward
    if(collision_line(xx, yy, x, y, obj_Solid, false, false)){
        x = xx;
        y = yy;
    }
    Code:
    ///AMMO STEP
    var _collide = instance_place(x, y, obj_Solid);
    //... do some other stuff with collisions... 
    //...
    if(move_x_sp != 0){
        var _collide_x = instance_place(x+move_x_sp,y,obj_Solid);
        if(instance_exists(_collide_x)){
            if(_collide && (owner.x > _collide.bbox_right || owner.x < _collide.bbox_left)){
                var _cbx = (owner.x > _collide.bbox_right) ? _collide.bbox_right: _collide.bbox_left;
                move_outside_solid(point_direction( 0, 0, sign(owner.x-_cbx), 0), 48);
                var _collide_destroy = instance_place(x,y,obj_Solid);
                if(_collide_destroy) instance_destroy();
            }
            move_x_sp = 0;
        }
        x += move_x_sp*scr_delta(time.Global);
    }
    else{
        move_x_sp = cos(move_direction) * move_speed;
    }
    
    if(move_y_sp != 0){
        var _collide_y = instance_place(x,y+move_y_sp,obj_Solid);
        if(instance_exists(_collide_y)){
            if(_collide){
                var _cby = (owner.y > _collide.bbox_top) ? _collide.bbox_top: _collide.bbox_bottom;
                move_outside_solid(point_direction( 0, 0, 0, sign(owner.y-_cby)), 48);
                var _collide_destroy = instance_place(x,y,obj_Solid);
                if(_collide_destroy) instance_destroy();
            }
            move_y_sp = 0;
        }
        y += move_y_sp*scr_delta(time.Global);
    }
    else{
        move_y_sp = sin(move_direction) * move_speed;
    }
     
  17. robproctor83

    robproctor83 Member

    Joined:
    Sep 30, 2019
    Posts:
    292
    I've attached a graphic that details the different collisions situations and the one that I am having problems with, maybe this will help visualize what is going on.
     

    Attached Files:

  18. Joe Ellis

    Joe Ellis Member

    Joined:
    Aug 30, 2016
    Posts:
    1,106
    Just letting you know I haven't forgotten about this, I'll hopefully have time in the next few days to help more
     
    robproctor83 likes this.
  19. robproctor83

    robproctor83 Member

    Joined:
    Sep 30, 2019
    Posts:
    292
    Thanks Joe, and no worries about responding, I'm just updating my progress... So close, but I have a feeling this last issue will be a real challenge, hopefully I don't have to redo everything again lol.
     
    Joe Ellis likes this.
  20. Alaska Minds

    Alaska Minds Member

    Joined:
    Feb 11, 2020
    Posts:
    12
    Hello robproctor83,

    The code below may help you. Add the code to the Ammo object and in a Collision Event with the Wall object. The code will cause the Ammo object to move to a random location 32 pixels away from the Wall and Character object. You can use this same code on all Collision Events (e.g. another Ammo object...)

    Code:
    // Moves instance away from wall (Provides Object Overlap Protection)
    var dir;
    var move_dis = 32;  // pixels to move away from other object in collision
    
    // If both instances are in the same location, set direction random
    if (x == other.x && y == other.y)
        dir = random(360);
    
    // Move in opposite direction of object in collision
    else
        dir = point_direction(other.x,other.y,x,y);
    
    // Move to new location but away from wall and character
    
    var dx = lengthdir_x(move_dis,dir);
    var dy = lengthdir_y(move_dis,dir);
    
    if (!place_meeting(x+dx,y,obj_character)) x += dx;
    if (!place_meeting(x,y+dy,obj_character)) y += dy;
     
    Last edited: Feb 15, 2020 at 6:26 AM

Share This Page