xxxxxxxxxx
/*
SMASH FOOTY
by hazzza
*/
const gameWidth = 700;
const gameHeight = 500;
let gameState = "Menu";
let players = [];
let lastMouseDown;
let font;
let redScore = 0;
let blueScore = 0;
let currentTurn = 0;
let turnsPassed = 0;
let redGoals = "";
let blueGoals = "";
let lastUsedPlayer = "";
function preload() {
//I like this font
//This guy made it -> https://www.dafont.com/guy-buhry.d1243
font = loadFont("GROBOLD.ttf");
}
function setup() {
createCanvas(700, 560);
makeTeams();
lastMouseDown = new p5.Vector(0, 0);
}
function draw() {
background(41, 84, 32);
if (turnsPassed > 40) {
gameState = "Game Over";
}
if (gameState == "Game") {
drawPitch();
runPlayers();
push();
textFont(font);
textSize(50);
strokeWeight(3);
stroke(255);
fill(0);
textAlign(CENTER, CENTER);
text(
redScore + " - " + blueScore,
width / 2,
height - (height - gameHeight) / 2
);
textSize(30);
text(
(currentTurn == 0 ? "Red Turn " : "Blue Turn ") +
(floor(turnsPassed / 2) + 1),
currentTurn == 0 ? width / 4 : (width * 3) / 4,
height - (height - gameHeight) / 2
);
pop();
} else if (gameState == "Menu") {
drawPitch();
push();
textFont(font);
strokeWeight(5);
stroke(255);
fill(0);
textAlign(CENTER, CENTER);
let t = map(sin(frameCount / 10), -1, 1, 0.95, 1.05);
textSize(70 * t);
text("SMASH FOOTY", gameWidth / 2, gameHeight * 0.3);
textSize(50);
strokeWeight(3);
text("?", gameWidth - 50, gameHeight - 50);
textSize(30 * t);
text("Press any key to start", gameWidth / 2, gameHeight * 0.75);
textSize(20);
textAlign(LEFT);
text("Made by hazzza (2023)", 10, gameHeight - 20);
pop();
//https://openprocessing.org/user/224122/?view=sketches&o=108
if (dist(mouseX, mouseY, gameWidth - 50, gameHeight - 50) < 40) {
push();
strokeWeight(5);
stroke(255);
fill(150);
textFont(font);
textAlign(CENTER, CENTER);
rect(100, 100, gameWidth - 200, gameHeight - 200);
textSize(20);
fill(0);
strokeWeight(2);
//IDEK what's going on with the # in this font but it looks cool
text(
"This game is for 2 players on the same device\nPass the mouse\n\n# Take turns to drag your players to move them\n# Hit the ball into the other team's goal\n# Most goals after 20 turns each is the winner ",
gameWidth / 2,
gameHeight / 2
);
pop();
}
} else if (gameState == "Game Over") {
drawPitch();
for (let p of players) {
p.display();
}
push();
textFont(font);
textSize(70);
strokeWeight(3);
stroke(255);
fill(0);
textAlign(CENTER, CENTER);
text(redScore + " - " + blueScore, width / 2, height / 2);
text(redScore - blueScore==0 ? "Draw!" : (redScore > blueScore ? "Red Won!" : "Blue Won!"), width / 2, height / 2 - 100);
textSize(30);
text("Reload the page to play again\nHeart if you liked it", width/2, height - 100);
text("Red Goals: \n" + redGoals, width * 1/5, height * 1/2);
text("Blue Goals : \n" + blueGoals, width * 4/5, height * 1/2);
pop();
}
}
function makeTeams() {
players = [];
//red team
players.push(
new Player(createVector(gameWidth / 2 - 100, gameHeight / 2), 0, "2")
);
players.push(new Player(createVector(100, gameHeight / 2), 0, "1"));
players.push(
new Player(createVector(gameWidth / 2 - 100, gameHeight * 0.2), 0, "3")
);
players.push(
new Player(createVector(gameWidth / 2 - 100, gameHeight * 0.8), 0, "4")
);
//blue team
players.push(
new Player(createVector(gameWidth / 2 + 100, gameHeight / 2), 1, "2")
);
players.push(new Player(createVector(gameWidth - 100, gameHeight / 2), 1, "1"));
players.push(
new Player(createVector(gameWidth / 2 + 100, gameHeight * 0.2), 1, "3")
);
players.push(
new Player(createVector(gameWidth / 2 + 100, gameHeight * 0.8), 1, "4")
);
//ball (actually a player but dont tell anyone shhhh)
players.push(new Player(createVector(gameWidth / 2, gameHeight / 2), 2, ""));
}
function keyPressed() {
if (gameState == "Menu") {
gameState = "Game";
}
if(gameState == "Game Over") {
gameState = "Menu";
}
}
function mousePressed() {
lastMouseDown = new p5.Vector(mouseX, mouseY);
}
function unreleaseAll() {
for (let p of players) {
p.unreleased = true;
}
}
function mouseReleased() {
//if(dist(lastMouseDown.x, lastMouseDown.y, mouseX, mouseY) > 40 ) {
lastMouseDown = new p5.Vector(mouseX, mouseY);
unreleaseAll();
//}
//else {
//lastMouseDown = new p5.Vector(9999999,0);
//}
}
function runPlayers() {
for (let p of players) {
p.display();
p.update(players);
}
}
function drawPitch() {
//stripes
for (let i = 0; i < 8; i++) {
if (i % 2 == 0) {
push();
rectMode(CORNER);
noStroke();
fill(53, 107, 42);
rect((gameWidth / 8) * i, 0, gameWidth / 8, gameHeight);
pop();
}
}
//
//https://openprocessing.org/user/224122/?view=sketches&o=108
//lines
push();
noFill();
stroke(255);
strokeWeight(4);
rectMode(CORNER);
rect(0, 0, gameWidth, gameHeight);
line(gameWidth / 2, 0, gameWidth / 2, gameHeight);
circle(gameWidth / 2, gameHeight / 2, gameHeight / 4);
rectMode(CENTER);
//goals
noStroke();
fill(0, 0, 255, 60);
rect(gameWidth, gameHeight / 2, 40, gameHeight / 3);
fill(255, 0, 0, 60);
rect(0, gameHeight / 2, 40, gameHeight / 3);
noFill();
stroke(255);
strokeWeight(4);
rect(0, gameHeight / 2, gameWidth / 8, gameHeight / 3);
rect(0, gameHeight / 2, gameWidth / 2.75, gameHeight / 1.5);
rect(gameWidth, gameHeight / 2, gameWidth / 8, gameHeight / 3);
rect(gameWidth, gameHeight / 2, gameWidth / 2.75, gameHeight / 1.5);
pop();
//
}
function goalScored(/*string*/ teamScored) {
if (teamScored == "blue") {
blueScore++;
} else {
redScore++;
}
makeTeams();
}
const physicsSolverResolution = 4; //4
const wallDamping = 0.9; //0.9
const groundFriction = 0.99; //0.99
const collisionVelocityDamping = 0.9; //0.9
const dragMultiplier = 0.2; //0.2
class Player {
constructor(_position, _team, _label) {
//p5.Vector
this.position = _position;
//p5.Vector
this.velocity = new p5.Vector();
//0 = Red 1 = Blue
this.team = _team;
this.label = _label;
this.radius = 40;
this.pSelected = false;
if (_team == 2) {
//this.radius = 25;
}
this.unreleased = false;
}
display() {
let mouseOver =
dist(lastMouseDown.x, lastMouseDown.y, this.position.x, this.position.y) <
this.radius;
push();
if (
mouseOver &&
mouseIsPressed &&
this.team != 2 &&
this.team == currentTurn
) {
this.unreleased = true;
let diff = this.position
.copy()
.sub(
new p5.Vector(
constrain(mouseX, 0, gameWidth),
constrain(mouseY, 0, gameHeight)
)
);
strokeWeight(4);
stroke(255, 255, 0);
strokeCap(ROUND);
strokeJoin(ROUND);
translate(this.position.x, this.position.y);
rotate(diff.heading());
beginShape();
vertex(0, -this.radius / 2);
vertex(0, this.radius / 2);
vertex(-diff.mag(), 0);
vertex(0, -this.radius / 2);
endShape();
}
pop();
push();
fill(this.team == 0 ? color(255, 0, 0) : color(0, 0, 255));
if (this.team == 2) fill(color(230));
stroke(mouseOver && this.team != 2 ? color(255, 255, 0) : 255);
strokeWeight(4);
circle(this.position.x, this.position.y, this.radius);
pop();
push();
if (
mouseOver &&
mouseIsPressed &&
this.team != 2 &&
this.team == currentTurn
) {
let diff = this.position
.copy()
.sub(
new p5.Vector(
constrain(mouseX, 0, gameWidth),
constrain(mouseY, 0, gameHeight)
)
);
strokeWeight(4);
stroke(255, 255, 0);
fill(255, 255, 0);
translate(this.position.x, this.position.y);
rotate(diff.heading());
line(0, 0, diff.mag() / 2, 0);
triangle(diff.mag() / 2, 5, diff.mag() / 2, -5, diff.mag() / 2 + 8, 0);
}
pop();
push();
fill(255);
stroke(0);
textSize(25);
//
textAlign(CENTER, CENTER);
text(this.label, this.position.x, this.position.y);
pop();
}
update(bodies) {
if (
dist(lastMouseDown.x, lastMouseDown.y, this.position.x, this.position.y) >
this.radius &&
this.pSelected &&
this.team != 2 &&
this.unreleased &&
this.velocity.mag() < 0.5 &&
this.team == currentTurn
) {
let drag = this.position
.copy()
.sub(
new p5.Vector(
constrain(mouseX, 0, gameWidth),
constrain(mouseY, 0, gameHeight)
)
);
drag = drag.mult(dragMultiplier);
this.velocity = this.velocity.add(drag);
currentTurn = currentTurn == 0 ? 1 : 0;
lastUsedPlayer = this.label;
turnsPassed++;
}
//REUSED CODE FROM DUDE ROYALE
//I couldnt be bothered
for (let other of bodies) {
if (other != this) {
for (var i = 0; i < 5; i++) {
//5 Solver iterations, can be lowered for better performance if required
if (
dist(
this.position.x,
this.position.y,
other.position.x,
other.position.y
) <
(this.radius + other.radius) / 2
) {
var center = createVector(
(this.position.x + other.position.x) / 2,
(this.position.y + other.position.y) / 2
);
var myDiffToCenter = createVector(
this.position.x,
this.position.y
).sub(center);
var theirDiffToCenter = createVector(
other.position.x,
other.position.y
).sub(center);
//if (UnitData[this.type].CanMove) {
let tpxa = (myDiffToCenter.x / physicsSolverResolution) * i;
let tpya = (myDiffToCenter.y / physicsSolverResolution) * i;
let opxa = (theirDiffToCenter.x / physicsSolverResolution) * i;
let opya = (theirDiffToCenter.y / physicsSolverResolution) * i;
let tpspeed = this.velocity.mag();
let opspeed = other.velocity.mag();
this.position.x += tpxa;
this.position.y += tpya;
this.velocity.x += tpxa;
this.velocity.y += tpya;
//}
//if (UnitData[other.type].CanMove) {
other.position.x += opxa;
other.position.y += opya;
other.velocity.x += opxa;
other.velocity.y += opya;
this.velocity.setMag(
((tpspeed + opspeed) / 2) *
collisionVelocityDamping *
(other.radius / this.radius)
);
other.velocity.setMag(
((tpspeed + opspeed) / 2) *
collisionVelocityDamping *
(this.radius / other.radius)
);
//}
}
}
}
}
this.position.add(this.velocity);
if (this.position.x < 0 || this.position.x > gameWidth) {
this.velocity.x *= -wallDamping;
}
if (this.position.y < 0 || this.position.y > gameHeight) {
this.velocity.y *= -wallDamping;
}
this.position.set(
constrain(this.position.x, 0, gameWidth),
this.position.y
);
this.position.set(
this.position.x,
constrain(this.position.y, 0, gameHeight)
);
this.velocity.mult(groundFriction);
this.pSelected =
dist(lastMouseDown.x, lastMouseDown.y, this.position.x, this.position.y) <
this.radius;
this.unreleased = false;
if (
this.position.y > gameHeight / 2 - gameHeight / 6 &&
this.position.y < gameHeight / 2 + gameHeight / 6 &&
this.team == 2
) {
if (this.position.x < 20) {
//blue team have scored#
goalScored("blue");
blueGoals += lastUsedPlayer + ", "+ turnsPassed + "\n";
}
if (this.position.x > gameWidth - 20) {
//red team have scored
goalScored("red");
redGoals += lastUsedPlayer + ", "+ turnsPassed + "\n";
}
}
}
}