//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); }