beginner problem with loops

Posted By: Saschaw04

beginner problem with loops - 04/04/15 09:49

Hello,

I want to make a flashlight for my horror-survival game. The battery of the flashlight should be empty in 300 seconds and flashlight should be automatically go off.
I used this code:


var x = 1;
var battery = 300;

function flashlight(ENTITY* ent){
if(battery>0){
my.ambient = 100;
my.lightrange = 150;
}
while((battery>0)){
wait(-1);
battery = battery - x;
}
my.ambient = 0;
my.lightrange = 0;

}

Action (){
if(key_f) flashlight(me);
}

The Problem is that the flashlight does go off in a few seconds Long before 300 seconds.
I watched the var battery and it fells rapid and not with the value of 1 in 1 second like in the code.

(Sorry my english is not so good - i am german^^)

Can anyone tell me why the flashlight goes off before 300 seconds are gone??
Posted By: 3run

Re: beginner problem with loops - 04/04/15 10:08

Hello, Saschaw04! laugh

I'll show how to make a count down timer, and you'll learn from it and adjust your code, so you'll be able to learn tongue
Code:
// 300 seconds
var counter_timer = 300;

void count_down(){

    // while we still have to count down:
    while(counter_timer > 0){

        DEBUG_VAR(counter_timer, 10);

        // count down each second:
        counter_timer -= time_step / 16;

        wait(1);
    }

    beep();
}



Best regards
Posted By: Kartoffel

Re: beginner problem with loops - 04/04/15 10:19

do you execute the flashlight function multiple times?
Posted By: Saschaw04

Re: beginner problem with loops - 04/04/15 11:10

First of all thank you for the answers.

@Kartoffel: Yes flashlight function is in a while Loop and will execute when I press f key.

@3run: I checked it out in a separate scipt and it runs.
But then I checked it out in my own scipt, but there it Counts less then 300 seconds. There it Counts just a few seconds. I could see like the 300 fells to 0 in a few seconds.

Have you a idea, why it does not work in the other script?
Posted By: Kartoffel

Re: beginner problem with loops - 04/04/15 11:21

Sorry I should've put it more clearly:

Do you accidently execute your flashlight function multiple times?

It happens if you use something like this for example:
Code:
while(1)
{
   if(key_a)
      do_something();
   
   wait(1);
}


If you hold [A] for 10 frames the function gets called 10 times.
So, if that's the same as your case, you have to make sure that the function gets called only once.

You could assign a fuction to a key and use a toggle var.
Let me know if you need an example.
Posted By: Saschaw04

Re: beginner problem with loops - 04/04/15 11:31

(Jetzt auf deutsch um weitere Missverständnisse zu vermeiden)
Ja, ich habe die Taschenlampen-Funktion innerhalb einer while(1) Schleifen aufgerufen, sodass ständig überprüft wird, ob die f-Taste gedrückt wird.
Also genauso wie in deinem Beispiel, nur dass die Schleife bei mir in einer Entity-Aktion steht
Posted By: Saschaw04

Re: beginner problem with loops - 04/04/15 11:43

@Kartoffel
Could make a example please. How it works?
Posted By: DLively

Re: beginner problem with loops - 04/04/15 12:19

Hey Saschaw04

First, I believe the manual said I read somewhere not to use while loops in functions (voids) but rather, nest the function into a while loop, in an action.

so in your flashlights action do this:
Code:
var light_on = 0;
var pressed = 0;
function press_f(){
     // -- Turn the Light On
     if(key_f && pressed == 0 && light_on == 0){light_on = 1;pressed = 1;}

     // -- Turn the Light Off
     if(key_f && pressed == 0 && light_on == 1){light_on = 0;pressed = 1;}

     // -- Wait until release of key_f to allow pressed again
     if(key_f==0 && pressed == 1) {pressed = 0;}

     if(light_on == 1){
           ..//Do this
     }
     else{
           ..//Reset / stop countdown
     }
}
action flashlight(){
      while(1){
            press_f();
            wait(1);
      }
}



EDIT: I Just edited the heck out of this - so now you can know its final tongue


I looked in the manual to see if I could back up my info... but I couldn't find it. I'm not sure where I read that, but feel it to be true. Someone correct me if I'm wrong here.
Posted By: Saschaw04

Re: beginner problem with loops - 04/04/15 12:46

OK, thank you.
I will think about it and check it out.
I write when I did it
Posted By: Kartoffel

Re: beginner problem with loops - 04/04/15 13:19

This is how I would approach it:

Code:
var flashlight_on = 0;

void toggle_flashlight()
{
	flashlight_on = 1 - flashlight_on; // toggle between 1 and 0
	
	if(flashlight_on)
	{
		// *** turn flashlight on
		
		while(flashlight_on)
		{
			// *** battery drain
		}
	}
	else
	{
		// *** turn flashlight off
	}
}


main()
{
	// blabla
	
	on_f = toggle_flashlight; // assign 'toggle_flashlight' to the [F]-key
	
	// blabla	
}


Note that the 'on_f'-event gets executed only a single time when you press the button, no matter how long you keep it pressed (which is exactly what you want in this case).

Edit: Obviously, you have to put your own stuff where the "// ***" are.

Edit2:
Quote:
Ja, ich habe die Taschenlampen-Funktion innerhalb einer while(1) Schleifen aufgerufen, sodass ständig überprüft wird, ob die f-Taste gedrückt wird.
Also genauso wie in deinem Beispiel, nur dass die Schleife bei mir in einer Entity-Aktion steht

Das ist dann auch das Problem. Damit wird nämlich die Funktion jeden frame gestartet so lange du die F-Taste gedrückt hältst. Deswegen läuft die countdown-funktion mehrmals parallel, was dann dazu führt dass der counter viel schneller und unregelmäßig runterzählt.
Posted By: DLively

Re: beginner problem with loops - 04/04/15 13:38

Cool, I like how you accomplished this task Kartoffel.
Posted By: Saschaw04

Re: beginner problem with loops - 04/04/15 15:49

Quote:

Das ist dann auch das Problem. Damit wird nämlich die Funktion jeden frame gestartet so lange du die F-Taste gedrückt hältst. Deswegen läuft die countdown-funktion mehrmals parallel, was dann dazu führt dass der counter viel schneller und unregelmäßig runterzählt.


1. Ich halte die F-Taste garnicht gedrückt.
2. Derselbe Countdown läuft in einem anderen Script perfekt, aber sobald ich ihn in mein anderes Skript (in eine SPieler-Aktion) reinpacke läuft der Countdown wieder schneller.

Im Prinzip funktioniert ja alles => Es leuchtet wenn man F drückt und hört automatisch auf. Nur der Countdown läuft komischerweise zu schnell
Posted By: Anonymous

Re: beginner problem with loops - 04/04/15 16:20

@Saschaw04
Would you please post you current script..
Posted By: Kartoffel

Re: beginner problem with loops - 04/04/15 16:21

mach mal den test und schau wie lang die flashlight in beiden situationen an ist:
- halte die f taste die ganze zeit gedrückt
- drück die f taste so kurz wie's geht

wenn du nen unterschied bemerkst ist es genau der fehler auf den ich hinaus will, wenn nicht ist es irgendwas anderes..

Edit: alternativ kannst du auch die anzahl an ausgeführten funktionen im debug panel anschaun
Posted By: Saschaw04

Re: beginner problem with loops - 04/04/15 16:24

@Kartoffel Du hast recht. Hält man es gedrückt dann läuft es sehr schnell, aber
trotzdem fragen ich mich wieso es in dem anderen Skript perfekt (300 Sekunden) läuft und sobald ich es in die aktion packe nicht mehr
Posted By: Saschaw04

Re: beginner problem with loops - 04/04/15 16:27

Here is the complete code. Maybe it helps

#include <acknex.h>
#include <default.c>


ENTITY* player1;
var counter_timer = 300;

function camera_follow(ENTITY* ent){
while(1){
vec_set(camera.x, vector(-130 ,0 , 110));
vec_rotate(camera.x,ent.pan);
vec_add(camera.x,ent.x);
wait(1);
}
}


void count_down(){
my.ambient = 100;
my.lightrange = 150;
// while we still have to count down:
while(counter_timer > 0){


// count down each second:
counter_timer -= time_step / 16;

wait(1);
}
my.ambient = 0;
my.lightrange = 0;

}

function battery(){
counter_timer = 300;
}




action drive(){
player1 = me;

while(1){ // ALLES SOLL FORTLAUFEND PASSIEREN
camera_follow(me);
if(key_f) count_down();
// Neige die Kamera nach unten
if(key_b) battery();

if(key_w){ //Wenn die W-Taste gedrückt wird, bewegt sich das Auto eine Einheit nach vorne
c_move(me, vector(6*time_step, 0, 0), nullvector, GLIDE);
}
if(key_a){ //Wenn die A-Taste gedrückt wird, neigt sich das Auto nach links
camera.pan += 0.5;
}
if(key_d){ //Wenn die D-Taste gedrückt wird, neigt sich das Auto nach rechts
camera.pan -= 0.5;
}
if(key_s){ //Wenn die S-Taste gedrückt wird, bewegt sich das Auto rückwärts
my.x -= 20 * time_step;
}
wait(1);
}
}


function main(){
// video_screen = 1;
level_load ("testlevel.wmb"); // Lade das Level "Testlevel"
camera.tilt = -34;
}

Without commentaries
Posted By: Kartoffel

Re: beginner problem with loops - 04/04/15 16:28

das problem is da wo du die funktion aufrufst.

wahrscheinlich verwendest du 'ne while die permanent durchläuft mit nem if(..) zum checken der taste.
d.h. solang du auf der taste bist, wird jeden frame (bei normalem fps-cap alle 16ms bzw. 60 mal in der sekunde) die funktion aufgerufen weil die while schleife weiterläuft.

mit der methode die ich vorhin gepostet hab tritt das aber nicht auf, weil ich die toggle-funktion über ein event beim drücken der taste ausführe
Posted By: Anonymous

Re: beginner problem with loops - 04/04/15 16:33

Yup Key_lock var will fix that.
Code:
var KEY_F_LOCKEDO_OR_OPEN = 0
if(!key_f && KEY_F_LOCKED_OR_OPEN == 1)
KEY_F_LOCKED_OR_OPEN =0;
IF(key_f && KEY_F_LOCKED_OR_OPEN ==0)
{
 KEY_F_LOCKED_OR_OPEN = 1;
 .... CALL FLASHLIGHT/TIMER HERE...
}

void count_down(){
my.ambient = 100;
my.lightrange = 150;
// while we still have to count down:
while(counter_timer > 0 && key_f) // CHANGED
{

// DEBUG_VAR(counter_timer, 10);

// count down each second:
counter_timer -= time_step / 16;

wait(1);
}
my.ambient = 0;
my.lightrange = 0;

}

Posted By: Saschaw04

Re: beginner problem with loops - 04/04/15 16:33

Kann man meinen Code etwas abändern sodass es funktioniert. Deine Lösung ist zwar besser, aber ich bin noch Anfänger und möchte eine Lösung nehmen, die ich selbst auch verstehe.

Quote:
wahrscheinlich verwendest du 'ne while die permanent durchläuft mit nem if(..) zum checken der taste.
d.h. solang du auf der taste bist, wird jeden frame (bei normalem fps-cap alle 16ms bzw. 60 mal in der sekunde) die funktion aufgerufen weil die while schleife weiterläuft.

OK das Problem hab ich jetzt glaub ich verstanden.
Posted By: Saschaw04

Re: beginner problem with loops - 04/04/15 17:23

Thank you smile
It works grin

I took the code from Malice and Change the while Loop a bit, because I wanted that the light is on after I press f and not press f all the time.
Posted By: Anonymous

Re: beginner problem with loops - 04/04/15 17:57

Welcome as long as you understand why it works and why it didn't before which is what the Great Kartoffel, was telling you.

Keep coding and keep learning, btw Welcome to 3dgs
Posted By: EpsiloN

Re: beginner problem with loops - 04/04/15 19:01

And, you might want to increment/decrement with "time_step / 16", and wait(1) (1 frame). Otherwise, your function stops for 1 second (wait(-1)) and runs again... With time_step / 16 your function runs with the frames per second speed. laugh

Not that its vital for a flashlight, but sometimes you might want to do other stuff around that if statement, that has to run more times per second...so use wait(-1) only when its trivial.
Posted By: Saschaw04

Re: beginner problem with loops - 04/05/15 10:12

Nur damit ich das richtig verstanden habe. Wenn ich sowas hier habe:

while(1){

if(key_f) Funktion();

wait(1);
}

Dann wird die function Funktion jeden Frame ausgelöst, weil es in einer Schleife mit wait(1) steht. Bei einer fps von 60 wird die Funktion also 60 mal in der Sekunde ausgelöst. Wenn ich also kurz auf die F-Taste drücke, sagen wir mal (1/20 Sekunden gedrückt) dann wird die Funktion (60/20) 3mal parallel durchgeführt und deshalb sinkt der Countdown schneller.

ISt das so ungefähr verstanden?
Posted By: Anonymous

Re: beginner problem with loops - 04/05/15 15:36

You understand perfectly- Remember to use a key_lock of some type because the very person will hold the key longer then 1 cycle.
BTW wait(1) is a frame not a time measure - it changes a bit for each cycle - however in your example of 60 fps then you are perfectly correct.

As a personal note, the new users who learn the fastest and best are people like you who want to understand the logic not just be hand a piece of code. My complements to you for start on a good foot.
Posted By: Saschaw04

Re: beginner problem with loops - 04/05/15 16:04

@Malice
Thank you for your opinion. I will give my best laugh
© 2024 lite-C Forums