We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › beginner:conditionals not fully respected
Page Index Toggle Pages: 1
beginner:conditionals not fully respected (Read 1022 times)
beginner:conditionals not fully respected
Mar 27th, 2010, 3:37pm
 
hello

I'm an absolute beginner and I'm currently going through the book of daniel schiffman.

I have my little creature that I'm working on.
Right now it moves on the Y-axis. when it reaches the top edge of the screen it has to reverse and go back till it reaches the bottom edge and then go up again.

It does that, however, it seems like the bottom limit I've set moves a couple of pixels down everytime.

it's kinda hard to explain but I've attached the code to try and see for yourself.

could anyone help me out with this and explain why this is happening?

thanks!
Code:
float x;
float y;
float speed=0;
float gravity=0.1;


void setup (){
 size(700,700);
 x=width/2;
 y=500;
 
 frameRate(60);
 
}
void draw(){
 background(255);
 y=y-speed;
 speed=speed+gravity;
 if (y>600 || y<150){
   speed=speed* -1;
 }

 
 //head
 smooth();
 strokeWeight(6);
 stroke(0);
 fill(255);
 ellipseMode(CENTER);
 ellipse(x,y,250,250);
 
 //wiskers
 line(x-20,y+60,x+20,y+40);
 line(x-20,y+40,x+20,y+60);
 
 //eyes
 strokeWeight(4);
 stroke(70,150,50);
 ellipseMode(CENTER);
 fill(mouseX,mouseY,mouseX/5);
 ellipse(x-40,y-30,30,30);
 ellipseMode(CENTER);
 fill(mouseX/3,mouseY*2,mouseX/5);
 ellipse(x+40,y-30,30,30);
 
 //ears
 fill(20,40,50);
 stroke(0);
 triangle(x-90,y-50,x-130,y-140,x-55,y-85);
 triangle(x+90,y-50,x+130,y-140,x+55,y-85);
}



Re: beginner:conditionals not fully respected
Reply #1 - Mar 27th, 2010, 4:08pm
 
I've done a little more testing and it seems that I have to put a limit the speed variable. since it keeps building and building.

I've also changed it up a bit so it only bounces on the ground  Smiley

The thing is though that I don't fully understand why this behaviour happens. since I say it the code if Y>600 reverse. why does it ignore this?

Code:
float x;
float y;
float speed=0;
float gravity=0.3;
float s=250;


void setup (){
 size(700,700);
 x=width/2;
 y=500;
 frameRate(60);
 
}
void draw(){
 background(255);
 y=y+speed;
 speed=speed+gravity;

 if (y>600){
   speed=speed* -1;
   s=280;
 }
 
speed=constrain(speed,-10,10);
 
s=s-1;
s=constrain(s,250,280);
 
 //head
 smooth();
 strokeWeight(6);
 stroke(0);
 fill(255);
 ellipseMode(CENTER);
 ellipse(x,y,s,250);
 
 //wiskers
 line(x-20,y+60,x+20,y+40);
 line(x-20,y+40,x+20,y+60);
 
 //eyes
 strokeWeight(4);
 stroke(70,150,50);
 ellipseMode(CENTER);
 fill(mouseX,mouseY,mouseX/5);
 ellipse(x-40,y-30,30,30);
 ellipseMode(CENTER);
 fill(mouseX/3,mouseY*2,mouseX/5);
 ellipse(x+40,y-30,30,30);
 
 //ears
 fill(20,40,50);
 stroke(0);
 triangle(x-90,y-50,x-130,y-140,x-55,y-85);
 triangle(x+90,y-50,x+130,y-140,x+55,y-85);
}
Re: beginner:conditionals not fully respected
Reply #2 - Mar 28th, 2010, 3:30am
 
I haven't checked through all your code, but this is a common enough issue for beginners.  

Let's assume speed = 10
You reach a frame where y=600.
On the next frame y+speed=610 so your condition is triggered and you multiply speed by -1.
However you also add gravity to y.
For the sake of argument let's say this just adds 1 to y.
So y is now equal to 611 and speed is -10.
What happens on the next frame?
y + speed == 611 -10 = 601...
So y is still greater than 600, the condition is still true and speed gets multiplied by -1 again... i.e. In the next frame it will add 10 to y bringing you back to the situation where y = 611 + gravity = 612...

