• Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

Discussion I try create perfect collisions

sinigrimi

Member
I'm trying to create perfect wall collisions like in one post from the forum, but my “oPlayer” skips through “oWall” from all sides except on the right. Help me find a mistake, please

create:
Code:
player_stats[0] = 5 ;    //speed
player_stats[1] =  100; //hp
player_stats[2] = 5; //damage
player_stats[3] =  500; //firing range
player_stats[4] = 1; //defence

sprite_bbox_top = bbox_top - y;
sprite_bbox_bottom = bbox_bottom - y;
sprite_bbox_right = bbox_right - x;
sprite_bbox_left = bbox_left - x;
step:
Code:
var hspd = player_stats[0];
var vspd = player_stats[0];
        if(keyboard_check(ord("W"))){
            y -= vspd;
        }
if(keyboard_check(ord("S"))){
            y += vspd;
        }
if(keyboard_check(ord("A"))){
            x -= hspd;
        }
if(keyboard_check(ord("D"))){
            x += hspd;
        }

if place_meeting(x,y,oWall) {
    var wall = instance_place(x+ sign (hspd),y,oWall);
    if (hspd > 0) { //right
        x = (wall.bbox_left-1)-sprite_bbox_right;
    } else if (hspd < 0) { //left
        x = (wall.bbox_right+1)-sprite_bbox_left;
    }
    hspd = 0;
}


if place_meeting(x,y,oWall) {
    var wall = instance_place(x,y+ sign (vspd),oWall);
    if (vspd > 0) {
        y = (wall.bbox_top-1)-sprite_bbox_bottom;
    } else if (vspd < 0) {
        y = (wall.bbox_bottom+1)-sprite_bbox_top;
    }
    vspd = 0;
}
upd:

I changed the code a bit in step event and now I have x-axis collision, but the y-axis does not work due to the x-axis, lmao. If I turn off the x-axis check, everything works on the y-axis. Help me please....

changes in step:
Code:
var  hspd = player_stats[0]
var vspd = player_stats[0];
if(keyboard_check(ord("W"))){
            vspd = -player_stats[0];
            y += vspd;
        }
if(keyboard_check(ord("S"))){
            vspd = player_stats[0];
            y += vspd;
        }
if(keyboard_check(ord("A"))){
    hspd = - player_stats[0]
            x +=  (hspd);
        }
if(keyboard_check(ord("D"))){
        hspd = + player_stats[0]
            x +=  (hspd);
        }

NOTE: The solution is in the second message.
NOTE2: I have new problem case in the third message. [SOLVED]
 
Last edited:

sinigrimi

Member
Ok guys, I found another way, I had to watch different articles and some videos on YouTube. For those reading this, here is the code I'm using now. If you have ideas on how to simplify it, I will be very grateful.
Code:
var input_speedX2 = (keyboard_check(vk_lshift));
var input_left = (keyboard_check(ord("A")));
var input_right = (keyboard_check(ord("D")));
var input_up = (keyboard_check(ord("W")));
var input_down = (keyboard_check(ord("S")));
var spd = player_stats[0];

if (input_speedX2){
    spd *= 2;
}
else {
    spd = player_stats[0];
}

    var spdX = 0;
    var spdY = 0;

spdY = (input_down - input_up) * spd;
    spdX = (input_right-input_left)*spd;

if (spdX !=0){
    if (place_meeting(x+spdX,y,oWall)){
        repeat (abs (spdX)){
            if (!place_meeting(x+sign(spdX),y,oWall)){
                x+=sign(spdX);
            }
            else{
                break;
            }
        }
        spdX = 0;
    }
}

if (spdY !=0){
    if (place_meeting(x,y+spdY,oWall)){
        repeat (abs (spdY)){
            if (!place_meeting(x,y+sign(spdY),oWall)){
                y+=sign(spdY);
            }
            else{
                break;
            }
        }
        spdY = 0;
    }
}


x+=spdX;
y+=spdY;
In the end, this is only part of the movement system and it already looks awfully bulky. Now I will work to push the enemies forward during the collisions, in my thoughts it does not seem difficult but in practice, there are always a lot of problems.
 
Last edited:

sinigrimi

Member
Hi again, and I ran into a new problem. Both oPlayer and oEnemy themselves cannot pass through the wall, BUT! They push each other into this, it really upsets me, please tell me how to get around this, or will I have to change the entire collision system?

Example in the video:


"player step" in the previous post. And here is the collision event with oPlayer prescribed in oEnemy:
Code:
var dir = point_direction(x, y, other.x, other.y);

while(place_meeting(x, y, other))
{
with (other)
    {
    x += lengthdir_x(0.25, dir);
    y += lengthdir_y(0.25, dir);
    }
x -= lengthdir_x(0.5, dir);
y -= lengthdir_y(0.5, dir);
}

and oEnemy step:
Code:
if instance_exists(oPlayer)
{
var dir = point_direction(x, y, oPlayer.x, oPlayer.y);
direction = dir;
speed = spd;
}
if (place_meeting(x+spd,y,oSolid)){
    hspeed = 0;

}
if (place_meeting(x-spd,y,oSolid)){
    hspeed = 0;

}
if (place_meeting(x,y+spd,oSolid)){
    vspeed = 0;
}
if (place_meeting(x,y-spd,oSolid)){
    vspeed = 0
}
help me please
 
Last edited:

gnysek

Member
Not sure, but maybe try to replace x += lengthdir_x(0.25, dir); with x = xprevious, should be better (as if other object didn't moved in last step, it won't move again). Now, you're moving objects by 0.25 when they collide, even when they not move.
 

sinigrimi

Member
Not sure, but maybe try to replace x += lengthdir_x(0.25, dir); with x = xprevious, should be better (as if other object didn't moved in last step, it won't move again). Now, you're moving objects by 0.25 when they collide, even when they not move.
I tried this and in this case new problems arise when the enemy collides with the player, the player cannot move in any direction except the opposite enemy. And of course pushing is much more interesting (if possible)
video:
 

sinigrimi

Member
Now I'm trying a new method in which I used the oSolid step event (yes, I suspect that this is one of the worst ways). And so it works great for the Player and works for the enemy. BUT! Sometimes, when the enemy runs through the wall to the enemy on the right side, he skips through the wall (he is teleported by coordinates not bbox_left, but bbox_right). New solutions equal new challenges. :)
help me if u can
and sorry for my english :D

Code:
bb_left = x -65;
bb_right = x +65;
bb_top = y -65;
bb_down= y +65;

and
Code:
if (place_meeting(x-1,y,oPlayer)){
    oPlayer.x = bb_left;
}
if (place_meeting(x+1,y,oPlayer)){
    oPlayer.x = bb_right;
}
if (place_meeting(x,y-1,oPlayer)){
    oPlayer.y = bb_top;
}
if (place_meeting(x,y+1,oPlayer)){
    oPlayer.y = bb_down;
}
//____________________________________________

if (place_meeting(x-1,y,oEnemy)){
    oEnemy.x = bb_left;
}
if (place_meeting(x+1,y,oEnemy)){
    oEnemy.x = bb_right;
}
if (place_meeting(x,y-1,oEnemy)){
    oEnemy.y = bb_top;
}
if (place_meeting(x,y+1,oEnemy)){
    oEnemy.y = bb_down;
}
 
Top