Loading...
Logo
Processing Forum
Hi, 

I've been googling and searching these forums for about an hour and I haven't been able to solve this problem.

I have a small "car" that moves around the screen and I want it to hit a "grape". I would like that grape to disappear and reappear somewhere else. 

I am new to processing and I don't really understand the differences between processing and processing.js but if I could find a tutorial like this one for Processing, that would be amazing!

My code is long and I know that this topic must have been covered already in a clear and concise manner, but I can not find it. 

Let me know if I need to post my code. 

Thanks!

Replies(17)

You probably should post your code.

You know where the car is.
You know where the grape is.
You can determine if the car is close enough to the grape.
When the car is close enough to the grape, you can move the grape by changing where the grape is.

I can't find where you deal w/ user input in your game!

You have the methods which update the object's variables related to its position, 
but no keyPressed() nor mousePressed() and other such callback event functions!

Anyways. here's a very simple movement online example:

That was a mistake of copy/paste. I do have that code in there.

Here is my best attempt so far to make this work.  Within the draw();

  for (int i = 0; i < 10; i++) {
    if (xposCar == xposGrape && yposCar == yposGrape) {
      newGrape.tele();
    }
  }

And here is the tele() function within the Grape Class.

void tele() {
    xpos = int(random(width));
    ypos = int(random(height));
    xposGrape = xpos;
    yposGrape = ypos;
   }
}

Nothing happens when the car goes over the grape. I have to stop now and go find some perspective.
Your conditional line ->  if (xposCar == xposGrape && yposCar == yposGrape) { // ...
would only work if the top-left coordinates of Car were exactly the same as Grape's.

Problem is, both Car & Grape represent 2D objects. That is, they have both width & height.
But you were checking collision as if they were a 1D dot!      Obviously, they have lotsa dots!  

Some online examples for squared-shape intersection:

Thanks for your suggestions GoToLoop. I was not able to understand any of the examples you posted. However, I had not known of that website previously, so thank you for the new resource. :)

Using your suggestions (obvious as it is to me now) I was able to get this sketch working. It may be ugly, but it feels good to have made *something* work. :)

I am, of course, open to any suggestions that would make this code more efficient, readable etc. 

Another way to do this is to use the dist( ) function. 
You know where the car is and where the grape is. 
You know how big the car is and how big the grape is.
if the car gets too close to the grape, they collide.

float d = dist( carX, carY, grapeX, grapeY );
if ( d <  some variable that is the minimum safe distance to avoid a collision)
   move the grape

One advantage of this approach is that you can make the game harder by altering the minimum distance variable every time they squash some number of grapes.

Hope this helps

Thank you for the the advice and resources, all. I have been trying to improve the functionality of this "car" by having it move diagonally. 

I found this example of diagonal movement and tried to apply it to my sketch without success. What am I missing? The car does not move at all now. 

EDIT: It might help to include my sketch. :)

Also, can anyone explain or point to an article or previous thread regarding the use of 'static' and 'final' in a lot of sketch examples? I do not understand any of javascript and can not make out why people are using these.

A few specific questions then:

  1. Why doesn't my car move at all?
  2. What is the advantage of using 'static' and 'final' when declaring variables?
  3. What is the disadvantage of not using them?
  4. In the above example of diagonal movement on line 88 and other if statements, the author does not use the curly brackets in his statements.  Are these optional or is it a special case when working with boolean variables? 
  5. His variables NORTH, SOUTH, EAST and WEST are capitalized. This seems to go against the conventions I have been learning for variable/function capitalization. Is this a mistake or an exception to the rule? 

Thanks!





Hello,

here comes a working version........


one problem we had was that you didn't call the move-methods of the car. No surprise the car didn't move

Another problem was that you had global vars

Copy code
  1. float xposGrape;
  2. float yposGrape;
  3. float xposCar;
  4. float yposCar;

that were part of the class.

I also made a better if-clause for collision.

On collision, the old grape gets over written with a new one (new color, new pos)

I also made the grape move for test purposes. Otherwise we don't have collisions.


your questions
1. see above
2. final means make a var a constant (then it is written in capitals, see 5)
3. when you know a var is const the code is better readable. You know the value stays put.
4. curly brackets are used to make a block of lines { } - all lines within that block belong to if. When there's only one line, the { } are not needed.
5. see 2


