Darkstar2
|
|
Posted on: May 07, 2014, 12:07:06 am |
|
|
Joined: Jan 2014
Posts: 1238
|
I am working with experimenting with different things What is not working for me is loops, while, do, until, variables are broken like it's not possible....... Here is just an example and yes I used in the create event i=0. Again I repeat, I tried with global, int, you name it I tried it. if i < 100 { draw_text(10,10,"Count: "+string(i++)); } else draw_text(10,10,"Count: "+string(i));
This is in draw event, and as you may have already guessed it this is causes a incremental counter to draw until it reaches 100 then it draws steady at 100. Now, there are other ways of doing this, and initially I tried using for but it did not work I tried everything, global, int, var, storing i in another variable, nothing worked. for (i=0; i < 99; i++) { draw_text(10,10,"Count: "+string(i)); }
This does not work......for some odd reason i starts at 100. Same if I use other methods except with the method #1 inside the string(i++). { while (i < 100) { draw_text(10,10,"Count: "+string(i++)); } }
Does nothing, nothing gets drawn so this proves the code is not being executed. I purposely removed the last line draw_text without the i++, as it would have mislead you and showed the last digit of i displayed, so I removed it for debugging purposes. Looked in GMS's docs, and that is how they document while and how it's supposed to be used. Now it's funny because while worked in other areas of my code, here is an example where I used while and it worked, for horizontal collision, in this example Hspd is set to +4 if player presses right and -4 if player presses left, and if a collision is detected ahead of time, it will move the player 1 pixel at a time until it touches the wall, sort of like the move to contact thingy. This works fine. if place_meeting(x+Hspd,y,wall) { while (!place_meeting(x+sign(Hspd),y,wall)) x+=sign(Hspd); Hspd = 0; }
This works, so why does a simple counter loop with while does not ? Here is another example not involving the draw event, this is in an object's step event, again i was set to 0 in create code. an object with a sprite, for (i=0; i < 100; i++) { x=i }
In this example the object should move 1 pixel at a time until it moved 100 total pixels. When run the object appears nowhere, as probably i is having some garbled values. tried with int, i starts at 100 and stays there. I made my own debug in draw event draw_text(10,10,"Variable i : "+string(i)); draw_text(10,20,"Value of x : "+string(x)); Result when run, i is 100 instantly,
|
|
« Last Edit: May 07, 2014, 12:36:22 pm by Darkstar2 »
|
Logged
|
|
|
|
|
Darkstar2
|
|
Reply #2 Posted on: May 07, 2014, 11:38:07 am |
|
|
Joined: Jan 2014
Posts: 1238
|
That's incorrect, the drawing gets refreshed and not drawn on top of itself. As I mentioned in my post if I do it manually instead of a for loop it works correctly
I tried the for loop in a script and in a non draw event, etc, still same problem
for (i=0; i < 100; i++)
This should start counting from 0 and increment i by 1 every step. Oddly, the i starts at 100 and not 0. and stays 100.
Tried placing this for in a non step event and debugging, and i still starts at 100, even if I declare the variable, global, int, var, same shit.
|
|
« Last Edit: May 07, 2014, 12:11:17 pm by Darkstar2 »
|
Logged
|
|
|
|
|
TheExDeus
|
|
Reply #4 Posted on: May 07, 2014, 01:25:23 pm |
|
|
Joined: Apr 2008
Posts: 1860
|
Now, there are other ways of doing this, and initially I tried using for but it did not work What you posted are NOT other ways to do that. They do something completely different. This does not work......for some odd reason i starts at 100. It's not odd at all. A for loop repeats the code inside it until a condition is met ( http://en.wikipedia.org/wiki/For_loop). In this case that means drawing 100 times (numbers from 0 to 99) in one step. After that loop i will be 99 (because it will have added one 99 times to it in that step). The next step it will be reset to 0 (the initializer in the for loop) and then draw 100 times again. After which i will be again 99. Does nothing, nothing gets drawn so this proves the code is not being executed. It does draw something. It draw the text (like in the for loop) for one step (the very first one). After which the i is more than 99 and the while(){} never executes again in the next steps (because unlike in the for loop, the i is never reset to 0 in this case). Looked in GMS's docs, and that is how they document while and how it's supposed to be used. I think you don't really understand how cycles work. Or how steps work. The code you put in events like draw or step are executed once every frame (called step in GM). By default there are 30 frames per second (changeable in room settings). Create event (where you set i to 0) is ran only once, when the object is created (in the beginning of the room). So all of the codes you posted work just fine. They would work like that in GM, ENIGMA, C++, Basic, Python or anywhere else. This works, so why does a simple counter loop with while does not ? It works just like you coded it. There are no bugs or problems with while, for or repeat cycles. In this example the object should move 1 pixel at a time until it moved 100 total pixels. No it shouldn't. As I mentioned before Draw event (the one actually drawing to the screen) is executed once per frame. While the for(){} you have created here executes 100 times per frame. So when using that loop you should see the object at x=100 in every frame. Imagine the code like this: //In step 10 here x = 100 for (i=0; i<100; i++){ //Here x = 0 x = i; //Here it is changed 100 times } //Here x = 100 again
//Here the draw happens and you actually see the object drawn at x,y position which is always 100 As you can see x will always be 100 in this case and the object will always be on the same position. Result when run, i is 100 instantly, As it should be. Read up on loops. You said you used Basic before, I think they had loops too. edit: This should start counting from 0 and increment i by 1 every step. No, it shouldn't. Your for(){} cycle is executed inside ONE step. You execute it every step from the beginning. You cannot have one script execute spanning multiple steps. Like this is impossible: //Step event code
x = 0; //Now do some magic to change steps x = 1; The "magic" part is impossible. What you can do is call screen redraw manually. Like you could do this: //Step event for (i=0; i < 99; i++) { screen_redraw(); }
//Draw event draw_text(10,10,"Count: "+string(i)); But that wouldn't change the step or execute any other code. It would just call all draw events. So that would work like the original code, but consume a lot more resources (as there isn't a frame rate limit here) and if you put screen_redraw() in draw, then that causes an infinite loop that crashes the game (that is normal as you are calling a draw event from a draw event from a draw event...). The screen_redraw() is most used to render screen to a surface: //Step event surface_set_target(screen_surf); screen_redraw(); surface_reset_target(); This would draw everything that is on the screen to the surface. Another popular use for screen_redraw() in the old days was to create loading bars. As GM didn't have threading, then the game usually froze when executing an intensive script (like loading a large level from a file). To create a loading bar you needed to redraw the screen while the script was executing and that was done via screen_redraw(). Like so: //Script that is slow loading_bar = 0; //Load models or something that takes 2 seconds loading_bar = 10; screen_redraw(); //Load map that takes 5 seconds loading_bar = 50; screen_redraw(); //Do some init or something that takes 7 seconds loading_bar = 100; scree_redraw();
//Draw event draw_rectangle(10,10,10+loading_bar,50,0); //Draws the loading bar So in this case even though the same script is executing in the same thread, the loading bar is still drawn as animating. No other events or scripts are called though (unless they happen in the draw event). So no "step" has actually happened. In ENIGMA we have functions like script_thread() that would be a more proper way to do this.
|
|
« Last Edit: May 07, 2014, 01:49:22 pm by TheExDeus »
|
Logged
|
|
|
|
Goombert
|
|
Reply #5 Posted on: May 07, 2014, 02:02:17 pm |
|
|
Location: Cappuccino, CA Joined: Jan 2013
Posts: 2993
|
Yes listen to Harri because you seem to be quite confused by how loops actually work. If loops were broken a lot more games, maybe even the majority, would be broken as well.
|
|
|
Logged
|
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.
|
|
|
Darkstar2
|
|
Reply #6 Posted on: May 07, 2014, 04:22:08 pm |
|
|
Joined: Jan 2014
Posts: 1238
|
Maybe I am not explaining myself correctly or what I want to do, but I will use an example I would do in BASIC, that would work. Yes obviously things work and execute differently but this is just as an example In this case the code is executed between the FOR and NEXT inside a LOOP. The loop starts with variable I set to 0 and increments by 1, the printing will take whatever value is in I and print it sequentially across the screen. That's how it worked in BASIC. You didn't have step events, draw events, etc. I guess maybe I have to do things differently now, but I tried with other methods that not involve for / loop and variable values were all over the place!
FOR I=0 TO 100 STEP 1 PRINT I NEXT I
In this example you would see numbers from 0 to 100 printed, as print is taking the value of I. I will not argue here, I used BASIC on an expert level and made complex apps and games back in the days using a combination of BASIC/ASM or native ASM, and it worked fine.
|
|
« Last Edit: May 07, 2014, 04:28:45 pm by Darkstar2 »
|
Logged
|
|
|
|
time-killer-games
|
|
Reply #7 Posted on: May 07, 2014, 04:32:22 pm |
|
|
"Guest"
|
If you mean like Visual Basic, their For-Loops are fucked up and way different from what ENIGMA does. Again, ENIGMA is derived from C++ and the closely related syntax of GML. Basic is a different animal. Read the YYG docs (in GMS press the F1 key + search "for"). You can achieve exactly what you want with a C++/GML syntax'd for loop but it's done a bit different. Last I checked, there is no "print","to" or "next" in GML/EDL. A lot of things are done differently in these.
Instead you could do this in the Draw GUI event (with a visible draw color / object depth):
// Note that it will draw to the game's window instead of being printed to the compile form... for (i=0; i<=100 i+=1) { draw_text(0,0,string(i)) }
Have more questions? I have answers. The only stupid question is one not asked...
|
|
« Last Edit: May 07, 2014, 04:41:41 pm by time-killer-games »
|
Logged
|
|
|
|
TheExDeus
|
|
Reply #8 Posted on: May 07, 2014, 04:43:46 pm |
|
|
Joined: Apr 2008
Posts: 1860
|
Maybe I am not explaining myself correctly or what I want to do You explained clearly enough. And I explained on why your thinking is wrong. I also gave numerous examples on how it works and how to replicate what you want. print it sequentially across the screen. It prints in the console. You can do show_error(string(i),false) with widget None and get the same thing. That would print to console while inside the for loop. On the other hand ENIGMA renders on graphics context by the GPU. OpenGL and DirectX don't render on the screen anything when you just say "draw_text()", it renders on a buffer (to be technical it doesn't render anything at all until the end of the frame). Then the last thing the driver does when the frame ends is render whole thing on the screen. This is called double buffering and is what most graphical programs/games use. So your for(){draw_text();} doesn't render anything on the screen. And it wouldn't render anything on the screen no matter what engine, graphics system or driver you use. It's just not going to do that, because it's not meant to. The only way to render things on the screen during a loop is by redrawing (swapping buffers) in the for loop. That is what my screen_redraw() example code did. Instead you could do this in the Draw GUI event (with a visible object depth): That will not do what he wants. He thinks that code will render a number i on the screen and then increment per frame. That is not how it works.
|
|
|
Logged
|
|
|
|
time-killer-games
|
|
Reply #9 Posted on: May 07, 2014, 04:50:08 pm |
|
|
"Guest"
|
Gotcha.
Instead of a for loop, I think he means an increment every step. Because if it all processed and rendered 100x through in 1 step it would all happen so quickly there'd be no point in it, the end user would be like "wtf that was a lot of numbers"
Edit - I'll just stay away from this thread - have no idea what darkstar wants or why, so I can't really help him under the circumstance.
|
|
« Last Edit: May 07, 2014, 04:54:01 pm by time-killer-games »
|
Logged
|
|
|
|
Darkstar2
|
|
Reply #10 Posted on: May 07, 2014, 05:42:29 pm |
|
|
Joined: Jan 2014
Posts: 1238
|
It's not odd at all. A for loop repeats the code inside it until a condition is met (http://en.wikipedia.org/wiki/For_loop). In this case that means drawing 100 times (numbers from 0 to 99) in one step.
But the reason for the loop in my example was to repeat code until the condition of i=100 is met. I have seen maybe print counter examples done with for/loop this way, that's why I am confused. I think you don't really understand how cycles work. Or how steps work. The code you put in events like draw or step are executed once every frame (called step in GM).
I knew that and understand how it works and am aware 1 frame = 1 step, and the draw/step is executed at room speed, by default 30 steps per second. And I know what create events are, I use those to initialize variables and set my object's settings upon create. codes you posted work just fine. They would work like that in GM, ENIGMA, C++, Basic, Python or anywhere else.
You are wrong about BASIC Harri You have no idea how much I used loops when I used BASICS, it was abused lol and I already gave you an example of a BASIC loop. But in BASIC there are no draw events, create events, step, begin and end step events shit works differently now apparently and I am seriously fucked, unless I know how things are to be done now. It works just like you coded it. There are no bugs or problems with while, for or repeat cycles.
If it worked I would not be posting this. I am working based on the logic of what I need done. perhaps a better way for me is to simply say what I need done and then someone recommends me code on how to do it I am pretty sure some of the stuff is broken in ENIGMA, because I don't always get the same outcome when running / compiling games ... here is an example, let's say I want to read from a file, start pos to end pos, i BASIC I used for loop for that and used the loop's for variable in the code between the for and next. I saw some C++ programs do this, so why can't I do it here? No it shouldn't. As I mentioned before Draw event (the one actually drawing to the screen) is executed once per frame. While the for(){} you have created here executes 100 times per frame. So when using that loop you should see the object at x=100 in every frame.
Understood. So, in this example, how can I make an object move 100 pixels (1 pixel at a time) using a for / loop then ? I thought that in each step the i would increment 1. I could have sworn seeing for loops in step events before, how can that be then ? Read up on loops. You said you used Basic before, I think they had loops too.
On an expert level yes I used BASIC and I can swear on my life that it worked differently. execute it every step from the beginning. You cannot have one script execute spanning multiple steps. Like this is impossible:
So what is the alternative then, incrementing the value of i myself, but then I would have to use do until or while, and that does not work either... When reading docs in enigma and GMS I see for loops being used, when I apply the examples they don't work.
|
|
|
Logged
|
|
|
|
Darkstar2
|
|
Reply #11 Posted on: May 07, 2014, 05:54:41 pm |
|
|
Joined: Jan 2014
Posts: 1238
|
If you mean like Visual Basic, their For-Loops are fucked up and way different from what ENIGMA does.
No TKG I did not mean visual basic, never used it and never will. I am talking about good old fashioned basic lol. I then used some powerbasic, but most of what I used was standard BASIC and QBASIC. Yes I am aware now that for loops are quite different in C++, and yes there are no NEXT all that is handled in the same line with for. Again, ENIGMA is derived from C++ and the closely related syntax of GML. Basic is a different animal.
Understood, but I saw some C++ examples where a message is printed in a foor loop, such as couting 100 times hello world for example, done in a for loop. Read the YYG docs (in GMS press the F1 key + search "for"). You can achieve exactly what you want with a C++/GML syntax'd for loop but it's done a bit different.
I access the docs through docs.yoyogames.com and I read them frequently. I know far more GML now and enough to make a platform game, but now I am stuck in a loop with the for while until do shit // Note that it will draw to the game's window instead of being printed to the compile form... for (i=0; i<=100 i+=1) { draw_text(0,0,string(i)) }
That's not right either TKG. Looks like for what I wanted to do I will have to do it differently, here is a method that does work: create event i=0 draw event { if i < 100 { draw_text(10,10,"Count: "+string(i++)); } else draw_text(10,10,"Count: "+string(i)); }
This increments 1 each step, and at 100 stops and continues displaying 100. I guess I have to do it this way for everything I guess. I was just curious as to why it did not work with for as it did in basic. Guess I know now, the entire loop is done in 1 step and not broken down into 100 steps whereas doing things as above, it is incremented every step.
|
|
« Last Edit: May 07, 2014, 06:15:06 pm by Darkstar2 »
|
Logged
|
|
|
|
Goombert
|
|
Reply #12 Posted on: May 07, 2014, 08:07:33 pm |
|
|
Location: Cappuccino, CA Joined: Jan 2013
Posts: 2993
|
The only stupid question is one not asked... I agree, I say that a lot too. Also, execute the following in an object in a new game as a slight variation of TKG's. // Note that it will draw to the game's window instead of being printed to the compile form... for (i=0; i<=100 i+=1) { show_message(string(i)); }
|
|
|
Logged
|
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.
|
|
|
onpon
|
|
Reply #13 Posted on: May 07, 2014, 08:15:00 pm |
|
|
Joined: Feb 2010
Posts: 102
|
Darkstar, this:
for (int i=0; i<10; i++) { show_message("Hello number " + string(i)) }
is EXACTLY the same as this:
show_message("Hello number " + string(0)) show_message("Hello number " + string(1)) show_message("Hello number " + string(2)) show_message("Hello number " + string(3)) show_message("Hello number " + string(4)) show_message("Hello number " + string(5)) show_message("Hello number " + string(6)) show_message("Hello number " + string(7)) show_message("Hello number " + string(8)) show_message("Hello number " + string(9))
The only difference is the for loop is less verbose.
You seem to be under the false impression that the for loop should be somehow connected to ENIGMA's "steps" (frames). No language's loops work like this. Not Visual Basic (Visual Basic supports for loops that are basically like C's, and "for each" loops that loop through lists the same way Python's for loop does; both of them are perfectly normal for loops that behave in exactly the same way as any other language), and probably not whatever BASIC dialect you used, either. You probably just didn't notice because you weren't working within an infinite loop of frames like ENIGMA's.
This is what ENIGMA's system, and every other similar system for games, looks like:
while (true) { do_logic(); limit_frame_rate(); redraw_screen(); }
Each iteration of this loop is a frame, or "step" as ENIGMA calls it. Each step, it executes appropriate code based on events; for the Step event, it's at a certain time every frame. This would happen in do_logic(). Let's say you write something that takes 30 seconds to do; in that case, the program is going to be stuck in do_logic for 30 seconds, and so the screen will be frozen during that time. That's because your code has to finish before the main infinite loop can continue to the next step.
|
|
|
Logged
|
|
|
|
|
|