Fangames > Programming Questions

Need help with traps, and something to help in my gamemaking future

(1/2) > >>

Rad:
So, I'm not sure how to make traps in the design that I want. I would like to make traps such as increasing the size of spikes, making spikes move and stop at specific positions (to make it so that the player will have to go through a segment fast or the spikes will block the exit). I am not good at coding to even do simple things like this.

Mainly, if you've played the trap area in "I Wanna Live", or the medley section of it in Kill the Maker, I'd like to do something like that for a whole game. Think Betty/Rukito area for normal skill levels. I'd like my game to be more of a trigger game rather than just traps aimed to cheese the player into trial-and-error.

I am mainly working off of Klazen's guide, and it has been very useful, but I am not skilled enough or knowledgeable enough to try new things. I am at a point where I can visualize all the concepts and ideas I have, but I cannot make them into a reality. A tutorial video/guide or anything that would help me is greatly appreciated. If someone could link me a couple of guides that THEY used to get them into fangame making, I am willing to take anything at this point! I'm thinking in terms of not having to ask on the forums everytime I can't figure something out.

I hope that I can become a complex and interesting gamemaker in the future! Thanks! :)

Anon70000:

--- Quote from: Rad on August 31, 2015, 12:12:33 PM ---increasing the size of spikes

--- End quote ---
(click to show/hide)objScaleFree
Create Event:
// this object will scale up or down when triggered
// you can specify the origin to use when scaling (see below)
// tarx, tary can be negative number, too.
//
// in the creation code, put:
//      trg : trigger number
//      tarx : target xscale
//      tary : target yscale
//      origin : as below
//  there are 2 ways of triggering
//
//  scaling speed triggering :
//      xsp  : xscale speed
//      ysp  : yscale speed
//
//  scaling time triggering :
//      time : the time to scale to target scale
//
//    origins :
//
//      1  2  3
//      4  5  6
//      7  8  9
//

width = sprite_get_width(sprite_index);
height = sprite_get_height(sprite_index);
xoff = sprite_get_xoffset(sprite_index);
yoff = sprite_get_yoffset(sprite_index);
depth = 1000002;
Step Event
if (global.triggered==trg) {
    if tarx!=0{
        if(time == 0){
            if tarx*(image_xscale-(tarx-xsp))<0{
                image_xscale+=xsp;
                x -= (((origin - 1) mod 3)/2*width-xoff)*xsp;
            }
            else{
                image_xscale=tarx;
                //given that the starting image_xscale = 1
                x = xstart - (((origin-1) mod 3)/2*width-xoff)*(tarx-1);
            }
        }
        else{
            if tarx*(image_xscale-tarx)<0{
                image_xscale+=(tarx-1)/time;
                x -= (((origin - 1) mod 3)/2*width-xoff)*(tarx-1)/time;
            }
        }
       
    }
    if tary!=0{
        if(time == 0){
            if tary*(image_yscale-(tary-ysp))<0{
                image_yscale+=ysp;
                y -= (((origin - 1) div 3)/2*height-yoff)*ysp;
            }
            else{
                image_yscale=tary;
                //given that the starting image_yscale = 1
                y = ystart - (((origin-1) div 3)/2*height-yoff)*(tary-1);
            }
        }
        else{
            if tary*(image_yscale-tary)<0{
                image_yscale+=(tary-1)/time;
                y -= (((origin - 1) div 3)/2*height-yoff)*(tary-1)/time;
            }
        }
    }
}
Example:
(put in creation code on the object in the room)
sprite_index=sprSpikeUp
tarx=2;
tary=2;
time=15;
trg=1;
origin=8;
--- Quote from: Rad on August 31, 2015, 12:12:33 PM ---making spikes move and stop at specific positions
--- End quote ---
(click to show/hide)objPathFree
Create Event:
// this object will move along a path when triggered
// in the creation code , put:
//
//      sprite_index : sprite
//      trg : trigger number
//      pth : path index
//      spd  : moving speed
//      move : whether the object will continue moving if player died (prevent spoilers)
//      enda : endaction
//      scl : path scale (for ex. if you need to move path 3 blocks, to not create another path type scl=3;
//
// endactions :
//  0 : stop the path
//  1: continue from the start position (if the path is not closed we jump to the start position)
//  2: continue from the current position
//  3: reverse the path, that is change the sign of the speed


depth = 1000002;
Step Event:
if (global.triggered==trg && !flag) {
    path_start(pth,spd,enda,0);
    if scl!=0{
        path_scale = scl;
    }
    flag=1;
}
End Step:
//  if player dies during when the spike is still moving
//  it continue moving along the previous direction
//  you can choose to disable this by deleting this event
if(!instance_exists(player) && path_speed!=0 && (!path_ended)){
    if(move){
        speed = path_speed;
        path_end();
        move = false;
    }
}
End of Path:
path_ended = 1;
Example:
pth=pD1; // you need to create pathes yourself and tick off the box called "Closed"
spd=4;
trg=2;
sprite_index=sprSpike;
thanks based Nikaple.

