highscores
parent
b226782295
commit
caa8723afe
|
@ -0,0 +1,6 @@
|
||||||
|
export function debugMsg(msg) {
|
||||||
|
fill(255);
|
||||||
|
stroke(0);
|
||||||
|
textSize(12);
|
||||||
|
text(msg, 24, 24);
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
class HighscoreManager {
|
||||||
|
constructor() {
|
||||||
|
this._deserialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
_deserialize() {
|
||||||
|
let raw = localStorage.getItem('rhythm.hst');
|
||||||
|
if(!raw) {
|
||||||
|
this._highscores = {};
|
||||||
|
this._serialize();
|
||||||
|
} else {
|
||||||
|
this._highscores = JSON.parse(atob(raw));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_serialize() {
|
||||||
|
localStorage.setItem('rhythm.hst', btoa(JSON.stringify(this._highscores)));
|
||||||
|
}
|
||||||
|
|
||||||
|
getHighscore(songId) {
|
||||||
|
return this._highscores[songId]
|
||||||
|
}
|
||||||
|
|
||||||
|
setHighscore(songId, name, score) {
|
||||||
|
let existing = this.getHighscore(songId);
|
||||||
|
if(existing != undefined && existing.score <= score)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._highscores[songId] = {
|
||||||
|
name,
|
||||||
|
score
|
||||||
|
}
|
||||||
|
this._serialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new HighscoreManager();
|
46
main.js
46
main.js
|
@ -1,25 +1,21 @@
|
||||||
import {
|
|
||||||
Entity,
|
|
||||||
Sprite
|
|
||||||
} from './entity.js';
|
|
||||||
import { GameScreen } from './screenGame.js';
|
|
||||||
import { SongSelectScreen } from './screenSongSelect.js';
|
import { SongSelectScreen } from './screenSongSelect.js';
|
||||||
import {
|
|
||||||
KeyHint
|
|
||||||
} from './ui.js'
|
|
||||||
import chartmgr from './chartmgr.js';
|
import chartmgr from './chartmgr.js';
|
||||||
import state from './state.js';
|
import state from './state.js';
|
||||||
|
import { HighscoreInputScreen } from './screenHighscoreInput.js'
|
||||||
|
import { debugMsg } from './debug.js';
|
||||||
|
import highscore from './highscore.js';
|
||||||
|
|
||||||
const charts = [
|
const charts = [
|
||||||
"bozo",
|
"bozo",
|
||||||
"dashstar",
|
"dashstar",
|
||||||
"golddust",
|
"golddust",
|
||||||
"pixelpalace"
|
"pixelpalace",
|
||||||
// "test"
|
// "test"
|
||||||
]
|
]
|
||||||
|
|
||||||
// STUFF
|
// STUFF
|
||||||
let songSelectScreen;
|
let songSelectScreen;
|
||||||
|
export let highscoreInputScreen;
|
||||||
|
|
||||||
// ASSETS
|
// ASSETS
|
||||||
let sndBoop;
|
let sndBoop;
|
||||||
|
@ -32,13 +28,6 @@ function blur(col, blurFactor) {
|
||||||
drawingContext.shadowBlur = blurFactor;
|
drawingContext.shadowBlur = blurFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
function debugMsg(msg) {
|
|
||||||
fill(255);
|
|
||||||
stroke(0);
|
|
||||||
textSize(12);
|
|
||||||
text(msg, 24, 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawFps() {
|
function drawFps() {
|
||||||
let fps = frameRate();
|
let fps = frameRate();
|
||||||
fill(255);
|
fill(255);
|
||||||
|
@ -105,6 +94,18 @@ function draw() {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(window.gameScreen.song.duration() - 0.01 < window.gameScreen.song.currentTime()) {
|
||||||
|
if(
|
||||||
|
highscore.getHighscore(window.gameScreen.chart.id) == undefined
|
||||||
|
|| window.gameScreen.score.score > highscore.getHighscore(this.chart.id)
|
||||||
|
) {
|
||||||
|
highscoreInputScreen = new HighscoreInputScreen(window.gameScreen.chart.id, window.gameScreen.score.score);
|
||||||
|
state.setState("highscoreInput")
|
||||||
|
} else {
|
||||||
|
state.setState("songselect")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
window.gameScreen.calcBeat();
|
window.gameScreen.calcBeat();
|
||||||
window.gameScreen.draw();
|
window.gameScreen.draw();
|
||||||
|
@ -117,6 +118,15 @@ function draw() {
|
||||||
}
|
}
|
||||||
songSelectScreen.draw()
|
songSelectScreen.draw()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "highscoreInput":
|
||||||
|
if(!highscoreInputScreen) {
|
||||||
|
debugMsg(`ERROR: HSI BUT NO SETUP`)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
highscoreInputScreen.draw();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawFps();
|
drawFps();
|
||||||
|
@ -131,6 +141,10 @@ function keyPressed() {
|
||||||
case "songselect":
|
case "songselect":
|
||||||
songSelectScreen.keyPressed()
|
songSelectScreen.keyPressed()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "highscoreInput":
|
||||||
|
highscoreInputScreen.keyPressed();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { PressIndicator, Highway } from './highway.js';
|
||||||
import { Note } from './note.js';
|
import { Note } from './note.js';
|
||||||
import { ScoreManager } from './score.js'
|
import { ScoreManager } from './score.js'
|
||||||
import chartmgr from './chartmgr.js';
|
import chartmgr from './chartmgr.js';
|
||||||
|
import { debugMsg } from './debug.js';
|
||||||
|
|
||||||
export class GameScreen {
|
export class GameScreen {
|
||||||
constructor(chart) {
|
constructor(chart) {
|
||||||
|
@ -109,7 +110,6 @@ export class GameScreen {
|
||||||
if(targetNotes[0].beat + GRACE_BEAT > pressBeat
|
if(targetNotes[0].beat + GRACE_BEAT > pressBeat
|
||||||
&& targetNotes[0].beat - GRACE_BEAT < pressBeat
|
&& targetNotes[0].beat - GRACE_BEAT < pressBeat
|
||||||
&& keyIsDown(KEYS[k.lane])){
|
&& keyIsDown(KEYS[k.lane])){
|
||||||
// console.log("HIT", k.lane)
|
|
||||||
|
|
||||||
// hit note!
|
// hit note!
|
||||||
this.notes.find(n=> n.symbol == k.symbol).pressed = true;
|
this.notes.find(n=> n.symbol == k.symbol).pressed = true;
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
import chartmgr from "./chartmgr.js"
|
||||||
|
import { Sprite } from './entity.js';
|
||||||
|
import highscore from "./highscore.js";
|
||||||
|
import state from "./state.js";
|
||||||
|
import { KeyHint } from "./ui.js";
|
||||||
|
import { sndBoop } from "./main.js";
|
||||||
|
|
||||||
|
class HighscoreSong extends Sprite {
|
||||||
|
static draw(img, name, artist, x, y) {
|
||||||
|
fill(255);
|
||||||
|
noStroke();
|
||||||
|
|
||||||
|
let wth = 0;
|
||||||
|
textSize(18);
|
||||||
|
let artistTextWidth = textWidth(artist);
|
||||||
|
textSize(24);
|
||||||
|
let songTextWidth = textWidth(artist);
|
||||||
|
|
||||||
|
wth += Math.max(artistTextWidth, songTextWidth)
|
||||||
|
wth += 128
|
||||||
|
|
||||||
|
fill(50)
|
||||||
|
rect(x - (wth / 2) - 16, y - 16, wth + 32, 64 + 32, 8)
|
||||||
|
|
||||||
|
fill(255)
|
||||||
|
textSize(18);
|
||||||
|
text(artist, x + 64 + 16 - (wth / 2), y + 56)
|
||||||
|
|
||||||
|
textSize(24);
|
||||||
|
text(name, x + 64 + 16 - (wth / 2), y + 32)
|
||||||
|
|
||||||
|
image(img, x - (wth / 2), y, 64, 64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class HighscoreInputScreen {
|
||||||
|
constructor(...args) {
|
||||||
|
this._init(...args);
|
||||||
|
|
||||||
|
this.name = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
async _init(songId, score) {
|
||||||
|
this.song = await chartmgr.get(songId);
|
||||||
|
this.cover = chartmgr.covers.get(songId);
|
||||||
|
this.score = score;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw() {
|
||||||
|
if(!this.song)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let bigTitle = "NEW HIGHSCORE!";
|
||||||
|
fill(255);
|
||||||
|
textSize(64);
|
||||||
|
let bigTitleW = (width - textWidth(bigTitle));
|
||||||
|
text(bigTitle, bigTitleW / 2, 128);
|
||||||
|
|
||||||
|
HighscoreSong.draw(this.cover, this.song.name, this.song.artist,
|
||||||
|
width / 2,
|
||||||
|
(height / 2) - 128
|
||||||
|
)
|
||||||
|
|
||||||
|
fill(255);
|
||||||
|
textSize(48);
|
||||||
|
text(this.score, (bigTitleW / 2) + 128 + 32, 256 + 128 + 32 + 4);
|
||||||
|
|
||||||
|
fill(255);
|
||||||
|
textSize(24);
|
||||||
|
text("NAME:", bigTitleW / 2, 256 + 128);
|
||||||
|
|
||||||
|
for(let i = 0; i < 3; i++) {
|
||||||
|
fill(255);
|
||||||
|
if(i == this.name.length && (frameCount % 32) > 16) {
|
||||||
|
console.log(i)
|
||||||
|
fill(255,255,255,0)
|
||||||
|
}
|
||||||
|
text((this.name.length > i) ? this.name[i] : "_", (bigTitleW / 2) + (i*20), 256 + 128 + 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.name.length > 2)
|
||||||
|
KeyHint.draw("Enter", (bigTitleW / 2) + 8 + 64, 256 + 128 + 36 - 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPressed() {
|
||||||
|
switch(keyCode) {
|
||||||
|
case 8: // backspace
|
||||||
|
this.name = this.name.slice(0, this.name.length - 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 13: //enter
|
||||||
|
if(this.name.length > 2) {
|
||||||
|
sndBoop.play();
|
||||||
|
highscore.setHighscore(this.song.id, this.name, this.score)
|
||||||
|
state.setState("songselect")
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.name.length > 2)
|
||||||
|
return
|
||||||
|
|
||||||
|
// special characters are > 1 letter (eg. SHIFT)
|
||||||
|
if(key.length > 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// regex to check if letter
|
||||||
|
if(!key.match(/[a-z]/i))
|
||||||
|
return
|
||||||
|
|
||||||
|
sndBoop.play();
|
||||||
|
this.name += key.toUpperCase();
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ import state from './state.js';
|
||||||
import chartmgr from './chartmgr.js';
|
import chartmgr from './chartmgr.js';
|
||||||
import { KeyHint } from './ui.js'
|
import { KeyHint } from './ui.js'
|
||||||
import { sndBoop, sndSongselect } from './main.js';
|
import { sndBoop, sndSongselect } from './main.js';
|
||||||
|
import highscore from './highscore.js';
|
||||||
|
|
||||||
export class SongSelectScreen {
|
export class SongSelectScreen {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -25,16 +26,19 @@ export class SongSelectScreen {
|
||||||
// current song
|
// current song
|
||||||
image(this.covers[this.curSelection], (width-256)/2, (height-256)/2, 256, 256)
|
image(this.covers[this.curSelection], (width-256)/2, (height-256)/2, 256, 256)
|
||||||
|
|
||||||
|
// song name
|
||||||
textSize(48);
|
textSize(48);
|
||||||
text(this.songs[this.curSelection].name,
|
text(this.songs[this.curSelection].name,
|
||||||
(width / 2) - (textWidth(this.songs[this.curSelection].name) / 2),
|
(width / 2) - (textWidth(this.songs[this.curSelection].name) / 2),
|
||||||
height - 128 - 36);
|
height - 128 - 36);
|
||||||
|
|
||||||
|
// song artist
|
||||||
textSize(24);
|
textSize(24);
|
||||||
text(this.songs[this.curSelection].artist,
|
text(this.songs[this.curSelection].artist,
|
||||||
(width / 2) - (textWidth(this.songs[this.curSelection].artist) / 2),
|
(width / 2) - (textWidth(this.songs[this.curSelection].artist) / 2),
|
||||||
height - 128);
|
height - 128);
|
||||||
|
|
||||||
|
// song meta
|
||||||
let etcmeta = this.songs[this.curSelection].difficulty + " - " + this.songs[this.curSelection].len
|
let etcmeta = this.songs[this.curSelection].difficulty + " - " + this.songs[this.curSelection].len
|
||||||
|
|
||||||
textSize(18);
|
textSize(18);
|
||||||
|
@ -42,6 +46,8 @@ export class SongSelectScreen {
|
||||||
(width - textWidth(etcmeta) ) / 2,
|
(width - textWidth(etcmeta) ) / 2,
|
||||||
height - 128 + 32);
|
height - 128 + 32);
|
||||||
|
|
||||||
|
|
||||||
|
// cover art side
|
||||||
let nextSelection = (this.curSelection + 1 > this.songs.length - 1)
|
let nextSelection = (this.curSelection + 1 > this.songs.length - 1)
|
||||||
? 0
|
? 0
|
||||||
: this.curSelection + 1
|
: this.curSelection + 1
|
||||||
|
@ -55,6 +61,30 @@ export class SongSelectScreen {
|
||||||
|
|
||||||
image(this.covers[nextSelection],
|
image(this.covers[nextSelection],
|
||||||
(width - 128) - 32, (height - 128) / 2, 128, 128);
|
(width - 128) - 32, (height - 128) / 2, 128, 128);
|
||||||
|
|
||||||
|
noStroke()
|
||||||
|
textSize(24);
|
||||||
|
|
||||||
|
if(highscore.getHighscore(this.songs[this.curSelection].id) != undefined) {
|
||||||
|
let hsw = textWidth("HIGH SCORE")
|
||||||
|
text("HIGH SCORE",
|
||||||
|
((width - hsw) / 2) - 48,
|
||||||
|
height - 512 - 64
|
||||||
|
);
|
||||||
|
|
||||||
|
textSize(16);
|
||||||
|
text(highscore.getHighscore(this.songs[this.curSelection].id).name,
|
||||||
|
((width - hsw) / 2) - 48,
|
||||||
|
height - 512 - 32
|
||||||
|
);
|
||||||
|
|
||||||
|
textAlign(RIGHT);
|
||||||
|
text(highscore.getHighscore(this.songs[this.curSelection].id).score,
|
||||||
|
(((width + 256) / 2)),
|
||||||
|
height - 512 - 32
|
||||||
|
);
|
||||||
|
textAlign(LEFT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async keyPressed() {
|
async keyPressed() {
|
||||||
|
|
6
ui.js
6
ui.js
|
@ -38,11 +38,13 @@ export class CurrentSongUi extends Sprite {
|
||||||
static draw(img, name, artist) {
|
static draw(img, name, artist) {
|
||||||
fill(255);
|
fill(255);
|
||||||
|
|
||||||
|
image(img, (width / 2) + 175, 40 - 32 + 6, 64, 64 + 4);
|
||||||
|
|
||||||
textSize(18);
|
textSize(18);
|
||||||
text(artist, (width / 2) + 175 + 40, 40 + 24)
|
text(artist, (width / 2) + 175 + 40 + 32 + 4, 40 + 24 + 4)
|
||||||
|
|
||||||
textSize(24);
|
textSize(24);
|
||||||
text(name, (width / 2) + 175 + 40, 40)
|
text(name, (width / 2) + 175 + 40 + 32 + 4, 40 + 4)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue