/* Dude Vs ball by JohnLee Cooper. This is a two player game, with one player controlling a ball with the mouse, and another controller the dude (square) with the arrow keys. The ball can be slung by clicking and dragging with the mouse. The dude can run left and right, and jump. When the dude goes off of one side, he returns on the other. he can also wall jump by pressing away from the side of the screen he's touching. The two players must avoid the deadly blue diamond, or knock each other into it. */ //--------------------------------------- //GLOBAL CONSTANTS: //--------------------------------------- //background square size: float backgroundSize = 50; //the message to display //used for an initial instruction thing and listing who died String words = "Control the square with the arrow keys, and the ball with the mouse."; //the opacity of the message //imma fade it over time. float alpha = 255; //dude constants: float dudeGrav = .5; //how much power the jump has float dudeJump=10; float maxDudeSpeed=10; //half the size of the dudes torso, the distance from his collision place to his sides. float squareSize = 15; //so, he's 30 wide, 30 tall. //ball constants: float ballGrav = .4; //balls can't move faster than ballMaxSpeed pixels per frame float ballMaxSpeed = 10; //the width and height of the ball float ballSize = 30; //I'm going to use box collision for the ball cause circles are hard: float ballWall = ballSize*.4; //diamond constants: //the distance between each point of the diamond float diamondSize = 15; //--------------------------------------- //GLOBAL VARIABLES: //--------------------------------------- //tracks the win condition. when someone loses, it records who and resets variables String ended = "none"; //whether or not to increase the above ball speed things boolean ballClicked = false; //dude starts 1/4th through the screen, on the ground. float dudeX = 100; float dudeY = 400; float dudeSpeedX = 0; float dudeSpeedY = 0; //the ball starts more'n 3/4ths through the screen float ballX = 300; float ballY = 350; float ballSpeedX = 0; float ballSpeedY = 0; //these are used to determine the power to launch with: //essentially, a line is drawn between the first two and the length of that line is the power. float launchX = 0; float launchY = 0; float tempSpeedX = 0; float tempSpeedY = 0; //diamond variables: //diamond speed is randomly set float diamondSpeedX=random(-3, 4); float diamondSpeedY=random(-3, 4); //diamond points, diamond starts in the dead centre. float diamondX1=200; float diamondY1=200-diamondSize; float diamondX2=diamondX1-diamondSize; float diamondY2=diamondY1+diamondSize; float diamondX3=diamondX1; float diamondY3=diamondY1+diamondSize*2; float diamondX4=diamondX1+diamondSize; float diamondY4=diamondY1+diamondSize; //functions: //the longer the player is alive, the higher this number gets. void timer() { } void squaresAnimation() { //this function alone would like corner mode rectMode(CORNER); //give these bois white outlines stroke(255, 255, 255); for (int x=0; x<width; x+=backgroundSize) { for (int y=0; y<height; y+=backgroundSize) {//times 2 cause resolutions are weird //the color depends on how far away the square is from the dude, diamond and ball. //it compares the centre of the background squares to the centre of the ball and dude. //the closer to the dude, the more red float red = 150 -abs(x+(backgroundSize/2)-dudeX) -abs(y+(backgroundSize/2)-dudeY+squareSize/2); //the closer to the ball, the more green. float green = 150 - abs(x+(backgroundSize/2)-ballX) -abs(y+(backgroundSize/2)-ballY); //the closer to the diamond, the more blue. float blue = 150 - abs(x+(backgroundSize/2)-diamondX1) -abs(y+(backgroundSize/2)-diamondY2); fill(red, green, blue); rect(x, y, backgroundSize, backgroundSize*2);//times 2 cause resolutions are weird } } //gotta change that back rectMode(CORNERS); noStroke(); } void ballCollide(float ballBottom, float ballTop, float ballRight, float ballLeft) { //if the bottomish of the circle is above the floor, you fall. if (ballBottom < height) { ballSpeedY+=ballGrav; } //the bounce formula is just divide speed by two and reverse else { //this is to make SURE they stay in bounds, by at first setting it at the length of it's hitbox away from the wall ballY=height-ballWall; ballSpeedY=-ballSpeedY; } if (ballTop<0) { //this is to make SURE they stay in bounds, by at first setting it at the length of it's hitbox away from the wall ballY=0+ballWall; ballSpeedY=-ballSpeedY; } if (ballRight>width) { //this is to make SURE they stay in bounds, by at first setting it at the length of it's hitbox away from the wall ballX=width-ballWall; ballSpeedX=-ballSpeedX; } if (ballLeft<0) { //this is to make SURE they stay in bounds, by at first setting it at the length of it's hitbox away from the wall ballX=0+ballWall; ballSpeedX=-ballSpeedX; } } void ballClick(float ballBottom, float ballTop, float ballRight, float ballLeft) { // when you click: if (mousePressed) { //when mouse is pressed, set the start of drag coords and toggle the boolean about it. if (!ballClicked) { //only does this if when mouse is first pressed. launchX=mouseX; launchY=mouseY; ballClicked = true; } //does the rest of this the whole time. int launchFract = 8; tempSpeedX = (launchX-mouseX)/launchFract; tempSpeedY = (launchY-mouseY)/launchFract; //draw a white line between the point you started dragging and the current point: stroke(255); line(mouseX, mouseY, launchX, launchY); noStroke(); } //when you let go: else if (ballClicked) { //reset the drag numbers and bool, and apply the speeds. ballClicked = false; ballSpeedX+=tempSpeedX; ballSpeedY+=tempSpeedY; tempSpeedX=0; tempSpeedY=0; launchX=0; launchY=0; } } void ballLimit(float ballBottom, float ballTop, float ballRight, float ballLeft) { //let's limit just how fast the ball can move ever: if (ballSpeedX>ballMaxSpeed) { ballSpeedX=ballMaxSpeed; } if (ballSpeedX<-ballMaxSpeed) { ballSpeedX=-ballMaxSpeed; } if (ballSpeedY>ballMaxSpeed) { ballSpeedY=ballMaxSpeed; } if (ballSpeedY<-ballMaxSpeed) { ballSpeedY=-ballMaxSpeed; } } void ballMove() { float ballBottom = ballY+ballWall; float ballTop = ballY-ballWall; float ballRight = ballX+ballWall; float ballLeft = ballX-ballWall; //determines how the ball falls over time and bounces off walls ballCollide(ballBottom, ballTop, ballRight, ballLeft); //controls the ball launching mechanic. ballClick(ballBottom, ballTop, ballRight, ballLeft); //makes sure the ball doesn't go too fast ballLimit(ballBottom, ballTop, ballRight, ballLeft); //actually move the ball: ballX+=ballSpeedX; ballY+=ballSpeedY; } void dudeLimit() { //this function limits dude's speed to his max speeds. if (dudeSpeedX>maxDudeSpeed) { dudeSpeedX=maxDudeSpeed; } if (dudeSpeedX<-maxDudeSpeed) { dudeSpeedX=-maxDudeSpeed; } if (dudeSpeedY>maxDudeSpeed) { dudeSpeedY=maxDudeSpeed; } if (dudeSpeedY<-maxDudeSpeed) { dudeSpeedY=-maxDudeSpeed; } } void dudeStop() { //dude, STOP //if neither left or right are being pressed, slow down to 0 dudeSpeedX=dudeSpeedX/1.5; } char dudeLeftRight() { //returns r if player is pressing right, l if they press left //n if they press neither. char dir = 'n'; if (keyPressed) { if (key == CODED) { if (keyCode == LEFT) { dir='l'; } else if (keyCode == RIGHT) { dir='r'; } } } return dir; } void verticalMove() { //if you press when up when on the ground, you jump if (dudeY==height) { if (keyPressed) { if (key == CODED) { if (keyCode == UP) { jump(); } } } } else { dudeSpeedY+=dudeGrav; } } void dudeWalls() { //when the dude hits a wall, he can either screenwrap or jump backwards if (dudeY>height) { //if you hit the floor, stop falling and set bottom to floor. dudeSpeedY=0; dudeY=height; } if (dudeY<0) { dudeSpeedY=0; dudeY=0; } if (dudeX>width) { if (dudeLeftRight() == 'l') { //jump and reverse direction jump(); dudeSpeedX=(-dudeSpeedX/2) -5; } //otherwise, warp to other side else { //plus 6 so as not to insta wall jump dudeX=6; } } //let's give a little extra lee way for wall jumps: //if the box is slightly over the side, you can still jump else if (dudeX+5>width) { if (dudeLeftRight() == 'l') { //jump and reverse direction jump(); dudeSpeedX=(-dudeSpeedX/2) -5; } } if (dudeX<0) { if (dudeLeftRight() == 'r') { //jump and reverse direction jump(); dudeSpeedX=(-dudeSpeedX/2) +5; } //otherwise warp to other side else { //minus six so as not to immediately wall jump. dudeX=width-6; } } else if (dudeX-5<0) { //let's give a little extra lee way for wall jumps: //if the box is slightly over the side, you can still jump if (dudeLeftRight() == 'r') { //jump and reverse direction jump(); //this formula flips the speed //then it adds a little more push so you can't have 0 speed out of this (caused problems) dudeSpeedX=(-dudeSpeedX/2) +5; } } } void horizontalMove() { //determine the direction currently being pressed char dir = dudeLeftRight(); if (dir=='r') { //if right, start accelerating right. dudeSpeedX++; } if (dir=='l') { //if left, accel left dudeSpeedX--; } if (dir=='n') { //if neither is pressed, and you're on the ground, slow down. if (dudeY==height) { dudeSpeedX/=1.1; } } } void dudeMove() { //general movement function //accels left if left is pressed, right if right, slows if neither. horizontalMove(); //applies jump if up is pressed and youse on the floor //otherwise apply gravity verticalMove(); //boundaries, screenwrapping, walljumping dudeWalls(); //limiting the guy's speed dudeLimit(); //actually move the dude: dudeX+=dudeSpeedX; dudeY+=dudeSpeedY; } void jump() { //apply the jump force dudeSpeedY-=dudeJump; } void bounceCollide() { //when the ball and dude overlap, they exchange speeds //this a really silly way of doing this. But I've been trying to get real collision for hours and it isn't worth the time. //basically, if the centre of dude is in the collision of ball: if (dudeX==constrain(dudeX, (ballX-ballWall), (ballX+ballWall))) { if ((dudeY-squareSize*2)==constrain((dudeY-squareSize*2), (ballY-ballWall), (ballY+ballWall))) { //exchange the x speeds float swapper=dudeSpeedX; dudeSpeedX=ballSpeedX; //this exception is for if the dude is just sitting on the floor. //other wise they get stuck together if (swapper==0) { ballSpeedX=-ballSpeedX; } else { ballSpeedX=swapper; } //exchange the y speeds swapper=dudeSpeedY; dudeSpeedY=ballSpeedY; //this exception is for if the dude is just sitting on the floor. //otherwise they get stuck together if (swapper==0) { ballSpeedY=-ballSpeedY; } else { ballSpeedY=swapper; } } } } void diamondCollide() { //if the top tip hits the top or the bottom hits the bottom: if (diamondY1<0 || diamondY3>height) { //push it back so it doesnt collide, //just a quick fix for some glitchiness in the corners diamondY1-=diamondSpeedY; //reverse vertical speed diamondSpeedY=-diamondSpeedY; //randomize horizontal speed diamondSpeedX= random(-3, 4); } //if the left point hits the left, or the right the right side: if (diamondX2<0 || diamondX4>width) { //push it back so it doesnt collide, //just a quick fix for some glitchiness in the corners diamondX1-=diamondSpeedX; //reverse horizontal speed diamondSpeedX=-diamondSpeedX; //randomize vertical speed diamondSpeedY= random(-3, 4); } } void diamondMove() { //when the diamond hits walls: diamondCollide(); //actually move the diamond: diamondX1+=diamondSpeedX; diamondY1+=diamondSpeedY; } void killBall(float pointX, float pointY) { //if the point is in the ball, the ball loses if (pointX==constrain(pointX, (ballX-ballWall), (ballX+ballWall))) { if (pointY==constrain(pointY, (ballY-ballWall), (ballY+ballWall))) { ended="ball"; } } } void killDude(float pointX, float pointY) { //if the point is in the ball, the ball loses if (pointX==constrain(pointX, (dudeX-squareSize), (dudeX+squareSize))) { if (pointY==constrain(pointY, (dudeY-squareSize*2), dudeY)) { ended="dude"; } } } void dudeDraw() { //draws a little rectangle, with little rectangle legs fill(255, 0, 0); //red //these variables are to get the corners of the rect //based on the bottom centre, which is the anchor float top = dudeY-squareSize*2; float bottom = dudeY; float left = dudeX-squareSize; float right = dudeX+squareSize; rect(left, top, right, bottom); } void ballDraw() { //draws a green circle. wooo fill(0, 255, 0); ellipse(ballX, ballY, ballSize, ballSize); // stroke(255); //these can be turned on if I want to see the ball's hitbox. // rect(ballX-ballWall, ballY-ballWall, ballX+ballWall, ballY+ballWall); // noStroke(); } void diamondDraw() { //diamond is blue fill(0, 0, 255); //lots a coords diamondX2=diamondX1-diamondSize; diamondY2=diamondY1+diamondSize; diamondX3=diamondX1; diamondY3=diamondY1+diamondSize*2; diamondX4=diamondX1+diamondSize; diamondY4=diamondY1+diamondSize; quad(diamondX1, diamondY1, diamondX2, diamondY2, diamondX3, diamondY3, diamondX4, diamondY4); //diamond no longer looks like a word } //imforms cube of their loss, resets all the variables to their initial things. void reset() { //display kill stuff words = ended+" is kill!"; alpha = 255; //reset the end trigger. ended = "none"; //the rest of this is the same as the top. //whether or not to increase the above ball speed things ballClicked = false; //dude starts 1/4th through the screen, on the ground. dudeX = 100; dudeY = 400; dudeSpeedX = 0; dudeSpeedY = 0; //the ball starts more than 3/4ths through the screen ballX = 300; ballY = 350; ballSpeedX = 0; ballSpeedY = 0; //these are used to determine the power to launch with: //essentially, a line is drawn between the first two and the length of that line is the power. launchX = 0; launchY = 0; tempSpeedX = 0; tempSpeedY = 0; //diamond variables: //diamond speed is randomly set diamondSpeedX=random(-3, 4); diamondSpeedY=random(-3, 4); //diamond points, diamond starts in the dead centre. diamondX1=200; diamondY1=200-diamondSize; diamondX2=diamondX1-diamondSize; diamondY2=diamondY1+diamondSize; diamondX3=diamondX1; diamondY3=diamondY1+diamondSize*2; diamondX4=diamondX1+diamondSize; diamondY4=diamondY1+diamondSize; } void displayText() { fill(255, 255, 255, alpha); text(words, 0, 0, width, height); if (alpha>0) { alpha--; } } void setup() { size(400, 400); noStroke(); rectMode(CORNERS); textSize(40); textAlign(CENTER); } void draw() { background(0); //draw the background squares squaresAnimation(); //UPDATES: ballMove(); dudeMove(); diamondMove(); //for the interaction between ball and dude bounceCollide(); //for their interaction with diamond //test each diamond point with each to see if anyone dies killDude(diamondX1, diamondY1); killBall(diamondX1, diamondY1); killDude(diamondX2, diamondY2); killBall(diamondX2, diamondY2); killDude(diamondX3, diamondY3); killBall(diamondX3, diamondY3); killDude(diamondX4, diamondY4); killBall(diamondX4, diamondY4); //DRAW: dudeDraw(); ballDraw(); diamondDraw(); //display text: displayText(); //set the things in the first place if (ended != "none") { reset(); } }