The solution seems crude but is essential.  As well as multiplying speed by -1 you have to reset the position to the boundary.  So:

Code:
if (y>600){
   y = 600; // this ensures that on the next frame this condition isn't triggered again
   speed=speed* -1;
   s=280;
 }
Re: beginner:conditionals not fully respected
Reply #3 - Mar 28th, 2010, 7:59am
 
aha! this makes sence. thank you for the reply.
I thought it was something like that but I couldn't quite explain why.

Re: beginner:conditionals not fully respected
Reply #4 - Mar 28th, 2010, 9:09am
 
I still do have a related question though. then I'm back on track.

right now my little creature is bouncing around the screen. and I've added some dampening so that in time it bounces less and less till it comes to a full stop.

however it's the full stop thing that isn't happening. it keeps bouncing on very low values after a while.

I know that I probably have to add an if statement
that says when "speedY" reaches a certain value speedY=0

the problem with this is that if I do that. it interferes with the code where I reverse the polarity of a number.

how should I best tackle this problem?
I've added the code here.

Code:
float x;
float y;
float speedy=15;
float speedx=5;
float gravity=0.3;
float s=250;
float s2=250;

void setup (){
 size(700,700);
 x=width/2;
 y=500;
 frameRate(60);

}
void draw(){
 background(255);
 y=y+speedy;
 x=x+speedx;
 speedy=speedy+gravity;

 
 if (y>600){
   y=600;
   speedy=speedy* -0.8;
   s=280;
   s2=210;
 }
 
 if (x>600){
   x=600;
   speedx=speedx* -0.8;
   
   s2=270;
 }
 if (x<0){
   x=0;
   speedx=speedx* -0.8;
 }
 
 speedy=constrain(speedy,-20,20);
 speedx=constrain(speedx,-5,5);

 s=s-1.5;
 s2=s2+2;
 s=constrain(s,250,280);
 s2=constrain(s2,210,250);


 //head
 smooth();
 strokeWeight(6);
 stroke(0);
 fill(255);
 ellipseMode(CENTER);
 ellipse(x,y,s,s2);

 //wiskers
 line(x-20,y+60,x+20,y+40);
 line(x-20,y+40,x+20,y+60);

 //eyes
 strokeWeight(4);
 stroke(70,150,50);
 ellipseMode(CENTER);
 fill(mouseX,mouseY,mouseX/5);
 ellipse(x-40,y-30,30,30);
 ellipseMode(CENTER);
 fill(mouseX/3,mouseY*2,mouseX/5);
 ellipse(x+40,y-30,30,30);

 //ears
 fill(20,40,50);
 stroke(0);
 triangle(x-90,y-50,x-130,y-140,x-55,y-85);
 triangle(x+90,y-50,x+130,y-140,x+55,y-85);

}






Re: beginner:conditionals not fully respected
Reply #5 - Mar 28th, 2010, 3:15pm
 
You can use abs() to test whether speedy is within a certain threshold:

Code:
  if(abs(speedy) < 0.1){
   speedy = 0;
 }


See the reference to see why this works Wink

You might also want to add another factor to control speed, namely friction: you'd normally set this to something around 0.99; and it's a good idea to apply gravity, friction etc. to speedx/y before applying it to the x/y position:

Code:
void draw(){
 background(255);
 
 speedy += gravity;  
 speedy *= friction;
 speedx *= friction;

 
 x += speedx;  
 y += speedy;

 // etc...
}


Note that:

 speedy += gravity;

is a shortcut way of writing:

 speedy = speedy + gravity;

One final piece of advice: avoid 'magic numbers'.  If -0.8 is the value to apply when it bounces then set this to a variable called 'bounce' (or something else that describes it, just like you've done with gravity)...  It makes it easier to understand what the number represents and you have the advantage of being able to change it in just one place...
Re: beginner:conditionals not fully respected
Reply #6 - Mar 29th, 2010, 1:52pm
 
yes I got it to work now.
the main problem was that , like you said, gravity and speed was set after the X Y position. without changing that, the (abs) code gave weird results.
why is that exactly? well...it's kinda logical when I think about it.

also added the friction. works great.  thanks!

and I just arrived at the chapter in the book where they explain the simplifed notiation of x=x+1 etc  Smiley

many thanks for your help.
Page Index Toggle Pages: 1