Derf:
Hey Rad, glad to see you're back again :~)


In order to manipulate the size of an object you'll need to know about two values called "image_xscale" and "image_yscale" which control how big an object is comparative to its original sprite size on the respective axis  (e.g. if you want a spike to be taller than normal you would increase the image_yscale value, if you want it to be wider then you'd increase the image_xscale value and if you want it to be bigger or smaller proportional to its normal size you need to increase or decrease both at the same increment). Two things to note about this though: the default all objects have these values set to is 1, so setting it them both to 2 would make an object two times the size it normally is and 0.5 would be half. The second thing to note is that object size and orientation manipulation all happen relative to its origin point as set in the sprite (the little crosshair) so its often best to have the origin of the sprite centered or else manipulation can look weird.

You don't just have to set these values either, you can use them like any other variable.


--- Code: ---if(image_xscale < 3){
     image_xscale += 0.25;
     image_yscale += 0.25;
}

--- End code ---

That code would gradually increase the size of an object until stopping when it was 3 times as big as it normally is. If you set a trigger with this you should easily be able to get to results you want.

As for triggers, I don't tend to use them all that often as I'm not a big fan of the trial-and-error approach you speak of, however for one of my latest games I did write an incredibly rudimentary trigger system to start and stop triggers which you might find useful. I'll say now that it's very limited, but I hope you find some use for it.

Create Event:

--- Code: ---ypos = y;
move = 0;

--- End code ---

Here we initialise two variables. "ypos" which is my shorthand for "y position" which we set to the object's starting y position; we need this because we want the trigger to stop when it gets a certain distance from its starting point, so having its starting position recorded is essential. "move" which is boolean variable (this means it's either a 0 or a 1, or a true or a false) in which 0 means it's stationary and 1 means it's moving.

Step Event:

--- Code: ---if(collision_rectangle(x-8,y,x+40,y-608,player,0,1) && move = 0){
     move = 1;
}

if(move = 1 && y != (ypos-dest)){
     y -= 8;
}
else if (move = 1 && y = (ypos-dest)){
     move = -1;
}

if(y < (ypos-dest)){
     y = ypos-dest;
     move = -1;
}

--- End code ---

Ok, so here is the meat of the code. I'll run through it bit by bit. I'm just going as thoroughly as I can, so sorry if any of this is patronising, it's not my intention! :~)

"if(collision_rectangle(x-8,y,x+40,y-608,player,0,1) && move = 0){
     move = 1;
}"

Okay so what this does is create an invisible collision box around the object. Since the spike sprite is 32 pixels wide, I have set this to create a box that is 48 pixels wide; an extra 8 pixels either side of the main 32 pixels so you can activate the trap by baiting it, this is achieved by the x-8 and x+40 in the code. That covers the width of the collision box, but the height is essentially just anything above the spike. So what this part of the code is doing is saying that if the player enters this collision box and the spike is not moving, set the move variable to 1 and therefore make the spike start moving. "&&" just means "and" so the code is checking if both of these conditions are true before proceeding, you can actually just write "and" in game maker instead of two ampersands and it will do the same thing but I prefer "&&".

"if(move = 1 && y != (ypos-dest)){
     y -= 8;
}
else if (move = 1 && y = (ypos-dest)){
     move = -1;
}"

This next part handle the movement and introduces two concepts which are important to learn in general, but will help a lot with triggers; I'll get onto these as they come up. The first part concerns making the object move, and the second part making it stop at a certain point. The first part says that if move = 1, e.g. the spike is in its moving state, and the spike's y coordinate does not equal the starting position "ypos" minus the destination "dest" the spike moves up by 8 pixels ("!=" means "does not equal", you can also write "<>" if you'd prefer). Now, you might rightly be saying "but we haven't set the 'dest' variable anywhere, have we?", and you'd be correct, we haven't set it in the object's main code. This is the first of two things that is useful to know in game maker:

In the room editor you might have noticed that there's more you can do than just add and delete objects. If you hold down the control key and right click any object a little menu pops up. Right at the bottom is an option called "Creation Code". This is a powerful feature to learn how to use. What it does essentially is add extra code to the creation of an object in the room, but it only effects that one instance of the object and not every other instance of the same object in the room. This means, instead of having to make 10 different triggers with different destination values, you only have to create one and add the value you want to each in the room. For instance, if you only wanted a spike trigger to move up by 64 pixels you'd open the creation code on that specific spike and add this to the code:


--- Code: ---dest = 64;
--- End code ---

Now the second part of this code essentially says if the spike is moving and it's at its destination point, set the move variable to -1. Now again, you might be thinking "but Derf said earlier it was a boolean variable which is either a 0 or a 1, and now he's setting it to a -1? What gives?", and again that would be a good question. What I'm doing here is setting it to what is known as a rogue value (or a sentinel value, or a dummy value, in case you read about it somewhere else). This is the second thing that is useful to learn about not only for Game Maker but for coding in general. What this is, is a value that terminates the process as there is no code which will activate upon the variable being set to this value, so it will stay there forever. By setting move to -1 we're not just saying "the spike will now go back to its stationary state", we're saying "the spike will now remain in its stationary state forever". This is because the spike is at its destination but the player might still be in the collision box and we don't want it to trigger again.

"if(y < (ypos-dest)){
     y = ypos-dest;
     move = -1;
}"

