//global variables
//positioning and movement-based variables for players and ball
float redPosX, redPosY, goalsRed, redVelX, redVelY;
float bluePosX, bluePosY, goalsBlue, blueVelX, blueVelY;
float ballPosX, ballPosY, ballVelX, ballVelY;
//variables holding goal positions
int redGoalX1=20;
int redGoalX2=30;
int redGoalY1=120;
int redGoalY2=280;
int blueGoalX1=370;
int blueGoalX2=380;
int blueGoalY1=120;
int blueGoalY2=280;
//score-keeping variables
int redScore=0;
int blueScore=0;
//variables used for fine-tuning key game elements
int playerWidth=25;
int ballWidth=15;
int playerAccel=1;
float kickStrength=1.2;
float fric=0.2;
void setup()
{
size(400, 400);
frameRate(60);
//the game should be reset when the program starts
resetGame();
}
void draw()
{
//check if the ball hit a goal
checkGoals();
//if a key is being pressed, check further to see what action needs to be done in response
if (keyPressed)
movePlayers();
//check if players have collided
checkPlayerCollision();
//creates drag on players so they slide to a stop
friction();
//after movement calculations are done, check if out of bounds before updating entity positions
updateEntities();
background(0, 100, 50);
//draw the players for this frame
drawEntities();
//draw scoreboards
drawScoreboards();
}
//resets the field conditions and places the ball at a random Y-coordinate in the centre of the field
void resetGame()
{
//move red back to starting pos
redPosX=60;
redPosY=200;
//move blue back to starting pos
bluePosX=340;
bluePosY=200;
//move ball back to starting pos
ballPosX=200;
ballPosY=random(1, 400);
//reset velocities
redVelX=0;
redVelY=0;
blueVelX=0;
blueVelY=0;
ballVelX=0;
ballVelY=0;
}
//applies drag on the players and ball
void friction()
{
//if objects have velocity, slow them down, but not past 0 velocity
//red friction
if (redVelX!=0)
{
if (redVelX<0)
redVelX+=fric;
else if (redVelX>0)
redVelX-=fric;
}
if (redVelY!=0)
{
if (redVelY<0)
redVelY+=fric;
else if (redVelY>0)
redVelY-=fric;
}
//blue friction
if (blueVelX!=0)
{
if (blueVelX<0)
blueVelX+=fric;
else if (blueVelX>0)
blueVelX-=fric;
}
if (blueVelY!=0)
{
if (blueVelY<0)
blueVelY+=fric;
else if (blueVelY>0)
blueVelY-=fric;
}
//ball friction
if (ballVelX!=0)
{
if (ballVelX<0)
ballVelX+=fric;
else if (ballVelX>0)
ballVelX-=fric;
}
if (ballVelY!=0)
{
if (ballVelY<0)
ballVelY+=fric;
else if (ballVelY>0)
ballVelY-=fric;
}
}
//checks whether or not the ball has hit a goal
void checkGoals()
{
//check red goal
if (ballPosX>redGoalX1&&ballPosX<redGoalX2&&ballPosY>redGoalY1&&ballPosY<redGoalY2)
{
blueScore++;
println("Blue scores!"+redScore+"-"+blueScore);
resetGame();
}
//check blue goal
else if (ballPosX>blueGoalX1&&ballPosX<blueGoalX2&&ballPosY>blueGoalY1&&ballPosY<blueGoalY2)
{
redScore++;
println("Red scores!"+redScore+"-"+blueScore);
resetGame();
}
}
//draws squares on the screen to show each player's current score
void drawScoreboards()
{
rectMode(CENTER);
for (int tally=1; tally<=blueScore; tally++)
{
fill(0, 0, 255);
rect(10, 10*tally, 5, 5);
}
for (int tally=1; tally<=redScore; tally++)
{
fill(255, 0, 0);
rect(390, 10*tally, 5, 5);
}
}
//handles player controls and movement
void movePlayers()
{
/*
HANDLE RED MOVEMENT
*/
if (keyCode==UP)
{
redVelY-=playerAccel;
} else if (keyCode==DOWN)
{
redVelY+=playerAccel;
} else if (keyCode==LEFT)
{
redVelX-=playerAccel;
} else if (keyCode==RIGHT)
{
redVelX+=playerAccel;
}
//caps the player's maximum speed
if (redVelX>6)
redVelX=6;
else if (redVelX<-6)
redVelX=-6;
if (redVelY>6)
redVelY=6;
else if (redVelY<-6)
redVelY=-6;
/*
HANDLE BLUE MOVEMENT
*/
if (key=='w')
{
blueVelY-=playerAccel;
} else if (key=='s')
{
blueVelY+=playerAccel;
} else if (key=='a')
{
blueVelX-=playerAccel;
} else if (key=='d')
{
blueVelX+=playerAccel;
}
//caps the player's maximum speed
if (blueVelX>6)
blueVelX=6;
else if (blueVelX<-6)
blueVelX=-6;
if (blueVelY>6)
blueVelY=6;
else if (blueVelY<-6)
blueVelY=-6;
}
//calculates the position of the red player, blue player, and ball in the next frame
void updateEntities()
{
/*
UPDATE RED PLAYER POSITIONS
*/
if (redPosX+redVelX>width)
redVelX=0;
if (redPosX+redVelX<0)
redVelX=0;
if (redPosY+redVelY>height)
redVelY=0;
if (redPosY+redVelY<0)
redVelY=0;
redPosX=redPosX+redVelX;
redPosY=redPosY+redVelY;
/*
UPDATE BLUE PLAYER POSITIONS
*/
if (bluePosX+blueVelX>width)
blueVelX=0;
if (bluePosX+blueVelX<0)
blueVelX=0;
if (bluePosY+blueVelY>height)
blueVelY=0;
if (bluePosY+blueVelY<0)
blueVelY=0;
bluePosX=bluePosX+blueVelX;
bluePosY=bluePosY+blueVelY;
/*
UPDATE BALL POSITION
*/
//check if the ball has been kicked
checkBallCollision();
//ball will reverse its velocity values when hitting the edge of the screen, causing it to "bounce"
if (ballPosX+ballVelX>width)
ballVelX=-ballVelX;
if (ballPosX+ballVelX<0)
ballVelX=-ballVelX;
if (ballPosY+ballVelY>height)
ballVelY=-ballVelY;
if (ballPosY+ballVelY<0)
ballVelY=-ballVelY;
ballPosX=ballPosX+ballVelX;
ballPosY=ballPosY+ballVelY;
}
//makes sure players do not simply pass through eachother without event
void checkPlayerCollision()
{
//if the players collide, they get thrown away from eachother
if (redPosX+redVelX<=bluePosX+blueVelX+playerWidth&&redPosX+redVelX>=bluePosX+blueVelX-playerWidth&&redPosY+redVelY<=bluePosY+blueVelY+playerWidth&&redPosY+redVelY>=bluePosY+blueVelY-playerWidth)
{
//temporary variable needed for swapping player velocities
float temp;
//swap velocities
temp=redVelX;
redVelX=blueVelX;
blueVelX=temp;
temp=redVelY;
redVelY=blueVelY;
blueVelY=temp;
}
}
//produces a "kick" of the ball if a player is nearby
void checkBallCollision()
{
//if player hitboxes collide with the ball, it inherits their velocity
//if both players kick the ball, then the ball stops completely (protects against rushing through the opponent)
if (redPosX<=ballPosX+playerWidth-ballWidth&&redPosX>=ballPosX-playerWidth+ballWidth&&redPosY<=ballPosY+playerWidth-ballWidth&&redPosY>=ballPosY-playerWidth+ballWidth&&bluePosX<=ballPosX+playerWidth-ballWidth&&bluePosX>=ballPosX-playerWidth+ballWidth&&bluePosY<=ballPosY+playerWidth-ballWidth&&bluePosY>=ballPosY-playerWidth+ballWidth)
{
ballVelX=0;
ballVelY=0;
}
//red kick check
else if (redPosX<=ballPosX+playerWidth&&redPosX>=ballPosX-playerWidth&&redPosY<=ballPosY+playerWidth&&redPosY>=ballPosY-playerWidth)
{
ballVelX=redVelX*kickStrength;
ballVelY=redVelY*kickStrength;
}
//blue kick check
else if (bluePosX<=ballPosX+playerWidth&&bluePosX>=ballPosX-playerWidth&&bluePosY<=ballPosY+playerWidth&&bluePosY>=ballPosY-playerWidth)
{
ballVelX=blueVelX*kickStrength;
ballVelY=blueVelY*kickStrength;
}
}
//draw the next frame
void drawEntities()
{
rectMode(CENTER);
//draw the red player
fill(255, 0, 0);
rect(redPosX, redPosY, playerWidth, playerWidth);
//draw the blue player
fill(0, 0, 255);
rect(bluePosX, bluePosY, playerWidth, playerWidth);
//draw ball
fill(255, 255, 200);
rect(ballPosX, ballPosY, ballWidth, ballWidth);
//draw goals
fill(200, 255, 30);
rectMode(CORNERS);
rect(redGoalX1, redGoalY1, redGoalX2, redGoalY2);
rect(blueGoalX1, blueGoalY1, blueGoalX2, blueGoalY2);
}