GithubHelp home page GithubHelp logo

melodycollider's Introduction

Melody Collider

Melody Colider Example

An online game based on collecting melodies. Implemented almost entirely in Vanilla Javascript, with visual rendering done in Canvas API, audio processing done in Tone.js, and keyboard event handling done in keymaster.js.

play Melody Collider

Gameplay

Colorful music orbs collide with each other inside of a grid. Each orb is associated with their own color and musical note. At the beginning of each level, these orbs play together in sequence, forming a melody. You will navigate this grid as a gray orb, collecting the melody in the sequence it was played. Avoid colliding with the wrong orbs, which will bring your melody out of sequence. Safety Zones are provided for you to shelter you from colliding with other orbs, as well as giving you the ability to trigger the melody sequence you have collected so far, followed by the remaining melody you must collect. Collecting the full melody advances you to the next level.

Implementation

Game Rendering

The GameView class determines which part of the game will be rendered at a given time. The start() function begins the process of running a new game:

// game_view.js

GameView.prototype.start = function () {
    window.setInterval(this.renderGame.bind(this), 20);
    this.bindKeyHandlers(this.game);
    this.game.menuStart();
};

setInterval() calls the function renderGame() to render the game at a refresh rate of 50fps. The Game class contains flags which keep track of the various states of the game, conditional statements within renderGame() will utilize these flags to determine which aspect of the game will be rendered.

// game_view.js

GameView.prototype.renderGame = function (e) {
    if (this.game.isPlayingMenuScreen()) {
        this.game.playMenuScreen(this.menuCtx);
    }
    else {
        if (this.game.isGamePaused()) {
            this.game.playPauseScreen(this.pauseCtx);
        }
        else { // at this point, gameplay is rendered
            this.game.drawGrid(this.gridCtx, 'level ' + this.game.currentLevel, this.headerCtx, this.audioCtx);
            this.game.drawSafetyZone(this.safetyZoneCtx, this.instructionsCtx, 'level ' + this.game.currentLevel);
            if (!this.game.isWon) {
                this.game.drawHeader(this.headerCtx)
                this.game.drawAudioIcon(this.audioCtx);
            }
            if (this.game.isPlayingIntroSequence()) {
                this.game.playIntroSequence(this.gameCtx, 'level ' + this.game.currentLevel);
            }
            else { // can only play a melodic sequence inside of a Safety Zone
                if (this.game.isPlayingSequence()) {
                    this.game.playSequence(this.gameCtx, null);
                }
                // render all the moving parts of the game
                this.game.moveObjects(this.gridCtx, this.gameCtx, this.safetyZoneCtx);
                this.game.draw(this.gameCtx);
            }
        }
    }
};

bindKeyHandlers() uses the key() function from the keymaster.js library to listen to any keyboard event calls pertaining to the game, and responds with the appropriate asynchonous callback function:

GameView.prototype.bindKeyHandlers = function (game) {
    let that = this;
    key('up', function () {game.player.direction('up')});
    key('down', function () {game.player.direction('down')});
    key('left', function () {game.player.direction('left')});
    key('right', function () {game.player.direction('right')});
    key('space', function () {if(game.player.isSafe) {game.isSequence = true}});
    key('up', function () {game.menuAction('up')});
    key('down', function () {game.menuAction('down')});
    key('left', function () {game.menuAction('left')});
    key('right', function () {game.menuAction('right')});
    key('enter', function () {game.menuAction('select', that.menuCtx)});
    key('left', function () {game.pauseAction('left')});
    key('right', function () {game.pauseAction('right')});
    key('enter', function () {game.pauseAction('select', that.pauseCtx, that.gameCtx, that.headerCtx, that.gridCtx, that.safetyZoneCtx, that.instructionsCtx, that.audioCtx)});
    key('m', function () {game.toggleAudio()});
}

GameView then calls Game's menuStart() function to toggle the isMenu flag to true. This begins the process of rendering the title screen menu:

Game.prototype.menuStart = function () {
    this.isMenu = true;
}

melodycollider's People

Contributors

umnum avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.