Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- let song;
- let notes = [];
- let columns = [870, 980, 1090, 1200]; // x positions for each column
- let speed = 9; // speed of falling notes
- let score = 0; // score from hitting notes/missing notes
- let combo = 0;
- let currentSong = null;
- let nextNoteIndex = 0;
- let currentState = 0;
- let highlightedSongIndex = 0; // which song is currently selected
- let timingOffset = 0; // milliseconds
- const gameState = {
- MENU: 0,
- GAME: 1,
- END: 2,
- };
- let songs = [
- {
- name: "It's Going Down Now",
- file: "song1.mp3",
- timings: [527.9791666666666, 1327.9791666666667, 2010.6458333333333, 2559.9791666666665, 3199.9791666666665, 3797.3125, 4431.979166666666, 4949.3125, 5471.979166666666, 5951.979166666667, 6570.645833333334, 7178.645833333333, 7717.3125, 8341.3125, 8927.979166666666, 9471.979166666668, 10047.979166666666, 10650.645833333334, 11237.3125, 11839.979166666666, 12469.3125, 13077.3125, 13631.979166666668, 14101.3125, 14629.3125, 15178.645833333332, 15738.645833333332, 16261.312499999998, 16810.645833333332, 17397.3125, 17919.979166666668, 18559.979166666668], // milliseconds of when notes spawn
- columns: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], // initially all 1, change them to 0, 1, 2, 3 for four columns
- durations: [180.10000000149012, 115.10000000149012, 209.80000000447035, 205.29999999701977, 290, 264.59999999403954, 274.79999999701977, 240, 235, 199.89999999850988, 264.5, 235.10000000149012, 209.70000000298023, 195, 204.69999999552965, 195, 205.19999999552965, 224.69999999552965, 169.79999999701977, 164.60000000149012, 180.20000000298023, 190.20000000298023, 175.20000000298023, 118.30000000447035, 140.20000000298023, 180.40000000596046, 125.10000000149012, 144.89999999850988, 120.10000000149012, 124.70000000298023, 89.5, 125.20000000298023] // note durations. 0 = tap note, > 0 = hold note
- },
- {
- name: "No More What Ifs",
- file: "song2.mp3",
- timings: [],
- columns: [],
- durations: [] // note durations. 0 = tap note, >0 = hold note
- }
- ];
- function preload() {
- songs.forEach(song => {
- song.sound = loadSound(song.file); // Load sound files
- });
- }
- function setup() {
- createCanvas(1280, 720);
- }
- function draw() {
- background(0); // Always clear screen
- if (currentState === gameState.MENU) {
- drawMenu();
- } else if (currentState === gameState.GAME) {
- drawGame();
- // Draw score and combo if in game
- fill(255);
- textSize(32);
- textAlign(LEFT);
- text("Score: " + score, 20, 40);
- text("Combo: " + combo, 20, 80);
- }
- }
- function drawMenu() {
- textSize(48);
- fill(255);
- textAlign(CENTER, CENTER);
- text("Song Select", width / 2, 100);
- textSize(32);
- songs.forEach((song, i) => {
- let y = 250 + i * 60; // spacing songs vertically
- if (i === highlightedSongIndex) {
- fill(255, 200, 0); // highlighted
- text("> " + song.name, width / 2, y);
- } else {
- fill(255); // normal
- text(song.name, width / 2, y);
- }
- });
- }
- function drawGame() {
- // Draw hit zones
- columns.forEach((col, i) => {
- fill(50);
- rect(col - 25, height - 100, 50, 10);
- });
- // Manage notes
- if (song.isPlaying()) {
- let currentTime = (song.currentTime() * 1000) + timingOffset; // Correcting timing offset
- // Adjust for note fall time
- let fallTimeMs = (height - 100) / speed * (1000 / 60);
- // Spawn new notes based on the current time
- while (nextNoteIndex < currentSong.timings.length && currentTime >= currentSong.timings[nextNoteIndex] - fallTimeMs) {
- spawnNote(
- currentSong.columns[nextNoteIndex],
- currentSong.timings[nextNoteIndex],
- currentSong.durations[nextNoteIndex]
- );
- nextNoteIndex++;
- }
- }
- // Update and show notes
- for (let i = notes.length - 1; i >= 0; i--) {
- notes[i].update();
- notes[i].show();
- if (notes[i].y > height + 100) { // give some grace before removing
- notes.splice(i, 1); // remove missed notes
- combo = 0; // break combo if missed
- score -= 25; // reduce score for missed note
- }
- }
- }
- function spawnNote(column, startTime, duration) {
- notes.push(new Note(columns[column], startTime, duration));
- }
- class Note {
- constructor(x, startTime, duration) {
- this.x = x;
- this.startTime = startTime; // when the note spawns
- this.duration = duration; // how long you must hold
- this.y = 0;
- this.size = 40;
- this.holding = false; // if player is holding it
- this.heldTime = 0; // how long the player held
- }
- update() {
- this.y += speed;
- if (this.holding) {
- this.heldTime += deltaTime;
- }
- }
- show() {
- fill(255);
- if (this.duration > 0) {
- rect(this.x - this.size / 2, this.y - this.size / 2, this.size, this.duration / 10); // Longer rectangle for hold notes
- } else {
- rect(this.x - this.size / 2, this.y - this.size / 2, this.size, this.size); // Normal tap note
- }
- }
- }
- function keyPressed() {
- if (currentState === gameState.MENU) {
- // Navigating through songs
- if (key === 'q' || key === 'Q') {
- highlightedSongIndex = (highlightedSongIndex - 1 + songs.length) % songs.length;
- }
- if (key === 'e' || key === 'E') {
- highlightedSongIndex = (highlightedSongIndex + 1) % songs.length;
- }
- // Check ENTER key to select song
- if (keyCode === ENTER) {
- selectSong(highlightedSongIndex);
- }
- } else if (currentState === gameState.GAME) {
- // Handle key presses during the game state
- for (let i = notes.length - 1; i >= 0; i--) {
- if (keyMatches(notes[i])) {
- checkHit(notes[i], i);
- return;
- }
- }
- }
- }
- function keyReleased() {
- for (let i = notes.length - 1; i >= 0; i--) {
- if (notes[i].holding) {
- if (notes[i].heldTime >= notes[i].duration - 100) { // allow small error
- score += 50; // Good hold
- combo++;
- } else {
- score -= 25; // Released too early
- }
- notes.splice(i, 1); // Remove the hold note
- }
- }
- }
- function checkHit(note, index) {
- if (isNearTarget(note)) {
- if (note.duration > 0) {
- note.holding = true; // Hold notes are marked holding
- } else {
- notes.splice(index, 1); // Tap notes are deleted immediately
- }
- score += 25;
- combo++;
- } else {
- combo = 0; // Reset combo if missed
- score -= 25; // Decrease score for missed note
- }
- }
- function selectSong(index) {
- currentSong = songs[index];
- notes = [];
- nextNoteIndex = 0;
- song = currentSong.sound;
- song.play();
- song.jump(0); // ensure it starts from 0
- currentState = gameState.GAME;
- }
- // helpers
- function keyMatches(note) {
- if (note.x === columns[0] && ['d', 'D'].includes(key)) return true;
- if (note.x === columns[1] && ['f', 'F'].includes(key)) return true;
- if (note.x === columns[2] && ['j', 'J'].includes(key)) return true;
- if (note.x === columns[3] && ['k', 'K'].includes(key)) return true;
- return false;
- }
- function isNearTarget(note) {
- return abs(note.y - (height - 100)) < 75;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement