Legacy GM [SOLVED] Particles spawning in the wrong location from projectiles hitting walls

S

Shawn

Guest
My issue is that when particles spawn from projectiles hitting a wall, they end up where that bullet should've been if it wasn't removed before allowing it to "skip" the wall/pass through the wall, using a collision line. So, if a bullet gets removed because its next location would've been 10 pixels behind the wall, the particles will spawn at the point that's 10 pixels behind the wall, but other times the particles will spawn some distance before the wall, if the bullet gets destroyed before reaching the wall. The particles are set to spawn from the wall, not at a distance away from it, nor are they meant to spawn at the location the bullet's were supposed to be. I've been looking around, and can't find ANY information on this, for some odd reason. You'd think this would be a more common problem that you can find answers to...

I've almost got this solved, but whenever the bullet actually impacts the wall, the bullet will spawn its particles in the step before its collision with the wall. I'm using a collision_line and while loop to ensure the bullets that pass through the wall still enact their collision event, and those bullets that do pass through the wall will spawn their particles in the proper location, due to the loop. So, I need to figure out a way to adjust the location of the particles from the bullet's step before collision, since they're set back.

The code I'm using to guarantee particles and ensure they're spawning in the proper location when bullets pass through the walls is as follows:
Code:
//For Tmp_Wall_Right
Collision_Location = collision_line(xprevious, yprevious, x, y, Tmp_Wall_Right, false, false);
if Collision_Location
   {
   Former_X = xprevious;
   if Former_X < Collision_Location.x
       {
       while Former_X < Collision_Location.x
           {
           Former_X = Former_X + 1
           }
       }
   else if Former_X > Collision_Location.x
       {
       while Former_X > Collision_Location.x
           {
           Former_X = Former_X - 1
           }
       }
       event_perform(ev_collision, Tmp_Wall_Right);
   }
If you use code, please explain the lines; I'm still really new to GameMaker and I prefer to understand the code I use.


~~
The following is from a previous edit to this post, and it's stuff that's already been resolved, so it can be ignored.
~~
Originally, I had a different reason for this post, but I've mostly found a way around the issue, but still have a couple that I need to get resolved, though they should be easier.

The following doesn't work as well as I'd like:
object1.x = object2.x
object1.y = object2.y
(THE SOLUTION TO THIS: I had to throw the object1.x = object2.x and object1.y = object2.y into the end_step, rather than a regular step)

This would be necessary for binding a gun or a shield to the player, but using it causes it to jump ahead of the player when the gun/shield is given the same movement controls while binding it to the player, and it causes it to lag behind the player when it's bound to the player and with no movement controls. Is there a way to do this?

