GML Visual Fnaf Power Help Please

C

COCOAMA

Guest
I literally spent hours trying to figure out how to make a power system in my fnaf fan game with the drag and drop also my game maker is 1.4 and I don't really know GML I'm afraid that I can mess this up with GML please help with drag & drop. If can't, then pls help with GML with a simple tutorial PLSSSS I made games with GML before but they were simply copy-pastes from tutorials.
 

TailBit

Member
have one object that controls the power and draws it, let's say you want to lose 10 power every hour and that 1 game hour is 8 seconds (with rooms speed 30 that is 240 steps), 10 power/240 steps is 1/24 = ~0.04 energy loss each step

but you also have 2 doors (or buttons), and they have a variable, active that can be true(1) or false(0)

so we need to calculate the power usage, normal useage is 1/24 .. if a door is open then it should drain 4 times more .. and if the other one is open too, another 4 .. so you sum that together and use it when lowering power
consume = 1 + 4*obj_left_door.active + 4*obj_right_door.active
so if ieft door is active then it will be like this:
consume = 1 + 4*1 + 4*0
consume = 1 + 4 + 0 = 5

obj_power create:
Code:
power = 100
step event:
Code:
consume = 1 + 4*obj_left_door.active + 4*obj_right_door.active
power -= consume/24
draw
Code:
i=0;
repeat(power/10) draw_sprite(spr_powerbar,0,20+i++*10,20)
most of these should just be "variable set" D&D and some with relative checked, nothing more ..

just rename obj_left_door and obj_right_door to whatever you use and give them the active variable

I'm not sure how to draw the "remaining power bars" in D&D .. could instead have a lot of objects that have "set variable" with something like "visible = obj_power.power > 90" 80 70 for every 10 inscrement .. a bit clunky but it would work
 
C

COCOAMA

Guest
Tysm but this looks really complicated I don't understand
 
GML is very intimidating, but it allows you to do the same things as drag-and-drop but much quicker and with more flexibility... Starting simple is the best way to learn, and luckily this is a pretty simple problem. You want to drain power from a battery if the doors are closed - And to draw a power bar. Don't be scared - I promise you can do this. Let me break down the solution:

First, you want to make an object. It sounds like you're familiar with them - Call it whatever you like. For this post, I'll assume you call it o_power. I'll also assume you have an object for the left door and the right door... o_leftdoor and o_rightdoor. The reason that the object names here start with "o_" is to classify them and prevent duplicate names. It just helps you stay organized, but you can really use any name you want. o_power doesn't need a sprite - We're treating it as a controller object... In other words, it handles numbers behind the scenes. In the create event of o_power - or whatever you call it - set a variable. A variable is just a "thing" that you can "describe" with a number or a reference to another number. For example, typing out power in the create event will create the variable... And now it needs to be described. The = symbol basically tells the game "is." After that, you can type a number or another variable name. Type 100, and a ;. You'll have the following code:
GML:
power = 1000;
That can be thought of as "power is 1000" - You've told o_power that it has 100 power. You've also told it that it is losing power at a rate of 0.

In the create event of both door objects, type:
GML:
open = true;
That can be thought of as "open is true" - You've told the doors that they are open. "true/false" are easy to understand - but you can do the same thing by setting the value to 0 or 1. This is called a boolean variable, and any time you set a variable with the = sign, that's called declaring a variable.