Good luck to you!


Greetings, Chrisir   


Copy code
  1. Car myCar;
  2. Grape newGrape;
  3. void setup() {
  4.   size(500, 500);
  5.   myCar = new Car();
  6.   newGrape = new Grape();
  7. }
  8. void draw() {
  9.   background(255);

  10.   newGrape.ypos+=1.6;
  11.   if (newGrape.ypos>height)
  12.     newGrape.ypos=0;

  13.   if (myCar.xpos >= newGrape.xpos-10 && myCar.ypos >= newGrape.ypos-10 &&
  14.     myCar.xpos <= newGrape.xpos+10 && myCar.ypos <= newGrape.ypos+10 ) {
  15.     println ("hit");
  16.     newGrape = new Grape();
  17.   }
  18.   else {
  19.     newGrape.display();
  20.   }
  21.   myCar.moveRight();
  22.   myCar.moveUp();
  23.   myCar.display();
  24. }
  25. // ===============================================
  26. class Car {
  27.   color c;
  28.   float xpos;
  29.   float ypos;
  30.   float speed;
  31.   int sizeW = 20;
  32.   int sizeH = 10;
  33.   float topBorder = ypos - sizeW/2;
  34.   float bottomBorder = ypos + sizeW/2;
  35.   float rightBorder = xpos + sizeH/2;
  36.   float leftBorder = xpos - sizeH/2;
  37.   Car() {
  38.     c = color(175);
  39.     xpos = width/2;
  40.     ypos = width/2;
  41.     speed = 5;
  42.   }
  43.   void display() {
  44.     rectMode(CENTER);
  45.     stroke(0);
  46.     fill(c);
  47.     rect(xpos, ypos, 20, 10);
  48.   }
  49.   void moveRight() {
  50.     xpos = xpos + speed;
  51.     if (xpos > width) {
  52.       xpos = 0;
  53.     }
  54.   }
  55.   void moveLeft() {
  56.     xpos = xpos - speed;
  57.     if (xpos < 0) {
  58.       xpos = width;
  59.     }
  60.   }
  61.   void moveUp() {
  62.     ypos = ypos - speed;
  63.     if (ypos < 0) {
  64.       ypos = height;
  65.     }
  66.   }
  67.   void moveDown() {
  68.     ypos = ypos + speed;
  69.     if (ypos > height) {
  70.       ypos = 0;
  71.     }
  72.   }
  73. }

  74. // ===============================================

  75. class Grape {
  76.   color c;
  77.   float xpos;
  78.   float ypos;
  79.   //  float speed;
  80.   Grape() {
  81.     c = color(random(216), 44, 208);
  82.     xpos = int(random(width));
  83.     ypos = int(random(height));
  84.     //    speed = 5;
  85.   }
  86.   void display() {
  87.     rectMode(CENTER);
  88.     stroke(0);
  89.     fill(c);
  90.     rect(xpos, ypos, 10, 10);
  91.   }
  92. }
  93. // ===============================================

Thanks for this response! A very interesting rendition of the 'game', but not what I am trying to accomplish. :)

I would like to control the car with the arrows, but have the functionality to move diagonally as well as up, down, left and right. 

The vars xposGrape, et al were a holdover from my old collision detection. 

Thank you for the if statement collision solution. This is similar to my first attempt at this, I see how you did the calculations there to make it work though. :)

I am confused about your observation that I did not call a move command. 

My code contains the following:

void draw() {
  background(255);

  newGrape.display(); 
  myCar.display();
  myCar.move();
}

and in the car Class:

void keyPressed() {
    
    int k = keyCode;
   
    if (k == ENTER | k == RETURN)
      speed = speed + 1;
    else if (k == ' ')   
      speed = speed - 1;
  
    else if (k == UP)    up    = true;
    else if (k == DOWN)  down  = true;
    else if (k == LEFT)  left  = true;
    else if (k == RIGHT) right = true;
  }
  
  void keyReleased() {
    int k = keyCode;
    
    if      (k == UP)    up    = false;
    else if (k == DOWN)  down  = false;
    else if (k == LEFT)  left  = false;
    else if (k == RIGHT) right = false;
    
  }
  
  void move() {
    if (up)    ypos -= speed;
    if (down)  ypos += speed;
    if (left)  xpos -= speed;
    if (right) xpos += speed;
  }
}