The other issue is mostly related to delta timing: how do you make projectiles NOT jump over objects as their speed increases? Examples alongside explanations would be helpful.
(THE SOLUTION TO THIS: I'm using
Code:
if collision_line(xprevious, yprevious, x, y, Wall_Object's_Name_Here, true, false)
    {
    event_perform(ev_collision, Wall_Object's_Name_Here_To_Destroy_Bullet_On_Collision);
    }
in the bullet's step event)
 
Last edited by a moderator:
S

Shawn

Guest
<Deleted stuff, updated original post>
 
Last edited by a moderator:
S

Shawn

Guest
<Deleted stuff, updated original post>
 
Last edited by a moderator:
S

Shawn

Guest
I updated the original post and deleted the stuff from the 2 update posts, since I've found a way around most of the issues I had. The issues remaining in the original post are the only issues I have left to resolve.
 

GMWolf

aka fel666
As for your first question:
It's to do with event order.
Your gun is being updated before the player moved (so it lags 1 frame behind).
To fix this, place your 'binding' code in the end_step event.


As for your second question:
(Check the comments for a couple fixed I didn't think about)
 
S

Shawn

Guest
Thanks! I was looking for information on the collision line, and couldn't find what I was looking for; must've overlooked that video, or just never found it. The step end, though, that's something I completely forgot existed, and I was so focused on other stuff, I had completely forgotten that processing order matters.

Though, there's now a new issue with when particles spawn. I have a blast-back effect when you shoot a wall, wherein particles will be launched away from the wall you shoot. I changed the particle spawning over to the wall, since the bullet's collision was occurring away from the wall when at high speeds, thus causing particles to spawn at the point of bullet's instance destruction. Moving the particle spawning over to the wall sorta fixed the issue, but they don't always spawn, since the bullets don't actually always collide with the wall when using a collision line, they just perform events before passing through the object, thus meaning they destroy themselves before reaching the wall, but giving the illusion of always making contact.

Code I have to define a variable to change delta timing, in a create event, in an object that has no sprite:
Code:
//Create a variable for slowing down time
globalvar Time_Control;
    Time_Control = 240

//Create a variable for delta time
global.Delta_Timing = Time_Control / 1000000 * delta_time;

Code I have for delta timing, inside the same object, in a step event:
Code:
//Create a variable for delta timing
global.Delta_Timing = Time_Control / 1000000 * delta_time;

Code I have for creating particles from the upper wall, inside a create event:
Code:
//Create a particle system and a variable
global.Tmp_Bullet_Shrapnel_Top = part_system_create();

//Create a particle type and a variable
global.Tmp_Bullet_Shrapnel_Top_Particle = part_type_create();

//Create a variable for updating particles to delta time
globalvar Update_Particles_Tmp_Bullet_Top;
    Update_Particles_Tmp_Bullet_Top = 1




/*
Adjust the particle's depth
part_system_depth(type variable, depth);
*/
part_system_depth(global.Tmp_Bullet_Shrapnel_Top_Particle, 3);




/*
Give particle its shape
part_type_shape(type variable, shape using pt_shape_shapehere);
Particle shapes:
    pixel, disc, square, line, star, circle, ring, sphere, flare,
    spark, explosion, cloud, smoke, snow
*/
part_type_shape(global.Tmp_Bullet_Shrapnel_Top_Particle, pt_shape_smoke);




/*
Give particle its size
part_type_size(type variable, minimum size, maximum size,
                size change per frame, random change to size per frame);
*/
part_type_size(global.Tmp_Bullet_Shrapnel_Top_Particle, 0.05, 0.25, 0, 0);




/*
Give particle its scale
part_type_scale(type variable, x axis number to be multiplied by size,
                y axis number to be multiplied by size);
*/
part_type_scale(global.Tmp_Bullet_Shrapnel_Top_Particle, 1, 1);




/*
Give particle its color
part_type_color1(type variable, color- using c_colorhere);
color2 if 2 colors, then use 2 colors
color3 if 3 colors, then use 3 colors
*/
part_type_color3(global.Tmp_Bullet_Shrapnel_Top_Particle, c_orange, c_red, c_red);




/*
Give particle its alpha
part_type_alpha1(type variable,
                0 for transparency or 1 for no transparency);
alpha2 if 2 alphas, then use 2 alphas
alpha3 if 3 alphas, then use 3 alphas
*/
part_type_alpha3(global.Tmp_Bullet_Shrapnel_Top_Particle, 1, 1, 0);



/*
Give particle its speed
part_type_speed(type variable, minimum speed, maximum speed,
                speed change per frame, speed change at random per frame);
*/
part_type_speed(global.Tmp_Bullet_Shrapnel_Top_Particle, 0.4, 1, -0.005, 0);



/*
Give particle its direction
part_type_direction(type variable, minimum direction the particle goes in,
                    maximum direction the particle goes in,
                    change in direction per frame,
                    change in direction at random per frame);
*/
part_type_direction(global.Tmp_Bullet_Shrapnel_Top_Particle, 250, 290, 0, 5);




/*
Give particle its orientation
part_type_orientation(type variable, minimum starting angle,
                        maximum starting angle, angle change per frame,
                        angle change at random per frame,
                        relative to direction of motion- using true or false);
*/
part_type_orientation(global.Tmp_Bullet_Shrapnel_Top_Particle, 0, 0, 0, 0, true);



/*
Give particle its blend
part_type_blend(type variable, compound colors as they overlap
                so colors are brighter as they're layered- using
                true or false);
*/
part_type_blend(global.Tmp_Bullet_Shrapnel_Top_Particle, false);



/*
Give particle its life, which determines how long it lasts
part_type_life(type variable, minimum time to last,
                maximum time to last);
Amount of time is based on number of frames, and the selected
time is actually randomized between the minimum and maximum times
*/
part_type_life(global.Tmp_Bullet_Shrapnel_Top_Particle, 2500, 15000);

Code used to bind the particles to delta timing, within the same wall object, in a step event:
Code:
//Disable automatic particle updates
part_system_automatic_update(global.Tmp_Bullet_Shrapnel_Top, false);

//Update the particles with delta timing
if Update_Particles_Tmp_Bullet_Top <= 0
    {
    part_system_update(global.Tmp_Bullet_Shrapnel_Top);
    Update_Particles_Tmp_Bullet_Top = 1
    }
else if Update_Particles_Tmp_Bullet_Top > 0
    {
    Update_Particles_Tmp_Bullet_Top =
        Update_Particles_Tmp_Bullet_Top - 0.005 * global.Delta_Timing
    }

Then the code used to spawn the particles, in the same wall object, in a collision event:
Code:
/*
Create a particle
part_particles_create(particle system variable,
                    x location, y location,
                    particle type variable,
                    amount of particles to spawn);
*/
part_particles_create(global.Tmp_Bullet_Shrapnel_Top,
    x, y, global.Tmp_Bullet_Shrapnel_Top_Particle, 3);
Also, sorry for my delayed response, I needed some sleep.
 
Last edited by a moderator:
S

Shawn

Guest
I tried using
Code:
if collision_line(xprevious, yprevious, x, y, Tmp_Wall_Top, true, false)
    {
    event_perform(ev_collision, Tmp_Wall_Top);
//The following line calls upon the event of the wall that creates particles from collision
    event_perform_object(Tmp_Wall_Top, ev_collision, Tmp_Bullet_Class_10);
    }
to create the particles from the wall, rather than having the bullets create the particles upon their impact, and it got closer to how it needs to be, but it keeps spawning the particles where the bullets would be if they didn't destroy themselves; the particles will spawn at the incorrect location, with said location being a good distance away from the wall.

That's the closest I've gotten, so far...
Ideas?
 
Last edited by a moderator:
S

Shawn

Guest
Here's an image that gives an example of the issue:
upload_2017-8-24_17-56-36.png

Forgive the ugliness of the game, it's all temporary stuff; I'm setting things up before gathering decent textures and sprites.

EDIT:
Seems shooting at a stretched wall actually causes this method to displace some of the particles on the wall's 0x, 0y position, if they don't pass through, but making the bullet handle the particle creation upon collision with the wall causes the effect in the image to occur, even on the side of the wall the player is shooting from, rather than just the side of the wall that's opposite of the player.

Either way, I still haven't found a solution to making this work..
 
Last edited by a moderator:
S

Shawn

Guest
Someone gave me this code:
Code:
var dx = //horizontal speed of bullet
var dy = //vertical speed of bullet

//Normalize the vector
var l = sqrt(dx*dx + dy*dy);
dx /= l;
dx /= l;

var xx = bullet.x;
var yy = bullet.y;

var dst = bullet.speed;


for(i = 0; /*no collision at (xx, yy)*/; i++ ) {
   xx += dx;
   yy += dy;
   if (i > dst) break;
}

// (xx, yy) is your collision point.
but I have no idea what it's supposed to be doing, nor do I know what to add the complete the loop, since it's incomplete. Supposedly, it's to fix the particle spawn issue, but it doesn't make sense. I've mostly managed to "translate" the variables into something I understand, so dx is the x-axis direction's speed, dy is the y-axis direction's speed, l is length, xx is the projectile's x location, and yy is the projectile's y location.

What I DON'T get is why any of this is needed, what it specifically does, aside from position and speed grabs, and I have no idea what the loop is supposed to be doing. The loop is the biggest issue, though, since I don't know what it's supposed to be checking against before enacting stuff, but even beyond the loop, I have no idea how any of this is supposed to DO anything, since there's no instructions given, other than some math with variables that are unused outside of this piece of code.

I can't find any information on any of this, so if someone could explain it in a simple way, that should prove to be extremely beneficial.
 
Last edited by a moderator:
S

Shawn

Guest
I'm assuming I can throw the xx and yy variables into the particle spawn's x and y coordinates, but I still can't figure out the loop.
 

Simon Gust

Member
Try this script
Code:
/// checkLinePosition(x1, y1, x2, y2, object)
var x1 = argument0;
var y1 = argument1;
var x2 = argument2;
var y2 = argument3;
var obj = argument4;
var i = x1;
var j = y1;

var flag1 = true;
var flag2 = true;
if (abs(x2 - x1) == 0) flag1 = false;
if (abs(y2 - y1) == 0) flag2 = false;

do
{
    if (abs(y2-y1) > abs(x2-x1))
    {
        if (y1 < y2) j++;
        else j--;
        if (flag1) i = x1 + (x2-x1) * (j-y1) / (y2-y1);       
    }
    else
    {
        if (x1 < x2) i++;
        else i--;
        if (flag2) j = y1 + (y2-y1) * (i-x1) / (x2-x1);
    }
  
    var collision = instance_position(i, j, obj);
    if (collision != noone)
    {
        x = i;
        y = j;
        return (true);
    }
}
until (i == x2 && j == y2);
return (false);
I don't know if it works correctly because in my game I use grid collisions so I don't have objects to collide with.
 
S

Shawn

Guest
I'm going to sound stupid, but I'm not sure I'm correctly calling the script, or I'm using the wrong variables in the particle's creation location. I'm still really new to this, so I've yet to figure out most of the programming aspects. I'm guessing I use "i" and "j" for the part_particles_create x and y, but doing so gives an error saying it wasn't set, even if I change them to global variables. I'm also not sure if "obj" should be swapped with an object, or if it should be left as is.

I called the script within the collision line:
Code:
if collision_line(xprevious, yprevious, x, y, Tmp_Wall_Top, true, false)
    {
    Grab_Collision_Location(xprevious, yprevious, x, y, Tmp_Wall_Top) //this is the script
    event_perform(ev_collision, Tmp_Wall_Top); //the particles are created within this event
    }
The collision line is there to prevent projectiles from passing through walls if the framerate reduces, since I'm using delta timing.
 

Simon Gust

Member
The script replaced the function collision line entirely. It sets the x and y of that object to the point of collision so you can spawn the particles directly at x and y.
Code:
var collision = Grab_Collision_Location(xprevious, yprevious, x, y, Tmp_Wall_Top);
if (collision)
{
 // create particle here at x and y
}

// increase x and y
I assumed that this is some kind of projectile object that flies across the screen and creates particles once it hits a wall.
 
S

Shawn

Guest
Well, that's the closest it's gotten, but it keeps freezing the game and forcing me to suspend its process so I can close it. Calling it in an end_step event in the bullet:
Code:
var collision = Grab_Collision_Location(xprevious, yprevious, x, y, Tmp_Wall_Top);
if (collision)
{
 // create particle here at x and y
 part_particles_create(global.Tmp_Bullet_Shrapnel_Top,
    x, y, global.Tmp_Bullet_Shrapnel_Top_Particle, 3);
    instance_destroy()
}
instance_destroy() wasn't there, at first, then I noticed the bullets were drilling through the wall and repeatedly creating particles, which was kinda neat, but it was then that I remembered I forgot to destroy the bullets, so I added it. I was hoping that destroying the bullets would fix the freezing, but it didn't work.

EDIT:
Hold on.. one of the weapons seems to have no issues, but it's set so it only shoots one bullet at a time, whereas the other shoots 5 at once. The game freezes when shooting the one that shoots 5 at once, but only after 2 or 5 shots have been fired. The projectiles also don't always show, for some reason.
 
Last edited by a moderator:

Simon Gust

Member
Well, that's the closest it's gotten, but it keeps freezing the game and forcing me to suspend its process so I can close it. Calling it in an end_step event in the bullet:
Code:
var collision = Grab_Collision_Location(xprevious, yprevious, x, y, Tmp_Wall_Top);
if (collision)
{
 // create particle here at x and y
 part_particles_create(global.Tmp_Bullet_Shrapnel_Top,
    x, y, global.Tmp_Bullet_Shrapnel_Top_Particle, 3);
    instance_destroy()
}
instance_destroy() wasn't there, at first, then I noticed the bullets were drilling through the wall and repeatedly creating particles, which was kinda neat, but it was then that I remembered I forgot to destroy the bullets, so I added it. I was hoping that destroying the bullets would fix the freezing, but it didn't work.

EDIT:
Hold on.. one of the weapons seems to have no issues, but it's set so it only shoots one bullet at a time, whereas the other shoots 5 at once. The game freezes when shooting the one that shoots 5 at once, but only after 2 or 5 shots have been fired. The projectiles also don't always show, for some reason.
I have it a little different with my projectiles.
Once I create them I give them an hspd and vspd value they can ride along.
Code:
var grid = checkGridLine(x, y, x+hspd, y+vspd);
if (grid)
{
    scr_play_sound_discard_at(snd_hurt1, x, y);
    scr_particle_create(object_index, 0, x, y);
    instance_destroy();
}
else
{
    x += hspd;
    y += vspd;
}
This is how I do projectiles.
It does the collision check and returns true or false,
if it's true, the projectile makes a sound, creates a particle and dies.
if it's false, the projectile continues it's way
 
S

Shawn

Guest
My projectile thing is a bit different, though I forgot I was using two different types, which is why the second gun didn't break the game. There'll eventually be more than two types of projectiles, with a different one for each gun, but I've been trying to make sure everything is running before I do that. I don't use a specific horizontal or vertical speed because I have it set to shoot where the cursor is, then the different bullets have different speeds, and I made sure to tie the speeds into delta timing, since they were slowing down when I was running tests and forcing the room's framerate to be below the desired amount.

So, for example, this is the gun that shoots 5 bullets per shot:
Code:
//For Class 10 weapons
//Check if it's the right gun's turn to shoot
if Class_10_Can_Shoot_R = true
    {

//Check if the shoot delay alarm is reset
    if Class_10_Alarm <= 0
        {

//Check if the gun can shoot
        if Class_10_Can_Shoot = true
            {

//Check for the proper weapon
            if Selected_Weapon = 10.0
                {

//Double check that the player has the gun class
                if Has_Class_10_Gun = true
                    {

//The following will define a bullet
                    Tmp_Bullet_Class_10_Shoot = instance_create(Displayed_Weapon_R.x, Displayed_Weapon_R.y, Tmp_Bullet_Class_10)
                    Tmp_Bullet_Class_10_Shoot2 = instance_create(Displayed_Weapon_R.x, Displayed_Weapon_R.y, Tmp_Bullet_Class_10)
                    Tmp_Bullet_Class_10_Shoot3 = instance_create(Displayed_Weapon_R.x, Displayed_Weapon_R.y, Tmp_Bullet_Class_10)
                    Tmp_Bullet_Class_10_Shoot4 = instance_create(Displayed_Weapon_R.x, Displayed_Weapon_R.y, Tmp_Bullet_Class_10)
                    Tmp_Bullet_Class_10_Shoot5 = instance_create(Displayed_Weapon_R.x, Displayed_Weapon_R.y, Tmp_Bullet_Class_10)
                    
//The following will set the bullet's speed   
                    Tmp_Bullet_Class_10_Shoot.speed = 10 * global.Delta_Timing
                    Tmp_Bullet_Class_10_Shoot2.speed = 10 * global.Delta_Timing
                    Tmp_Bullet_Class_10_Shoot3.speed = 10 * global.Delta_Timing
                    Tmp_Bullet_Class_10_Shoot4.speed = 10 * global.Delta_Timing
                    Tmp_Bullet_Class_10_Shoot5.speed = 10 * global.Delta_Timing

//The following will set the bullet's direction
//so that it shoots towards the cursor
                    Tmp_Bullet_Class_10_Shoot.direction = point_direction(x, y, mouse_x, mouse_y) - 4
                    Tmp_Bullet_Class_10_Shoot2.direction = point_direction(x, y, mouse_x, mouse_y) - 2
                    Tmp_Bullet_Class_10_Shoot3.direction = point_direction(x, y, mouse_x, mouse_y)
                    Tmp_Bullet_Class_10_Shoot4.direction = point_direction(x, y, mouse_x, mouse_y) + 2
                    Tmp_Bullet_Class_10_Shoot5.direction = point_direction(x, y, mouse_x, mouse_y) + 4
    
//The following will rotate the bullet so that
//it's aimed at the cursor
                    Tmp_Bullet_Class_10_Shoot.image_angle = Tmp_Bullet_Class_10_Shoot.direction
                    Tmp_Bullet_Class_10_Shoot2.image_angle = Tmp_Bullet_Class_10_Shoot2.direction
                    Tmp_Bullet_Class_10_Shoot3.image_angle = Tmp_Bullet_Class_10_Shoot3.direction
                    Tmp_Bullet_Class_10_Shoot4.image_angle = Tmp_Bullet_Class_10_Shoot4.direction
                    Tmp_Bullet_Class_10_Shoot5.image_angle = Tmp_Bullet_Class_10_Shoot5.direction
        
//Reset the timer to create a shooting delay
                    Class_10_Alarm = 24
                    Class_10_Can_Shoot_R = false
                    Class_10_Can_Shoot_L = true
                    }
                }
            }
        }
    }
The alarm isn't a real alarm; it's a variable with a stored number. The R and L guns are because there's 2 floaty guns that follow the player, and they interchangeably shoot. There's only 2 gun objects, and changing weapons simply swaps their sprites and changes a variable to use the proper speed. I haven't yet added any sounds, so they're not yet present.
 

Simon Gust

Member
My projectile thing is a bit different, though I forgot I was using two different types, which is why the second gun didn't break the game. There'll eventually be more than two types of projectiles, with a different one for each gun, but I've been trying to make sure everything is running before I do that. I don't use a specific horizontal or vertical speed because I have it set to shoot where the cursor is, then the different bullets have different speeds, and I made sure to tie the speeds into delta timing, since they were slowing down when I was running tests and forcing the room's framerate to be below the desired amount.
Try this
Code:
var collision = Grab_Collision_Location(x, y, x + lengthdir_x(speed, direction), y + lengthdir_y(speed, direction), Tmp_Wall_Top);
if (collision)
{
  // create particle here at x and y
  part_particles_create(global.Tmp_Bullet_Shrapnel_Top,
  x, y, global.Tmp_Bullet_Shrapnel_Top_Particle, 3);
  instance_destroy()
}
I don't know how game maker handles speed and updates x / y, I've never used those built-in variables.
 
S

Shawn

Guest
That one did the same thing. Should be noted that whatever's causing the freezing, it's not a lack of CPU availability, as it's unchanged when the game freezes vs when the game is running, and the usage isn't particularly high. Although, for whatever reason, the real fps also ends up freezing. I had the room, currently, set to 30fps, just for the sake of testing things with collision, since the delta timing is set to be much higher and I've been testing its scaling to lower framerates, and the real fps froze at 310 when the game froze, while looking at the debug window.
 
S

Shawn

Guest
A bit more testing to see if I could figure out what's going on with it, and I found that bullet speed and distance are the factors causing it to freeze. The farther away from the wall the player is, the larger the hit to the framerate, but missing the wall and sending the projectile off-screen, as in out of the room's designated area, causes it to become confused and endlessly calculate for a collision, even though the projectiles are set to destroy themselves when they go out of the room. Even at short distances, however, the framerate tanks, going from 350fps, down to as low as 26fps.

The game's confusion would explain why the real fps was continuing, despite the game being frozen. I'm also guessing that the speed being a factor is due to it attempting to calculate and re-calculate the collision when the bullet would've originally passed through a wall. It also appears that the lack of a projectile sprite is a permanent thing, for some reason, but only when the code and its called-upon script is in use. As a side-effect of the lacking projectile sprites, the projectile impact is instantaneous.

EDIT:
If there's another response with some more information or something to test, I'll have to read it when I wake up. I've been awake for nearly 15 hours, so I need to get some sleep. If the lag spikes, endless processing for collision, and missing projectile issue can all be fixed, then the script should work, but I have absolutely no idea how to go about fixing that.
 
Last edited by a moderator:

Simon Gust

Member
A bit more testing to see if I could figure out what's going on with it, and I found that bullet speed and distance are the factors causing it to freeze. The farther away from the wall the player is, the larger the hit to the framerate, but missing the wall and sending the projectile off-screen, as in out of the room's designated area, causes it to become confused and endlessly calculate for a collision, even though the projectiles are set to destroy themselves when they go out of the room. Even at short distances, however, the framerate tanks, going from 350fps, down to as low as 26fps.

The game's confusion would explain why the real fps was continuing, despite the game being frozen. I'm also guessing that the speed being a factor is due to it attempting to calculate and re-calculate the collision when the bullet would've originally passed through a wall. It also appears that the lack of a projectile sprite is a permanent thing, for some reason, but only when the code and its called-upon script is in use. As a side-effect of the lacking projectile sprites, the projectile impact is instantaneous.

EDIT:
If there's another response with some more information or something to test, I'll have to read it when I wake up. I've been awake for nearly 15 hours, so I need to get some sleep. If the lag spikes, endless processing for collision, and missing projectile issue can all be fixed, then the script should work, but I have absolutely no idea how to go about fixing that.
Well I'm not surprised if you have a million objects for collision, because my version that works with grids brings the fps from 1500 to about 1490.
So either you reduce precision on the checks, reduce the amount of objects in the room or go along with grid collisions.

This one is can adjust precision by passing it as an argument. The higher the value, the less precise, the faster.
Code:
///Grab_Collision_Location(x1, y1, x2, y2, object, precision)
var x1 = argument0;
var y1 = argument1;
var x2 = argument2;
var y2 = argument3;
var obj = argument4;
var p = argument5;

var i = x1;
var j = y1;

var flag1 = true;
var flag2 = true;
if (abs(x2 - x1) == 0) flag1 = false;
if (abs(y2 - y1) == 0) flag2 = false;

do
{
    if (abs(y2-y1) > abs(x2-x1))
    {
        if (y1 < y2) j += p;
        else j -= p;
        if (flag1) i = x1 + (x2-x1) * (j-y1) / (y2-y1);      
    }
    else
    {
        if (x1 < x2) i += p;
        else i -= p;
        if (flag2) j = y1 + (y2-y1) * (i-x1) / (x2-x1);
    }
 
    var collision = instance_position(i, j, obj);
    if (collision != noone)
    {
        x = i;
        y = j;
        return (true);
    }
}
until (i > x2 || i < x1) && (j > y2 || j < y1);
return (false);
One more thing to note is that the faster a projectile goes per step the higher the lagspike.
 
S

Shawn

Guest
Okay, now that I'm awake, I changed the test room's layout so it doesn't have a bunch of separate objects for the walls, but only a few, which have been stretched. The framerate of the test room has been increased from 350fps, to 4500fps, but shooting, with the previous code, still froze the game. I still need to test the new code, but I'll be doing that after I get something to eat.

I am curious about the grid implementation you have, though, as in what it does. When I think of a grid system, my mind just keeps jumping to the old SNES games I grew up with, where movement of RPGs would be as simple as pressing a key and moving forward to the next square, but a system like that won't work for the game I'm trying to make, since it's supposed to be my own spin on games like "Enter the Gungeon", even though I clearly have a long way to go in familiarizing myself with GameMaker before I can even come close to something like that.

I'll update this post after I've tested the new code.

EDIT:
Either I'm doing something wrong, or the new code isn't working. I'm siding more that I'm doing something wrong..

I did find out that I have to find a way to adjust the particles, though, since they seem to move faster when there's more objects in the room and slower with less objects, but that'll be something I figure out on my own.
 
Last edited by a moderator:

Simon Gust

Member
The grid collisions are not like you think they are, they work the same as objects except that you can't do slopes or anything like that.
First you need to create the grid in your room creation code. DON'T DELETE ANY OF YOUR WALLS OBEJCTS IN YOUR ROOM!
Code:
var wdt = room_width  / 16;
var hgt = room_height / 16;

global.tiles[wdt, hgt] = 0;

with (obj_ground)
{
    var x1 = x / 16;
    var y1 = y / 16;
    var x2 = x1 + image_xscale;
    var y2 = y1 + image_yscale;
    for (var i = x1; i < x2; i++) {
        for (var j = y1; j < y2; j++) {
            global.tiles[i, j] = 1;
        }
    }
    instance_destroy();
}
This will make it so that the array presents a 1 where a wall would be, 0 for air.

basic character collision
Code:
//HORIZONTAL COLLISION
if (scr_grid_place_meeting(x+hspd,y))
{    
    while (!scr_grid_place_meeting(x+sign(hspd),y))
    {
        x += sign(hspd);
    }
    hspd = 0;
}
x += hspd;

//VERTICAL COLLISION
if (scr_grid_place_meeting(x,y+vspd))
{
    while (!scr_grid_place_meeting(x,y+sign(vspd)))
    {
        y += sign(vspd);
    }
    vspd = 0;
}
y += vspd;
scr_grid_place_meeting(x, y)
Code:
///scr_grid_place_meeting(x,y)
//REMEMBER POSITIONS
var xp = x;
var yp = y;

//UPDATE POSITIONS
x = argument0;
y = argument1;

var rgt_bot = global.tiles[@ bbox_right / 16, bbox_bottom / 16];
var lft_bot = global.tiles[@ bbox_left / 16, bbox_bottom / 16];
x_meeting = rgt_bot || lft_bot;

var rgt_top = global.tiles[@ bbox_right / 16, bbox_top / 16];
var lft_top = global.tiles[@ bbox_left / 16, bbox_top / 16];
y_meeting = rgt_top || lft_top;

//UPDATE POSITIONS
x = xp;
y = yp;

return (y_meeting || x_meeting);
Projectile collision
Code:
/// checkGridLine(x1,y1,x2,y2)
var x1 = argument0;
var y1 = argument1;
var x2 = argument2;
var y2 = argument3;
var i = x1;
var j = y1;

var flag1 = true;
var flag2 = true;
if (abs(x2 - x1) == 0) flag1 = false;
if (abs(y2 - y1) == 0) flag2 = false;
if (!flag1 && !flag2) exit;

do
{
    if (abs(y2-y1) > abs(x2-x1))
    {
        if (y1 < y2) j++;
        else j--;
        if (flag1) i = x1 + (x2-x1) * (j-y1) / (y2-y1);        
    }
    else
    {
        if (x1 < x2) i++; 
        else i--;
        if (flag2) j = y1 + (y2-y1) * (i-x1) / (x2-x1);
    }
   
    if (global.tiles[@ i/16, j/16])
    {
        x = i;
        y = j;
        return (true);
    }
}
until (i == x2 && j == y2);
return (false);
 
S

Shawn

Guest
I can't figure out any of this. Nothing is working and I can't even fix the particles, let alone fix the point of collision where they're supposed to be spawning from. I don't know why the particles are speeding up when the framerate gets lower, when you'd think they would slow down, and I can't adjust their speed to compensate for framerate changes because, for some stupid reason, delta timing isn't working to resolve their speed.

When I try to use a script, I don't even know what I'm doing, so I'm either calling something in the wrong way, or something isn't placed in the proper location. It's stupid that there's not a simple way of ensuring proper collision and obtaining the point of collision as an x-axis and y-axis coordinate.
 
Last edited by a moderator:
S

Shawn

Guest
Okay.. so..
if someone can explain what the scripts do, line-for-line, that may be helpful, as would explaining how I'm supposed to even attempt using them. Also, if someone knows how to make particles properly update with the framerate, that'll also be helpful, because everything I've tried isn't working.

None of the scripts or particles make sense because of two reasons:
1) It simply defies logic
2) I don't have enough information about what's being attempted

What I'm doing to try and make particles work:

This part's in a create event
Code:
//Create a particle system and a variable
global.Tmp_Bullet_Shrapnel_Left = part_system_create();

//Create a particle type and a variable
global.Tmp_Bullet_Shrapnel_Left_Particle = part_type_create();

//Create variables for updating particles to delta time
globalvar Update_Particles_Tmp_Bullet_Left;
    Update_Particles_Tmp_Bullet_Left = 1


//Adjust the particle's depth
part_system_depth(global.Tmp_Bullet_Shrapnel_Left_Particle, 3);

//Give particle its shape
part_type_shape(global.Tmp_Bullet_Shrapnel_Left_Particle, pt_shape_smoke);

//Give particle its size
part_type_size(global.Tmp_Bullet_Shrapnel_Left_Particle, 0.05, 0.25, 0, 0);

//Give particle its scale
part_type_scale(global.Tmp_Bullet_Shrapnel_Left_Particle, 1, 1);

//Give particle its color
part_type_color3(global.Tmp_Bullet_Shrapnel_Left_Particle, c_orange, c_red, c_red);

//Give particle its alpha
part_type_alpha3(global.Tmp_Bullet_Shrapnel_Left_Particle, 1, 1, 0);

//Give particle its speed
part_type_speed(global.Tmp_Bullet_Shrapnel_Left_Particle,
    4, 10, -0.5, 0); //0.4, 1, -0.005, 0);

//Give particle its direction
part_type_direction(global.Tmp_Bullet_Shrapnel_Left_Particle, 340, 380, 0, 5);

//Give particle its orientation
part_type_orientation(global.Tmp_Bullet_Shrapnel_Left_Particle, 0, 0, 0, 0, true);

//Give particle its blend
part_type_blend(global.Tmp_Bullet_Shrapnel_Left_Particle, false);

//Give particle its life, which determines how long it lasts
part_type_life(global.Tmp_Bullet_Shrapnel_Left_Particle, 2500, 15000);

//Disable automatic particle updates
part_system_automatic_update(global.Tmp_Bullet_Shrapnel_Left, false);
This part's in a step event
Code:
//Update the particles with delta timing
if Update_Particles_Tmp_Bullet_Left <= 0
    {
    part_system_update(global.Tmp_Bullet_Shrapnel_Left);
    Update_Particles_Tmp_Bullet_Left = 1
    }
else if Update_Particles_Tmp_Bullet_Left > 0
    {
    Update_Particles_Tmp_Bullet_Left =
        Update_Particles_Tmp_Bullet_Left - 1 * global.Delta_Timing
    }
The particles end up slowing down as the framerate reduces and increases as the framerate increases.
 
Last edited by a moderator:
S

Shawn

Guest
Okay, back to the particle spawn location issue, since I found a weird way of fixing the particle speed issue with the following:
Code:
//Update the particles with delta timing
if Update_Particles_Tmp_Bullet_Left <= 0
    {
    part_system_update(global.Tmp_Bullet_Shrapnel_Left);
    Update_Particles_Tmp_Bullet_Left = room_speed
    }
else if Update_Particles_Tmp_Bullet_Left > 0
    {
    Update_Particles_Tmp_Bullet_Left =
        Update_Particles_Tmp_Bullet_Left - 1 * room_speed / 10 * global.Delta_Timing
    }
The line that was changed to make the fix was this:
Code:
Update_Particles_Tmp_Bullet_Left - 1 * room_speed / 10 * global.Delta_Timing
The line used to be this:

Code:
    Update_Particles_Tmp_Bullet_Left - 1 * global.Delta_Timing
Also,
Code:
   Update_Particles_Tmp_Bullet_Left = 1
was changed to
Code:
   Update_Particles_Tmp_Bullet_Left = room_speed
 
S

Shawn

Guest
Of course, it seems I ran into ANOTHER issue. When the framerate exceeds 800fps, the movement of the player will increase, but only when running into a veritical wall and only when hitting it from the left side while going down and to the right (diagonal), or hitting it from the right and going up and to the left (diagonal). When the framerate gets high enough, the player's speeds causes them to clip into the wall, and thus get stuck.

Code for movement and collisions:
Code:
//Sets horizontal movement and speed
hspeed = (3 * (keyboard_check(ord('D')) -
    keyboard_check(ord('A')))) * global.Delta_Timing;

//Sets vertical movement and speed
vspeed = (3 * (keyboard_check(ord('S')) -
    keyboard_check(ord('W')))) * global.Delta_Timing;


//Sets collision and sliding on walls of horizontal movement
if hspeed != 0
    {
    if !place_free(x + hspeed, y)
        {
        if hspeed > 0
            {
            move_contact_solid(0, hspeed)
            }
        if hspeed < 0
            {
            move_contact_solid(180, -hspeed)
            }
        hspeed = 0
        }
    }


//Sets collision and sliding on walls of vertical movement
if vspeed != 0
    {
    if !place_free(x + vspeed, y + vspeed)
        {
        if vspeed > 0
            {
            move_contact_solid(270, vspeed)
            }
        if vspeed < 0
            {
            move_contact_solid(90, -vspeed)
            }
        vspeed = 0
        }
    }
Hoping this one's easier to solve than the particle spawning issue I've yet to resolve...

EDIT:
I looked back at the scripts to set movement to a grid, just to see if it fixed the issue with the player getting stuck in the wall, but it was actually worse, so I stopped using it. If the projectile script is also necessary, then I don't know if it fixes it, since I don't know how to use the projectile script.
 
Last edited by a moderator:
S

Shawn

Guest
Don't suppose using lengthdir_x and lengthdir_y could fix the particle spawn position, could it? Playing with those two things, but if they can be used to fix it, I haven't found a way.
 
S

Shawn

Guest
Still can't figure this out...
I don't know why grabbing the point of collision should be so hard to do.
 

Simon Gust

Member
I'm thinking of when you collide with the object using collision_line() that you store that previous x and y and move outisde the object in that direction until no collision.
Code:
var collision = collision_line(x, y, x + lengthdir_x(speed, direction), y + lengthdir_y(speed, direction), Tmp_Wall_Top, false, false);
if (collision != noone)
{
 var xgoto = xprevious;
 var ygoto = yprevious;

 var newCollision = place_meeting(x, y, collision);
 while (newCollision)
 {
  move_towards_point(xx, yy, 2);
  newCollision = place_meeting(x, y, collision);
 }
 
 // crate particle
 
}
I haven't tried this. It's just an idea.
 
S

Shawn

Guest
I'm thinking of when you collide with the object using collision_line() that you store that previous x and y and move outisde the object in that direction until no collision.
Code:
var collision = collision_line(x, y, x + lengthdir_x(speed, direction), y + lengthdir_y(speed, direction), Tmp_Wall_Top, false, false);
if (collision != noone)
{
 var xgoto = xprevious;
 var ygoto = yprevious;

 var newCollision = place_meeting(x, y, collision);
 while (newCollision)
 {
  move_towards_point(xx, yy, 2);
  newCollision = place_meeting(x, y, collision);
 }
 
 // crate particle
 
}
I haven't tried this. It's just an idea.
Not quite sure what the point of storing the xprevious and yprevious locations would be, though, since that's the location the bullet's at prior to the location of its destruction as per the triggered collision event that's activated by the collision line. Regardless, I did test the code you gave, but it didn't work; particles were still spawning in the wrong location, they were just on the proper side of the wall.
 
S

Shawn

Guest
Actually, that last suggestion gave me an idea that almost gave a solution to this problem, but it seems it only works for low framerates, and only when the delta time is unchanged, so pressing a key to change the delta time, and thereby create a slow-time effect, stops particles from spawning...

In the bullet's create event:
Code:
Former_X = 0;
Former_Y = 0;
In the bullet's end_step event:
Code:
//For Tmp_Wall_Right
if collision_line(xprevious, yprevious, x, y, Tmp_Wall_Right, false, false)
    {
    Former_X = xprevious;
    while Former_X < Tmp_Wall_Right.x
        {
        Former_X = Former_X + 1
        }
    event_perform(ev_collision, Tmp_Wall_Right);
    }
This properly aligned the particle spawns while traveling fast enough that they'd pass through the wall if the collision line wasn't present, but slower speeds, or any time the bullet is actually supposed to collide with the wall, doesn't work.

EDIT:
After one more quick test, since I forgot to check something, it seems I'd also only be able to use a single wall of that name, otherwise there would be issues; it doesn't work when between two walls of that same name, for example.
 

Simon Gust

Member
Actually, that last suggestion gave me an idea that almost gave a solution to this problem, but it seems it only works for low framerates, and only when the delta time is unchanged, so pressing a key to change the delta time, and thereby create a slow-time effect, stops particles from spawning...

In the bullet's create event:
Code:
Former_X = 0;
Former_Y = 0;
In the bullet's end_step event:
Code:
//For Tmp_Wall_Right
if collision_line(xprevious, yprevious, x, y, Tmp_Wall_Right, false, false)
    {
    Former_X = xprevious;
    while Former_X < Tmp_Wall_Right.x
        {
        Former_X = Former_X + 1
        }
    event_perform(ev_collision, Tmp_Wall_Right);
    }
This properly aligned the particle spawns while traveling fast enough that they'd pass through the wall if the collision line wasn't present, but slower speeds, or any time the bullet is actually supposed to collide with the wall, doesn't work.

EDIT:
After one more quick test, since I forgot to check something, it seems I'd also only be able to use a single wall of that name, otherwise there would be issues; it doesn't work when between two walls of that same name, for example.
You should avoid comparing to Tmp_Wall_Right, since it is an object and not an instance you should be comparing to.
If you compare to Tmp_Wall_Right.x
it actually compares to the latest instance of Tmp_Wall_Right placed in the room.
Collision_line returns the individual instance id it collided with for a reason.
The function returns either -4 (no collision)
or the id of the instance.
store it in a variable and compare to that variable.
 
S

Shawn

Guest
You should avoid comparing to Tmp_Wall_Right, since it is an object and not an instance you should be comparing to.
If you compare to Tmp_Wall_Right.x
it actually compares to the latest instance of Tmp_Wall_Right placed in the room.
Collision_line returns the individual instance id it collided with for a reason.
The function returns either -4 (no collision)
or the id of the instance.
store it in a variable and compare to that variable.
Yeah, the use of the object's name is why I ran one more test and edited the post, since I forgot about that. I tried adjusting it to this:
Code:
//For Tmp_Wall_Right
Collision_Point = collision_line(xprevious, yprevious, x, y, Tmp_Wall_Right, false, false);
if Collision_Point
    {
    Former_X = xprevious;
    while Former_X < Collision_Point.x
        {
        Former_X = Former_X + 1
        }
    event_perform(ev_collision, Tmp_Wall_Right);
    }
But, it didn't work any better than not using the additional variable. Just out of curiosity, I also tried just using Collision_Point, instead of Collision_Point.x, but that just gave huge lag spikes and ultimately did nothing, other than let the bullets destroy themselves. Also, it just now occurred to me that there's a built-in function called collision_point, but that's not what I used, so the caps there is important, since it's an entirely different variable that I created.
 
S

Shawn

Guest
Okay, so I found out why the bullets sometimes don't spawn particles upon collision, but I can't figure out a way to force them to spawn particles when this issue occurs. I temporarily removed the instance_destroy portion in the collision event, then found that the bullets are stopping their motion if their next step would place them inside the wall. Of course, they're still calling upon some of the collision event, since they would destroy themselves when they were told to, but the particles weren't working, for some reason. To attempt a fix for this, I tried setting the walls so they weren't solid, but that didn't work, likely due to the collision line, so I set the walls back to solid, then tried the following code:
Code:
else if speed <= 1
    {
    event_perform(ev_collision, Tmp_Wall_Right);
    }
Only, that code also didn't work. Particle spawning is within the same collision event as the instance_destroy, so even if the bullets didn't destroy themselves, they should've still created particles, suggesting it worked, but that didn't happen, nor did it happen after restoring the instance_destroy. However, these tests were also done after I updated the previous code I said I tested so that it was the following:
Code:
//For Tmp_Wall_Right
Collision_Location = collision_line(xprevious, yprevious, x, y, Tmp_Wall_Right, false, false);
if Collision_Location
    {
    Former_X = xprevious;
    if Former_X < Collision_Location.x
        {
        while Former_X < Collision_Location.x
            {
            Former_X = Former_X + 1
            }
        }
    else if Former_X > Collision_Location.x
        {
        while Former_X > Collision_Location.x
            {
            Former_X = Former_X - 1
            }
        }
        event_perform(ev_collision, Tmp_Wall_Right);
    }
An image of the bullets stopping is below; the particles are only there from trying to find the right location where shooting the bullets would cause them to enter the wall, so those particles can be ignored. The bullets aren't solid, either, since they would causing the player's motion to be interrupted with each shot, due to the player's collision with the bullets at the moment they were shot.
upload_2017-8-30_1-31-15.png
It's like they're retaining motion without actually moving. If they weren't doing this, I highly suspect the issue would be resolved, then I'd be able to move on to the issue with the player getting stuck in the wall, but this little issue is.. weird...

Also, ignore the blue wall in that image; it's a test of a wall that bullets can pass through, but the player can't, to give the illusion of depth on some walls, I just need to adjust the particle travel distance to clear the blue wall, rather than landing on it, but that'll be done after fixing the issue I've been dealing with.
 
Last edited by a moderator:
S

Shawn

Guest
Tried adding:
Code:
else if x = Collision_Location.x
    {
    event_perform(ev_collision, Tmp_Wall_Right);
    }
The thing decided to ignore the fact that Collision_Location was previously defined, so it returned an error, claiming it was an unknown object, even though it's supposed to be a variable holding collision_line information. The code was placed under the "if Collision_Location" portion, as an extension, hence the "else" portion. Even within the "if Collision_Location" statement, Collision_Location.x is used, without issue, and it's what fixes the issue, aside from when the bullet actually makes contact with the wall. Not sure why it would consider Collision_Location an object in one, but not the other...
 
S

Shawn

Guest
Without being able to do something with the bullets that are supposed to actually make a collision, I can't think of any ways to fix this issue. It doesn't make sense why they would destroy themselves, as per the collision event's instructions, but they won't spawn the particles that the collision event orders them to spawn.
 
S

Shawn

Guest
Since I still haven't figured out a way to fix the bullet collision issue, I played around with player movement and found a way to fix the issue of the player getting stuck in the walls.

Still not sure how I'd go about fixing the bullets refusing to spawn particles when they make contact with the walls, though.
 
S

Shawn

Guest
What does the collision event actually look like?
Code:
part_particles_create(global.Tmp_Bullet_Shrapnel_Right,
    Former_X, y, global.Tmp_Bullet_Shrapnel_Right_Particle, 3)
Then a drag-and-drop to destroy the instance

This works when the bullets don't actually hit the wall, then the collision_line and loop fix the particle spawn location, just not when they actually make real contact with the wall. I also tried foregoing the drag-and-drop and using instance_destroy() after the particle creation code, but it didn't make a difference.

Everything else for collision is handled in the create and end_step events.
 

Simon Gust

Member
Code:
part_particles_create(global.Tmp_Bullet_Shrapnel_Right,
    Former_X, y, global.Tmp_Bullet_Shrapnel_Right_Particle, 3)
Then a drag-and-drop to destroy the instance

This works when the bullets don't actually hit the wall, then the collision_line and loop fix the particle spawn location, just not when they actually make real contact with the wall. I also tried foregoing the drag-and-drop and using instance_destroy() after the particle creation code, but it didn't make a difference.
Your particle is a smoke shaped particle right?
I've never used shapes and have always used sprites instead. So the origin of the shrapnels is in the center meaning it will always stick out the wall unless you translate it by the radius if the particle if that is a thing. Since I'm guessing there isn't, you could make your own shrapnels by making 2x2 sprites or similar.
So instead of creating a smoke shape in the wall, create multiple particles with a sprite assigned to them.
 
S

Shawn

Guest
Your particle is a smoke shaped particle right?
I've never used shapes and have always used sprites instead. So the origin of the shrapnels is in the center meaning it will always stick out the wall unless you translate it by the radius if the particle if that is a thing. Since I'm guessing there isn't, you could make your own shrapnels by making 2x2 sprites or similar.
So instead of creating a smoke shape in the wall, create multiple particles with a sprite assigned to them.
It's set to use the smoke shape, there's just a lot of them on the images because of the number created mixed with the number of bullets (3 particles per bullet, 5 bullets per shot)

This sounds a bit confusing, so hopefully this image will help clear up what I'm talking about:
upload_2017-8-31_6-13-19.png

All of this is part of attempting to ensure bullets always make a collision with the wall, no matter the framerate, and spawn particles upon their contact. The collision with the wall was fixed with a collision_line and the particle spawn was "fixed" with a loop, but the particles only spawn if the bullets miss the wall. The bullets that miss the wall are still technically colliding with it, though, due to the collision_line, but those that actually do hit, without the need of the collision_line, are the ones that aren't spawning particles, even though they're still destroying themselves, thus enacting the collision event.

In other words, when the bullets actually make contact with the wall, without the need for the collision_line and loop's correction, the collision event is skipping the particle spawn and jumping straight to destroying itself.
 
Last edited by a moderator:
S

Shawn

Guest
What if you don't do the event perform and have the particle spawning code directly in the collision code?
There's no change when trying this, and it was something I already attempted. I also attempted to force the particles to spawn when the bullet's speed is less than 1, since removing the instance_destroy caused the ones that actually make impact to freeze in place, one step before collision, but this also didn't work.
 
S

Shawn

Guest
Threw the code into the left wall and played around with it, then found that the left wall seemed to be working, but I wasn't sure why, so I shot a different left wall and found that the particles were actually jumping to the wall farthest to the left side of the room. Since it's the same code, just adjusted for the left wall, I threw another right wall close to one I was testing the shooting on, but found the problem couldn't be replicated with the right wall. I then tried changing the left wall's collision event code to the following:
Code:
if Former_X != 0
    {
part_particles_create(global.Tmp_Bullet_Shrapnel_Left,
    Former_X, y, global.Tmp_Bullet_Shrapnel_Left_Particle, 3)
    }
else
    {
    part_particles_create(global.Tmp_Bullet_Shrapnel_Left,
    x, y, global.Tmp_Bullet_Shrapnel_Left_Particle, 3)
    }
After doing so, I ran another test and found that I fixed the issue of bullets not spawning particles, but the ones that make contact with the wall are spawning particles in the wrong location, whereas the bullets that don't make contact with the wall, and are corrected by the collision_line and loop, do spawn from the correct location. So, I guess I'm one step closer. Just need to figure out a way to correct the spawn location of the particles created by the bullets that actually make contact with the wall, that way there's no difference in their spawn location over the ones that are already spawning in the correct location.

EDIT:
To clarify the current behavior: the bullets that make contact are creating their particles in the step before making contact, whereas the bullets that pass through the wall are correctly affected by the collision_line and loop, so they spawn their particles in the correct location. This means the current thing I need to do is find a way to make the bullets that make contact with the wall actually spawn their bullets when they make contact, rather than the step before contact.
 
Last edited by a moderator:
S

Shawn

Guest
Thought adjusting the x axis of the particles would be easy after I fixed their spawn location when bullets miss, but it's not allowing me to do anything with the x axis of the bullet. So, I can't create a variable that stores the value of the x axis, then use a loop to set the value of that variable to what the x axis is. There's gotta be some simple solution that I'm overlooking; this isn't making sense. Not sure why it allows me to adjust a variable that stores xprevious, but not x.
 
S

Shawn

Guest
I tried this:
Code:
Collision_Location_Tmp_Wall_Left = collision_line(
    xprevious, yprevious, x, y, Tmp_Wall_Left, false, false);
if Collision_Location_Tmp_Wall_Left
    {
    Former_X = xprevious;
    if Former_X < Collision_Location_Tmp_Wall_Left.x
        {
        while Former_X < Collision_Location_Tmp_Wall_Left.x
            {
            Former_X = Former_X + 1
            }
        }
    else if Former_X > Collision_Location_Tmp_Wall_Left.x
        {
        while Former_X > Collision_Location_Tmp_Wall_Left.x
            {
            Former_X = Former_X - 1
            }
        }
    event_perform(ev_collision, Tmp_Wall_Left);
    }
//THE FOLLOWING WAS ADDED TO WHAT DOES WORK
else
    {
    Other_X = x;
    if Other_X < Collision_Location_Tmp_Wall_Left.x
        {
        while Other_X < Collision_Location_Tmp_Wall_Left.x
            {
            Other_X = Other_X + 1
            }
        }
    else if Other_X > Collision_Location_Tmp_Wall_Left.x
        {
        while Other_X > Collision_Location_Tmp_Wall_Left.x
            {
            Other_X = Other_X - 1
            }
        }
    }
However, the portion that was added, dealing with Other_X, yells at me with an error, claiming Collision_Location_Tmp_Wall_Left.x is an unknown object, when it's supposed to be a variable. This doesn't make sense when it's accepting the same variable and its stored x-axis value in the portion of the if statement that's dealing with Former_X.

I also tried using:
Code:
else if !Collision_Location_Tmp_Wall_Left.x
in place of the standard else, but it didn't change the behavior.
 

Simon Gust

Member
I tried this:
Code:
Collision_Location_Tmp_Wall_Left = collision_line(
    xprevious, yprevious, x, y, Tmp_Wall_Left, false, false);
if Collision_Location_Tmp_Wall_Left
    {
    Former_X = xprevious;
    if Former_X < Collision_Location_Tmp_Wall_Left.x
        {
        while Former_X < Collision_Location_Tmp_Wall_Left.x
            {
            Former_X = Former_X + 1
            }
        }
    else if Former_X > Collision_Location_Tmp_Wall_Left.x
        {
        while Former_X > Collision_Location_Tmp_Wall_Left.x
            {
            Former_X = Former_X - 1
            }
        }
    event_perform(ev_collision, Tmp_Wall_Left);
    }
//THE FOLLOWING WAS ADDED TO WHAT DOES WORK
else
    {
    Other_X = x;
    if Other_X < Collision_Location_Tmp_Wall_Left.x
        {
        while Other_X < Collision_Location_Tmp_Wall_Left.x
            {
            Other_X = Other_X + 1
            }
        }
    else if Other_X > Collision_Location_Tmp_Wall_Left.x
        {
        while Other_X > Collision_Location_Tmp_Wall_Left.x
            {
            Other_X = Other_X - 1
            }
        }
    }
However, the portion that was added, dealing with Other_X, yells at me with an error, claiming Collision_Location_Tmp_Wall_Left.x is an unknown object, when it's supposed to be a variable. This doesn't make sense when it's accepting the same variable and its stored x-axis value in the portion of the if statement that's dealing with Former_X.

I also tried using:
Code:
else if !Collision_Location_Tmp_Wall_Left.x
in place of the standard else, but it didn't change the behavior.
Let's start with making the code easier. Because of now you're breaking several code rules.
Code:
var collision = collision_line(xprevious, yprevious, x, y, Tmp_Wall_Left, false, false);
if (collision != noone)
{
    x = clamp(x, collision.bbox_left, collision.bbox_right);
    event_perform(ev_collision, Tmp_Wall_Left);
}
 
S

Shawn

Guest
Let's start with making the code easier. Because of now you're breaking several code rules.
Code:
var collision = collision_line(xprevious, yprevious, x, y, Tmp_Wall_Left, false, false);
if (collision != noone)
{
    x = clamp(x, collision.bbox_left, collision.bbox_right);
    event_perform(ev_collision, Tmp_Wall_Left);
}
Not sure what that's supposed to even do, but it doesn't fix anything. Particles that make contact with the wall are still spawning at the location before their impact, leaving the exact same problem I've been trying to solve since using the code I already wrote.

Also, what "rules" have I broken? I'm using instance variables, which are defined in the create_event, so the bullets don't accidentally share values when there's multiple of them in the room, then using a loop to set a variable to the proper location, which is then used in the particle spawn. This would've worked on the second portion if the program wasn't bipolar and decided to forget that the variable I JUST CALLED ON actually existed.
 

Simon Gust

Member
Not sure what that's supposed to even do, but it doesn't fix anything. Particles that make contact with the wall are still spawning at the location before their impact, leaving the exact same problem I've been trying to solve since using the code I already wrote.
Why are you so desperate to make a thing like particles work if you don't understand actual mechanical code? I advise you to continue on working on more important parts of the game than particles. This is going in circles, I don't know how to help you.
 
Top