#GameMakerScript
Explore tagged Tumblr posts
learn-blesshaygaming · 8 years ago
Text
Testing for Collisions with Multiple Different Objects in GameMaker:Studio
Should work in GameMaker:Studio (version 1.1.1013 or newer). Should work in GameMaker:Studio 2 (all versions).
This tutorial is written for both GameMaker:Studio and GameMaker:Studio 2.
Problem
Sometimes you want to do a place_meeting(); test for multiple objects. Sometimes a parent object can help you do this, but other times you may want more control over, which objects or instances you are testing against. It is the latter, I wish to offer a solution for.
In this tutorial I will focus on the place_meeting(); function, but the concept is applicable to every single, other collision function out there.
Solution
First part of the solution is how we best compile a list of various objects. Here I suggest an array, since these are easy to overwrite and clean up. "But wait!" I hear you say. "place_meeting(); does not accept an array as an argument!?"
Right you are. This is why, the next step is to create a new script, which we will use instead of the function. Let us name the new script something like place_meeting_ext();, so that the name mirrors the extended functionality, and let us use the first line of the script to define the name and the arguments, and the second line to make some temporary variables:
///place_meeting_ext(x,y,array); var _x = argument0, _y = argument1, _a = argument2;
Next thing we need to do, is to loop through the array and do place_meeting(); for all the array's instances or objects - at least until a collision is found. We do this with a for-loop.
///place_meeting_ext(x,y,array); var _x = argument0, _y = argument1, _a = argument2; var _l = array_length_1d(_a); for(var i=0;i<array_length_1d(_a);i++){ if place_meeting(_x,_y,_a[i]) { return 1; } } return 0;
And here we go, a fully functioning script you can use instead of place_meeting(); to test for multiple different objects and instances.
Note that I store the array length in the variable _l, so that the loop does not have to look it up during every iteration. Also, we do not have to break; the loop ourselves upon collision, as the return; will automatically do this for us, as it functions as an exit; statement.
Something Extra
If you want the script to both take arrays and singular object types or instances, you can easily allow for this by doing an is_array(); test, in which case the script would look like this:
///place_meeting_ext(x,y,object|array); var _x = argument0, _y = argument1, _a = argument2; if is_array(_a) { var _l = array_length_1d(_a); for(var i=0;i<array_length_1d(_a);i++){ if place_meeting(_x,_y,_a[i]) { return 1; } } return 0; } else { return place_meeting(_x,_y,_a); }
You can further extend the script to allow for string input as well, so that you can write out the object name:
///place_meeting_ext(x,y,object|array); var _x = argument0, _y = argument1, _a = argument2; if is_array(_a) { var _l = array_length_1d(_a); for(var i=0;i<array_length_1d(_a);i++){ if place_meeting(_x,_y,_a[i]) { return 1; } } return 0; } else { if is_string(_a) { if asset_get_type(_a) == asset_object { return place_meeting(_x,_y,asset_get_index(_a)); } else { return 0; } } else { return place_meeting(_x,_y,_a); } }
Likewise this check could be added to the for-loop as well. The possibilities are truly endless, though be aware, that every line of code makes the script ever so slightly slower to run, so please do only extend the code to the functionalities you need!
Conclusion and Next Step
In this tutorial I have shown you, how you alter place_meeting(); to accommodate for multiple instances or objects through the use of an array. I have also shown you how to extend on this. In my next tutorial I will reverse the topic, and instead show you how to return an array with all the met instances on a given placement.
Feel free to share this post if you enjoyed it!
Until next time, Simon
1 note · View note
learn-blesshaygaming · 8 years ago
Text
Timers and Countdowns
Should work in GameMaker:Studio (all versions). Should work in GameMaker:Studio 2 (all versions).
These scripts are written for both GameMaker:Studio and GameMaker:Studio 2.
Introduction
Something I use often when making games are timers and countdowns. Sometimes it is enough to do a simple my_timer++; in the Step event, but sometimes I need more precision. It is for those times I have made the following scripts for easily making timers and countdowns!
The timers and countdowns are initiated like so;
my_timer = timer_create(); my_countdown = countdown_create(10000);
They both function similarly, and are based around milliseconds. Only difference: Timers count up and countdowns count... down.
To update a timer or coundown, which you normally would do once every step, you simply use timer_update(my_timer); or countdown_update(my_countdown);, and to get the current time of the timer or countdown you use timer_get(my_timer); or countdown_get(my_countdown);. This will return how much time has passed for the timers, or how much time is left for the countdowns, both in milliseconds. Divide this with 1000 to get the value in seconds.
Timer Scripts
///timer_create(); //Usage: my_timer = timer_create(); var _a; _a[0] = 0; return _a;
///timer_update(timer); //Usage: timer_update(my_timer); var _a = argument0; _a[@ 0] += delta_time/1000; return _a;
///timer_get(timer); //Usage: time_passed = timer_get(my_timer); var _a = argument0; return _a[0];
///timer_set(timer,time); //Usage: timer_set(my_timer,0); var _a = argument0; _a[@ 0] = argument1; return _a;
///timer_add(timer,amt); //Usage: timer_add(my_timer,1000); var _a = argument0; _a[@ 0] += argument1; return _a;
///timer_subtract(timer,amt); //Usage: timer_subtract(my_timer,1000); var _a = argument0; _a[@ 0] -= argument1; return _a;
///timer_multiply(timer,scalar); //Usage: timer_multiply(my_timer,2); var _a = argument0; _a[@ 0] *= argument1; return _a;
///timer_divide(timer,val); //Usage: timer_divide(my_timer,2); var _a = argument0; _a[@ 0] /= argument1; return _a;
Countdown Scripts
///countdown_create(ms); //Usage: my_countdown = countdown_create(); var _a; _a[0] = argument0; return _a;
///countdown_update(countdown); //Usage: countdown_update(my_countdown); var _a = argument0; _a[@ 0] -= delta_time/1000; return _a;
///countdown_get(countdown); //Usage: time_left = countdown_get(my_countdown); var _a = argument0; return _a[0];
///countdown_set(countdown,time); //Usage: countdown_set(my_countdown,10000); var _a = argument0; _a[@ 0] = argument1; return _a;
///countdown_add(countdown,amt); //Usage: countdown_add(my_countdown,1000); var _a = argument0; _a[@ 0] += argument1; return _a;
///countdown_subtract(countdown,amt); //Usage: countdown_subtract(my_countdown,1000); var _a = argument0; _a[@ 0] -= argument1; return _a;
///countdown_multiply(countdown,scalar); //Usage: countdown_multiply(my_countdown,2); var _a = argument0; _a[@ 0] *= argument1; return _a;
///countdown_divide(countdown,val); //Usage: countdown_divide(my_countdown,2); var _a = argument0; _a[@ 0] /= argument1; return _a;
Example of use
Say we have a game where the room restarts every 60 seconds. A controller object could keep track of this, and be set up like this:
Create event
restart_cd = countdown_create(60000);
Step event
if !global.pause { countdown_update(restart_cd); if countdown_get(restart_cd) <= 0 { room_restart(); } }
Draw gui event
draw_text(10,10,string(ceil(countdown_get(restart_cd)/1000)));
The countdown will then keep counting down unless paused by the global.pause variable. The countdown will be drawn to the screen in seconds, and when the countdown reaches 0 the room will restart.
Behind the Scripts
As you may notice I use one-value-arrays to store the timers and countdowns. This is simple because they have accessors (the @ I use when setting the array), which means you do not have to use the akward my_timer = timer_update(my_timer);. I did leave in returning the array though, in case that is the style you prefer.
A timer system could easily be made, where you do not need the update scripts. In fact, the first iterations of the scripts did not need them, since it was using current_time for the timing. However, I opted to use delta_time instead, because this allows you to still use pause systems and generally gives more control - current_time would still keep counting no matter the state of the game! The delta_time still works across all room speeds and lag.
Hope you will find these scripts helpful!
Until next time, Simon
1 note · View note
learn-blesshaygaming · 7 years ago
Text
Multiple Keys Mapped for the Same Action
Should work in GameMaker:Studio 2 (all versions).
This tutorial is written for GameMaker:Studio 2.
Problem
Oftentimes we want to be able to check multiple optional keys to perform an action. This might be to control a character both with WASD and with the arrow keys, or maybe to allow pausing on both the P key and the Pause key. I see a lot of people handling it like this:
if (keyboard_check(vk_left) || keyboard_check(ord("A"))) { // Do something }
This is of course fine in many cases, but it can turn into some very long conditionals sometimes. Also, if we want to change the controls at some point (or want to allow the player to do so), it becomes quite an inconvenience.
Solution
In GameMaker:Studio 2 you can define arrays like this:
var _array = ["index0", "index2", "etc."];
It is an easy way to pack multiple values into a variable. This does of course not help us directly, as keyboard_check(); does not accept arrays as their argument, but what if we make our own script? A keyboard_check_ext(); script? This would allow us to do something like this instead:
var _left = [vk_left, ord("A")]; if (keyboard_check_ext(_left)) { // Do something } // OR if (keyboard_check_ext([vk_left, ord("A")])) { // Do something }
Would that not be nice? We can even use a global or instance level variable to hold the mapped keys, changing them whenever we want to. But how would such script look?
First and foremost, we want to be able to use the script with singular input as well, so we start off the script by checking if our argument is an array, and if it is not, then we simple do a regular keyboard_check();.
var _array = argument0; if (!is_array(_array)) { return keyboard_check(_array); }
This also allows us to do a Ctrl + Shift + F in our project, and replace all uses of keyboard_check(); with our new script, without anything breaking.
Next we get the length of the array and loop though it. For each element in the array we do a keyboard_check();, and if it returns true, then the loop ends there due to our return. After the loop we make sure to return 0, to let the user know that none of the keys are being pressed. A full script would look something like this:
/// keyboard_check_ext(array_with_keys); /// @desc Is one of multiple keys held down? /// @arg array_with_keys var _array = argument0; if (!is_array(_array)) { return keyboard_check(_array); } var _length = array_length_1d(_array); for(var i=0; i<_length; i++){ if (keyboard_check(_array[i])) { return 1; } } return 0;
Of course the exact same thing can be used for keyboard_check_pressed();, keyboard_check_released();, keyboard_check_direct();, mouse_check_button_pressed();, etc., simply by replacing the function used in the script.
I hope this script and tutorial helped you making even more awesome games, and please share it, if you know someone who could learn something from it.
Kind regards, Simon
0 notes
learn-blesshaygaming · 9 years ago
Text
Delta Time Adventures!
A.K.A. my time implementing delta timing in Tale of Omni.
The Starting Point
After about half a year of development on Tale of Omni, I thought it was about time to think about adding some delta timing. Best thing would have been to make delta timing part of the project from the very beginning, but at least the game had not yet grown to a size, where the addition would be completely unfathomable.
Delta timing, for those unfamiliar with it, is a term used about the time between program iterations (or “steps”), and GameMaker: Studio has a handy, built-in variable delta_time to get this timing in microseconds. When I say, that I wanted to “add it to my game”, I am referring to the usage of delta timing: Making lag less visible.
Normally, when a game encounters lag, the game will continue as-it-was, and the lag will be very noticeable, and planning your movement can become quite hard. To make up for this, you can use delta timing to calculate how far you should have moved in the given time span. If the current step was twice as slow as it should have been, then you need to move everything twice as far!
The Solution
The first part of the solution, is one I think most people ready for delta timing can think up: Changing the delta_time value to a scalar. My game was up until this point made to run at 60 fps, so all my values was made for this speed, and this was the factor I needed to measure against. Fps stands for “frames per second”, and there goes a million microseconds to a second, so first things first I simply had to figure out, how many microseconds an ordinary step at 60 fps should take:
var __rd = 1000000/60;
Now, dividing the time since the last step (delta_time) with this value will then give us our scalar:
DELTA = delta_time/__rd;
This needs to be recalculated once per step! (I do it in the begin step event)
The simplest part is now done. We can multiply speed, image speed, and a lot of other values with this variable (better make it global), but you will quickly run into trouble when you begin multiplying it with gravity, friction, or other accelatory values. I know I did.
Thing is, these types of values affects OTHER values, and not linearly. Let’s say we jump by setting our vertical speed (vspd) to -10, and that we have a gravity (g) of 1. We add one to our speed, then moves, then add one, then move, then add one, then moves... You get the idea. This might look linear, since we add one each step, but the amount we move will be altered each step exponentially! Take a look at this for proof:
Step 0: We move up 10. Total moved: 10. Applies gravity. Step 1: We move up 9. Total moved: 19. Applies gravity. Step 2: We move up 8. Total moved: 27. Applies gravity. Step 3: We move up 7. Total moved: 34. Applies gravity. Step 4: We move up 6. Total moved: 40. Applies gravity. Step 5: We move up 5. Total moved: 45. Applies gravity. Step 6: We move up 4. Total moved: 49. Applies gravity.
If we just multiply both speed and gravity with the DELTA scalar (and the scalar is 4), then we should have a speed of 40, and a gravity of 4. Subtracting the gravity from the speed then gives us a movement of 36 - but wait, if done step-by-step this should be 34 (step 3 is the fourth step)?
At step 1 the gravity (applied after the previous step) has affected the speed by 1. At step 2 the gravity has affected the speed by 3, not 2. At step 3 the gravity has affected the speed by 6, not 3. At step 4 the gravity has affected the speed by 10, not 4. And so it goes on...
So. When we work with accelerations we need a different multiplier, though this multiplier should still be dependent on the DELTA variable!
After doing some math
(I could not get any solutions from around the web to work, so I had to do it myself), I came up with this:
DELTA_ACC = (.5*DELTA*(DELTA+1));
These two scalars ended up being all I needed for my game’s physics! When I add acceleration, I multiply the acceleration with DELTA_ACC, and for other things I multiply with DELTA - simple as that!
..though.. I then found I needed more. I use the lerp() function a lot, and none of these multipliers worked for that. Luckily, that one didn’t take too long, and I came up with this script:
///lerp_dt(amt); return 1-power(1-argument0,DELTA);
Where I normally would write lerp(x,100,.1), now I would simply write lerp(x,100,lerp_dt(.1)) to add the proper amount of lerping.
The End
So far, I have not needed anything else for implementing delta timing, than these three bits of code, and so far it works beautifully! I have tried to keep this post close to the bone, but if you have any questions, feel free to ask!
Hope you enjoyed the read.
Some quick notions:
Spine animations’ image speed is not depending on the room speed (so they need special care)!
Be careful with just subtracting DELTA from alarms - make a script to do this, which runs the alarm’s code if it goes below 1.
...I might add more as I further develop Tale of Omni.
1 note · View note
learn-blesshaygaming · 9 years ago
Text
Star Wars Lasers in GameMaker: Studio
In lue of Star Wars: The Force Awakens, I made a script for GameMaker: Studio, allowing you to draw very customizable lasers like those seen in the Star Wars universer. Now I have written this small, explanation post about it. The script is used like this:
sw_laser(x1,y1,x2,y2,w1,w2,c1,c2,a1,a2,a3);
And could look something like this:
Tumblr media
You draw the laser as a line going from (x1,y1) to (x2,y2). You then select a inner width (w1) of the normally white, opaque part of the laser. You can, however, change the color of the core (c1) and the opacity (a1) should you like it. Then you set the width of the glow (w2), the color of it (c2), the alpha where the core and the glow meets (a2), and the alpha at the end of the glow (a3). A regular, blue laser could thus look something like this:
sw_laser(x,y,x,y-100,16,8,c_white,c_blue,1,1,0);
The fully drawn laser will in this case be vertically straight, with a length of 100+16+8+8 = 132 from end of glow to end of glow, and a width of 16+8+8 = 32. You see, the core width is the full width of the core, but the glow width is existing on both sides of the core, thus you need to count it twice. 
First thing that happens in the script, is simply assigning the arguments to variables, and making a couple of our own:
var _x1, _y1, _x2, _y2, _w1, _w2, _c1, _c2, _c3, _a1, _a2, _a3, _s, _amt; _x1 = argument0; _y1 = argument1; _x2 = argument2; _y2 = argument3; _w1 = argument4; _w2 = argument5; _c1 = argument6; _c3 = argument7; _c2 = merge_color(_c1,_c3,.1); _a1 = argument8; _a2 = argument9; _a3 = argument10; _dir = point_direction(_x1,_y1,_x2,_y2); _s = max(1,ceil((_w1+_w2*2)/16)); _amt = 90/_s;
As you can see, we make a third color, which is a slight mix of our two other colors. We do this simply so that the core is not completely white all the way through, which is a personal preference of mine. Secondly we make the variable _dir, which is the direction of the laser beam going from (x1,y1) to (x2,y2). Thirdly _s and _amt is simply to calculate how smoothly we need to draw the laser, depending on the size of it - the bigger it is, the more points we need to draw to make it smooth-looking.
Then, using primitive-drawing and a series of for-loops, we first draw the core of the laser:
//Inner draw_primitive_begin(pr_trianglestrip); { for(var i=0;i<=_s;i++){  draw_vertex_color(_x1+lengthdir_x(_w1/2,_dir+180+i*_amt),_y1+lengthdir_y(_w1/2,_dir+180+i*_amt),_c2,_a2);  draw_vertex_color(_x1,_y1,_c1,_a1); } for(var i=0;i<=_s;i++){  draw_vertex_color(_x2+lengthdir_x(_w1/2,_dir-90+i*_amt),_y2+lengthdir_y(_w1/2,_dir-90+i*_amt),_c2,_a2);  draw_vertex_color(_x2,_y2,_c1,_a1); } for(var i=0;i<=_s;i++){  draw_vertex_color(_x2+lengthdir_x(_w1/2,_dir+i*_amt),_y2+lengthdir_y(_w1/2,_dir+i*_amt),_c2,_a2);  draw_vertex_color(_x2,_y2,_c1,_a1); } for(var i=0;i<=_s;i++){  draw_vertex_color(_x1+lengthdir_x(_w1/2,_dir+180-90+i*_amt),_y1+lengthdir_y(_w1/2,_dir+180-90+i*_amt),_c2,_a2);  draw_vertex_color(_x1,_y1,_c1,_a1); } //End draw_primitive_end(); }
The four loops are the four “corners” of the laser.
Afterwards we draw the laser’s glow. This is done in the same manor - look how our mixed color _c2 is used as the meeting point of the core and the glow.
//Out draw_primitive_begin(pr_trianglestrip); { for(var i=0;i<=_s;i++){  draw_vertex_color(_x1+lengthdir_x(_w1/2+_w2,_dir+180+i*_amt),_y1+lengthdir_y(_w1/2+_w2,_dir+180+i*_amt),_c3,_a3);  draw_vertex_color(_x1+lengthdir_x(_w1/2,_dir+180+i*_amt),_y1+lengthdir_y(_w1/2,_dir+180+i*_amt),_c2,_a2); } for(var i=0;i<=_s;i++){  draw_vertex_color(_x2+lengthdir_x(_w1/2+_w2,_dir-90+i*_amt),_y2+lengthdir_y(_w1/2+_w2,_dir-90+i*_amt),_c3,_a3);  draw_vertex_color(_x2+lengthdir_x(_w1/2,_dir-90+i*_amt),_y2+lengthdir_y(_w1/2,_dir-90+i*_amt),_c2,_a2); } for(var i=0;i<=_s;i++){  draw_vertex_color(_x2+lengthdir_x(_w1/2+_w2,_dir+i*_amt),_y2+lengthdir_y(_w1/2+_w2,_dir+i*_amt),_c3,_a3);  draw_vertex_color(_x2+lengthdir_x(_w1/2,_dir+i*_amt),_y2+lengthdir_y(_w1/2,_dir+i*_amt),_c2,_a2); } for(var i=0;i<=_s;i++){  draw_vertex_color(_x1+lengthdir_x(_w1/2+_w2,_dir+180-90+i*_amt),_y1+lengthdir_y(_w1/2+_w2,_dir+180-90+i*_amt),_c3,_a3);  draw_vertex_color(_x1+lengthdir_x(_w1/2,_dir+180-90+i*_amt),_y1+lengthdir_y(_w1/2,_dir+180-90+i*_amt),_c2,_a2); }
//End draw_primitive_end(); }
And that makes the whole laser! Hope you find the script useful, and that you are learning something from it. Feel free to tweet me how and where you are using it at @blesshaygaming
You can either just copy all the code from this post, or you can download it - and a lot more, cool scripts - here or on the GameMaker Marketplace.
1 note · View note
learn-blesshaygaming · 10 years ago
Text
Intersecting Lines in GameMaker: Studio
So, I just made a new script for GameMaker: Studio:
lines_intersect(x1,y1,x2,y2,x3,y3,x4,y4);
It is something I have wanted to do for a long while, but I had a hard time figuring out the math - after digging up the ol’ trigonometry everything fell into place though.
The x1, y1, x2 and y2 arguments are the two points of the primary line, and x3, y3, x4 and y4 of the secondary line. The script will return -1 if there is no intersection between the lines, or a value between 0 or 1 if there is an intersection. This value is telling where the intersection point is on the primary line, if you do something like this:
intersection_x = lerp(primary_line_x1,primary_line_x2,the_returned_value); intersection_y = lerp(primary_line_y1,primary_line_y2,the_returned_value); 
The first part of the script, is simply initializing the variables, and finding the directions from the two lines’ starting points toward both their own end points and the other lines end points.
var _x1 = argument0, //Line 1, point 1    _y1 = argument1,    _x2 = argument2, //Point 2    _y2 = argument3,    _x3 = argument4, //Line 2, point 1    _y3 = argument5,    _x4 = argument6, //Point 2    _y4 = argument7;
var _dir1 = point_direction(_x1,_y1,_x2,_y2), //From line 1, point 1    _dir2 = point_direction(_x1,_y1,_x3,_y3),    _dir3 = point_direction(_x1,_y1,_x4,_y4),    _dir4 = point_direction(_x3,_y3,_x4,_y4), //From line 2, point 1    _dir5 = point_direction(_x3,_y3,_x1,_y1),    _dir6 = point_direction(_x3,_y3,_x2,_y2);
Then we can do our first test: if the secondary line’s end points are on the same side of the primary line (like, both end points are on the left of it, relative to the primary line’s direction), a collision is not possible.
Tumblr media
//Compare line 1's directions var _diff1 = sign(angle_difference(_dir1,_dir2)),    _diff2 = sign(angle_difference(_dir1,_dir3));
if abs(_diff1+_diff2) > 1 { return -1; }
If a collision is still possible, we can do the same check again, but this time from the secondary line; are the primary line’s end points on the same side of the secondary line?
//Compare line 2's directions _diff1 = sign(angle_difference(_dir4,_dir5)); _diff2 = sign(angle_difference(_dir4,_dir6));
if abs(_diff1+_diff2) > 1 { return -1; }
Now, this part is enough, if we just want to know if there is an intersection. UNLESS the two lines are following the exact same linear formula, in which case the two checks will not catch it. Now I will use the sinus relations to figure out where the two lines intersect.
First, we form a right triangle between the starting point of both of our lines, and an unknown spot on the primary line. This unknown spot is where the angle must be 90 degrees (_C). We already know the angle difference between the direction of our primary line, and the direction from this line’s starting point to the secondary line’s starting point (_A), and since a triangle’s corners are always 180 degrees in total, we can find the last angle (_B).
Tumblr media
Using point_distance() we know the length of one side (_a), yet the other two sides (_b and _c) are unknown to us. However, these can easily be found using the knowledge, that in a right triangle, _a/sin(_A) = _b/sin(_B) = _c/sin(_C), also known as the sinus relations.
We now store the value of _b in another variable (_l), since this is “half the way” to the intersection point, and we need to change _b in a moment.
//Calculate triangle formed in the lines var _C = 90, _A = (_dir2-_dir1), _B = 180-_A-_C, _c = point_distance(_x1,_y1,_x3,_y3), _b, _c, _l; _a = _c/dsin(_C)*dsin(_A); _b = _c/dsin(_C)*dsin(_B);
_l = _b;
We now need to change the right triangle, to figure out the rest of the amount.
Tumblr media
This new triangle will share the same _a side, and still follow the primary line, meaning _C will still be 90. Knowing the direction of our secondary line, we can easily find the angle _B, and since we then know two angles, we can find the third one (_A) just as before.
_B = (_dir4-_dir1)-90; _A = 180-_B-_C;
Now we solve the calculations for a moment, since there is a chance that sin(_A) is 0, in which case our further calculations will fail, since you cannot divide with 0. Good thing is that sin(_A) will return 0 when the line is following the same linear formula, and the lines are laying on top of each other. This means they are not colliding on one, single point, and we need to decide what the script then should return. I chose to return the mean of the colliding part.
if dsin(_A) == 0 { var _x, _y; _x = mean(max(min(_x1,_x2),min(_x3,_x4)),min(max(_x1,_x2),max(_x3,_x4))); _y = mean(max(min(_y1,_y2),min(_y3,_y4)),min(max(_y1,_y2),max(_y3,_y4))); _l = point_distance(_x1,_y1,_x,_y); return _l/point_distance(_x1,_y1,_x2,_y2); }
If this was not the case, we can continue our calculations. We need to calculate the new _b, and add it to our _l variable, the old _b value. Like in the code above, we then need to divide it with the length of our primary line, to get the value to return. And then we are done!
_b = _a/dsin(_A)*dsin(_B);
_l += _b;
//Find the scalar of line 1 to the collision point var _sc = _l/point_distance(_x1,_y1,_x2,_y2); return _sc;
The script has been uploaded as part of my script collection, which can be found both on The GameMaker Marketplace and in my Gumroad store.
Hope you enjoyed! Simon
Ps. I plan on going through more stuff in blog form, since it is faster than doing videos all the time, so hopefully it can mean more content for you guys.
Please do share this, and also let me know if this stuff is usable for you at all, since I see no reason to spit out more blog posts, if they are not useful.
I plan on mostly doing blog post for smaller scripts, or changes to my more organic engines, like The Cardboard Engine, also available both on The Marketplace and on Gumroad.
1 note · View note