Problem with sprite corners [apparently solved]

Hello there!,
Let me introduce this; the game has weapons such as bows, staffs... which can create projectiles.
I wanted walls, signs, furniture... to break those projectiles, as it wouldn't make sense that arrows went through walls.
All the objects able to destroy the projectiles are my "destroyer objects", that execute the same script;
Code:
var projectile_inst = collision_rectangle(x - sprite_xoffset, y - sprite_yoffset, x - sprite_xoffset + sprite_width, y - sprite_yoffset + sprite_height, obj_projectile, true, true);
if (projectile_inst != noone) {
    with (projectile_inst) instance_destroy();
}
It was meant to detect the corners of the sprites and then check whether any projectile was there (and destroy him).

For debugging reasons, I decided to draw the collision borders and this is what I found:
strange.png
The collision boxes seem to have moved, and I don't know why... As well there are some little spaces where the collision system is not working. What's wrong?

Before detecting this BIG error, the collision was defined the same, but the "final y" of the rectangle was the same minus 5, so it made some space for if the player was touching the wall to fire the arrow, but it made this other screen:
strange2.png

So it seems I have 2 big problems here, that I didn't expect at all; one of them (the last one) I thought I solved it (https://forum.yoyogames.com/index.php?threads/setting-up-a-projectile-solution-found.12150) <-- Take a look at the images there, I think you will understand the projectile-creation in-wall problem (just the images, the mechanics have been changed!, now the arrows are 360º).

I am trying to figure out a way to kill those two problems once for all, doing research of sprites, but nothing. I tried even changing to the "default view system" (view[0] > object following: player) but it's not a view problem, it remains the same. I appreciate any suggestion, or even if you think this is an odd way to do that, please say it!

Thank you all!

EDIT: The "final y" - 5 is to create a gap between the player and the objects that destroy the projectiles, so if the player approaches to the walls too much, the projectile isn't destroyed. (in the link there are some pictures that illustrate this)

EDIT+: The collision mask of the projectiles is really small, in order to prevent what I told you before when approaching the destroying objects; look!,
half.png
 
Last edited:

Jakylgamer

Member
this is what i do for bullets / projectiles
step event:
Code:
//this is the directional control of the projectile
hspd = lengthdir_x( spd ,_dir);
vspd = lengthdir_y( spd ,_dir);

//collision code and apply movements
if place_meeting(x+hspd,y,obj_solid) {
    while (!place_meeting(x+sign(hspd),y,obj_solid)) {
        x+=sign(hspd);
    }
    hspd = 0;
    spd = 0;
    instance_destroy();
}
x+=hspd;

if place_meeting(x,y+vspd,obj_solid) {
    while (!place_meeting(x,y+sign(vspd),obj_solid)) {
        y+=sign(vspd);
    }
    vspd = 0;
    spd = 0;
    instance_destroy();
}
y+=vspd;
then to create the bullet / projectile
Code:
var b = instance_create(x,y,obj_bullet);
    b._spd = 10; //how fast to move
    b._dir = angle;//angle to shoot at
    b.image_angle = angle; //set sprites angle
this will work no matter how close the player is to the wall
 
this is what i do for bullets / projectiles
step event:
Code:
//this is the directional control of the projectile
hspd = lengthdir_x( spd ,_dir);
vspd = lengthdir_y( spd ,_dir);

//collision code and apply movements
if place_meeting(x+hspd,y,obj_solid) {
    while (!place_meeting(x+sign(hspd),y,obj_solid)) {
        x+=sign(hspd);
    }
    hspd = 0;
    spd = 0;
    instance_destroy();
}
x+=hspd;

if place_meeting(x,y+vspd,obj_solid) {
    while (!place_meeting(x,y+sign(vspd),obj_solid)) {
        y+=sign(vspd);
    }
    vspd = 0;
    spd = 0;
    instance_destroy();
}
y+=vspd;
then to create the bullet / projectile
Code:
var b = instance_create(x,y,obj_bullet);
    b._spd = 10; //how fast to move
    b._dir = angle;//angle to shoot at
    b.image_angle = angle; //set sprites angle
this will work no matter how close the player is to the wall
It's a nice system, but I am using right now impulses (the projectiles use physics). Thanks anyway!! ^^'
(i prefer to use a physics system to avoid objects teleporting!, as well my player moves using forces)
 
you can adjust it to physics
just change x and y to phy_speed_x and y
should have same results
"I" just made this, and it seems to work:
Code:
var collision_instance = instance_place(x, y, obj_solid);
if (collision_instance != noone and collision_instance != exception.id) {
    instance_destroy();
}
Your system is not compatible at all with mine, i set the arrow's speed with an original impulse and it keeps going; i don't change it's x or y directly! Anyway, this leads me to the old bug (nostalgia and terror at the same time!) which is this [sorry old pic!]:
index.png
My game is 2.5D perspective, meaning that the player can actually get "inside" the walls in order to give this 3D perception to the player, but if the player is at the top and wants to throw an arrow right there he can't; the arrow auto-destructs!
That's why I set the collision to "yfinal - 5" on the previous system!, but it created a gap...

So the final code I ended up with, which seems to work (!!!!), is the following:
Code:
//               - Projectile destruction -
// Detect the destroyer in the current position and below
var destroyer_instance = instance_place(x, y, obj_solid);
var destroyer_top_instance = instance_place(x, y + 5, obj_solid);

// In case the position below is "free" (noone) then don't destroy!
if ((destroyer_instance != noone and destroyer_instance != exception.id) and (destroyer_top_instance != noone and destroyer_top_instance != exception.id)) {
    instance_destroy();
}
Basically, what I did there was to first check if it is meeting an obj_solid and as well if there is one of them below, so, if it's the ending of the wall, if you are at the end, it just will keep going. Do you think this is good? I mean it works, but I don't really know if it's good code or not! ^^'

PS: Thanks for all!!!
 
Top