xxxxxxxxxx
322
// Instantiate the variables
let mySwing;
let Swing1;
let BGimg;
let radio;
// park or radio to manage which scene to display
let scene = 'park';
let birdSpriteSheet;
let bird;
function preload(){
BGimg = loadImage('BG.jpg');
birdSpriteSheet = loadImage('bird.png');
}
function setup() {
createCanvas(windowWidth, windowHeight);
rectMode(CENTER);
// Create a new Swing object
Swing0 = new Swing(550, 400, 50, 15, 100);
Swing1 = new Swing(150, 400, 50, 15, 100);
// Create the radio
radio = new Radio(350, 550, 70, 40);
bird = new Bird(200, 200);
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
function keyTyped() {
// $$$ For some reason on Chrome/Mac you may have to press f twice to toggle. Works correctly on Firefox/Mac
if (key === 'f') {
toggleFullscreen();
}
// uncomment to prevent any default behavior
// return false;
}
// Toggle fullscreen state. Must be called in response
// to a user event (i.e. keyboard, mouse click)
function toggleFullscreen() {
let fs = fullscreen(); // Get the current state
fullscreen(!fs); // Flip it!
}
function draw() {
// Draw the park background
if (scene === 'park') {
image(BGimg, 0, 0, windowWidth, windowHeight);
// Display swings
Swing0.update();
Swing0.display();
Swing1.update();
Swing1.display();
Swing0.addFigure();
Swing1.addFigure();
// Display the radio
bird.display(); // Display the bird
radio.display();
} else if (scene === 'radio') {
// Display the enlarged radio
radio.displayEnlarged();
}
}
// Radio class
class Radio {
constructor(x, y, w, h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.isClicked = false;
}
display() {
push();
translate(this.x, this.y);
noStroke();
rectMode(CENTER);
fill('#1B3C73');
rect(0,-10,this.w-10, this.h,5);
fill('#8B9714');
rect(0,-5,this.w-17, this.h,5);
fill('#1B3C73');
rect(0, 0, this.w, this.h,5);
// Sound symbol
fill('#FFCAD4');
ellipse(-20,5,20);
fill('#FF407D')
ellipse(-20,5,15);
fill('#FFFFFF');
ellipse(-20,6,10);
// Buttons on the Radio
noStroke();
fill(255);
rect(0,-15,50,2,5);
rect(0,-12,50,2,5);
fill('#FF407D')
ellipse(5,-4,10);
ellipse(15,-4,10);
fill('#FFCAD4');
// Pause and stop button
rect(10,10,30,15,5);
fill('#FF407D')
rect(0,10,5,10);
rect(7,10,5,10);
triangle(13,4,20,11,13,17);
pop();
}
displayEnlarged() {
background('rgb(213,244,242)');
push();
fill('#1B3C73');
noStroke();
rectMode(CENTER);
rect(width / 2, height / 2-100,300,200,30);
fill('rgb(213,244,242)');
rect(width / 2, height / 2-90,280,200,30);
fill('#1B3C73');
rect(width / 2, height / 2, 350, 190, 10);
fill('#FFCAD4');
ellipse(width / 2-110,height / 2+30,100);
fill('#FF407D')
ellipse(width / 2-109,height / 2+30,85);
fill('#40679E');
ellipse(width / 2-109,height / 2+30,70);
stroke(255);
// lines on the circle on the radio
line(width / 3-15,height / 2+5,width / 3+30,height / 2+5);
line(width / 3-21,height / 2+15,width / 3+37,height / 2+15);
line(width / 3-25,height / 2+25,width / 3+41,height / 2+25);
line(width / 3-25,height / 2+35,width / 3+42,height / 2+35);
line(width / 3-21,height / 2+45,width / 3+37,height / 2+45);
line(width / 3-14,height / 2+55,width / 3+31,height / 2+55);
noStroke();
fill(255);
rect(350,220,270,10,5);
rect(350,235,270,10,5);
fill('#FF407D')
ellipse(350,270,30);
ellipse(390,270,30);
fill('#FFCAD4');
// Pause and stop button
rect(350,330,70,40,5);
fill('#FF407D')
rect(330,330,10,30);
rect(345,330,10,30)
triangle(360,315,380,330,360,345);
// song change button
fill('#FFCAD4');
rect(450,330,60,40,5);
fill('#FF407D');
triangle(430,330,440,315,440,345);
triangle(440,330,450,315,450,345);
triangle(455,315,465,330,455,345);
triangle(465,315,475,330,465,345);
// Back button
fill('black');
rect(60, height - 35, 100, 50);
fill('rgb(255,255,255)');
textSize(20);
textAlign(CENTER, CENTER);
text('Back', 60, height - 35);
pop();
}
click(mousex, mousey) {
// Toggle scene only if in 'park' scene
if (scene === 'park' && mousex > this.x - this.w / 2 && mousex < this.x + this.w / 2 &&
mousey > this.y - this.h / 2 && mousey < this.y + this.h / 2) {
this.isClicked = true;
scene = 'radio';
}
}
}
// Define a Swing class
class Swing {
constructor(x, y, width, height, frameHeight) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
// Height of the swing frame
this.frameHeight = frameHeight;
// Start angle for swing motion
this.angle = 0;
// Speed of swing motion
this.angleVelocity = 0.03;
}
addFigure() {
// Create a new Figure associated with this swing
this.figure = new Figure(this);
}
update() {
// Oscillate the scale between 0.5 and 1.2 to simulate forward and backward motion
this.swingScale = lerp(0.5, 1.2, (sin(this.angle) + 1) / 2);
this.angle += this.angleVelocity;
}
display() {
// Swing frame
stroke(139, 69, 19);
strokeWeight(10);
// Left side of the frame
line(this.x -50, this.y - this.frameHeight, this.x -50, this.y);
// Right side of the frame
line(this.x + 50, this.y - this.frameHeight, this.x+ 50, this.y);
// Top of the frame
line(this.x -50, this.y - this.frameHeight, this.x +50, this.y - this.frameHeight);
// Swing seat - scale for depth effect
// Start a new drawing state
push();
// Translate to the position of the swing seat
translate(this.x, this.y-15);
// Apply scale transformation
scale(this.swingScale);
fill(160, 82, 45);
// Seat
rect(0, 0, this.width, this.height);
pop();
// Swing ropes
stroke(160, 82, 45);
// Scale the stroke weight to simulate depth
strokeWeight(2 * this.swingScale);
// Left rope
line(this.x-20, this.y - this.frameHeight, this.x -20 * this.swingScale, this.y - this.height/2-10 * this.swingScale);
// Right rope
line(this.x + this.width/2, this.y - this.frameHeight, this.x + this.width/2 * this.swingScale, this.y-10 - this.height/2 * this.swingScale);
if (this.figure) {
this.figure.display();
}
}
}
class Figure {
constructor(swing) {
this.swing = swing; // Associate the figure with a swing
}
display() {
push(); // Start a new drawing state
translate(this.swing.x, this.swing.y - this.swing.height / 2); // Position on the swing seat
scale(this.swing.swingScale); // Scale the figure with the swing for depth effect
noStroke();
fill('rgb(224,141,151') // Color for the figure
// Draw the head
ellipse(0, -40, 20, 20);
quad(-5,-30,-11,-25,10,-25,5,-30);
// Draw the body
rect(0, -15, 20, 20);
ellipse(0,-5,20,10)
// Draw the legs
rect(-5, 15, 5, 20);
rect(5, 15, 5, 20);
// foot
ellipse(-4,23,8,5);
ellipse(7,23,8,5);
// Draw the arms
quad(-10, -25,-10,-15,-20,-40,-20,-45 );
quad(10, -25,10,-15,20,-40,20,-45 );
pop(); // Restore original state
}
}
class Bird {
constructor(x, y) {
this.x = x;
this.y = y;
this.frame = 0; // Current frame for animation
this.flying = false; // Is the bird flying?
}
display() {
push();
translate(this.x, this.y);
if (!this.flying) {
// If the bird is not flying, display the first frame (sitting)
image(birdSpriteSheet, 0, 0, 64, 64, 0, 0, 64, 64);
} else {
// Animate the bird flying
let frameX = (this.frame % 3) * 64; // Calculate X position of the frame
let frameY = Math.floor(this.frame / 3) * 64; // Calculate Y position of the frame
image(birdSpriteSheet, 0, 0, 64, 64, frameX, frameY, 64, 64);
this.frame++;
if (this.frame > 8) this.flying = false; // Reset after animation
}
pop();
}
fly() {
this.flying = true;
this.frame = 0; // Reset frame to start flying animation
}
}
function mousePressed() {
if (scene === 'park') {
radio.click(mouseX, mouseY);
} else if (scene === 'radio') {
// Check if the click is within the back button bounds
if (mouseX >= 10 && mouseX <= 110 && mouseY >= height - 60 && mouseY <= height - 10) {
// Change the scene back to park
scene = 'park';
radio.isClicked = false;
}
}
}