OK!
I have made some minor tweaks (see code below).
-
Changed the keys being used so the three players don’t get tangled up. q/w for one, o/p for another, and v/b for the third.
-
Made the paddles rectangular and simpler.
-
Reduced the colours to get closer to the aesthetics of a Cathode Ray Tube.
Next we need to avoid the paddles overlapping… any ideas?
Then we need to discuss how to add skill, variability and unpredictability to the shots. Skill, variability and unpredictability are probably all the same thing. I will list some options: The angle of reflection is proportional to the distance from the centre of the paddle, so the ball bounces more towards the ends of the paddle. The approach I like might not be possible, but let’s see…
If the paddle is moving in the direction of the cyan arrow then the reflection of the ball is as cyan. If the paddle is moving in the direction of the magenta arrow then the reflection of the ball is as magenta. What do you think?
// Pong in a Triangle (2D) for 3 players
// USE q/w and v/b and o/p respectively
// see https://discourse.processing.org/t/triangular-pong-game/42548/16
// triangle data
PVector[] listCorners = new PVector[3];
// Paddle data
Paddle[] listPaddles = new Paddle[3];
// we need this array to allow for multiple keys pressed at the same time
// cf. https://discourse.processing.org/t/keypressed-for-multiple-keys-pressed-at-the-same-time/18892
boolean[] moveKeys = new boolean[256];
// --------------------------------------------------------------------
// Core functions
void setup() {
size( 800, 800);
// make corners
for (int i = 0; i < 3; i++) {
float angle = i * (TWO_PI/3.0) + TWO_PI/20.0;
float x1= width/2+cos(angle) * ((height / 2) -60);
float y1= height /2+sin(angle) * ((height / 2) -60);
listCorners [i] = new PVector( x1, y1) ;
}
// Make The paddles / players: the corners between the paddle moves and its 2 keys
listPaddles[0] = new Paddle ( listCorners [0], listCorners [1], 'b', 'v', color(255, 255, 255) );
listPaddles[1] = new Paddle ( listCorners [1], listCorners [2], 'q', 'w', color(255, 255, 255) );
listPaddles[2] = new Paddle ( listCorners [2], listCorners [0], 'o', 'p', color(255, 255, 255) );
} // setup
void draw() {
background(0);
// show game field
showGameField();
// manage paddles
for (Paddle pd : listPaddles) {
pd.checkKeys();
pd.display();
}//for
} // draw
// --------------------------------------------------------------------
// Input functions
void keyPressed() {
if (key>32&&key<256)
moveKeys[key] = true;
}//func
void keyReleased() {
if (key>32&&key<256)
moveKeys[key] = false;
}//func
// --------------------------------------------------------------------
// Other functions
void showGameField() {
// show triangle
stroke(0);
noFill();
triangle (listCorners[0].x, listCorners[0].y,
listCorners[1].x, listCorners[1].y,
listCorners[2].x, listCorners[2].y);
fill(255, 2, 2);//red
for (PVector pv : listCorners) {
ellipse(pv.x, pv.y, 12, 12);
}//for
}//func
// ====================================================================
class Paddle {
final PVector from, to; // its 2 corner data
final char leftC, rightC;
float amt=0.5;
final float speed1 = 0.01;
final float amtHalfPaddleWidth = .042;
final color colorMy;
int score=0;
// -----------------
//constr
Paddle(PVector f_, PVector t_,
char left_, char right_,
color col_) {
from = f_;
to = t_;
leftC = left_;
rightC = right_;
colorMy=col_;
}//constr
// -----------------
void display() {
// display Paddle
//calc start and end of paddle line
float x1=lerp(from.x, to.x, amt-amtHalfPaddleWidth);
float y1=lerp(from.y, to.y, amt-amtHalfPaddleWidth);
float x2=lerp(from.x, to.x, amt+amtHalfPaddleWidth);
float y2=lerp(from.y, to.y, amt+amtHalfPaddleWidth);
// draw paddle
strokeWeight(12);
strokeCap(PROJECT);
stroke(colorMy);
line (x1, y1,
x2, y2 );
//quad (x1, y1, x1+2, y1,
// x2, y2, x2+2, y2 );
strokeWeight(1);
}//func
void checkKeys() {
// check keys / move paddle
if (moveKeys[leftC]) {
amt-=speed1;
} else if (moveKeys[rightC]) {
amt+=speed1;
}
// check values
if (amt-amtHalfPaddleWidth<0)
amt=amtHalfPaddleWidth;
if (amt+amtHalfPaddleWidth>1)
amt=1-amtHalfPaddleWidth;
}//func
//
} //class
//