GM:S 1.4 Bullet Shooting Relative to Object - Simple but Not (GML)

Discussion in 'Programming' started by Benjamin Crump, Jul 15, 2016.

  1. Hey all,

    This is my first time posting on here. I've been through the asteroids tutorial and am now playing around with some different variations to help solidify the knowledge. I've taken the basic asteroids tutorial and I'm trying to make a modification to the firing of the bullet. The tutorial teaches you how to fire 1 bullet from the center of the player object (the ship), but I'm trying to make a modification to fire 2 bullets (1 from Y+10 and 1 from Y-10) simultaneously and in the correct direction (image angle of the player object). Code below:

    bullet_direction = image_angle

    bullet1 = instance_create(x,y+10,obj_bullet);
    bullet2 = instance_create(x,y-10,obj_bullet);

    bullet1.direction = bullet_direction
    bullet2.direction = bullet_direction

    bullet1.speed=10
    bullet2.speed=10


    The player object successfully fires 2 bullets from the correct position when facing right (position 0) and facing left (180). When facing up or down, however, the bullets are no longer separated but are firing on top of each other (the gap between the bullets begins to close as soon as you begin turning the ship from 0 or 180. I've tried doing it through DnD and through anything I can find of GML (lots of using Google and the help file). Could anyone please help me understand why this code isn't forcing the bullets to fire with the degrees of separation in each and every direction as opposed to just left and right? Thanks in advance!
     
  2. joakimFF

    joakimFF Member

    Joined:
    Jun 20, 2016
    Posts:
    119
    This should do what you want

    //create event

    xx = x;
    yy = y-10;

    Len = point_distance(0, 0, xx, yy);
    Angle = point_direction(0, 0, xx, yy);

    xx2 = x;
    yy2 = y+10;

    Len2 = point_distance(0, 0, xx2, yy2);
    Angle2 = point_direction(0, 0, xx2, yy2);


    //create bullet event

    instance_create(x + hspeed + lengthdir_x(Len, Angle + image_angle),y + vspeed + lengthdir_y(Len, Angle + image_angle),obj_bullet);
    instance_create(x + hspeed + lengthdir_x(Len2, Angle2 + image_angle),y + vspeed + lengthdir_y(Len2, Angle2 + image_angle),obj_bullet);
     
  3. TehCupcakes

    TehCupcakes Member

    Joined:
    Jun 21, 2016
    Posts:
    63
    What joakimFF posted should pretty much work, but they didn't explain what the code is doing and I think adding Angle + image_angle might not be the effect you want.

    The problem is that the Y axis is relative to the room, not relative to your object.

    Code:
    bullet1 = instance_create(x+dsin(image_angle)*10, y+dcos(image_angle)*10,obj_bullet);
    bullet2 = instance_create(x-dsin(image_angle)*10, y-dcos(image_angle)*10,obj_bullet);
    
    bullet1.direction = image_angle;
    bullet2.direction = image_angle;
    
    bullet1.speed = 10;
    bullet2.speed = 10;
    
    This will allow you to create the bullets with the same direction and speed that you have been, but their place of creation will always be at the sides of the ship regardless of angle. dcos() and dsin() allow you to determine the x factor and y factor to multiply by based on the angle to adjust the position. If math isn't your strong suite, open up a calculator and try plugging in angles in then doing sin and cos. You'll notice that you always get a number between -1 and 1. So for examle, when your player is facing fully right (angle 0), cos will give you 1, so you get bullets at y+10 and y-10. Whereas at angle 90, cos is 0 so the bullets originate from the player's y, but x+10 and x-10.
     
    Papa Doge and Waffle like this.
  4. flyingsaucerinvasion

    flyingsaucerinvasion Member

    Joined:
    Jun 20, 2016
    Posts:
    2,113
    To add a slightly different take on above solutions.

    This requires you to define the position of each gun relative to the ship's origin. You want to define the position as if the ship were NOT rotated, and the origin is at coordinates (0,0). I'm assuming here that zero image_angle is pointing to the right.

    So say I want two guns.
    Code:
    num_guns = 2;
    gun_array[0,0] = 5; //x coordinate of first gun
    gun_array[0,1] = -10 // y coordinate of first gun
    gun_array[1,0] = 5; //x coordinate of second gun
    gun_array[1,1] = 10 // y coordinate of second gun
    
    now that I have the positions for my guns defined, I can calculate their position in the room by taking into account the ship's position and orientation. Then once I have the gun's position in the room, I can create a bullet at that location.
    Code:
    var _c = dcos(image_angle);
    var _s = dsin(image_angle);
    for (var i = 0; i < num_guns; i++)
    {
          var _gun_x = x + _c * gun_array[i,0] + _s * gun_array[i,1];
          var _gun_y = y + _c * gun_array[i,1] - _s * gun_array[i,0];
          with instance_create(_gun_x,_gun_y,obj_bullet) { direction = other.image_angle; }
    }
    
     
    Crossoni likes this.
  5. Yal

    Yal GMC Memer GMC Elder

    Joined:
    Jun 20, 2016
    Posts:
    3,556
    To add context to @flyingsaucerinvasion's code, it's basically using the 2D rotation matrix (see below) to compute the position after rotation using the position before rotation. The sign of the y terms are reversed because GM's y axis is reversed (positive downwards instead of positive upwards).

    upload_2016-7-15_21-46-51.jpeg
     
  6. Thank you guys for the responses! I'm going to spend some time deciphering the answers to make sure I understand what you're doing, and then I'll implement. Again, thanks everybody!
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice