Skip to content

Commit

Permalink
Add initial audio, update scene init
Browse files Browse the repository at this point in the history
  • Loading branch information
jpweeks committed Mar 1, 2015
1 parent 3fea5d4 commit eb1fb65
Show file tree
Hide file tree
Showing 13 changed files with 310 additions and 24 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Expand Up @@ -19,3 +19,5 @@
*.as binary

*.mp3 binary
*.ogg binary
*.wav binary
3 changes: 2 additions & 1 deletion bower.json
Expand Up @@ -5,6 +5,7 @@
"dependencies": {
"red-sass": "~0.2.0",
"particulate": "0.3.1",
"handlebars": "1.3.0"
"handlebars": "1.3.0",
"howler.js": "~1.1.25"
}
}
1 change: 1 addition & 0 deletions grunt/config/copy.js
Expand Up @@ -13,6 +13,7 @@ module.exports = function (config) {
config.source + '*.{ico,txt}',
config.source + '.htaccess',
config.source + 'img/{,*/}*.{jpg,jpeg,png,webp,gif}',
config.source + 'audio/{,*/}*.{mp3,ogg,wav}',
config.source + 'fonts/*',
config.source + 'lib/modernizr/modernizr.js'
],
Expand Down
1 change: 1 addition & 0 deletions pages/_base.html
Expand Up @@ -30,6 +30,7 @@ <h1>Medusae</h1>

<div class="controls">
<div id="toggle-info" class="controls-button" title="About"></div>
<div id="toggle-audio" class="controls-button" title="Audio"></div>
</div>

<div id="container"></div>
Expand Down
Binary file added static/audio/bg-loop.mp3
Binary file not shown.
Binary file added static/audio/bg-loop.ogg
Binary file not shown.
15 changes: 14 additions & 1 deletion static/js/app.js
Expand Up @@ -13,11 +13,24 @@ require('js/items/*');
require('js/scenes/*');
require('js/controllers/*');

var scene = App.MainScene.create();
var audioToggle = App.ToggleController.create({
name : 'audio'
});

App.ModalController.create({
name : 'info'
});

setTimeout(function () {
var scene = App.MainScene.create();
scene.initItems();
scene.initAudio();
scene.appendRenderer();
scene.loop.start();

audioToggle.addListener(scene, 'toggleAudio');
}, 0);

setTimeout(function () {
audioToggle.toggleState();
}, 2000);
123 changes: 123 additions & 0 deletions static/js/controllers/AudioController.js
@@ -0,0 +1,123 @@
/*global Howl*/
var Tweens = App.Tweens;

App.AudioController = AudioController;
function AudioController(config) {
this._isEnabled = true;
this._urls = {};
this._soundNames = [];
this._volume = {};
this._volumeTarget = {};
this._playing = {};

this.baseUrl = config.baseUrl;
this.sounds = {};

this.tweenVolume = Tweens.factorTween(this._volume, 0.05);
}

AudioController.create = App.ctor(AudioController);

AudioController.prototype.addSound = function (path, name) {
name = name || path;
var url = this.baseUrl + path;

this._soundNames.push(name);

this._urls[name] = [
url + '.mp3',
url + '.ogg'
];
};

AudioController.prototype.createSound = function (name, params) {
var sound = this.sounds[name];
if (sound) { return sound; }

params = params || {};
params.urls = this._urls[name];

sound = new Howl(params);
sound.sid = name;

this._volume[name] = 0;
this._volumeTarget[name] = params.volume || 0;
this.sounds[name] = sound;
return sound;
};

AudioController.prototype.getSound = function (name) {
return this.sounds[name] || this.createSound(name);
};

AudioController.prototype.playSound = function (name) {
if (!this._isEnabled) { return; }
var sound = this.getSound(name);
if (!sound) { return; }
if (!sound._loaded) {
setTimeout(this.playSound.bind(this, name), 250);
return;
}

this._playing[name] = true;
sound.play();
};

AudioController.prototype.pauseSound = function (name) {
if (!this._playing[name]) { return; }
this.sounds[name].pause();
this._playing[name] = false;
};

AudioController.prototype.setVolume = function (name, volume) {
this._volumeTarget[name] = volume;
};

AudioController.prototype.stopSound = function (name) {
this.getSound(name).stop();
};

AudioController.prototype.stopAllSounds = function () {
var names = this._soundNames;
var sounds = this.sounds;
var sound;

for (var i = 0, il = names.length; i < il; i ++) {
sound = sounds[names[i]];
if (!sound) { continue; }
sound.stop();
}
};

AudioController.prototype.enableSound = function () {
this._isEnabled = true;
};

AudioController.prototype.disableSound = function () {
this._isEnabled = false;
this.stopAllSounds();
};

AudioController.prototype.update = function () {
var sounds = this.sounds;
var names = this._soundNames;
var playing = this._playing;
var volumeTarget = this._volumeTarget;
var name, sound, volume;

for (var i = 0, il = names.length; i < il; i ++) {
name = names[i];
sound = sounds[name];
if (!(sound && sound._loaded)) { continue; }

// Update volume
volume = this.tweenVolume(name, volumeTarget[name]);

if (volume < 0.0001 && playing[name]) {
sound.pause();
} else {
if (!playing[name]) { this.playSound(name); }
sound.volume(volume);
}
}
};
42 changes: 42 additions & 0 deletions static/js/controllers/ToggleController.js
@@ -0,0 +1,42 @@
App.ToggleController = ToggleController;
function ToggleController(config) {
var name = config.name;
var toggle = this.toggle = document.getElementById('toggle-' + name);

this.isActive = config.isActive != null ? config.isActive : false;
this._toggleClassName = toggle.className;
this._listeners = [];

toggle.addEventListener('click', this.toggleState.bind(this), false);
}

ToggleController.create = App.ctor(ToggleController);

ToggleController.prototype.addListener = function (context, fn) {
this._listeners.push({
context : context,
fn : fn
});
};

ToggleController.prototype.triggerListeners = function () {
var listeners = this._listeners;
var listener;

for (var i = 0, il = listeners.length; i < il; i ++) {
listener = listeners[i];
listener.context[listener.fn].call(listener.context, this.isActive);
}
};

ToggleController.prototype.toggleState = function (event) {
if (this.isActive) {
this.toggle.className = this._toggleClassName;
this.isActive = false;
} else {
this.toggle.className += ' active';
this.isActive = true;
}

this.triggerListeners();
};
2 changes: 2 additions & 0 deletions static/js/libs.js
Expand Up @@ -15,3 +15,5 @@ require('lib-extras/three/postprocessing/ShaderPass');
require('lib-extras/three/postprocessing/TexturePass');
require('lib-extras/three/postprocessing/MaskPass');
require('lib-extras/three/postprocessing/BloomPass');

require('lib/howler.js/howler.js');
98 changes: 77 additions & 21 deletions static/js/scenes/MainScene.js
Expand Up @@ -13,10 +13,8 @@ function MainScene() {
this.initRenderer();
this.initFxComposer();
this.addPostFx();
this.onWindowResize();

this.initControls();
this.initItems();
this.onWindowResize();

camera.position.set(200, 100, 0);
camera.lookAt(scene.position);
Expand All @@ -29,6 +27,10 @@ function MainScene() {

MainScene.create = App.ctor(MainScene);

// ..................................................
// Graphics
//

MainScene.prototype.initRenderer = function () {
var renderer = this.renderer = new THREE.WebGLRenderer({
devicePixelRatio : this.pxRatio,
Expand All @@ -37,8 +39,15 @@ MainScene.prototype.initRenderer = function () {

renderer.setClearColor(0x111111, 1);
renderer.autoClear = false;
};

MainScene.prototype.appendRenderer = function () {
var canvas = this.renderer.domElement;

this.el.appendChild(renderer.domElement);
this.el.appendChild(canvas);
setTimeout(function () {
canvas.className = 'active';
}, 0);
};

MainScene.prototype.initFxComposer = function () {
Expand Down Expand Up @@ -104,6 +113,27 @@ MainScene.prototype.initItems = function () {
dust.addTo(this.scene);
};

MainScene.prototype.onWindowResize = function () {
var width = window.innerWidth;
var height = window.innerHeight;
var pxRatio = this.pxRatio;
var postWidth = width * pxRatio;
var postHeight = height * pxRatio;

this.width = width;
this.height = height;

this.camera.aspect = width / height;
this.camera.updateProjectionMatrix();

this.renderer.setSize(width, height);
this.composer.setSize(postWidth, postHeight);
};

// ..................................................
// Controls
//

MainScene.prototype.initControls = function () {
var controls = new THREE.TrackballControls(this.camera, this.el);

Expand All @@ -122,23 +152,6 @@ MainScene.prototype.initControls = function () {
this.controlsUp = controls.object.up;
};

MainScene.prototype.onWindowResize = function () {
var width = window.innerWidth;
var height = window.innerHeight;
var pxRatio = this.pxRatio;
var postWidth = width * pxRatio;
var postHeight = height * pxRatio;

this.width = width;
this.height = height;

this.camera.aspect = width / height;
this.camera.updateProjectionMatrix();

this.renderer.setSize(width, height);
this.composer.setSize(postWidth, postHeight);
};

MainScene.prototype.onDocumentKey = function (event) {
switch (event.which) {
case 32:
Expand All @@ -148,12 +161,55 @@ MainScene.prototype.onDocumentKey = function (event) {
}
};

// ..................................................
// Audio
//

MainScene.prototype.initAudio = function () {
var audio = this.audio = App.AudioController.create({
baseUrl : App.STATIC_URL + 'audio/'
});

audio.addSound('bg-loop', 'bgLoop');
audio.createSound('bgLoop', {
loop : true
});
};

MainScene.prototype.beginAudio = function () {
var audio = this.audio;

audio.playSound('bgLoop');
audio.setVolume('bgLoop', 1);
this._audioIsPlaying = true;
};

MainScene.prototype.pauseAudio = function () {
var audio = this.audio;

audio.setVolume('bgLoop', 0);
this._audioIsPlaying = false;
};

MainScene.prototype.toggleAudio = function () {
if (this._audioIsPlaying) {
this.pauseAudio();
} else {
this.beginAudio();
}
};

// ..................................................
// Loop
//

MainScene.prototype.update = function (delta) {
var up = this.controlsUp;
var gravity = this.gravity;

this.gravityForce.set(up.x * gravity, up.y * gravity, up.z * gravity);
this.medusae.update(delta);
this.audio.update(delta);
};

MainScene.prototype.render = function (delta, stepProgress) {
Expand Down

0 comments on commit eb1fb65

Please sign in to comment.