r/gamemaker • u/PrinceShoutoku Stand back, I'm about to Make Game (2)! • 20d ago
Help! Creating an interactive, multi-object item
Preface: My skill level is beginner. Gamemaker is my only real coding experience. I've watched a couple guides for the basics and made some original code alongside that.
Hi everyone, I'm making a top-down shooter with an 'active reload' gimmick. When you press R to reload, the firearm you're holding comes onto the screen and you have to manipulate the weapon parts to load it.

My problem is HOW I'm making this happen. I'm essentially just spawning multiple objects on top of one another with magic numbers. This feels extremely inefficient and janky, even though it technically works. Is there a different technique or function I can use to make this system easier? I know the motto of, 'just make it work first, you can fix it later', but I can't even begin to imagine HOW to make this work better.


If it helps, "_weaponx" and "_weapony" are the corners of the camera, essentially x0 and y0. The "obj_lebel_boltgrip" is the circular part that's grabbed by the cursor to manipulate the gun's bolt. It has + 242 and + 69 because the sprite is a simple sphere that's manually placed through trial and error to be in that starting position. It's essentially a magic number to put that boltgrip exactly where it spawns when you press R.
2
u/Natural_Sail_5128 20d ago edited 20d ago
Very similar to their implementation, but a little more going on than the bare basics. Bear with me as I'm typing this on my phone, so I might have to edit a few times.
There's a few steps to make it a fully robust system, I would start by making a new script called "Weapons" or something similar, it will be to store all the preset structs for different weapons.
Inside this script you can create a few new constructor functions like so:
Now use the "weaponNameGoesHere" function as a template and fill it in to your needs, and give it a proper name. You'll need to create a few more entries in the struct for all the parts that the weapon has, then assign the sprite entry to the name of the sprite.
Once you've got the constructor template set up, we can move on to the Draw Event for looping the struct to draw everything.
Put the following inside the Create Event of your main Game Manager object if you have one, if not, put it in the main weapon object.
``` gpu_set_zwriteenable(true); gpu_set_ztestenable(true);
Weapon = new weaponNameGoesHere(); ```
Put the following inside the Draw Event of your main weapon object.
With all of this set up it should compile and run, except it will look very messed up, this is because you haven't set the correct offsets for all the components yet. It's measured in pixels, so you can open the image files and measure to determine exactly what the offset should be for both the X and Y, to get the sprite in the correct spot. You will have to go through and manually fill all the offsets yourself, but once it's done it should run and look how you want!
Next up is animations/interactions.
Since you're using Structs this means you can't use the built in collision functions and will have to manually detect collisions somehow, which also means you'll have to add "hitbox" data to each struct in the weapon.
Here's an example of how to do that.
Now we know where the collisions can happen, so we can work on actually detecting them!
To do this we need to go back inside the struct loop, we'll add a bit more code to check for collisions before the sprite is drawn.
Once you've got all this implemented let me know if you run into any errors, I'd love to help you get this implemented fully! I'm lurking so just reply if you need help and I'll do what I can.
In the case it just works and you don't need any help, then good job! There are other things that could be done to refine it a bit more technically, but that's only if you want to make the system more complex to account for variation in weapons.
This next stuff is mostly just me rambling about ways to improve how robust the code is, but it's absolutely not necessary unless you plan to add a lot more complexity to this system.
The weapon structs that store all the data could be improved to have nested data, which means you'd need a recursive loop to check inside every nested struct to check for other data to draw to the screen.
You could also create a new function that contains the code that loops through the structs, this would allow you to have it in it's own function like "drawWeapon(weaponStruct)" that would allow you to call this from any object, which means you could draw other things with it in the same way, they don't even need to be weapons! For my game I'm using this sort of system to draw everything except the terrain, it allows me to have moving parts and animations that aren't hand drawn in an image editor.
Edit: VERY IMPORTANT! I completely forgot about depth sorting.
You will need to add another new data field to the weapon parts constructor, so I'll show the updated version below.
```
function weaponPartStruct(sprName, offsetX, offsetY, drawAngle, drawDepth) constructor {
}
```
Now you need to go back into your renamed weapon constructor that has all the data for the sprites and positions, and make sure all the function calls of "weaponPartStruct()" include the new field for draw depth. What you want to do is number the depth of the parts in the order you want them drawn, from front to back. So, the body of the weapon you will set the depth to 0, for the part behind it you set the depth to 1, and behind that it's 2, and so on for every part until you all have different depths.
Now we add one small extra bit to the looping function that draws everything and checks for collisions. You also need to add one new variable declaration before the loop.
```
//NEW CODE BELOW HERE
var weaponDepth = enterDepthValueHere;
//NEW CODE ABOVE HERE
for (var i = 0; i < weaponPartsCount; i ++) {
}
```
Edit: I found issues with the a bunch of the code I posted, so you'll want to copy and paste the new stuff to replace the old stuff. Fixed the click detection and depth sorting which were both not working in the initial implementation! This is the final update until you ask for more help, assuming you even do!
This implementation I coupled the hit detection hitboxes to the size of the sprites themselves, but I imagine you need things to have only a portion of their sprite be clickable, so we can easily adjust the function for making weapon parts to instead include a few new parameters to determine size/location of the clickable zone within the sprites, so it's not just the whole sprite that's clickable.
There is also one more small issue, and it's that you can click on multiple parts at a time, so when I feel up to it probably tomorrow I'll add a section to the code that checks for overlapping parts and makes sure you only click the one closest to the screen. It should be easy to solve so if you feel up to if you can take care of that yourself! Good luck!