Now your objects know everything they need to know, and we can code their behavior.
In the step event of o_power, we want to check if the doors are closed and reduce power if they are.
We'll be using if here, as well as brackets. The brackets work the same as the triangles in drag and drop. Type if and the game knows to start checking on a variable. We want to check the door's open variable, so first we type the object's name and then the variable, like so:
GML:
if o_leftdoor.open = false
...But this isn't a complete piece of code. We've just told the game to check "if the left door's open variable is set to false and the door is closed," but not to what to do if it is. We type an open bracket { and then reduce power by a certain amount. To do that, we'll want to reference power, and type a - to tell the game we'll be reducing that value, and then an equals sign. We can reduce it by any value - for testing, let's go for reducing it by 1 every step. This means in 1000 steps of having the left door open you will run out of power. Finally, we close it with a closing bracket }. It looks like this:
GML:
if o_leftdoor.open = false { power -= 1; }
"If the left door's open value is false and the door is closed reduce power by 1." Repeat this for the right door... If both are open, power will be reduced by 2 every step. We also don't want the power to go under 0... So we're going to do another if. This time, we're checking power, and seeing if it is less than zero... So type a < and 0, then place "power = 0;" inside brackets. The final step event should look like this:
GML:
if o_leftdoor.open = false { power -= 1; }
if o_rightdoor.open = false { power -= 1; }
if power < 0 { power = 0; }
There are a lot of ways to improve that, but it'll do. Generally, you want to avoid having a lot of if statements, but they're easy to learn. Your power system is done - it will now count down as long as the doors are open. Tailbit's method works very similarly - It uses 1 and 0 instead of true and false, so the power is reduced by a value if the closed variable is 1. For our purposes, we still need to draw.

In the draw event of o_power we'll be using repeat - which makes the code after it perform multiple times. We also need to set a variable. I'll show you the draw code, then explain it:
GML:
i=0;
repeat floor(power/100) {draw_sprite(s_powerbar,0,10+i,10); i+=25;}
i=0; sets a variable i which tells the script how far over to draw each power bar. Make a sprite, call it s_powerbar and make it 20 pixels wide... Depending on how big your screen is. The repeat event will make it draw a maximum of 1000/100 sprites... Since we set power to 1000. We type floor first to round the number down. If power was at 999, for example, dividing it by 100 would give us 9.99. Since we typed floor, 999/100 reduces to 9, instead of 9.99. You don't always want to round down, but it can be helpful! Once power goes down to the 800s, it'll draw 8 sprites, when it gets to the 700s it'll draw 7, and so on. Thus, the bar will get shorter as power approaches 0.

The draw_sprite function draws our sprites - we need it in the draw event or we won't be able to see it. Inside the parenthesis are all the things the function needs to work - The name of the sprite to draw, which frame to draw, the x position to draw it at, and the y position to draw it at. Here, it should draw at the upper right of the room. Finally, we increase i by 25... So it draws each sprite a little farther away.
And we're done! There are so many ways to simplify this code that you can worry about when you're comfortable making the game do things via text, but it'll do for now.

Now o_power checks both door objects and reduces its power variable if they are closed. It sets power to 0 if power goes below zero, and it draws up to 10 sprites. To make a FNAF style game you'll need to make the doors open if o_power's power is 0 or less, and you'll probably want to change the rate at which the power reduces. Drag and drop can only get you so far - And FNAF is a fairly complicated game that is all about counting variables. Getting started with simple coding now will help you a lot down the road. Let me know if you run into problems - You probably will, and that's okay!
 
K

KiD_Rager

Guest
I'm gonna be blunt here.

You need to really learn GML.

There's no beating around it. Drag and drop does well for beginner purposes but at some point, your programming process is gonna become extremely limited and very, very messy. It's far easier to take it step by step in GML with some very basic fundamentals than trying to go into game development, only to re-do everything once you're halfways in because you're intimated by some coding. We've all been there - and honestly, still there at times.

Tutorials are great for putting you on the right path. But if anything, they should act more as a guide rather than a one-stop solution. @TailBit and @OfficerFriendly did great jobs starting and explaining the process to you but if you don't bother actually testing them yourself and learning to accept the risk of failure, you're never going to get this right. There's no "simple solution" that will magically fit your needs, and even if there was, it sure wouldn't do you any good if you don't take time to understand why it works.
 

woods

Member
We've all been there - and honestly, still there at times.
^this^

the faster you break into actual coding, the easier it will become.. you can only do so much with drag n drop ;o)
even with a handful of if statements.. it becomes VERY long and unwieldly with using just DnD.
 
