//Nicholas Short 2018 //ABOUT GAME //Bumper cars 2.0 //Reach a score of 30 to win //Bump cars from the back to earn points //Watchout, if hit from another car by the front, you will lose points //CONTROLS //Press and hold LEFT keyboard to move to the left //Press and hold RIGHT keyboard to move to the right //Press and hold UP keyboard to go up //Press and hold DOWN keyboard to go down //Declare all global variables //Declare movement false so that later on when key is pressed, they will become true and function properly boolean carL=false; boolean carR=false; boolean carU=false; boolean carD=false; //Use random, to change car colours with the intent of confusing players float R = random(150, 255); float G = random(100, 255); float B = random(100, 255); //Declare and set the dimensions of the car including its x,y initial coordinate float carx=300; float cary=250; float carw=60; float carh=30; //This will reduce code for hitboxes float carLL, carRR, carUU, carDD; float carLL2, carRR2, carUU2, carDD2; //Speed for car float carM=4; //Human head on cars float humanH=15; // First enemy car float tailw =20; float tailx=150; float taily=250; float tailL, tailR, tailT, tailB; // Second enemy car float sTailx= 340; float sTaily=250; float sTailL, sTailR, sTailT, sTailB; //Third enemy car/ first one to attack player float stAilx=50; float stAily=70; float stAilL, stAilR, stAilT, stAilB; //Fourth enemy car/second one to attack player float ftailx=320; float ftaily=320; float ftailL, ftailR, ftailT, ftailB; // score int score=0; int finish = 30; //Statements that will be used with boolean type functions to create a hitbox boolean checkTouch; boolean checkTouch2; boolean checkTouch3; boolean checkTouch4; //Blocks for bumper cars floor float gridx=0; float gridy=20; //Replacing sin() and cos() for declared variables float dcount=40; float mcount=50; void setup() { size(400, 400); //Making primitive shapes CENTERED will allow me to use carw/2 and carh/2 rectMode(CENTER); ellipseMode(CENTER); } void draw() { background(255); //Use functions for modularity. Instead of condensing it all in draw(), code will become more legible in separate blocks //Design background backgroundNew(); grid(); //Draw player and enemy cars bumperTry(); testHit(); testHit2(); testHit3(); testHit4(); //Update on player and enemy hitboxes checkTouch=checkCircle(); checkTouch2=checkCircle2(); checkTouch3=checkCircle3(); checkTouch4=checkCircle4(); updateCollision(); //Congratulate player and restart game youWin(); } void backgroundNew() { //background float w=600; float c=0; c=constrain(c, 0, 255); while (w>0) { w=w-14; c=c+3; fill(c); ellipse(200, 200, w, w); } } //Function for floor effect //Horizontal and vertical lines void grid() { float grid=0; stroke(150); strokeWeight(1); //Translate multiple lines from one side of the screen to another //Both vertically and horizontally while (grid<400) { fill(255); line(grid, 0, grid, 400); grid=grid+70; line(0, grid, 400, grid); } noStroke(); } //Player car void bumperTry() { //Composes car parts and colour //Colour tone will change every game fill(R, 0, 0); stroke(0); strokeWeight(4); rect(carx, cary, carw, carh, 40); fill(0); rect(carx, cary+20, carw+20, carh-20, 50); line(carx, cary-30, carx, cary-15); fill(0); ellipse(carx, cary-30, humanH, humanH); //Variables are given the value of operation between other variables to shorten future code for hitboxes carLL=carx-carw/2; carRR=carx+carw/2; carUU=cary-carh/2; carDD=cary+carh/2; carLL2=carx-carw/2; carRR2=carx+carw/2; carUU2=cary-carh/2; carDD2=cary+carh/2; //When LEFT key is pressed, car will face the left and move based on speed if (carL) { carx=carx-carM; stroke(0); fill(R, 0, 0); line(carx+30, cary-60, carx+30, cary-10); strokeWeight(4); rect(carx, cary, carw, carh, 40); fill(0); rect(carx, cary+20, carw+20, carh-20, 50); rect(carx+24, cary, carw-40, carh+10, 40); fill(0); line(carx-45, cary, carx-30, cary); noStroke(); fill(0, 0, 255); ellipse(carx-45, cary, 10, 10); rect(carx+31, cary-61, 8, 8); } //When RIGHT key is pressed, car will face the right and move based on speed if (carR) { carx=carx+carM; fill(R, 0, 0); stroke(0); line(carx-30, cary-60, carx-30, cary-10); strokeWeight(4); rect(carx, cary, carw, carh, 40); fill(0); rect(carx, cary+20, carw-20, carh-20, 50); rect(carx-24, cary, carw-40, carh+10, 40); fill(0); line(carx+45, cary, carx+30, cary); noStroke(); fill(0, 0, 255); ellipse(carx+45, cary, 10, 10); rect(carx-31, cary-61, 8, 8); } //When UP key is pressed car will move decrease on Y axis if (carU) { cary=cary-carM; } //When DOWN key is pressed car will move increase on the Y axis if (carD) { cary=cary+carM; } //Boundaries for car, so car is not lost outside of the setup size if (carx-carw/2<0) { carx=carx+carM; } if (carx+carw/2>width) { carx=carx-carM; } } //When keys are pressed car will move to assigned direction void keyPressed() { if (keyCode==LEFT) { carL=true; } if (keyCode==RIGHT) { carR=true; } if (keyCode==UP) { carU=true; } if (keyCode==DOWN) { carD=true; } } //When keys are released car must stop moving void keyReleased() { if (keyCode==LEFT) { carL=false; } if (keyCode==RIGHT) { carR=false; } if (keyCode==UP) { carU=false; } if (keyCode==DOWN) { carD=false; } } //First enemy car void testHit() { //Initialize car to always start moving to the right tailx=tailx+2; //When enemy reaches the end of screen, pull back to the beginning if (tailx+carw/2>width) { tailx=tailx-500; } //Shapes that brought together form the car stroke(0); fill(0, G, 0); line(tailx+30, sin(frameCount/40)*50 + taily-60, tailx+30, sin(frameCount/40)*50 + taily-10); strokeWeight(4); rect(tailx, sin(frameCount/40)*50 + taily, carw, carh, 40); fill(0); rect(tailx, sin(frameCount/40)*50 + taily+20, carw+20, carh-20, 50); rect(tailx+24, sin(frameCount/40)*50 + taily, carw-40, carh+10, 40); fill(0); line(tailx-45, sin(frameCount/40)*50 + taily, tailx-30, sin(frameCount/40)*50 + taily); noStroke(); fill(0, 0, 255); ellipse(tailx-45, sin(frameCount/40)*50 + taily, 10, 10); rect(tailx+31, sin(frameCount/40)*50 + taily-61, 8, 8); noStroke(); fill(0, 0, 255); ellipse(tailx+30, sin(frameCount/40)*50 + taily, tailw, 30); fill(0); line(tailx, sin(frameCount/40)*50+taily-30, tailx, taily-15); fill(0); ellipse(tailx, sin(frameCount/40)*50 +taily-30, humanH, humanH); //Global variables that reduce code and will establish a hitbox tailL=tailx-carw/2; tailR=tailx+carw/2; tailT=taily-carh/2; tailB=taily+carh/2; } //Second enemy car void testHit2() { //Car starts by moving to left downward sTailx=sTailx-1.5; sTaily=sTaily-1.9; //If cars ever reach the end of the screen, pull them back to origin if (sTailx-carw/2<0) { sTailx=sTailx+500; } if (sTaily<0) { sTaily=sTaily+300; } //Shapes that brought together form the car stroke(0); fill(50, 100, 150); line(sTailx-30, sTaily-60, sTailx-30, sTaily-10); strokeWeight(4); rect(sTailx, sTaily, carw, carh, 40); fill(0); rect(sTailx, sTaily+20, carw+20, carh-20, 50); rect(sTailx-24, sTaily, carw-40, carh+10, 40); fill(0); line(sTailx+45, sTaily, sTailx+30, sTaily); noStroke(); fill(0, 0, 255); ellipse(sTailx+45, sTaily, 10, 10); rect(sTailx-31, sTaily-61, 8, 8); noStroke(); fill(0, 0, 255); ellipse(sTailx-30, sTaily, tailw, 30); fill(0); line(sTailx, sTaily-30, sTailx, sTaily-15); fill(0); ellipse(sTailx, sTaily-30, humanH, humanH); //Global variables that reduce code and will establish a hitbox sTailL=sTailx-carw/2; sTailR=sTailx+carw/2; sTailT=sTaily-carh/2; sTailB=sTaily+carh/2; } //Third enemy car/first to attack player void testHit3() { //Car starts moving right downward stAilx=stAilx+1; stAily=stAily+2; //If cars ever reach the end of the screen, pull them back to origin if (stAilx+carw/2>400) { stAilx=stAilx-500; } if (stAily>400) { stAily=stAily-450; } //Shapes that brought together form the car stroke(0); fill(50, 180, B); line(stAilx-30, stAily-60, stAilx-30, stAily-10); strokeWeight(4); rect(stAilx, stAily, carw, carh, 40); fill(0); rect(stAilx, stAily+20, carw+20, carh-20, 50); rect(stAilx-24, stAily, carw-40, carh+10, 40); fill(0); line(stAilx+45, stAily, stAilx+30, stAily); noStroke(); fill(0, 0, 255); ellipse(stAilx+45, stAily, 10, 10); rect(stAilx-31, stAily-61, 8, 8); noStroke(); fill(0, 0, 255); ellipse(stAilx-30, stAily, tailw, 30); fill(0); line(stAilx, stAily-30, stAilx, stAily-15); fill(0); ellipse(stAilx, stAily-30, humanH, humanH); //Global variables that reduce code and will establish a hitbox stAilL=stAilx-carw/2; stAilR=stAilx+carw/2; stAilT=stAily-carh/2; stAilB=stAily+carh/2; } //Fourth enemy car/second to attack player void testHit4() { //Car starts moving to the left end of the screen ftailx=ftailx-2.5; //If cars ever reach the end of the screen, pull them back to origin if (ftailx<0) { ftailx=ftailx+500; } //Shapes that brought together form the car stroke(0); fill(200, 0, 100); line(ftailx+30, cos(frameCount/dcount)*mcount+ftaily-60, ftailx+30, cos(frameCount/dcount)*mcount+ ftaily-10); strokeWeight(4); rect(ftailx, cos(frameCount/dcount)*mcount+ftaily, carw, carh, 40); fill(0); rect(ftailx, cos(frameCount/dcount)*mcount+ftaily+20, carw+20, carh-20, 50); rect(ftailx+24, cos(frameCount/dcount)*mcount+ftaily, carw-40, carh+10, 40); fill(0); line(ftailx-45, cos(frameCount/dcount)*mcount+ftaily, ftailx-30, cos(frameCount/dcount)*mcount+ftaily); noStroke(); fill(0, 0, 255); ellipse(ftailx-45, cos(frameCount/dcount)*mcount+ftaily, 10, 10); ellipse(ftailx+30, cos(frameCount/dcount)*mcount + ftaily, tailw, 30); rect(ftailx+31, cos(frameCount/dcount)*mcount+ftaily-61, 8, 8); fill(0); ellipse(ftailx, cos(frameCount/dcount)*mcount+ftaily-30, humanH, humanH); //Global variables that reduce code and will establish a hitbox ftailL=ftailx-carw/2; ftailR=ftailx+carw/2; ftailT=ftaily-carh/2; ftailB=ftaily+carh/2; } //Hitbox for first enemy car boolean checkCircle() { if (tailL<carRR&&tailR>carLL&tailB>carUU&tailT<carDD) { return true; } else { return false; } } //Hitbox for second enemy car boolean checkCircle2() { if (sTailL<carRR2&&sTailR>carLL2&&sTailB>carUU2&&sTailT<carDD2) { return true; } else { return false; } } //Hitbox for third enemy car boolean checkCircle3() { if (stAilL<carRR&&stAilR>carLL&stAilB>carUU&stAilT<carDD) { return true; } else { return false; } } //Hitbox for fourth enemy car boolean checkCircle4() { if (ftailL<carRR&&ftailR>carLL&ftailB>carUU&ftailT<carDD) { return true; } else { return false; } } //When NPCs touch player, player will be pushed away or enemy will be pushed away //When Collision occurs player will earn points or lose points void updateCollision() { //Collision with first enemy car coming from the left if (checkTouch) { score=score+2; println("nice you have " + score +" points"); tailx=tailx-100; } //Collision with second enemy car coming from the right if (checkTouch2) { score=score+2; println("nice you have " + score +" points"); sTailx=sTailx+200; } //Collision with third car/ first one to attack player coming from the top left corner if (checkTouch3) { score=score-3; println("ouch, that must of hurt. Now you have " + score + " points"); carx=carx+50; } //Collision with fourth car/ second one to attack player coming from the bottom right corner if (checkTouch4) { score=score-3; println("ouch, that must of hurt. Now you have " + score + " points"); carx=carx-50; } } //Congratulate and restart game void youWin() { //When player reaches 30 points, congratulate and restart score if (score>=30) { score=0; println("Congrats! you won, try again"); } }