How to forcefully end an iteration of a for-loop (without stopping the for-loop)? - for-loop

This may be a stupid question, but here goes. Is there a way to forcefully end an iteration of a for-loop and ignore all other conditional statements within the loop, and move onto the next iteration?
I'm trying to make a tool where whenever a user types a letter, it's printed to the canvas.
I'm using a for loop to do this, with each iteration making the next letter move to the right each time.
Inside the for-loop includes the conditional statements for typing the letter:
function draw(){
}
function keyPressed(){
for(i=0; i<100; i++){
if(keyCode == 65){
text("a", 60 + i*10, 60)
}
...
...
...
}
}
and so on, and so forth. However, this would only work if after each letter it moved onto the next iteration (otherwise the letters would be printed in the same place due to 'i' not increasing, making it unreadable).
Using 'return' at the end of each condition statement doesn't work for me as 'return' ends the entire for-loop, whereas I just want to end that specific iteration.
All help is appreciated, thank you.

It sounds like you're looking for the continue keyword. Here's an example from W3Schools:
for (i = 0; i < 10; i++) {
if (i === 3) { continue; }
text += "The number is " + i + "<br>";
}
Here is a linke to try the code yourself.
But taking a step back, this feels like a flawed design. If you want to get the key they user pressed, you don't have to use a bunch of if statements. You can just use the key variable. From the P5.js reference:
function setup() {
fill(245, 123, 158);
textSize(50);
}
function draw() {
background(200);
text(key, 33, 65); // Display last key pressed.
}
Even if that won't work for some reason (if you want to display something for the arrow keys, for example), there are probably better ways to solve this problem than a bunch of if statements in a for loop. For example you could create a mapping from keyCode to the string you want to display, and then call that mapping. Something like:
var m = new Map()
m.set(65, 'a');
m.set(66, 'b');
//..
function keyPressed(){
text(m.get(keyCode), 50, 50);
}

Related

My program appears to stop working

I am quite new to programming and decided to make a little game, so far I have only made a small block that is able to move in all 4 directions (left, right, up and down). Pretty simple and nothing extra-ordinary. However, when I run my program, sometimes it will stop working, not as in crashing causing Processing itself to crash, but my program will just end.
As far as my testing goes, I think this happens when I press two keys at the same time (like W and S). Does anyone happen to know what causes it to stop, and perhaps how to fix it as well?
void setup(){
size(1080,720);
frameRate(30);
}
int shipLR = 0; //Variable for the ship to go left/right
int shipUD = 0; //Variable for the ship to go up / down
void draw(){
background(0);
shipLR = constrain(shipLR, 0, 1040); //Constrain the ship in the window
shipUD = constrain(shipUD,0,680); // Constrain the ship in the window
move();
Shuttle();
}
void Shuttle(){
rect(shipLR, shipUD, 40,40); //Draw the ship
}
void move(){
if (keyPressed) {
if (key == 'a') {
shipLR = shipLR - 20; // Go left
return;}
if (key == 'd') {
shipLR = shipLR + 20; // Go right
return;}
if (key == 'w'){
shipUD = shipUD - 20; // Go up
return;}
if (key == 's') {
shipUD = shipUD + 20; // Go down
return;}
}
}
Any help will be greatly appreciated.
Edit: I found something that causes this problem to occur more frequent; If I implement a frameRate of a value lower than 60 (currently trying with 30) this happens more often.
Edit 2: With the suggestions below of making my move function in a single if block had a lot of good impact. The program no longer stops when I move the ship in the middle of the window it no longer stops, it now only does it at rare occasions when I bump too often against the borders of the window. Perhaps it has something to do with constrain?
in move() (java naming conventions specify that method names start with lower case) you should exit on the first key pressed found. the code can be re-organized to reduce multiple identical conditions:
void move(){
if (keyPressed) {
if (key == 'a') {
shipLR = shipLR - 20; // Go left
return;
}
if (key == 'd') { // still inside if keyPressed
shipLR = shipLR + 20; // Go right
return;
}
if (key == 'w') {
...
}
} // end of if keyPressed
}
My guess it that the program doesn't "stop working" or end- it's just that your rectangle stops moving. If you let go of all the keys, then push just one key, I'd bet that the rectangle starts moving again. (In the future, please try to be more specific- saying "it stops working" isn't very helpful.)
Anyway, that's because of the way you're handling the key presses. What happens if you press a key other than the ones you're checking for?
You'll enter the move() function, and you'll enter the if(keyPressed) block, but you won't enter any if the other if statements inside that block. The key variable only holds the most recently pressed key.
Depending on what you want to do, you should either refactor those if statements to only change the direction if the key was valid, and to ignore all other key presses. Or you might want to use a set of boolean variables to track multiple keys being pressed at the same time. More info on that approach can be found here.
If you still can't get it working, then please try to be more specific about exactly what happens.

How to create something happen when time = x

I have a question about timers in Processing. I want to make a square spawn after every second that passes. Would I use a for loop, an if statement, etc.?
You could just use the millis() function or the frameCount variable in an if statement.
Something like this:
void draw(){
if(frameCount % 60 == 0){
//do something
}
}
More info can be found in the reference.

Processing - If statement and ids

I'm an Italian student and I'm new in programming. I need your help for a school project.
I'm making a blob tracking program using Daniel Shiffman's tutorials. Currently I have 2 blobs on the screen. I am identifying them with 2 IDs: number 0 and number 1.
I need to put some conditions on those blobs: if one blob is in a certain part of the screen and the other one is in another part, I need to call a function.
I don't know how to put the if conditions separately for the two ids. Below is some pseudo code of what I would like to achieve:
for (id==0)
if (...) and
for (id==1)
if(...) then {
void()
}
I would really appreciate any help!
I don't really know where you want the blobs to be when the desired function fires, but I can try to give you an example...
Blob
Assign some sort of position variable, in this case PVector, to your blob object.
class Blob {
PVector position;
Blob (PVector position) {
this.position = position;
}
void update() {
*random movements, etc...*
}
}
Create two blob objects
Create two objects and assign a position to each of them.
Blob[] blobs = new Blob[2];
void setup() {
size(400, 400);
blobs[0] = new Blob(5, new PVector(40, 40));
blobs[1] = new Blob(13, new PVector(100, 100));
}
Check if blobs is at left or right side of the screen
I check if blob[0] is at the left side of the screen and if blob[1] is at right side of the screen. If they are, at the same time, the desiredFunction(); will fire.
void draw() {
for (int i = 0; i < blobs.length; i++) {
blobs.update();
}
if (blobs[0].position.x < (width / 2) && blobs[1].position.x < (width / 2) {
desiredFunction();
}
}
Remember
This is just an example. You could of course check other parts of the screen instead of the left and right parts. You can also use IDs on your blobs instead of an array, I just thought it was better to just use an array in this case.
PS: I wrote this answer without having processing started. The code has certainly a couple of typing errors.
For the example you have described, you can achieve this using the && operator in one if statement.
First assign the conditions you want to test to boolean variables. For example, create the boolean variables id0IsThere, and id1IsThere, and set them to true if the blobs are in the locations you want them to be in. Then use the following if statement:
if (id0IsThere && id1IsThere) {
yourFunction();
}
The && operator means that the code inside the if statement that executes yourFunction() is only executed if both conditions are true. In this case, if both blobs are in the positions you want them to be in. Hope that helps. Read more about if statements and the && operator here:
https://processing.org/reference/if.html
https://processing.org/reference/logicalAND.html

Lap timer in XNA 4.0?

Right, I've got a slight problem here, in which I've attempted to implement a lap timer.
In my protect override void update I've got this;
if ((IntersectPixels(destinationRedRect, car2redTextureData, startingLineRectangle, startingLineTextureData)))
{
{
redHit = true;
_timer1 += gameTime.ElapsedGameTime.TotalMilliseconds;
}
}
What I'm saying here^ is, if car2red is colliding with the starting line, the timer begins, but if it's not, timer does not add seconds (it just stops_ . How can I make it so, if car2red hits the startingLine and moves forward a few pixels (without touching starting line) the timer still continues?
Thank you.
You should have a separate if statement like this:
if (redHit) {
_timer1 += gameTime.ElapsedGameTime.TotalMilliseconds;
}
if ((IntersectPixels(destinationRedRect, car2redTextureData, startingLineRectangle, startingLineTextureData)))
{
redHit = true;
//Only use this line if you want to reset the timer to 0 when the player crosses that line again.
_timer1 = 0;// I'm assuming that _timer1 is a double
}

GTK+ - How to listen to an event from within a method?

I'm writing an application that runs an algorithm, but allows you to 'step through' the algorithm by pressing a button - displaying what's happening at each step.
How do I listen for events while within a method?
eg, look at the code I've got.
static int proceed;
button1Event(GtkWidget *widget)
{
proceed = 0;
int i = 0;
for (i=0; i<15; i++) //this is our example 'algorithm'
{
while (proceed ==0) continue;
printf("the nunmber is %d\n", i);
proceed = 0;
}
}
button2Event(GtkWidget *widget)
{
proceed = 1;
}
This doesn't work because it's required to exit out of the button1 method before it can listen for button2 (or any other events).
I'm thinking something like in that while loop.
while(proceed == 0)
{
listen_for_button_click();
}
What method is that?
The "real" answer here (the one any experienced GTK+ programmer will give you) isn't one you will like perhaps: don't do this, your code is structured the wrong way.
The options include:
recommended: restructure the app to be event-driven instead; probably you need to keep track of your state (either a state machine or just a boolean flag) and ignore whichever button is not currently applicable.
you can run a recursive main loop, as in the other answer with gtk_main_iteration(); however this is quite dangerous because any UI event can happen in that loop, such as windows closing or other totally unrelated stuff. Not workable in most real apps of any size.
move the blocking logic to another thread and communicate via a GAsyncQueue or something along those lines (caution, this is hard-ish to get right and likely to be overkill).
I think you are going wrong here:
while(proceed == 0)
{
listen_for_button_click();
}
You don't want while loops like this; you just want the GTK+ main loop doing your blocking. When you get the button click, in the callback for it, then write whatever the code after this while loop would have been.
You could check for pending events & handle the events in while loop in the clicked callback. Something on these lines:
button1Event(GtkWidget *widget)
{
proceed = 0;
int i = 0;
for (i=0; i<15; i++) //this is our example 'algorithm'
{
while (proceed ==0)
{
/* Check for all pending events */
while(gtk_events_pending())
{
gtk_main_iteration(); /* Handle the events */
}
continue;
}
printf("the nunmber is %d\n", i);
proceed = 0;
}
}
This way when the events related click on the second button is added to the event queue to be handled, the check will see the events as pending and handle them & then proceed. This way your global value changes can be reflected & stepping should be possible.
Hope this helps!
If you want to do it like this, the only way that comes to my mind is to create a separate thread for your algorithm and use some synchronization methods to notify that thread from within button click handlers.
GTK+ (glib, to be more specific) has its own API for threads and synchronization. As far as I know Condition variables are a standard way to implement wait-notify logic.

Resources