C

COCOAMA

Guest
GML is very intimidating, but it allows you to do the same things as drag-and-drop but much quicker and with more flexibility... Starting simple is the best way to learn, and luckily this is a pretty simple problem. You want to drain power from a battery if the doors are closed - And to draw a power bar. Don't be scared - I promise you can do this. Let me break down the solution:

First, you want to make an object. It sounds like you're familiar with them - Call it whatever you like. For this post, I'll assume you call it o_power. I'll also assume you have an object for the left door and the right door... o_leftdoor and o_rightdoor. The reason that the object names here start with "o_" is to classify them and prevent duplicate names. It just helps you stay organized, but you can really use any name you want. o_power doesn't need a sprite - We're treating it as a controller object... In other words, it handles numbers behind the scenes. In the create event of o_power - or whatever you call it - set a variable. A variable is just a "thing" that you can "describe" with a number or a reference to another number. For example, typing out power in the create event will create the variable... And now it needs to be described. The = symbol basically tells the game "is." After that, you can type a number or another variable name. Type 100, and a ;. You'll have the following code:
GML:
power = 1000;
That can be thought of as "power is 1000" - You've told o_power that it has 100 power. You've also told it that it is losing power at a rate of 0.

In the create event of both door objects, type:
GML:
open = true;
That can be thought of as "open is true" - You've told the doors that they are open. "true/false" are easy to understand - but you can do the same thing by setting the value to 0 or 1. This is called a boolean variable, and any time you set a variable with the = sign, that's called declaring a variable.

