982 lines
23 KiB
JavaScript
982 lines
23 KiB
JavaScript
|
"use strict";
|
||
|
import { kaboom, easings, tween, tweentypes } from "../deps.js";
|
||
|
import { charts } from "./charts.js";
|
||
|
|
||
|
// initialize context
|
||
|
kaboom({
|
||
|
width: 700,
|
||
|
height: 400,
|
||
|
background: [ 0, 0, 0 ],
|
||
|
crisp: true,
|
||
|
touchToMouse: true,
|
||
|
canvas: document.querySelector("#kaboom"),
|
||
|
font: "MidSim",
|
||
|
scale: 1,
|
||
|
|
||
|
});
|
||
|
var ismobile = isTouch();
|
||
|
|
||
|
load(new Promise((resolve, reject) => {
|
||
|
loadFont("unscii", "sprites/unscii_8x8.png", 8, 8, {chars: " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"});
|
||
|
loadFont("MidSim", "sprites/MidSimFont2.png", 10, 10, {chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz:;><^%-.!?/()[]\"'|1234567890"});
|
||
|
// Music
|
||
|
loadSound("gameover", "sounds/gameover.mp3");
|
||
|
//
|
||
|
|
||
|
// Sounds
|
||
|
loadSound("nullHit", "sounds/nullHit.mp3");
|
||
|
loadSound("score", "sounds/score.mp3");
|
||
|
loadSound("metro", "sounds/metro.wav");
|
||
|
loadSound("explode", "sounds/explode.mp3");
|
||
|
//
|
||
|
|
||
|
//Menus
|
||
|
loadSprite("bgCake", "sprites/bgCake.png");
|
||
|
loadSprite("jellybeanTitle", "sprites/jellybeanTitle.png");
|
||
|
loadSprite("logo", "sprites/logo.png");
|
||
|
loadSprite("jellybeanFail", "sprites/jellybeanFail.png");
|
||
|
//
|
||
|
|
||
|
// Main Game
|
||
|
loadSprite("noteClick", "sprites/noteClick.png", {
|
||
|
sliceX: 4,
|
||
|
sliceY: 2,
|
||
|
anims: {
|
||
|
idle: {
|
||
|
from: 7,
|
||
|
to: 7,
|
||
|
speed: 30
|
||
|
},
|
||
|
click: {
|
||
|
from: 0,
|
||
|
to: 7,
|
||
|
speed: 60
|
||
|
}
|
||
|
},
|
||
|
})
|
||
|
|
||
|
for (let ided in charts) {
|
||
|
console.log("Loading game assets...");
|
||
|
charts[ided].events.preload();
|
||
|
console.log("Assets of song " + charts[ided].name + " loaded.");
|
||
|
}
|
||
|
|
||
|
resolve("All assets loaded.");
|
||
|
}));
|
||
|
|
||
|
scene("Game", (idx, noTrans) => {
|
||
|
var song = charts[idx.song].id; //Also Chart access
|
||
|
var char = charts[idx.song].characters[idx.character][0];
|
||
|
var hitsound = "hitsound" + charts[idx.song].characters[idx.character][0];
|
||
|
var chart = charts[idx.song].chart;
|
||
|
var crochet = ((60 / charts[idx.song].bpm) * 1000);
|
||
|
var board = width() - strumLine;
|
||
|
var curBeat;
|
||
|
var prevBeat;
|
||
|
var prevStep;
|
||
|
var curStep;
|
||
|
var autoplay = false;
|
||
|
var debugMode = false;
|
||
|
var score = 0;
|
||
|
var combo = 0;
|
||
|
var health = 1;
|
||
|
var font = "MidSim";
|
||
|
if (char == "MarkyMark") {
|
||
|
font = "unscii";
|
||
|
}
|
||
|
|
||
|
// Music
|
||
|
var strumLine = width() / 2;
|
||
|
const music = play(charts[idx.song].id, {
|
||
|
volume: 1,
|
||
|
loop: false
|
||
|
});
|
||
|
const underlay = play("score", {
|
||
|
volume: 1,
|
||
|
loop: false
|
||
|
});
|
||
|
music.pause()
|
||
|
wait(charts[idx.song].speed, () => {
|
||
|
underlay.pause();
|
||
|
music.play();
|
||
|
underlay.play(music.time() + charts[idx.song].speed);
|
||
|
});
|
||
|
|
||
|
// Sprites
|
||
|
layers([
|
||
|
"bg",
|
||
|
"JELLYBEAN",
|
||
|
"SKELETONS",
|
||
|
"fg",
|
||
|
"ui0",
|
||
|
"ui1"
|
||
|
], "ui0");
|
||
|
var players = {
|
||
|
main: 0,
|
||
|
empty: 0,
|
||
|
};
|
||
|
var bg;
|
||
|
var tweenVals = {
|
||
|
fade: 1,
|
||
|
triggered: false
|
||
|
}
|
||
|
tween(tweenVals, ["fade"], 1, 1, 0, easings.easeOutCirc, tweentypes.NORMAL);
|
||
|
if (!charts[idx.song].makeScript.customChar) {
|
||
|
players.main = add([
|
||
|
sprite(char + song),
|
||
|
layer("JELLYBEAN"),
|
||
|
"dances",
|
||
|
pos(charts[idx.song].characters[idx.character][2], charts[idx.song].characters[idx.character][3]),
|
||
|
scale(charts[idx.song].scale)
|
||
|
]);
|
||
|
}
|
||
|
if (!charts[idx.song].makeScript.customBG) {
|
||
|
bg = add([
|
||
|
sprite(song + "BG0"),
|
||
|
layer("bg"),
|
||
|
scale(charts[idx.song].scale)
|
||
|
]);
|
||
|
const fg = add([
|
||
|
sprite(song + "FG0"),
|
||
|
(song == "faith" ? layer("bg") : layer("fg")),
|
||
|
scale(charts[idx.song].scale)
|
||
|
]);
|
||
|
}
|
||
|
var script = charts[idx.song].makeScript.script(players, char, bg);
|
||
|
if (script.returnType != undefined && script.returnType == "character") {
|
||
|
players.main = script.main;
|
||
|
players.empty = script.empty;
|
||
|
}
|
||
|
const noteClick = add([
|
||
|
sprite("noteClick"),
|
||
|
scale(0.25),
|
||
|
pos(strumLine, 15)
|
||
|
])
|
||
|
const bspButton = add([
|
||
|
pos(0, 0),
|
||
|
color(CYAN),
|
||
|
text(ismobile ? "<" : "BACKSPACE TO EXIT", {
|
||
|
size: ismobile? 32 : 20, // 48 pixels tall
|
||
|
}),
|
||
|
area({
|
||
|
offset: ismobile ? vec2(canvas.offsetLeft, canvas.offsetTop) : vec2(0, 0),
|
||
|
}),
|
||
|
"back"
|
||
|
])
|
||
|
const entButton = add([
|
||
|
pos(width(), 0),
|
||
|
origin("topright"),
|
||
|
color(YELLOW),
|
||
|
text(ismobile ? "||" : "ENTER TO PAUSE", {
|
||
|
size: ismobile? 32 : 20, // 48 pixels tall
|
||
|
}),
|
||
|
area({
|
||
|
offset: ismobile ? vec2(canvas.offsetLeft, canvas.offsetTop) : vec2(0, 0),
|
||
|
}),
|
||
|
"ent"
|
||
|
])
|
||
|
// Gameplay
|
||
|
onUpdate(() => {
|
||
|
if (health > 1) health = 1;
|
||
|
if (health < 0) {
|
||
|
health = 0;
|
||
|
if(!tweenVals.triggered) {
|
||
|
tween(tweenVals, ["fade"], 1, 0, 1, easings.easeOutCirc, tweentypes.NORMAL, function () {
|
||
|
underlay.stop();
|
||
|
music.stop();
|
||
|
go("Lose", score, idx);
|
||
|
});
|
||
|
underlay.pause();
|
||
|
music.pause();
|
||
|
tweenVals.triggered = true;
|
||
|
}
|
||
|
}
|
||
|
if (music.time() > music.duration() && health >= 0) {
|
||
|
if(!tweenVals.triggered) {
|
||
|
tween(tweenVals, ["fade"], 1, 0, 1, easings.easeOutCirc, tweentypes.NORMAL, function () {
|
||
|
go("Help");
|
||
|
});
|
||
|
tweenVals.triggered = true;
|
||
|
}
|
||
|
}
|
||
|
strumLine = lerp(18, width() / 2, health);
|
||
|
noteClick.pos.x = strumLine - 5;
|
||
|
curBeat = Math.floor(((music.time() * 1000) / crochet) * 10) / 10;
|
||
|
curStep = Math.floor((music.time() * 1000) / (crochet / 4));
|
||
|
prevBeat = Math.floor(((underlay.time() * 1000) / crochet));
|
||
|
prevStep = Math.floor((underlay.time() * 1000) / (crochet / 4));
|
||
|
if (!get("bar" + prevBeat).length) {
|
||
|
var bar = add([
|
||
|
prevBeat % 4 == 0 ? rect(3, 50) : rect(2, 50),
|
||
|
pos(width(), 20),
|
||
|
color(255, 255, 255),
|
||
|
("bar" + prevBeat),
|
||
|
{
|
||
|
mainBar: prevBeat % 4 == 0,
|
||
|
created: underlay.time()
|
||
|
},
|
||
|
"bar"
|
||
|
]);
|
||
|
}
|
||
|
if (get("note" + prevStep).length <= 0) {
|
||
|
makeNote(charts[idx.song].chart[Math.floor(prevStep)]);
|
||
|
}
|
||
|
if (!underlay.isPaused()) {
|
||
|
every("bar", (j) => {
|
||
|
j.pos.x = lerp(width(), strumLine, (underlay.time() - j.created) / charts[idx.song].speed);
|
||
|
if(j.pos.x <= strumLine) {
|
||
|
beatHit();
|
||
|
if (debugMode) play("metro", {detune: j.mainBar ? 200 : 0});
|
||
|
destroy(j);
|
||
|
}
|
||
|
if (charts[idx.song].events.onBeat != undefined) {
|
||
|
charts[idx.song].events.onBeat(curBeat);
|
||
|
}
|
||
|
});
|
||
|
every("note", (j) => {
|
||
|
j.pos.x = lerp(width(), strumLine, (underlay.time() - j.created) / charts[idx.song].speed);
|
||
|
if(autoplay) {
|
||
|
if(j.pos.x <= strumLine && !j.empty) {
|
||
|
play(hitsound);
|
||
|
players.main.play("talk"); //Check this area later, you want to add in Note Modularity!
|
||
|
destroy(j);
|
||
|
}
|
||
|
} else {
|
||
|
if(j.pos.x <= strumLine - 20 && !j.empty) {
|
||
|
score -= 200;
|
||
|
destroy(j);
|
||
|
play("explode");
|
||
|
players.main.play("miss");
|
||
|
shake(5);
|
||
|
combo = 0;
|
||
|
health -= 0.1;
|
||
|
}
|
||
|
}
|
||
|
if(j.pos.x <= strumLine && j.empty) {
|
||
|
if (!j.normal) {
|
||
|
j.function(j.empty, curBeat, j.type);
|
||
|
}
|
||
|
destroy(j);
|
||
|
players.empty?.play("talk");
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
})
|
||
|
var mt;
|
||
|
onKeyPress("enter", () => {
|
||
|
if (!underlay.isPaused()) {
|
||
|
underlay.pause();
|
||
|
music.pause();
|
||
|
mt = [underlay.time(), music.time()];
|
||
|
} else {
|
||
|
underlay.play(mt[0]);
|
||
|
music.play(mt[1]);
|
||
|
}
|
||
|
});
|
||
|
onKeyPress("space", () => {judgeHitsLol()});
|
||
|
onKeyPress("backspace", () => {
|
||
|
tween(tweenVals, ["fade"], 1, 0, 1, easings.easeOutCirc, tweentypes.NORMAL, function () {
|
||
|
underlay.stop();
|
||
|
music.stop();
|
||
|
go("Help");
|
||
|
});
|
||
|
underlay.pause();
|
||
|
music.pause();
|
||
|
});
|
||
|
onKeyPress("a", () => {autoplay = !autoplay});
|
||
|
onKeyPress("d", () => {debugMode = !debugMode});
|
||
|
onClick("back", () => {
|
||
|
tween(tweenVals, ["fade"], 1, 0, 1, easings.easeOutCirc, tweentypes.NORMAL, function () {
|
||
|
underlay.stop();
|
||
|
music.stop();
|
||
|
go("Help");
|
||
|
});
|
||
|
underlay.pause();
|
||
|
music.pause();
|
||
|
});
|
||
|
onClick("ent", () => {
|
||
|
if (!underlay.isPaused()) {
|
||
|
underlay.pause();
|
||
|
music.pause();
|
||
|
mt = [underlay.time(), music.time()];
|
||
|
} else {
|
||
|
underlay.play(mt[0]);
|
||
|
music.play(mt[1]);
|
||
|
}
|
||
|
});
|
||
|
onClick(() => {judgeHitsLol()});
|
||
|
onDraw(() => {
|
||
|
drawLine({
|
||
|
p1: vec2(0, 20),
|
||
|
p2: vec2(width(), 20),
|
||
|
width: 2,
|
||
|
color: rgb(255, 255, 255),
|
||
|
})
|
||
|
drawLine({
|
||
|
p1: vec2(0, 70),
|
||
|
p2: vec2(width(), 70),
|
||
|
width: 2,
|
||
|
color: rgb(255, 255, 255),
|
||
|
})
|
||
|
drawLines({ // 80 * 240, 20 * 60
|
||
|
pts: [ vec2(strumLine, 18), vec2(strumLine + 10, 18), vec2(strumLine + 10, 72), vec2(strumLine, 72), vec2(strumLine, 18) ],
|
||
|
width: 2,
|
||
|
pos: vec2(100, 200),
|
||
|
color: rgb(255, 255, 255),
|
||
|
})
|
||
|
drawText({
|
||
|
text: "MID-SIMULATOR DEMO",
|
||
|
size: 20,
|
||
|
pos: vec2(0, height() - 20),
|
||
|
font: font
|
||
|
});
|
||
|
if (debugMode) {
|
||
|
drawText({
|
||
|
text: underlay.time() * 1000,
|
||
|
size: 20,
|
||
|
pos: vec2(0, 20),
|
||
|
font: font
|
||
|
});
|
||
|
drawText({
|
||
|
text: curBeat,
|
||
|
size: 20,
|
||
|
pos: vec2(0, 40),
|
||
|
font: font
|
||
|
});
|
||
|
drawText({
|
||
|
text: prevStep + "/" + (charts[idx.song].chart.length - 1),
|
||
|
size: 20,
|
||
|
pos: vec2(0, 60),
|
||
|
font: font
|
||
|
});
|
||
|
drawText({
|
||
|
text: (charts[idx.song].chart[Math.floor(prevStep)] ? charts[idx.song].chart[Math.floor(prevStep)] : "."),
|
||
|
size: 20,
|
||
|
pos: vec2(0, 80),
|
||
|
font: font
|
||
|
});
|
||
|
drawText({
|
||
|
text: (charts[idx.song].chart[Math.floor(curStep)] ? charts[idx.song].chart[Math.floor(curStep)] : "."),
|
||
|
size: 20,
|
||
|
pos: vec2(0, 100),
|
||
|
font: font
|
||
|
});
|
||
|
drawText({
|
||
|
text: "Health: " + health,
|
||
|
size: 20,
|
||
|
pos: vec2(strumLine, 120),
|
||
|
font: font
|
||
|
});
|
||
|
}
|
||
|
drawText({
|
||
|
text: "Score: " + score,
|
||
|
size: 20,
|
||
|
pos: vec2(strumLine, 80),
|
||
|
font: font
|
||
|
});
|
||
|
drawText({
|
||
|
text: "Combo: " + combo,
|
||
|
size: 20,
|
||
|
pos: vec2(strumLine, 100),
|
||
|
font: font
|
||
|
});
|
||
|
if (autoplay) {
|
||
|
drawText({
|
||
|
text: "AUTOPLAY",
|
||
|
size: 20,
|
||
|
pos: vec2(strumLine, debugMode? 140: 120),
|
||
|
font: font
|
||
|
});
|
||
|
}
|
||
|
drawRect({
|
||
|
width: 702,
|
||
|
height: 402,
|
||
|
pos: vec2(-1, -1),
|
||
|
color: BLACK,
|
||
|
opacity: tweenVals.fade
|
||
|
})
|
||
|
})
|
||
|
|
||
|
//Functions
|
||
|
|
||
|
function makeNote(letter) {
|
||
|
if (charts[idx.song].noteTypes.hasOwnProperty(letter)) {
|
||
|
charts[idx.song].noteTypes[letter](underlay.time(), prevStep, char);
|
||
|
}
|
||
|
}
|
||
|
function judgeHitsLol() {
|
||
|
var iv = false;
|
||
|
var hits = 0;
|
||
|
every("note", (j) => {
|
||
|
if (!iv) {
|
||
|
if (!j.empty) {
|
||
|
var str = "No Rating";
|
||
|
var theColor = WHITE;
|
||
|
if(j.pos.x >= strumLine - 20) {
|
||
|
if(j.pos.x <= strumLine + 22) {
|
||
|
hits++;
|
||
|
iv = true;
|
||
|
if (!j.normal) {
|
||
|
j.function(j.empty, curBeat, j.type);
|
||
|
}
|
||
|
destroy(j); //Destroys note. No score.
|
||
|
noteClick.play("click");
|
||
|
combo += 1;
|
||
|
str = "MID";
|
||
|
theColor = RED;
|
||
|
}
|
||
|
if(j.pos.x <= strumLine + 12) {
|
||
|
play(hitsound); //Plays sound!
|
||
|
players.main.play("talk");
|
||
|
score += 20;
|
||
|
health += 0.01;
|
||
|
str = "Perfect!";
|
||
|
theColor = MAGENTA;
|
||
|
}
|
||
|
if(j.pos.x <= strumLine + 5) {
|
||
|
score += 50;
|
||
|
health += 0.02;
|
||
|
str = "Perfect!!";
|
||
|
}
|
||
|
if(j.pos.x <= strumLine - 3) {
|
||
|
score += 50;
|
||
|
health -= 0.01;
|
||
|
str = "Perfect!";
|
||
|
}
|
||
|
if(j.pos.x <= strumLine - 8) {
|
||
|
score -= 100;
|
||
|
health -= 0.02;
|
||
|
str = "Overshot";
|
||
|
theColor = CYAN;
|
||
|
}
|
||
|
}
|
||
|
if (str != "No Rating") {
|
||
|
var origpos = strumLine - 16;
|
||
|
var ratingtxt = add([
|
||
|
text(str, {
|
||
|
size: 30, // 48 pixels tall
|
||
|
}),
|
||
|
pos(origpos, 48),
|
||
|
color(theColor),
|
||
|
origin("right")
|
||
|
]);
|
||
|
tween(ratingtxt.pos, ["y"], 5, 48, 300, easings.easeOutSine, tweentypes.NORMAL);
|
||
|
tween(ratingtxt, ["opacity"], 5, 1, 0, easings.easeOutSine, tweentypes.NORMAL, function() {
|
||
|
destroy(ratingtxt);
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
if (hits <= 0) {
|
||
|
play("nullHit");
|
||
|
}
|
||
|
}
|
||
|
function beatHit() {
|
||
|
every("dances", (obj) => {
|
||
|
if (obj.curAnim() != "talk" && obj.curAnim() != "miss") {
|
||
|
obj.play("idle");
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
scene("Help", (noTrans) => {
|
||
|
var index = {
|
||
|
character: 0,
|
||
|
song: 0
|
||
|
}
|
||
|
var tweenVals = {
|
||
|
fade: 0
|
||
|
}
|
||
|
if (!noTrans) tween(tweenVals, ["fade"], 1, 1, 0, easings.easeOutCirc, tweentypes.NORMAL);
|
||
|
const bg = add([
|
||
|
sprite("bgCake")
|
||
|
]);
|
||
|
onDraw(() => {
|
||
|
if (!ismobile) {
|
||
|
drawText({
|
||
|
text: "D: ENABLE DEBUG MODE",
|
||
|
size: 30,
|
||
|
pos: vec2(25, 25)
|
||
|
});
|
||
|
drawText({
|
||
|
text: "A: ENABLE AUTOPLAY",
|
||
|
size: 30,
|
||
|
pos: vec2(25, 60)
|
||
|
});
|
||
|
}
|
||
|
drawText({
|
||
|
text: ismobile ? "TAP TO HIT NOTES" : "SPACE/CLICK: HIT NOTE",
|
||
|
size: 30,
|
||
|
pos: ismobile ? vec2(25, 60) : vec2(25, 95)
|
||
|
});
|
||
|
drawText({
|
||
|
text: charts[index.song].characters[index.character][1] + " ("+ (index.character + 1) +"/"+ charts[index.song].characters.length +")",
|
||
|
size: 30,
|
||
|
pos: vec2(width() / 2, 200),
|
||
|
origin: "top"
|
||
|
});
|
||
|
drawText({
|
||
|
text: charts[index.song].name,
|
||
|
size: 30,
|
||
|
pos: vec2(width() / 2, 160),
|
||
|
origin: "top"
|
||
|
});
|
||
|
drawSprite({
|
||
|
sprite: charts[index.song].characters[index.character][0] + "Pre",
|
||
|
width: 64,
|
||
|
height: 64,
|
||
|
pos: vec2((width() / 2) - 34, 248)
|
||
|
});
|
||
|
drawRect({
|
||
|
width: 702,
|
||
|
height: 402,
|
||
|
pos: vec2(-1, -1),
|
||
|
color: BLACK,
|
||
|
opacity: tweenVals.fade
|
||
|
})
|
||
|
})
|
||
|
add([
|
||
|
pos(0, 140),
|
||
|
rect(700, 200),
|
||
|
color(0, 0, 0)
|
||
|
])
|
||
|
var lt = add([
|
||
|
pos(10, 200),
|
||
|
text("<", {
|
||
|
size: 30
|
||
|
}),
|
||
|
area({
|
||
|
height: 30,
|
||
|
offset: ismobile ? vec2(canvas.offsetLeft, canvas.offsetTop) : vec2(0, 0),
|
||
|
width: 30,
|
||
|
cursor: "pointer"
|
||
|
}),
|
||
|
"LeftText"
|
||
|
])
|
||
|
var rt = add([
|
||
|
pos(width() - 10, 200),
|
||
|
origin("topright"),
|
||
|
text(">", {
|
||
|
size: 30
|
||
|
}),
|
||
|
area({
|
||
|
height: 30,
|
||
|
offset: ismobile ? vec2(canvas.offsetLeft, canvas.offsetTop) : vec2(0, 0),
|
||
|
width: 30,
|
||
|
cursor: "pointer"
|
||
|
}),
|
||
|
"RightText"
|
||
|
])
|
||
|
var dt = add([
|
||
|
pos(10, 160),
|
||
|
text("%", {
|
||
|
size: 30
|
||
|
}),
|
||
|
area({
|
||
|
height: 30,
|
||
|
offset: ismobile ? vec2(canvas.offsetLeft, canvas.offsetTop) : vec2(0, 0),
|
||
|
width: 30,
|
||
|
cursor: "pointer"
|
||
|
}),
|
||
|
"DownText"
|
||
|
])
|
||
|
var ut = add([
|
||
|
pos(width() - 10, 160),
|
||
|
origin("topright"),
|
||
|
text("^", {
|
||
|
size: 30
|
||
|
}),
|
||
|
area({
|
||
|
height: 30,
|
||
|
offset: ismobile ? vec2(canvas.offsetLeft, canvas.offsetTop) : vec2(0, 0),
|
||
|
width: 30,
|
||
|
cursor: "pointer"
|
||
|
}),
|
||
|
"UpText"
|
||
|
])
|
||
|
var clickText = add([
|
||
|
pos(width() / 2, height() - 45),
|
||
|
text(ismobile ? "TAP HERE TO START" : "SPACE TO START", {
|
||
|
size: 30
|
||
|
}),
|
||
|
origin("top"),
|
||
|
area({
|
||
|
height: 30,
|
||
|
offset: ismobile ? vec2(canvas.offsetLeft, canvas.offsetTop) : vec2(0, 0),
|
||
|
width: 700,
|
||
|
cursor: "pointer"
|
||
|
}),
|
||
|
"TEXT TEXT"
|
||
|
])
|
||
|
function changeIdx(amt) {
|
||
|
index.character += amt;
|
||
|
if (index.character < 0) {
|
||
|
index.character = charts[index.song].characters.length - 1;
|
||
|
} else if (index.character >= charts[index.song].characters.length) {
|
||
|
index.character = 0;
|
||
|
}
|
||
|
}
|
||
|
function changeSongIdx(amt) {
|
||
|
index.song += amt;
|
||
|
index.character = 0;
|
||
|
if (index.song < 0) {
|
||
|
index.song = charts.length - 1;
|
||
|
} else if (index.song >= charts.length) {
|
||
|
index.song = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
onKeyPress("left", () => {changeIdx(-1)});
|
||
|
onKeyPress("right", () => {changeIdx(1)});
|
||
|
onKeyPress("down", () => {changeSongIdx(-1)});
|
||
|
onKeyPress("up", () => {changeSongIdx(1)});
|
||
|
onKeyPress("`", () => {go("Chart", index.song)});
|
||
|
onKeyPress("D", () => {go("Chart", index.song)});
|
||
|
onKeyPress("/", () => {go("Chart", index.song)});
|
||
|
onKeyPress("7", () => {go("Chart", index.song)});
|
||
|
lt.onClick(() => {changeIdx(-1)});
|
||
|
rt.onClick(() => {changeIdx(1)});
|
||
|
dt.onClick(() => {changeSongIdx(-1)});
|
||
|
ut.onClick(() => {changeSongIdx(1)});
|
||
|
onKeyPress("space", () => {
|
||
|
tween(tweenVals, ["fade"], 1, 0, 1, easings.easeOutCirc, tweentypes.NORMAL, function () {
|
||
|
go("Game", index);
|
||
|
});
|
||
|
});
|
||
|
clickText.onClick(() => {go("Game", index);/*losemus.stop();*/});
|
||
|
});
|
||
|
|
||
|
scene("Title", () => {
|
||
|
const bg = add([
|
||
|
sprite("bgCake")
|
||
|
]);
|
||
|
const jb = add([
|
||
|
sprite("jellybeanTitle"),
|
||
|
pos(0, height() - 320)
|
||
|
]);
|
||
|
const logo = add([
|
||
|
sprite("logo"),
|
||
|
pos(0, 0),
|
||
|
scale(0.5, 0.5)
|
||
|
]);
|
||
|
onDraw(() => {
|
||
|
drawText({
|
||
|
text: "SPACE TO START",
|
||
|
size: 30,
|
||
|
origin: "top",
|
||
|
pos: vec2(width() / 2, height() - 45)
|
||
|
});
|
||
|
})
|
||
|
onKeyPress("space", () => {go("Help", true);/*losemus.stop();*/});
|
||
|
onClick(() => {go("Help", true);/*losemus.stop();*/});
|
||
|
onTouchStart(() => {go("Help", true);/*losemus.stop();*/});
|
||
|
});
|
||
|
|
||
|
scene("Lose", (score, song) => {
|
||
|
const lost = add([
|
||
|
sprite("jellybeanFail"),
|
||
|
"dances",
|
||
|
pos((width() / 2) - 162, height() / 2 - 162)
|
||
|
])
|
||
|
const losemus = play("gameover", {
|
||
|
volume: 1,
|
||
|
loop: true
|
||
|
});
|
||
|
onDraw(() => {
|
||
|
drawText({
|
||
|
text: "OUCHIE!",
|
||
|
size: 60,
|
||
|
pos: vec2(0, height() - 120)
|
||
|
});
|
||
|
drawText({
|
||
|
text: ismobile ? "TAP TO RESTART" : "SPACE TO RESTART",
|
||
|
size: 30,
|
||
|
pos: vec2(0, height() - 60)
|
||
|
});
|
||
|
drawText({
|
||
|
text: "SCORE: " + score,
|
||
|
size: 30,
|
||
|
pos: vec2(0, height() - 30)
|
||
|
});
|
||
|
})
|
||
|
onKeyPress("space", () => {go("Game", song);losemus.stop();});
|
||
|
onClick(() => {go("Game", song);losemus.stop();});
|
||
|
});
|
||
|
|
||
|
scene("Chart", (idx) => {
|
||
|
var chart = charts[idx].chart;
|
||
|
var crochet = ((60 / charts[idx].bpm) * 1000);
|
||
|
var curBeat;
|
||
|
var curStep;
|
||
|
var songTime = 0;
|
||
|
var tool = "J";
|
||
|
const music = play(charts[idx].id, {
|
||
|
volume: 1,
|
||
|
loop: false
|
||
|
});
|
||
|
music.pause();
|
||
|
|
||
|
var lastTargeted = 4;
|
||
|
var tempChart = Array.from(Array(Math.floor((music.duration() * 1000) / (crochet / 4))), () => ".");
|
||
|
// Incredibly redundant, sadly I don't care
|
||
|
var coords = [
|
||
|
width() * 0.1,
|
||
|
width() * 0.2,
|
||
|
width() * 0.3,
|
||
|
width() * 0.4,
|
||
|
width() * 0.5,
|
||
|
width() * 0.6,
|
||
|
width() * 0.7,
|
||
|
width() * 0.8,
|
||
|
width() * 0.9
|
||
|
];
|
||
|
var theEmpty = add([
|
||
|
pos(width() * 0.2, height() * 0.8),
|
||
|
rect(60, 60),
|
||
|
text(".", {
|
||
|
size: 48, // 48 pixels tall
|
||
|
width: 60
|
||
|
}),
|
||
|
color(255, 255, 255),
|
||
|
outline(4, WHITE),
|
||
|
origin("center"),
|
||
|
area(),
|
||
|
"theEmpty"
|
||
|
]);
|
||
|
var theJ = add([
|
||
|
pos(width() * 0.4, height() * 0.8),
|
||
|
rect(60, 60),
|
||
|
text("J", {
|
||
|
size: 48, // 48 pixels tall
|
||
|
width: 60
|
||
|
}),
|
||
|
color(255, 255, 255),
|
||
|
outline(4, WHITE),
|
||
|
origin("center"),
|
||
|
area(),
|
||
|
"theJ"
|
||
|
]);
|
||
|
var theP = add([
|
||
|
pos(width() * 0.6, height() * 0.8),
|
||
|
rect(60, 30),
|
||
|
text("P", {
|
||
|
size: 24, // 48 pixels tall
|
||
|
width: 60
|
||
|
}),
|
||
|
color(255, 255, 255),
|
||
|
outline(4, WHITE),
|
||
|
origin("center"),
|
||
|
area(),
|
||
|
"theP"
|
||
|
]);
|
||
|
var theD = add([
|
||
|
pos(width() * 0.6, height() * 0.8 + 30),
|
||
|
rect(60, 30),
|
||
|
text("D", {
|
||
|
size: 24, // 48 pixels tall
|
||
|
width: 60
|
||
|
}),
|
||
|
color(255, 255, 255),
|
||
|
outline(4, WHITE),
|
||
|
origin("center"),
|
||
|
area(),
|
||
|
"theD"
|
||
|
]);
|
||
|
var consoleButton = add([
|
||
|
pos(width() * 0.8, height() * 0.8),
|
||
|
rect(60, 60),
|
||
|
text("EXPORT", {
|
||
|
size: 30, // 48 pixels tall
|
||
|
}),
|
||
|
color(255, 255, 255),
|
||
|
outline(4, WHITE),
|
||
|
origin("center"),
|
||
|
area(),
|
||
|
"consoleButton"
|
||
|
]);
|
||
|
onClick("theEmpty", (o) => {tool = "."})
|
||
|
onClick("theJ", (o) => {tool = "J"})
|
||
|
onClick("theP", (o) => {tool = "P"})
|
||
|
onClick("theD", (o) => {tool = "D"})
|
||
|
onClick("consoleButton", (o) => {console.log(tempChart.join(""));})
|
||
|
onUpdate(() => {
|
||
|
curBeat = Math.floor(((music.time() * 1000) / crochet) * 10) / 10;
|
||
|
curStep = Math.floor((music.time() * 1000) / (crochet / 4));
|
||
|
if (mousePos().y >= height() * 0.4 && mousePos().y < (height() / 2) + 34) { // I shouldve used a Switch Case here :/
|
||
|
if (mousePos().x < width() * 0.15) {
|
||
|
// blk0
|
||
|
lastTargeted = 0;
|
||
|
} else if (mousePos().x < width() * 0.25) {
|
||
|
// blk1
|
||
|
lastTargeted = 1;
|
||
|
} else if (mousePos().x < width() * 0.35) {
|
||
|
// blk2
|
||
|
lastTargeted = 2;
|
||
|
} else if (mousePos().x < width() * 0.45) {
|
||
|
// blk3
|
||
|
lastTargeted = 3;
|
||
|
} else if (mousePos().x < width() * 0.55) {
|
||
|
// blk4
|
||
|
lastTargeted = 4;
|
||
|
} else if (mousePos().x < width() * 0.65) {
|
||
|
// blk5
|
||
|
lastTargeted = 5;
|
||
|
} else if (mousePos().x < width() * 0.75) {
|
||
|
// blk6
|
||
|
lastTargeted = 6;
|
||
|
} else if (mousePos().x < width() * 0.85) {
|
||
|
// blk7
|
||
|
lastTargeted = 7;
|
||
|
} else if (mousePos().x < width()) {
|
||
|
// blk8
|
||
|
lastTargeted = 8;
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
onMouseDown(() => {
|
||
|
if (mousePos().y >= height() * 0.4 && mousePos().y < (height() / 2) + 34) {
|
||
|
tempChart[curStep + lastTargeted] = tool;
|
||
|
}
|
||
|
});
|
||
|
onDraw(() => {
|
||
|
drawText({
|
||
|
text: songTime * 1000,
|
||
|
size: 20,
|
||
|
pos: vec2(0, )
|
||
|
});
|
||
|
drawText({
|
||
|
text: music.time() * 1000,
|
||
|
size: 20,
|
||
|
pos: vec2(0, 20)
|
||
|
});
|
||
|
drawText({
|
||
|
text: curBeat,
|
||
|
size: 20,
|
||
|
pos: vec2(0, 40)
|
||
|
});
|
||
|
drawText({
|
||
|
text: curStep + "/" + (tempChart.length - 1),
|
||
|
size: 20,
|
||
|
pos: vec2(0, 60)
|
||
|
});
|
||
|
drawText({
|
||
|
text: tool,
|
||
|
size: 50,
|
||
|
pos: vec2(width() / 2, height() * 0.65),
|
||
|
origin: "center"
|
||
|
});
|
||
|
drawLine({
|
||
|
p1: vec2(coords[lastTargeted] - 30, (height() / 2) + 30),
|
||
|
p2: vec2(coords[lastTargeted] + 30, (height() / 2) + 30),
|
||
|
width: 4,
|
||
|
color: rgb(255, 0, 0),
|
||
|
})
|
||
|
drawText({
|
||
|
text: tempChart[curStep] ? tempChart[curStep] : "",
|
||
|
size: 30,
|
||
|
pos: vec2(coords[0], height() / 2),
|
||
|
color: curStep % 4 == 0 ? RED : MAGENTA,
|
||
|
origin: "center"
|
||
|
})
|
||
|
drawText({
|
||
|
text: tempChart[curStep + 1] ? tempChart[curStep + 1] : "",
|
||
|
size: 30,
|
||
|
pos: vec2(coords[1], height() / 2),
|
||
|
color: (curStep + 1) % 4 == 0 ? RED : WHITE,
|
||
|
origin: "center"
|
||
|
})
|
||
|
drawText({
|
||
|
text: tempChart[curStep + 2] ? tempChart[curStep + 2] : "",
|
||
|
size: 30,
|
||
|
pos: vec2(coords[2], height() / 2),
|
||
|
color: (curStep + 2) % 4 == 0 ? RED : WHITE,
|
||
|
origin: "center"
|
||
|
})
|
||
|
drawText({
|
||
|
text: tempChart[curStep + 3] ? tempChart[curStep + 3] : "",
|
||
|
size: 30,
|
||
|
pos: vec2(coords[3], height() / 2),
|
||
|
color: (curStep + 3) % 4 == 0 ? RED : WHITE,
|
||
|
origin: "center"
|
||
|
})
|
||
|
drawText({
|
||
|
text: tempChart[curStep + 4] ? tempChart[curStep + 4] : "",
|
||
|
size: 30,
|
||
|
pos: vec2(coords[4], height() / 2),
|
||
|
color: (curStep + 4) % 4 == 0 ? RED : WHITE,
|
||
|
origin: "center"
|
||
|
})
|
||
|
drawText({
|
||
|
text: tempChart[curStep + 5] ? tempChart[curStep + 5] : "",
|
||
|
size: 30,
|
||
|
pos: vec2(coords[5], height() / 2),
|
||
|
color: (curStep + 5) % 4 == 0 ? RED : WHITE,
|
||
|
origin: "center"
|
||
|
})
|
||
|
drawText({
|
||
|
text: tempChart[curStep + 6] ? tempChart[curStep + 6] : "",
|
||
|
size: 30,
|
||
|
pos: vec2(coords[6], height() / 2),
|
||
|
color: (curStep + 6) % 4 == 0 ? RED : WHITE,
|
||
|
origin: "center"
|
||
|
})
|
||
|
drawText({
|
||
|
text: tempChart[curStep + 7] ? tempChart[curStep + 7] : "",
|
||
|
size: 30,
|
||
|
pos: vec2(coords[7], height() / 2),
|
||
|
color: (curStep + 7) % 4 == 0 ? RED : WHITE,
|
||
|
origin: "center"
|
||
|
})
|
||
|
drawText({
|
||
|
text: tempChart[curStep + 8] ? tempChart[curStep + 8] : "",
|
||
|
size: 30,
|
||
|
pos: vec2(coords[8], height() / 2),
|
||
|
color: (curStep + 8) % 4 == 0 ? RED : WHITE,
|
||
|
origin: "center"
|
||
|
})
|
||
|
});
|
||
|
|
||
|
onKeyPress("left", () => {
|
||
|
music.pause();
|
||
|
songTime = songTime - ((crochet / 4) / 1000);
|
||
|
try {
|
||
|
music.play(songTime);
|
||
|
} catch (err) {
|
||
|
console.log(err);
|
||
|
songTime = 0;
|
||
|
music.play(0);
|
||
|
}
|
||
|
music.pause();
|
||
|
});
|
||
|
onKeyPress("right", () => {
|
||
|
music.pause();
|
||
|
songTime = songTime + ((crochet / 4) / 1000);
|
||
|
try {
|
||
|
music.play(songTime);
|
||
|
} catch (err) {
|
||
|
console.log(err);
|
||
|
songTime = 0;
|
||
|
music.play(0);
|
||
|
}
|
||
|
music.pause();
|
||
|
});
|
||
|
onKeyPress("space", () => {
|
||
|
if (!music.isPaused()) {
|
||
|
music.pause();
|
||
|
songTime = music.time();
|
||
|
} else {
|
||
|
try {
|
||
|
music.play(songTime);
|
||
|
} catch (err) {
|
||
|
console.log(err);
|
||
|
songTime = 0;
|
||
|
music.play(0);
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
|
||
|
go("Title");
|