My assumption is that I need some kind of conditional in the draw() block to call the myCar.move() when any key is pressed? I tried some versions of this that did not work and the example I was pulling from only put the move() function in the draw() block. 

I'm honestly just blindly stumbling around without any real experience for debugging so I really appreciate all the help!

Thank you for clearing up the other questions. Some follow up re: final and static.

  1. Sometimes I see only 'final' or only 'static' and other times both. What is the difference? How does one know when to use what combination?
  2. If I am working with a variable that I know will not change is it best to use these terms de facto?
Thanks.


I am very sorry, I overlooked your new version on openprocessing.org and was referring to the old version above

Hello,

In the version on openprocessing.org, your car moves.
But not diagonally.

Is your expectation that the car moves diagonally when hold cursor up and cursor right simultaneously?
Hm.... not sure that works at all
Maybe processing can only check one key at a time?


keyPressed inside a class
A problem could be that you have the function
Copy code
  1. void keyPressed() {
in the car class.
It must be outside all classes.
Instead of    up = true; you need then probably    myCar.up = true;

Same goes for
Copy code
  1.   void keyReleased() {
not within the class please.


Logical OR
Also
Copy code
  1.     if (k == ENTER | k == RETURN)
should be
Copy code
  1.     if (k == ENTER || k == RETURN)
with a double ||
Should give you an error.

Greetings, Chrisir    



could you post your entire code please?


check out V.2 on openprocessing

Heading out to work, so I will have to look at this when I get back. Thanks. 

here you go...

problems were:
  • you had the var speed declared on a global level (before setup()) and also in the class; only on a global level it was set to 7, the var speed in the class over ruled that and this speed was 0. So you ended up adding 0 to the position of the car. Remeber to put all vars in the class that belong to it. Same goes for position and Borders.
  • keyPressed and KeyReleased don't belong in the class. They are called automatically but can only be called automatically by processing when they are not in the class but top level in the program (like setup() and draw()).


Copy code
  1. //    Car Game v.3
  2. //
  3. Car myCar;
  4. Grape newGrape;
  5. //
  6. // =========================================================
  7. void setup() {
  8.   size(500, 500);
  9.   myCar = new Car();
  10.   newGrape = new Grape();
  11. }
  12. void draw() {
  13.   background(255);
  14.   //
  15.   newGrape.display();
  16.   myCar.display();
  17.   myCar.move();
  18.   //
  19.   if (rectangle_collision (myCar.xpos, myCar.ypos, myCar.sizeW, myCar.sizeH,
  20.   newGrape.xpos, newGrape.ypos, newGrape.sizeW, newGrape.sizeH)) { 
  21.     // println ("hit");
  22.     newGrape = new Grape();
  23.   }
  24. }
  25. //
  26. boolean rectangle_collision(float x_1, float y_1, float width_1, float height_1,
  27. float x_2, float y_2, float width_2, float height_2)
  28. // from PhiLho
  29. {
  30.   return !(x_1 > x_2+width_2 || x_1+width_1 < x_2 || y_1 > y_2+height_2 || y_1+height_1 < y_2);
  31. }
  32. // =========================================================
  33. void keyPressed() {
  34.   int k = keyCode;
  35.   if (k == ENTER | k == RETURN)
  36.     myCar.speed = myCar.speed + 1;
  37.   else if (k == ' ') 
  38.     myCar.speed = myCar.speed - 1;
  39.   else if (k == UP)     myCar.up    = true;
  40.   else if (k == DOWN)   myCar.down  = true;
  41.   else if (k == LEFT)   myCar.left  = true;
  42.   else if (k == RIGHT)  myCar.right = true;
  43. }
  44. void keyReleased() {
  45.   int k = keyCode;
  46.   if      (k == UP)     myCar.up    = false;
  47.   else if (k == DOWN)   myCar.down  = false;
  48.   else if (k == LEFT)   myCar.left  = false;
  49.   else if (k == RIGHT)  myCar.right = false;
  50. }
  51. // =========================================================
  52. class Car {
  53.   color c;
  54.   float xpos;
  55.   float ypos;
  56.   float speed=7;
  57.   int sizeW = 50;
  58.   int sizeH = 50;
  59.   boolean up, down, left, right;
  60.   float topBorderC;
  61.   float bottomBorderC;
  62.   float rightBorderC;
  63.   float leftBorderC;
  64.   Car() {
  65.     c = color(175);
  66.     xpos = width/2;
  67.     ypos = width/2;
  68.     setBordersC() ;
  69.   }
  70.   void setBordersC() {
  71.     topBorderC = ypos - sizeW/2;
  72.     bottomBorderC = ypos + sizeW/2;
  73.     rightBorderC = xpos + sizeH/2;
  74.     leftBorderC = xpos - sizeH/2;
  75.   }
  76.   void display() {
  77.     rectMode(CENTER);
  78.     stroke(0);
  79.     fill(c);
  80.     rect(xpos, ypos, sizeW, sizeH);
  81.   }
  82.   void move() {
  83.     if (up)    ypos -= speed;
  84.     if (down)  ypos += speed;
  85.     if (left)  xpos -= speed;
  86.     if (right) xpos += speed;
  87.   }
  88. }
  89. // =========================================================
  90. class Grape {
  91.   color c;
  92.   float xpos;
  93.   float ypos;
  94.   int sizeW = 10;
  95.   int sizeH = 10;
  96.   float topBorderG;
  97.   float bottomBorderG;
  98.   float rightBorderG;
  99.   float leftBorderG;
  100.   //  float speed;
  101.   Grape() {
  102.     c = color(random(180, 255), 44, 208);
  103.     xpos = int(random(width));
  104.     ypos = int(random(height));
  105.     setBordersG();
  106.   }
  107.   void setBordersG() {
  108.     topBorderG = ypos - sizeW/2;
  109.     bottomBorderG = ypos + sizeW/2;
  110.     rightBorderG = xpos + sizeH/2;
  111.     leftBorderG = xpos - sizeH/2;
  112.   }
  113.   void display() {
  114.     rectMode(CENTER);
  115.     stroke(0);
  116.     fill(c);
  117.     setBordersG();
  118.     rect(xpos, ypos, sizeW, sizeH);
  119.   }
  120.   void tele() {
  121.     xpos = int(random(width));
  122.     ypos = int(random(height));
  123.   }
  124. }
  125. // =========================================================

A little late, but here's my reply:
  1. Sometimes I see only 'final' or only 'static' and other times both. What is the difference? How does one know when to use what combination?
  2. If I am working with a variable that I know will not change is it best to use these terms de facto?
You can see both Java keywords @ Processing's reference:
http://processing.org/reference/final.html
http://processing.org/reference/static.html

The static keyword has a very limited use in Processing, so you don't need to worry about that too much. 
Just take notice that only field variables can be static. Local ones can't.
Its advantage is that we can access a field or a method from a class w/o instantiating it 1st if they are static!
Also, a static field variable is shared among all instantiated objects from a class. And thus avoids redundancy.

The final keyword is very handy for someone examining your source code for debugging.
For it's assured its stored value won't change later once set. So it's 1 less problem to worry about! 

And if it happens a field variable be of a primitive type as well, Java compiler replaces all occurrences of it
for its real literal constant value, thus boosting performance a tiny little! 

And if a primitive field variable is final, it also makes sense to declare it static.
Since it's a constant, there's no need to make redundant copies of it when its class is instantiated. 

And as you've noticed already, it's a Java's convention to make final field labels be in all caps.

And sorry for my example below:
http://studio.processingtogether.com/sp/pad/export/ro.9bY07S95k2C2a/latest
wasn't using 100% Java's naming convention yet.

It's an old code example and I was still in transition to be fully compliant for it! 
It's correct now. Check that out! 
Thanks again for taking time to look through my code. All of these suggestions and coaching has really been a help. 


Your code was a little buggy in that it made the grape redraw sometimes when the car was not over it and it did not redraw when the car was over it. It seemed to depend on the direction that the grape was approach. 

However, this was a fun learning experience to debug and fix. I used your boolean idea and tweaked around with it until it finally worked. 

------

Protocol question:

Is it better to keep posting updates and questions related to this sketch in the same thread or start a new thread for each "version" (theoretically each version comes with it's own special problem to solve).

Thanks again! :)


Generally, keep them in the same thread, while reposting your current progress like you did!