xxxxxxxxxx
258
class SportsCar{
constructor(x, y,pic){
this.x = x;
this.y = y;
this.picture = pic;
}
show(){
//display picture of car attached in this.picture
image(this.picture, this.x, this.y);
}
}
class checkedLine{
constructor(x,y,length, blockcolor){
this.x =x;
this.y = y;
this.length = length;
this.blockcolor = blockcolor;
}
showVertical(){ //to be used in the opening screen
for(let i =this.y; i< this.length; i+=30){
noStroke();
fill(255);
square(this.x, i, 15);
fill(this.blockcolor);
square(this.x, i+15, 15);
}
}
showHorizontal(){ //to be used in the main screen
for(let i =this.x; i< this.length; i+=30){
noStroke();
fill(255);
square(i, this.y, 15);
fill(this.blockcolor);
square(i+15, this.y, 15);
}
}
}
class stats { //pins placed on the countries' location and stats displayed
constructor(countryCode, x, y, countryCount) {
this.countryCode = countryCode;
this.x = x;
this.y = y;
this.diameter = 3; // Initial circle diameter
this.isHovered = false; //boolean variable to know whether the pin is hovered or not
this.hoveredDiameter = 20;//diameter of the circle when hovered on
this.countryCount = countryCount;
}
display() {
noStroke();
fill(255, 0, 0);
ellipse(this.x, this.y, this.isHovered ? this.hoveredDiameter : this.diameter); // Adjust size when hovered accordingly
if (this.isHovered) {//display the stats above when pin is hovered
fill(220);
textSize(22);
textAlign(CENTER, CENTER);
text(str(this.countryCount), width - 70 , 15);
text(str(this.countryCode),width/2 - 50 , 15)
}
}
checkMouseHover() {
// Calculate the distance between mouse and pin center
let distance = dist(mouseX, mouseY, this.x, this.y);
// Check if the mouse is within the pin
this.isHovered = distance < (this.diameter / 2) + 2;
}
}
let x1 = 450;//starting positions for the cars
let x2 = 450;
let s1 = 15; //speeds for intial round
let s2 = 14.7;
function openingscreen(){
background(120);
//vertical checked lines
let line0 = new checkedLine(50,50,width - 60, 'lightgray');
line0.showHorizontal();
let line1 = new checkedLine(65,65,width - 80, 'lightgray');
line1.showHorizontal();
let line2 = new checkedLine(50,0,height, 'red');
line2.showVertical();
let line3 = new checkedLine(width-65,0,height, 'red');
line3.showVertical();
//grass areas at the sides of the screen
fill(0,180,0);
rect(0, 0, 50,height);
rect(width-50, 0, height);
//FINISH text at the top center
fill(255);
textSize(25);
textAlign(CENTER);
text("FINISH", width/2, 30);
//street lanes on the screen
strokeWeight(5);
stroke(255);
line(width/2, 150, width/2, 200);
line(width/2, 250, width/2, 300);
line(width/2, 350, width/2, 400);
if(x1 < -100 && x2 < -100 ){ //to make sure both cars start together each time
x1 = 700;
s1 = random(12,17); // have varying speed after intial round
x2 = 700;
s2 = random(12,17);
}
let SpCar1 = new SportsCar(250,x1-=s1,car1);
let SpCar2 = new SportsCar(110,x2-=s2,car2);
car1.resize(50,100);
car2.resize(50,100);
for(let i = height-100; i>100; i--){
SpCar1.show();
SpCar2.show();
}
}
function mainscreen(){
background(230);
noStroke();
//burgundy top and bottom
fill(160,0,0)
rect(0, 0, width,50);
rect(0,height-50, width, 50);
//Horizontal checked lines
let line0 = new checkedLine(0,30,width , 'black');
line0.showHorizontal();
let line1 = new checkedLine(-15,45,width , 'black');
line1.showHorizontal();
let line2 = new checkedLine(0,60,width , 'black');
line2.showHorizontal();
let line3 = new checkedLine(0,height-40,width , 'black');
line3.showHorizontal();
let line4 = new checkedLine(-15,height-55,width , 'black');
line4.showHorizontal();
let line5 = new checkedLine(0,height-70,width , 'black');
line5.showHorizontal();
//map
image(map, 0, 75)
//text shown at bottom of screen
fill(200);
textSize(17);
textAlign(CENTER, CENTER);
text("hover over a pin to see the number of drivers", width/2, height-12);
}
let car1;
let car2;
let map;
let table;
let countryCounts = {};
let pins = [];
let table2;
let screen = 1;
function preload(){
car1 = loadImage('bluecar.png');
car2 = loadImage('greencar.png');
map = loadImage('map.png');
table = loadTable('drivers_details.csv', 'csv', 'header');
table2 = loadTable('countries.csv', 'csv', 'header');
}
function setup() {
createCanvas(400, 400);
background(120);
//creates a dictionary of country codes with corresponding total number of drivers
for (let i = 0; i < table.getRowCount(); i++) {
let country = table.getString(i, 'Nationality');
if (countryCounts[country]) {
countryCounts[country]++;
} else {
countryCounts[country] = 1;
}
}
// display the country counts in the countryCounts dictionary
console.log(countryCounts);
//goes through the countries csv file and creates a pin at the corresponding positions accordingly
for (let row of table2.rows) {
let countryCode = str(row.get('COUNTRYCODE'));
let x = parseFloat(row.get('X'));
let y = parseFloat(row.get('Y'));
let countryName = str(row.get('COUNTRY'));
let pin = new stats(countryName, x, y, countryCounts[countryCode] );
pins.push(pin);
}
}
function draw() {
let countries = Object.keys(countryCounts);
if (screen === 2){
map.resize(400,255);
mainscreen();
for (let pin of pins) {
pin.checkMouseHover();
pin.display();
}
}else{if(screen === 1){
openingscreen();
}
}
}
function mouseClicked() {
// Switch between screens when mouse is clicked
if (screen === 1) {
screen = 2;
} else if (screen === 2) {
screen = 1;
}
}