Leaderboard
It's like the high score screen in your (least?) favorite arcade game. Names borrowed from SSA.gov's most popular baby names.
Source Code for this Sketch
const names = ["Aaron", "Abigail", "Adam", "Alan", "Albert", "Alexander", "Alexis", "Alice", "Amanda", "Amber", "Amy", "Andrea", "Andrew", "Angela", "Ann", "Anna", "Anthony", "Arthur", "Ashley", "Austin", "Barbara", "Benjamin", "Betty", "Beverly", "Billy", "Bobby", "Bradley", "Brandon", "Brenda", "Brian", "Brittany", "Bruce", "Bryan", "Caleb", "Carl", "Carol", "Carolyn", "Catherine", "Charles", "Charlotte", "Cheryl", "Christian", "Christina", "Christine", "Christopher", "Cynthia", "Daniel", "Danielle", "David", "Deborah", "Debra", "Denise", "Dennis", "Diana", "Diane", "Donald", "Donna", "Dorothy", "Douglas", "Dylan", "Edward", "Elijah", "Elizabeth", "Emily", "Emma", "Eric", "Ethan", "Evelyn", "Frances", "Frank", "Gabriel", "Gary", "George", "Gerald", "Gloria", "Grace", "Gregory", "Hannah", "Harold", "Heather", "Helen", "Henry", "Isaac", "Isabella", "Jack", "Jacob", "Jacqueline", "James", "Janet", "Janice", "Jason", "Jean", "Jeffrey", "Jennifer", "Jeremy", "Jerry", "Jesse", "Jessica", "Joan", "Joe", "John", "Jonathan", "Jordan", "Jose", "Joseph", "Joshua", "Joyce", "Juan", "Judith", "Judy", "Julia", "Julie", "Justin", "Karen", "Katherine", "Kathleen", "Kathryn", "Kathy", "Kayla", "Keith", "Kelly", "Kenneth", "Kevin", "Kimberly", "Kyle", "Larry", "Laura", "Lauren", "Lawrence", "Liam", "Linda", "Lisa", "Logan", "Lori", "Lucas", "Luke", "Madison", "Margaret", "Maria", "Marilyn", "Mark", "Martha", "Mary", "Mason", "Matthew", "Megan", "Melissa", "Michael", "Michelle", "Nancy", "Natalie", "Nathan", "Nicholas", "Nicole", "Noah", "Olivia", "Pamela", "Patricia", "Patrick", "Paul", "Peter", "Rachel", "Randy", "Raymond", "Rebecca", "Richard", "Robert", "Roger", "Ronald", "Ruth", "Ryan", "Samantha", "Samuel", "Sandra", "Sara", "Sarah", "Scott", "Sean", "Sharon", "Shirley", "Sophia", "Stephanie", "Stephen", "Steven", "Susan", "Teresa", "Terry", "Theresa", "Thomas", "Tiffany", "Timothy", "Tyler", "Victoria", "Vincent", "Virginia", "Walter", "Wayne", "William", "Willie", "Zachary"]
let scores = []
let particles = []
let scoreboard
class Particle{
constructor() {
this.x = Math.random() * width
this.y = Math.random() * height
}
draw() {
this.x += deltaTime/1000 * 10
if(this.x > width) {
this.x = 0
}
fill(240, 90, 70)
noStroke()
circle(this.x, this.y, 4)
}
}
function chrisRandom(min, max, step) {
let result = 0
if(step === 0) {
// kludge because we want this to be inclusive
result = Math.random() * (max+.00000001 - min) + min
while(result > max) {
result = random(min, max, step)
}
} else {
// We need to make sure that max is a multiple of step relative to the
// minimum value. E.g. if we do range 1 to 6 step 2 then our maximum
// should be 5, giving us valid outputs of 1, 3, and 5 in even
// distribution. So even though the user asked for 1-6, 6 is not
// actually a valid output.
result = Math.random() * (Math.floor((max-min+step)/step)*step)
result = Math.floor(result / step) * step + min
}
if (step %1 < 1 && step%1 !== 0) {
return result.toFixed(String(step%1).length-2)
} else {
return result
}
}
class Scoreboard{
constructor(scores) {
this.scores = scores
this.highScore = scores[0].score
// Text size
this.size = 16
// Scrolling through the list
this.frame = 0
this.maxHeight = scores.length * (this.size+8) - height + 50
this.offset = this.size * 3.5
this.wait = 0
}
draw() {
// Our timing logic should go like this:
//
// Show the high scores for 2 seconds. Then start scrolling. Scroll the
// entire list until the last item is visible. Pause for 2 seconds. Then
// blank for 2 seconds. Then repeat.
//
// The math is a bit of a headache because we're using a single unit,
// frames, to control timing, pixel coordinates, and track scrolling
// progress. It could definitely be improved, but it works and I'm tired
// of messing with it.
// wait 120 frames before scrolling
if(this.frame > 120) {
// If our scroll position has reached the maximum height, stop
if (Math.abs(this.offset) > this.maxHeight) {
this.wait++
} else {
// Scroll
this.offset--
}
}
// reset 240 frames after scrolling has finished (we have 120 frames of
// showing nothing)
if(this.wait > 240) {
this.frame = 0
this.wait = 0
this.offset = this.size * 3.5
}
// after we've scrolled, show high scores for 120 frames
if(this.wait < 120) {
textAlign(CENTER, CENTER)
textSize(this.size * 2)
textStyle(BOLD)
fill(100)
text("TOP SCORES", width / 2, this.offset - this.size * 1.5)
textSize(this.size)
for (let i = 0; i < this.scores.length; i++) {
let rightSide = 300 * (this.scores[i].score / this.highScore)
fill(50, 100, 50, .9)
rect(50, i * (this.size + 8) + 2 + this.offset, rightSide, this.size + 4)
fill(0)
textAlign(LEFT, CENTER)
text(this.scores[i].name, 55, i * (this.size + 8) + (this.size + 8) / 2 + this.offset)
textAlign(RIGHT, CENTER)
text(this.scores[i].score, rightSide + 45, i * (this.size + 8) + (this.size + 8) / 2 + this.offset)
}
}
this.frame++
}
}
function setup() {
createCanvas(400, 800, P2D, canvas)
chrisDefaults()
// Generate random leaderboard data
for(let i = 0; i < 50; i++) {
scores.push({name: random(names), score: chrisRandom(80000, 100000, 1000)})
}
scores.sort((a, b) => b.score- a.score)
for(let i = 0; i < 1000; i++) {
particles.push(new Particle())
}
scoreboard = new Scoreboard(scores)
}
function draw() {
background(240, 100, 20)
for (let i = 0; i < particles.length; i++) {
particles[i].draw()
}
scoreboard.draw()
}
You may use all or part of the p5 code seen on this page for your own creations, without restriction. Attribution is appreciated but not required.
This sketch also includes the following sources: p5common.js . Sources are available under their respective licenses.