Loading...
Logo
Processing Forum
Hi Guys. I'm working on an n-player pong, in which I need to dynamically generate paddles for each player. I'm currently translating the coordinate system to the center (width/2, height/2), and basing all coordinates off of that origin (to make it more similar to a normal coordinate grid). Then, I generate coordinates for each of the end points based on the number of players, by rotating a radius around the origin. That portion works fine, and adds to an ArrayList with each of the points in the form of a PVector in that arraylist.

I then (attempt to) generate paddles.

Paddles are generated by using the same method I used to create endpoints, but providing a smaller radius (so each coordinate endpoint is inside the polygon generated by the boundaryGen function. So, here's the paddle class:

Copy code
  1. class Paddle {

  2.   PVector endPointA;
  3.   PVector endPointB;
  4.   PVector smallPosA;
  5.   PVector smallPosB;
  6.   PVector midpoint;
  7.   PVector slope;

  8.   Paddle(PVector point1, PVector point2, int rIndexI) {
  9.     
  10.     endPointA = new PVector(point1.x, point1.y);
  11.     endPointB = new PVector(point2.x, point2.y);
  12.     
  13.     slope = new PVector(endPointB.x - endPointA.x,endPointB.y - endPointA.y);
  14.       slope.setMag(1);
  15.       slope.mult(5);

  16.     midpoint = new PVector((endPointA.x + endPointB.x )/2, (endPointA.y + endPointB.y)/2);
  17.     
  18.     smallPosA = midpoint;
  19.     smallPosB = midpoint;
  20.     smallPosA.add(slope);
  21.     smallPosB.add(slope);
  22.   }

  23.   void display(int i) {

  24.     line (smallPosA.x, smallPosA.y, smallPosB.x, smallPosB.y);

  25.   }  
  26. }
So, the paddle class had endPointA and endPointB which define the line that bounds the axis that the paddle can move around. Those points are passed from the paddle edge generation function, as defined above. If needed, I can post that as well.

So, then it defines a vector as a slope between those two points. That slope seems to work okay. A midpoint is then generated between the two endpoints, to which I figured I'd add or subtract the slope (multiplied by a width) to the midpoint, which should hopefully generate two points that are slightly away from the midpoint. The problem is, those points are somehow equal when the time to create the line comes around, and it becomes just a point (which is not what I want to happen). I've been gnawing at this for 5 hours and I still haven't been able to figure out what is wrong. I'd really appreciate any pointers.

Thanks,
Hades

EDIT: The main class is below:

Copy code
  1. ArrayList<PVector> bPoints = new ArrayList<PVector>(); //boundary Points arraylist
  2. ArrayList<Paddle> paddles = new ArrayList<Paddle>();

  3. final int numberOfSides = 8;
  4. final int buffer = 8; //distance to keep away from the sides
  5. final float innerBuffer = .95; //modifier for the distance the paddles are away from the boundary
  6. final float pAngle = (180*(numberOfSides-2))/numberOfSides; //inner angle between the shape
  7. final float innerAngle = 360/numberOfSides; //distance to rotate the coordinate system to generate each point

  8. void setup() {

  9.   size (650, 650);

  10.   bPoints = boundaryGen();
  11.   paddles = makePaddles();
  12. }

  13. float smallerOf(float one, float two) {
  14.   if (one > two) return two;
  15.   else return one;
  16. }

  17. ArrayList<PVector> boundaryGen () {

  18.   pushMatrix();
  19.   translate(width/2, height/2);  

  20.   float degrees = 0;
  21.   float degreesToAdd = 360/numberOfSides;
  22.   float radius = smallerOf(width/2-buffer, height/2 -buffer);

  23.   ArrayList<PVector> temp = new ArrayList<PVector>();

  24.   for (int i = 0; i < numberOfSides; i++) {
  25.     temp.add(new PVector(radius*cos(radians(degrees)), radius*sin(radians(degrees))));
  26.     degrees += degreesToAdd;
  27.   }

  28.   popMatrix();

  29.   return temp;
  30. }

  31. ArrayList<Paddle> makePaddles () {

  32.   pushMatrix();
  33.   translate(width/2, height/2);

  34.   float degrees = 0;
  35.   float degreesToAdd = 360/numberOfSides;
  36.   float radius = smallerOf(width/2-buffer, height/2 -buffer)*innerBuffer;
  37.   ArrayList<PVector> points = new ArrayList<PVector>();
  38.   ArrayList<Paddle> paddlesTemp = new ArrayList<Paddle>();

  39.   //makes a smaller set of coordinates inside
  40.   for (int i = 0; i < numberOfSides; i++) {
  41.     points.add(new PVector(radius*cos(radians(degrees)), radius*sin(radians(degrees))));
  42.     degrees += degreesToAdd;
  43.   }

  44.   popMatrix();

  45.   //adds to the paddlesTemp array for each point on the previously generated array
  46.   for (int i = 0; i < points.size(); i++) {
  47.     paddlesTemp.add(new Paddle(points.get(i%points.size()), points.get((i+1)%points.size()), i));
  48.   }  

  49.   return paddlesTemp;
  50. }

  51. void draw() {

  52.   background(100);

  53.   //bunch of drawing stuff goes here
  54.   translate(width/2, height/2);
  55.   stroke(0);  
  56.   noFill();
  57.   strokeWeight(2);
  58.   stroke(color(100, 255, 150));
  59.   //stroke(random(150), random(150), random (150));

  60.   //create the outside border
  61.   beginShape(); 
  62.   {

  63.     for (int i  = 0; i < bPoints.size(); i++) {
  64.       vertex(bPoints.get(i).x, bPoints.get(i).y);
  65.     }
  66.     //need to manually assign the last/first vertex again or the loop won't be closed
  67.     vertex(bPoints.get(0).x, bPoints.get(0).y);
  68.   }  
  69.   endShape();

  70.   //reprint the paddles every round
  71.   for (int i = 0; i < paddles.size(); i++) {    
  72.     paddles.get(i).display(i);
  73.   }

  74. }
Note: I've removed a good bit of code from this program that isn't relevant to the question, including collision and the ball.

Replies(3)

This is a PVector FAQ. The problem are these lines:
Copy code
  1.     smallPosA = midpoint;
  2.     smallPosB = midpoint;
  3.     smallPosA.add(slope);
  4.     smallPosB.add(slope);
You are passing a reference of the midpoint PVector to both smallPosA and smallPosB. So both are pointing to the same PVector. Second, you add slope to both. So there are actually two problems, but the reference problem is probably what's the main problem for you. There are two possible solutions.

Solution 1
Copy code
  1.     smallPosA = midpoint.get();
  2.     smallPosB = midpoint.get();
  3.     smallPosA.sub(slope);
  4.     smallPosB.add(slope);
Solution 2
Copy code
  1.     smallPosA = PVector.sub(midpoint, slope);
  2.     smallPosB = PVector.add(midpoint, slope);
Ah, alright. Thank you amnon, you're a genius.

The reference bit makes sense now. I suppose it's just one of those things with java/processing I need to keep track of. Thanks! I'm guessing by doing a .get() on the midpoint, you're actually creating a new instance of the midpoint, not just a reference to it? And thanks for pointing out the add bug. I think that one was induced by copy/paste.

Note: To anyone reading this in the future, don't forget to use .setMag to limit the size of the vector.
Indeed, get() creates an individual, separate object instance instead of just a reference to the original.

So you get a second TV, instead of just a second remote to the original TV.