Steam telepítése
belépés
|
nyelv
简体中文 (egyszerűsített kínai)
繁體中文 (hagyományos kínai)
日本語 (japán)
한국어 (koreai)
ไทย (thai)
Български (bolgár)
Čeština (cseh)
Dansk (dán)
Deutsch (német)
English (angol)
Español - España (spanyolországi spanyol)
Español - Latinoamérica (latin-amerikai spanyol)
Ελληνικά (görög)
Français (francia)
Italiano (olasz)
Bahasa Indonesia (indonéz)
Nederlands (holland)
Norsk (norvég)
Polski (lengyel)
Português (portugáliai portugál)
Português - Brasil (brazíliai portugál)
Română (román)
Русский (orosz)
Suomi (finn)
Svenska (svéd)
Türkçe (török)
Tiếng Việt (vietnámi)
Українська (ukrán)
Fordítási probléma jelentése
Create it like this:
-----------------------
[destroy]
var textDisplay = instance_create(x, y, objTextDisplay);
textDisplay.text = "+10"; //Change this value for each plane
-----------------------
Then in the object objTextDisplay:
-----------------------
[create]
text = "";
alarm[0] = room_speed;
[alarm0]
instance_destroy();
[draw]
draw_text(x, y, text);
-----------------------
Thats actually the first thing I tried, and it worked, but there was a bug. when I would kill a plane with "+10", then kill a plane with "+30" soon after, the "+10" would turn into "+30".
Again, i'm not sure if i did exactly what you did or not
Thanks for the reply btw
Like Harrk stated, in the planes' Destroy event, you want to create one of your score pop-ups. Drag and drop can do that, but because of the previously stated limitation you've wound up in your present situation. You're going to have to pull a code equivalent, and his should work just fine, but if you've not touched GML yet you're going to be a bit confused. Let's go through the steps.
First, the code. Adding code to an event is easy; the drag and drop item is in the Control Tab. Someday it will be your best friend, but right now it's a black abyss of confusion, so let's start by pasting in Harrk's code.
This is all super cool. You're going to see colors and junk, and you're going to be all like "wow what is this crap?" That's okay! I'll tell you what is this crap. I'll tell you right now.
First up, "var" is an expression used to declare a temporary variable. This is for things that aren't important in the long term, and they're especially handy once you get around to writing scripts (which you could do, if you want, for this same task, and then feel pretty much like the coolest guy. One step at a time, though). The most basic form of var is
This would create a variable named VariableName that only exists for the duration of the code being executed (or, in some special cases, within certain actions done via code, but that's for another day). Harrk went ahead and assigned a value to that variable immediately, but to understand that, you need to understand this:
This is a function, and it works exactly the same as the drag and drop equivalent; you're creating an instance at position (x, y) of the object given (obj_TextDisplay). In D&D, you'll recognize this as the things it asks you for in the prompt that comes up, so if you can associate one to the other you're in pretty familiar ground. The function is instance_create(), and everything in the parenthesis are called arguments. (Once again, not the most important knowledge now, but super handy to know if you start writing scripts.)
That line by itself will do everything the drag and drop does, with one added advantage: it returns the id of the instance it creates. This is super handy, because it solves the problem with the D&D's limitations. The way it works out is sort of like this:
Putting var before textDisplay and then assigning it immediately is just a way to keep things compact; he's declaring that the temporary variable "textDisplay" should exist, and then telling GM that the variable should be the id of an instance of obj_TextDisplay that it then simultaniously creates. He's basically crammed three awesome things into one line of code.
Next, we have the textDisplay.text, and this is the important difference between assigning an object's variable and an instance's. Because textDisplay is the exact instance that we're setting the number to, anything we do referencing that id will only affect that instance, instead of every floating number in the room. Basically, "object id dot variable" means you're working with the given variable in that instance's memory. If you tried to draw the value of textDisplay.text, you should get "+10" as is the object's default. All we're doing here is setting the value of our new object's text variable remotely, which is something you'll probably end up needing to do a lot in the future.
Finally, we have the weird double slash, which is simply a comment. Your compiler ignores it, it can say anything you want, it's so you can make notes, look at the code later, and not be completely confused trying to figure out what you were even thinking. Use these liberally. They are your bestest of friends.
I'm sorry that was so unbelievably long but if we're going to dump you into using code to accomplish something when you've never touched the stuff before, I figured it's in everyone's best itnerest to break things down as best as possible so you actually understood what all this fresh gibberish was accomplishing. You were really close to the solution, but drag and drop inherently limited your ability to solve the problem. It does that sometimes. It's sort of a jerk.
As for your draw question, the Draw event triggers all your basic draw functions; the room's backgrounds, background color, tiles, etc. all occur at this point. Draw occurs after Step, so anything drawn before the Draw event gets drawn over by the room itself in almost any given ocassion. Come the draw event, things are drawn in order as dictated by any given object's depth, which like so many things I've blathered on about isn't the most important now but is good to understand later.
Hope some of that helps. If it's all swirling around and just being confusing, dreadfully sorry! D:
Going from barely having a grasp on D&D to this is pretty far leap, but ill try.
The main thing im confused about is the textDisplay.text and where he wrote
text = "";
So (at least from what i understand,) textDisplay is a variable that holds an exact instance of the obj_textDisplay. textDisplay also gets discarded after the event finished. But if thats the case, wouldnt the "+10" be deleted right after the destroy event?
Another thing I dont understand is what the textDisplay.text is.
Isn't textDisplay a variable? are we assigning a variable to a variable? I dont understand what exactly the .text is...
and further more in harrks code if on the creation event for the obj_textDisplay has text = ""; doesnt that mean everytime its created it will equal to nothing? also, dont you have to write textDisplay.text = ""; ? because its in a different object? I dont understand how it knows what your talking about if its in a different object... and like i said before I dont understand what textDisplay.text IS.
Ok sorry for asking so many questions, it's just that this is starting to be really fun, and I want to understand it better! (but very challengning as well!)
Again thank you so much for help!
The way he has it set up, text = ""; means that you have a variable that's basically an empty string. What this ends up meaning is that if you don't assign anything (or rather, mess up assigning something) to the variable, nothing will be displayed, letting you know something went wrong.
Something like that where an error occurs in your intentions is a semantic error. The difference between this and a syntax error is that a syntax error means your code won't compile, resulting in GM throwing a delightful little fit, whereas a semantic error compiles fine but doesn't do what you intended it to. As far as GM can tell, it's fine because the code works like it's built to, but something in how it's been done results in it not having the desired outcome. It's another word for human error, mostly, but it's a fancier way of putting it.
On the matter of textDisplay, you're basically working with a pointer. (GM won't refer to it as such, but the concept is entirely the same.) Basically, when instance_create() returns the id of the instance it created, textDisplay is holding that id as a reference point, but otherwise has nothing to do with the newly created instance. The text display object exists in your room now and is handled by GM like very other object. Because of that, once the variable is discarded at the end of the script, all you're losing is the variable holding that object's id; the object itself still has it, and all textDisplay was doing was storing that information for your use.
Consequently, pointers are usually just reference points that direct information from different points in memory, between objects, or whatever else depending on what you're using. In this case (and most any case that will come up in GM), it's a reference point for the object itself, which is where our tiny friend the period comes in.
Collision events in GM are an easy example of the same concept; the keyword "other" shows up in drag and drop all the time, but often doesn't do much. In collision events, however, "other" refers to the object you're colliding with, and in code you'd use it much the same way we're using textDisplay here. As an example, if a bullet hits an enemy plane and you want to reduce their HP by 5 before destroying the bullet, the code would look like this:
(Random good thing to know: instance_destroy() ends the existance of the instance calling it, meaning anything placed after it, code or drag and drop, is ignored because the object calling those functions no longer exists to do so.)
So, basically, "other" in this case points at the plane the bullet hit, and the way GM does that is by automatically assigning "other" the collided instance's id, which is the same information textDisplay is storing. Much like with var, "other" only holds that information for the duration of the event and then discards it, but doesn't effect the other object in any way you don't tell it to.
When you use a period/decimal/magic dot after an instance id (or, as we've demonstrated, a variable holding one like other or textDisplay), anything after it is referring to specific information in that instance. Thus, textDisplay.text is referring to the variable text in that specific instance, whereas the drag and drop's option would set the text of every instance of obj_TextDisplay in the room, which is why all of your numbers were changing at once.
And just to clarify the last bit of confusion about how this all works, when you call instance_create(), the very first thing GM does is that instance's create event; consequently, when obj_TextDisplay is created, the variables and their default settings are all executed immediately before proceeding, so text is already the blank string we've defaulted to. After that, the next line of code where textDisplay.text is set finally executes, setting that variable to what we want right after.
As a fun excersize of the concept, you could try for some heat-seeking missles. Another function that returns the instance id is instance_nearest(); So, your missles could do something like this:
If you understand what's going on there, then you've made a lot of progress! (Especially since we haven't covered a lot of it, so I'm testing you a little too, I guess.) As an aside, the help index is your best friend, and the search function can serve you well in learning what specific functions do or need you to tell them. Also, in the code window, if you type "instance_nearest(", down on the bottom you'll notice a little bit of text that reads "instance_nearest(x, y, sp);" or something similar. That's telling you what arguments the function needs as a quick reminder / reference, and it can be super handy. What's more, GM does try to auto-predict what you're after, so if you type "instance_" and then blank out, a handy little list of everything starting with that phrase will come up (which is super handy when pondering default colors, as typing "c_" will bring up a comprehensive list of all of GM's preset color values).
As with last time, I hope this is more helpful than overwhelming and I'm sorry if I've left you clutching at your head in desperation or anything. x.x
ok I understand most of what you just said, and I have a little tiny more Idea of how it works, but all of this in just 2-3 days is a lot so bear with me here.
so I understand now that:
var textDisplay = instance_create(x, y, obj_textDisplay);
creates a variable textDisplay (which is then deleted after the event finishes). then instance_create(x, y, obj_textDisplay); creates an instance of obj_textDisplay with the instance ID put into textDisplay.
but this is where it confuses me.
when the instance of the textDisplay object is created, does it perform just the create event of the textDisplay object before continuing with the code? or does it do all the events before continuing the code? or does it create the instance, and continue the code while the events and actions of the instance are happening?
Also, does the code run in all one step?
ALSO: does the draw event happen every step?
I guess im just confused on the timing, and what happens when, and all the jumping around. It's really confusing >.<.
Again, thanks for being so patient with me, and helping so much!
What I mean by that is that an object's Create event happens for an instance of that object when it is created. Because of that, we have our weird cut in timing that basically goes
Basically, because the create event has been triggered, it interrupts what we're doing until it's done. On a code level, this is because an object's Create event is handled like a normal function on Game Maker's back end. instance_create() calls its own block of code we don't have access to, but basically when you call something like that, the program goes to that chunk of code to execute it. This is why it's possible to create an infinite loop and crash everything by having two functions call on each other repeatedly; they'll just keep interrupting each other and stacking and the program will stop responding and freeze up. Infinite loops are nasty like that.
I keep bringing up scripts, but this might be as good a time as any to use them to explain things a little more clearly. If you create a script in GM and name it, say, "scr_TimeWaster", you can call it in code like so:
That script could be empty and accomplish nothing, but GM is still going to jump to and execute anything you put in it before continuing with the code that called it. It all happens in a miniscule amount of time that makes milliseconds seem bloated, but it happens all the same, constantly.
The reason Step and Draw happen every frame is because it's part of GM's process; the step event calculates out all of the automated functionality (moving instances based on their speed and direction, for example, or calculating automated physics) and then draws the result, starting with the backgrounds and working its way forward. The draw event defaults to drawing your object the way you set things up to, unless your object has a draw event, which takes priority. Consequently, if you go into one of your enemy ships and add a Draw event that then draws a big red number 4, you're going to see the number 4 but no plane, because you didn't tell it to draw the plane. There's a function to do that very easily (draw_self()), but as soon as you add your own Draw event, it becomes optional, which sounds like a pain but can actually be really useful.
I'm not super sure of the priority of events outside of that. Create will always call the instant you create something, whereas I think most of the keyboard and mouse input stuff triggers sometime before or during the step process, while collisions logically would probably be after Step so everything has moved beforehand. A lot of people don't care for the uncertainty or lack of control, though, and will just code everything right into the Step event themselves. Regardless, when you create your textDisplay object, the Create event happens, but GM won't get to its Step event or anything else until some time after it's done with what it's up to already. Programs can multitask, through a process called threading, and GM is starting to support that, but generally speaking things in programming are happening one at a time unless you specifically tell them otherwise.
So, in a more brief answer, yes, this all happens in one step, and Draw happens after every step, at which point the next step begins. GM doesn't frame skip unless you find a way to bludgeon it into doing so, so because of this loop it'll actually slow down your frame rate if you're overloading it rather than skip over anything.
I read what you said about 4 times, and I think I understand it slightly better.
So I have a completely unrelated question that I should probably ask on a different thread, but I want to ask you specifically because you are so thorough (im being so selfish!)
anyway, heres my question. is this:
as
Would the second one work exactly the same as the first one? Is there a benefit to the first one besides readability, or would it be better to write the second one?
Again, you have no idea how grateful I am for your help the past couple of days, I really like talking to you!
Consequently, both of those would end up working the same, as would
This is a good way to save space sometimes, but it only really works for brief statements, and if your conditions or loops have more than one statement they're executing you need the brackets. That said, you can still pull something like this, too:
That can get unweildly if the line gets too long, but if you're only executing a couple short statements like that and you're comfortable with it, it's completely workable.
(Code readability is a good thing to maintain; same reason you comment what you're doing so you understand coming back to it later!)
another question:
which event should you put keyboard keys in? I would just create a "keyboard event for left key", but I want to add gamepad support to the game. Would I just add it to the step event?
Thanks.
Also, if you are getting tired of me bugging you, please please please tell me and I will ask questions on new threads!
I managed to smack together some keymapping support just the other day, so I'm freshly entrenched in this process. My process wound up using a few scripts, globals and constants, granted, so for now let's take the baby steps and not drown you in a sea of gibberish.
You can handle most of your input through GM's keyboard events, but at the same time this can give you conflicts. What happens if someone hits left and right at the same time? How do you handle some smartalek dual-weilding a keyboard and gamepad trying to exploit your controls? Things of that nature.
Fortunately, keyboard handling in GM is generally pretty easy, and relatively recently gamepads became just as approachable when they were overhauled to have multiplatform support. The documentation tucks it all under "Mouse, Keyboard and Other Controls[docs.yoyogames.com]". If you start with "Keyboard Input," you can get a list of preset keys, and example of checking the A key with ord(), and a list of functions, of which the most immediately useful are all related to keyboard_check();
The page there is actually about as good at providing quick examples as I would be (which is no small part of why I adore GM's docs so), but this also reenforces our previous conversation regarding returned values; keyboard_check() and its kin all return true or false based on if the button in question meets the criteria or not (ie. keyboard_check(vk_space); will return true if the spacebar is held at all, whereas keyboard_check_pressed(vk_space) only returns true if the spacebar was pressed that step). Gamepad follows most of the same rules with it's own set of constants, so what ends up being left is prioritizing.
I've seen you using a for loop, so I'm guessing you're familiar with if statements, but an example all the same:
In this example, the initial statement checks to see if either the left arrow key or left d-pad button are held, and performs the appropriate actions if they are. If and only if that's not true does it check the same for moving right. What this ends up meaning is that if someone tries pressing left and right at the same time, left will take priority in this case. As a bonus, since we're not moving with several different events, someone trying to outsmart you by holding the same direction on both means of input will find themselves sorely disappointed since the results don't stack; GM's events would exectute both the right arrow and right d-pad, meaning that if you're using hspeed += or x+= for movement, things would double and they'd be running around like a jerk all proud of themselves. It gives you more control over the situation, which is rarely a bad thing.
is there any way to make the speed of an object go lower if the game room speed is higher?
for example if I had a room with the speed set to 30. Then, if I were to make a create event in a ball object and make the speed 8.
Later in my project if I decided to change the room speed to 120, the speed of the ball would greatly increase.
I guess i'm asking for a math equation, haha. I was always horrible at math. something like
The first is delta_time, which I've played very little with but would serve you well to learn if you plan on stepping outside of GM at some point down the line; delta time reads how many milliseconds have gone by, basically, so you can plan based on that, which means even if a game is not running at the target framerate, things should still move roughly in time to how you intended. Basically, delta_time is behind any competent form of frame skipping.
The other method is to scale your speed by a percentage, which is pretty straightforward stuff. 1/100 = 1%, 2/50 = 4/100 = 4%, etc. So, if your present room speed is 30 and that's what you want things based on, 100% is 30/30, and what you want to do is halve the speed (50%) if the fps were raised to 60. 60/30 = 2, or 200%, which is the opposite of what we want, so it must be 30/60.
We know 30 is are default fps that we're basing all of our speed on, so 30 is basically our constant, meaning that your scale is always going to be 30/room_speed. This will tell us how much to speed up or slow down based on your target frame rate; delta time would follow much the same principle, though your scale will be considerably different.
To adjust a number by scale, you just need to multiply it by the percentage, which basically gives us this:
Programming is one of those few things where when someone asks "when are we ever going to use this?" in class you can answer with and be completely right. You're not going to break out of algebra a lot in 2D, but if you go full Hedgehog or try for a third plane you'll probably want a decent geometry understanding, 'cause you're gonna be best friends with triangles by the end of it. Also, I'm an idiot at that second part because geometry was taught early by a terrible teacher and then never applied again, which is a good way to forget absolutely all of it.
@Shadowblades: Hope some of this eases the transistion! There's a few of us around here who can help with things, though I think I might be the one who stalks the boards the most often. Heh.
scale by percentage. bleh, I feel really dumb! I spent so long trying to figure this out, and now I feel really stupid, haha.
Do little things like this just come with experience?
thanks again!