Now your objects know everything they need to know, and we can code their behavior.
In the step event of o_power, we want to check if the doors are closed and reduce power if they are.
We'll be using if here, as well as brackets. The brackets work the same as the triangles in drag and drop. Type if and the game knows to start checking on a variable. We want to check the door's open variable, so first we type the object's name and then the variable, like so:
GML:
if o_leftdoor.open = false
...But this isn't a complete piece of code. We've just told the game to check "if the left door's open variable is set to false and the door is closed," but not to what to do if it is. We type an open bracket { and then reduce power by a certain amount. To do that, we'll want to reference power, and type a - to tell the game we'll be reducing that value, and then an equals sign. We can reduce it by any value - for testing, let's go for reducing it by 1 every step. This means in 1000 steps of having the left door open you will run out of power. Finally, we close it with a closing bracket }. It looks like this:
GML:
if o_leftdoor.open = false { power -= 1; }
"If the left door's open value is false and the door is closed reduce power by 1." Repeat this for the right door... If both are open, power will be reduced by 2 every step. We also don't want the power to go under 0... So we're going to do another if. This time, we're checking power, and seeing if it is less than zero... So type a < and 0, then place "power = 0;" inside brackets. The final step event should look like this:
GML:
if o_leftdoor.open = false { power -= 1; }
if o_rightdoor.open = false { power -= 1; }
if power < 0 { power = 0; }
There are a lot of ways to improve that, but it'll do. Generally, you want to avoid having a lot of if statements, but they're easy to learn. Your power system is done - it will now count down as long as the doors are open. Tailbit's method works very similarly - It uses 1 and 0 instead of true and false, so the power is reduced by a value if the closed variable is 1. For our purposes, we still need to draw.

In the draw event of o_power we'll be using repeat - which makes the code after it perform multiple times. We also need to set a variable. I'll show you the draw code, then explain it:
GML:
i=0;
repeat floor(power/100) {draw_sprite(s_powerbar,0,10+i,10); i+=25;}
i=0; sets a variable i which tells the script how far over to draw each power bar. Make a sprite, call it s_powerbar and make it 20 pixels wide... Depending on how big your screen is. The repeat event will make it draw a maximum of 1000/100 sprites... Since we set power to 1000. We type floor first to round the number down. If power was at 999, for example, dividing it by 100 would give us 9.99. Since we typed floor, 999/100 reduces to 9, instead of 9.99. You don't always want to round down, but it can be helpful! Once power goes down to the 800s, it'll draw 8 sprites, when it gets to the 700s it'll draw 7, and so on. Thus, the bar will get shorter as power approaches 0.

The draw_sprite function draws our sprites - we need it in the draw event or we won't be able to see it. Inside the parenthesis are all the things the function needs to work - The name of the sprite to draw, which frame to draw, the x position to draw it at, and the y position to draw it at. Here, it should draw at the upper right of the room. Finally, we increase i by 25... So it draws each sprite a little farther away.
And we're done! There are so many ways to simplify this code that you can worry about when you're comfortable making the game do things via text, but it'll do for now.

Now o_power checks both door objects and reduces its power variable if they are closed. It sets power to 0 if power goes below zero, and it draws up to 10 sprites. To make a FNAF style game you'll need to make the doors open if o_power's power is 0 or less, and you'll probably want to change the rate at which the power reduces. Drag and drop can only get you so far - And FNAF is a fairly complicated game that is all about counting variables. Getting started with simple coding now will help you a lot down the road. Let me know if you run into problems - You probably will, and that's okay!
tysm
 
You're welcome! Just going to mirror what's being said here, though - Please learn GML. Let this be your first step and then take more steps from here. You have to.
 

Yal

šŸ§ *penguin noises*
GMC Elder
Tysm but this looks really complicated I don't understand
I'm going to be even more blunt than KiD here.

You just got served code samples you can literally just copypaste into your game, labelled with which events to paste them. How can you not understand how to use them? You might want to start learning english before you try to learn GML if you're having trouble understanding simple instructions (or alternatively, switch over to a forum using your native language instead). We're not going to make your games for you, you're gonna need to start putting in an actual effort if you want results.
 
C

COCOAMA

Guest
I'm going to be even more blunt than KiD here.

You just got served code samples you can literally just copypaste into your game, labelled with which events to paste them. How can you not understand how to use them? You might want to start learning english before you try to learn GML if you're having trouble understanding simple instructions (or alternatively, switch over to a forum using your native language instead). We're not going to make your games for you, you're gonna need to start putting in an actual effort if you want results.
hey calm down :D I understand english it is just I didn't understand the events & stuff but I understand now
 

Toque

Member
Donā€™t feel bad. Itā€™s looks complicated to me too. Unfortunately there isnā€™t a lot of help for Drag and drop. Most people that can help donā€™t know how to use the drag and drop.
 
C

COCOAMA

Guest
You're welcome! Just going to mirror what's being said here, though - Please learn GML. Let this be your first step and then take more steps from here. You have to.
hey man I started a conversation with ya can you check it please
 
W

William Not Afton

Guest
Why hello there! I will work on a fnaf game actually and i will try fix all this issues, more details soon!
 
C

COCOAMA

Guest
GML is very intimidating, but it allows you to do the same things as drag-and-drop but much quicker and with more flexibility... Starting simple is the best way to learn, and luckily this is a pretty simple problem. You want to drain power from a battery if the doors are closed - And to draw a power bar. Don't be scared - I promise you can do this. Let me break down the solution:

First, you want to make an object. It sounds like you're familiar with them - Call it whatever you like. For this post, I'll assume you call it o_power. I'll also assume you have an object for the left door and the right door... o_leftdoor and o_rightdoor. The reason that the object names here start with "o_" is to classify them and prevent duplicate names. It just helps you stay organized, but you can really use any name you want. o_power doesn't need a sprite - We're treating it as a controller object... In other words, it handles numbers behind the scenes. In the create event of o_power - or whatever you call it - set a variable. A variable is just a "thing" that you can "describe" with a number or a reference to another number. For example, typing out power in the create event will create the variable... And now it needs to be described. The = symbol basically tells the game "is." After that, you can type a number or another variable name. Type 100, and a ;. You'll have the following code:
GML:
power = 1000;
That can be thought of as "power is 1000" - You've told o_power that it has 100 power. You've also told it that it is losing power at a rate of 0.

In the create event of both door objects, type:
GML:
open = true;
That can be thought of as "open is true" - You've told the doors that they are open. "true/false" are easy to understand - but you can do the same thing by setting the value to 0 or 1. This is called a boolean variable, and any time you set a variable with the = sign, that's called declaring a variable.

Now your objects know everything they need to know, and we can code their behavior.
In the step event of o_power, we want to check if the doors are closed and reduce power if they are.
We'll be using if here, as well as brackets. The brackets work the same as the triangles in drag and drop. Type if and the game knows to start checking on a variable. We want to check the door's open variable, so first we type the object's name and then the variable, like so:
GML:
if o_leftdoor.open = false
...But this isn't a complete piece of code. We've just told the game to check "if the left door's open variable is set to false and the door is closed," but not to what to do if it is. We type an open bracket { and then reduce power by a certain amount. To do that, we'll want to reference power, and type a - to tell the game we'll be reducing that value, and then an equals sign. We can reduce it by any value - for testing, let's go for reducing it by 1 every step. This means in 1000 steps of having the left door open you will run out of power. Finally, we close it with a closing bracket }. It looks like this:
GML:
if o_leftdoor.open = false { power -= 1; }
"If the left door's open value is false and the door is closed reduce power by 1." Repeat this for the right door... If both are open, power will be reduced by 2 every step. We also don't want the power to go under 0... So we're going to do another if. This time, we're checking power, and seeing if it is less than zero... So type a < and 0, then place "power = 0;" inside brackets. The final step event should look like this:
GML:
if o_leftdoor.open = false { power -= 1; }
if o_rightdoor.open = false { power -= 1; }
if power < 0 { power = 0; }
There are a lot of ways to improve that, but it'll do. Generally, you want to avoid having a lot of if statements, but they're easy to learn. Your power system is done - it will now count down as long as the doors are open. Tailbit's method works very similarly - It uses 1 and 0 instead of true and false, so the power is reduced by a value if the closed variable is 1. For our purposes, we still need to draw.

In the draw event of o_power we'll be using repeat - which makes the code after it perform multiple times. We also need to set a variable. I'll show you the draw code, then explain it:
GML:
i=0;
repeat floor(power/100) {draw_sprite(s_powerbar,0,10+i,10); i+=25;}
i=0; sets a variable i which tells the script how far over to draw each power bar. Make a sprite, call it s_powerbar and make it 20 pixels wide... Depending on how big your screen is. The repeat event will make it draw a maximum of 1000/100 sprites... Since we set power to 1000. We type floor first to round the number down. If power was at 999, for example, dividing it by 100 would give us 9.99. Since we typed floor, 999/100 reduces to 9, instead of 9.99. You don't always want to round down, but it can be helpful! Once power goes down to the 800s, it'll draw 8 sprites, when it gets to the 700s it'll draw 7, and so on. Thus, the bar will get shorter as power approaches 0.

The draw_sprite function draws our sprites - we need it in the draw event or we won't be able to see it. Inside the parenthesis are all the things the function needs to work - The name of the sprite to draw, which frame to draw, the x position to draw it at, and the y position to draw it at. Here, it should draw at the upper right of the room. Finally, we increase i by 25... So it draws each sprite a little farther away.
And we're done! There are so many ways to simplify this code that you can worry about when you're comfortable making the game do things via text, but it'll do for now.

Now o_power checks both door objects and reduces its power variable if they are closed. It sets power to 0 if power goes below zero, and it draws up to 10 sprites. To make a FNAF style game you'll need to make the doors open if o_power's power is 0 or less, and you'll probably want to change the rate at which the power reduces. Drag and drop can only get you so far - And FNAF is a fairly complicated game that is all about counting variables. Getting started with simple coding now will help you a lot down the road. Let me know if you run into problems - You probably will, and that's okay!
I tried your method and it says this:

FATAL ERROR in
action number 1
of Step Event0
for object o_power:

Unable to find any instance for object index '1' name 'o_left'
at gml_Object_o_power_StepNormalEvent_1 (line 1) - if o_left.open = false { powers -= 1; }

I renamed the power as powers since it wasn't being set as a variable because "power" is a function. Also my opened door objects are called o_left and o_right. That is why I put your code like that instead of o_leftdoor.open.
 

TailBit

Member
It's saying that there is no instance of o_left in the room.. so put it into the room? Or check if it exist before you allow that line of code to run:
if instance_exists(o_left) before that line that require it
 
C

COCOAMA

Guest
It's saying that there is no instance of o_left in the room.. so put it into the room? Or check if it exist before you allow that line of code to run:
if instance_exists(o_left) before that line that require it
I put the "true" codes for the open doors but when I close it it changes the instance to a closed one. I also tried putting "false" in the closed doors too but then it says there isn't any instance of that when I open or close them they change into each other, which destroys the other one. How can I do this :(
 

TailBit

Member
We never expected you to change it into another object, just change the variable and sprite .. but ..

You can give the o_left_closed door the o_left as a parent object, so then the o_left_door door will be detected as o_left too and that should stop the error. (should be the simplest solution .. just make sure they both got the open variable)

OR

You can lower the energy by checking if the correct door exists:
powers -= instance_exists(o_left);
as if the instance exist then it will return true (which is the value 1) or false ( .. 0) .. skipping the whole if check.
 
C

COCOAMA

Guest
We never expected you to change it into another object, just change the variable and sprite .. but ..

You can give the o_left_closed door the o_left as a parent object, so then the o_left_door door will be detected as o_left too and that should stop the error. (should be the simplest solution .. just make sure they both got the open variable)

OR

You can lower the energy by checking if the correct door exists:
powers -= instance_exists(o_left);
as if the instance exist then it will return true (which is the value 1) or false ( .. 0) .. skipping the whole if check.
I am so sorry I really don't wanna bother ya but it doesn't draw anything despite I did everything right.
 

TailBit

Member
Well, you could draw the value directly..

draw event:
GML:
draw_text(0,0,string(powers))
..so you at least see that it does something

You could open the object information for the power object, and ctrl+a to select all then ctrl+c to copy it and then paste it here .. that will give us a better image of what you have done and what could be the cause.
 
C

COCOAMA

Guest
Well, you could draw the value directly..

draw event:
GML:
draw_text(0,0,string(powers))
..so you at least see that it does something

You could open the object information for the power object, and ctrl+a to select all then ctrl+c to copy it and then paste it here .. that will give us a better image of what you have done and what could be the cause.
Information about object: o_power
Sprite:
Solid: false
Visible: false
Depth: 0
Persistent: false
Parent:
Children:
Mask:


No Physics Object

Create Event:
execute code:

powers = 1000;

Begin Step Event:
execute code:

instance_exists(o_rightc) powers -= 1;
instance_exists(o_leftc) powers -= 1;
if powers < 0 { powers = 0; }

Draw Event:
execute code:

i=0;
repeat floor(powers/100) {draw_sprite(s_powerbar,0,10+i,10); i+=25;}

If begin step should be step only, I tried that too, nothing happened.
 
C

COCOAMA

Guest
omg I didn't make it visible because I didn't want to see the spriteless blue object but now it shows. the problem is it just decreases even if the doors aren't closed

(I think it is because of the begin step-step change)
nope it still decreases
I put if and now it works
omg I'm so happy
thank you guys so much for everything!!
 
Last edited by a moderator:
Top