This is the last part of the code and essentially just makes sure that the spike doesn't for some reason over shoot its mark by setting it to the destination if it does. (Since the spike moves at -8 pixels on the y value per step, if you set the destination to something that is not a multiple of 8 it won't line up correctly and we want to avoid this).

As I said, this code is far from perfect. The flaws with it include: it can only be triggered once, so no fancy retriggering can be achieved; since the collision box takes up all the space above it, it will trigger even if it's at the bottom of the screen and the player is at the top; it can only be triggered by being near it, so you can't trigger it from far away. But the the main pros for me include that you only need one object for each of the four directions (the code I gave you only moves upwards, but you should easily be able to reconfigure it for moving down, left and right), that you don't need separate trigger objects to set it off and most importantly that its code is relatively simple.

I hope I didn't miss anything here, I'd be happy to answer questions if something didn't make sense.


Something worth doing, as anon has alluded to, is going through different engines and learning their different approaches to things. While I think Nikaple handles funny and is cluttered, it has a lot of interesting things you can more or less just steal without having to edit much to fit into other engines. Yutuuu is another engine I wouldn't recommend actually using, but is worth looking at the internals of to observe coding and steal some of the extra things it includes. You shouldn't pass over more streamlined engines such as Lemon (personal favourite) or Seph's engine as their code may be easier to understand and you can learn a lot from how neatly they handle things.

Honestly, I learnt from working on fangames. I know it's trite and I know it's what you expected to hear but working on games really is the best way to get better. My two main jolts in my game making experience were: working on I Wanna Be The Sublime and getting to delve into the GMK of someone who was far my superior with coding and just getting to tinker with things & secondly working on my current game and pushing myself to not give up when I couldn't work out how to do something but instead search the internet for how to fix it. I haven't personally checked this out but I assume it would be helpful, Sephalos' Super Kid Bros. 3 Source Code. Looking at other people's code is 100% one of the best ways to learn as I mentioned.

I hope some of this helped :~)

klazen108:
Holy cow, that was pretty comprehensive! You should consider splitting it off into a sort of "intro to coding" tutorial, I know a lot of people who are craving something exactly like this ;)

As a small addition, I definitely agree that the best way to learn coding is to look at code that does what you want to do. Lemon's engine in particular has a sample room with a few trigger types in it, you can see how he implemented those there and generalize that approach. Or just google "changing object size in game maker" - you might be surprised how many results you get! Learning how to code on your own isn't so much memorizing how to do everything yourself, but rather it's learning the right questions to ask in order to get what you need :Kappa: (Although a solid base of knowledge and experience certainly makes coding faster, easier, and less error-prone, you need to get that experience somehow!)

After you've figured out the way that many of these gimmicks are implemented, and have a basic grasp of the kinds of things you have control of (in this case, knowing that you can change the sprite's scale with image_xscale and image_yscale makes it a lot more obvious what you need to do to stretch it), then you'll find the whole world is open to you!

Rad:
Thanks for all the suggestions and tips! :D

I began by downloading the only other engine I know of for GM:S, which was just only recently released. I think that my main problem thus far has been, like you all said, not having experience. The other problem is that I was using the KS Engine, which is a great engine for skilled coders, but is not exactly a good place to start for myself having no coding prior. When people said they liked Klazen/Seph engines because they were good for coders to just go at it, I didn't realize the extent of that.

I think that by using YoYo's engine, in addition to some of the tips you guys gave, I will be able to implement a lot of the ideas I want into my game.

I do have one quick question though, can I simply take the spikeTrigger objects from Yoyo's code and apply it to the KS Engine? I really like the Main Menu and options that come embedded in the KS Engine, and I only really want jump refreshers and the triggers/spike traps. Will I run into a lot of problems if I try to do that, or should I just suck it up for now until I am a little more skilled and use Yoyo's engine?

I really appreciate all the help! Also, I think Klazen's idea of creating a coding tutorial would be really helpful to people like me. Frankly, I really didn't understand much of the code you posted due to my vast inexperience. Some of it I could follow but huge lines of code are hard for me to understand and are very intimidating to me :P

Finally, is there a way I can decompile games made in 8.0 so that I can look at them and their codes in Studio? I've tried once before but it seems GM:S doesn't like the format the decompiler makes the decompiled game. In the future I have an idea for a medley game that I'd like to do, and I might as well know if I can decompile now before I get myself excited for it or plan. Thanks again!

Navigation

[0] Message Index

[#] Next page

Go to full version