/games/pacman/pacman.js |
@@ -1,9 +1,13 @@ |
/*************************************************************************/ |
/* Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 */ |
/*************************************************************************/ |
/* Original by: Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> */ |
/*************************************************************************/ |
/*jslint browser: true, undef: true, eqeqeq: true, nomen: true, white: true */ |
/*global window: false, document: false */ |
|
/* |
* fix looped audio |
* add fruits + levels |
* fix what happens when a ghost is eaten (should go back to base) |
* do proper ghost mechanics (blinky/wimpy etc) |
*/ |
|
var NONE = 4, |
UP = 3, |
LEFT = 2, |
@@ -684,9 +688,92 @@ |
}; |
}; |
|
Pacman.Audio = function(game) { |
|
var files = [], |
endEvents = [], |
progressEvents = [], |
playing = []; |
|
function load(name, path, cb) { |
|
var f = files[name] = document.createElement("audio"); |
|
progressEvents[name] = function(event) { progress(event, name, cb); }; |
|
f.addEventListener("canplaythrough", progressEvents[name], true); |
f.setAttribute("preload", "true"); |
f.setAttribute("autobuffer", "true"); |
f.setAttribute("src", path); |
f.pause(); |
}; |
|
function progress(event, name, callback) { |
if (event.loaded === event.total && typeof callback === "function") { |
callback(); |
files[name].removeEventListener("canplaythrough", |
progressEvents[name], true); |
} |
}; |
|
function disableSound() { |
for (var i = 0; i < playing.length; i++) { |
files[playing[i]].pause(); |
files[playing[i]].currentTime = 0; |
} |
playing = []; |
}; |
|
function ended(name) { |
|
var i, tmp = [], found = false; |
|
files[name].removeEventListener("ended", endEvents[name], true); |
|
for (i = 0; i < playing.length; i++) { |
if (!found && playing[i]) { |
found = true; |
} else { |
tmp.push(playing[i]); |
} |
} |
playing = tmp; |
}; |
|
function play(name) { |
if (!game.soundDisabled()) { |
endEvents[name] = function() { ended(name); }; |
playing.push(name); |
files[name].addEventListener("ended", endEvents[name], true); |
files[name].play(); |
} |
}; |
|
function pause() { |
for (var i = 0; i < playing.length; i++) { |
files[playing[i]].pause(); |
} |
}; |
|
function resume() { |
for (var i = 0; i < playing.length; i++) { |
files[playing[i]].play(); |
} |
}; |
|
return { |
"disableSound" : disableSound, |
"load" : load, |
"play" : play, |
"pause" : pause, |
"resume" : resume |
}; |
}; |
|
var PACMAN = (function () { |
|
var state = WAITING, |
audio = null, |
ghosts = [], |
ghostSpecs = ["#00FFDE", "#FF0000", "#FFB8DE", "#FFB847"], |
eatenCount = 0, |
@@ -708,7 +795,7 @@ |
|
function drawScore(text, position) { |
ctx.fillStyle = "#FFFFFF"; |
ctx.font = "12px monospace"; |
ctx.font = "12px BDCartoonShoutRegular"; |
ctx.fillText(text, |
(position["new"]["x"] / 10) * map.blockSize, |
((position["new"]["y"] + 5) / 10) * map.blockSize); |
@@ -716,11 +803,15 @@ |
|
function dialog(text) { |
ctx.fillStyle = "#FFFF00"; |
ctx.font = "14px monospace"; |
ctx.font = "14px BDCartoonShoutRegular"; |
var width = ctx.measureText(text).width, |
x = ((map.width * map.blockSize) - width) / 2; |
ctx.fillText(text, x, (map.height * 10) + 8); |
} |
|
function soundDisabled() { |
return localStorage["soundDisabled"] === "true"; |
}; |
|
function startLevel() { |
user.resetPosition(); |
@@ -727,6 +818,7 @@ |
for (var i = 0; i < ghosts.length; i += 1) { |
ghosts[i].reset(); |
} |
audio.play("start"); |
timerStart = tick; |
setState(COUNTDOWN); |
} |
@@ -743,12 +835,17 @@ |
function keyDown(e) { |
if (e.keyCode === KEY.N) { |
startNewGame(); |
} else if (e.keyCode === KEY.S) { |
audio.disableSound(); |
localStorage["soundDisabled"] = !soundDisabled(); |
} else if (e.keyCode === KEY.P && state === PAUSE) { |
audio.resume(); |
map.draw(ctx); |
setState(stored); |
} else if (e.keyCode === KEY.P) { |
stored = state; |
setState(PAUSE); |
audio.pause(); |
map.draw(ctx); |
dialog("Paused"); |
} else if (state !== PAUSE) { |
@@ -797,13 +894,13 @@ |
ctx.fill(); |
} |
|
ctx.fillStyle = "#FF0000"; |
ctx.font = "bold 16px monospace"; |
ctx.fillStyle = !soundDisabled() ? "#00FF00" : "#FF0000"; |
ctx.font = "bold 16px sans-serif"; |
//ctx.fillText("♪", 10, textBase); |
ctx.fillText("s", 10, textBase); |
|
ctx.fillStyle = "#FFFF00"; |
ctx.font = "14px monospace"; |
ctx.font = "14px BDCartoonShoutRegular"; |
ctx.fillText("Score: " + user.theScore(), 30, textBase); |
ctx.fillText("Level: " + level, 260, textBase); |
} |
@@ -838,7 +935,8 @@ |
|
for (i = 0, len = ghosts.length; i < len; i += 1) { |
if (collided(userPos, ghostPos[i]["new"])) { |
if (ghosts[i].isVunerable()) { |
if (ghosts[i].isVunerable()) { |
audio.play("eatghost"); |
ghosts[i].eat(); |
eatenCount += 1; |
nScore = eatenCount * 50; |
@@ -847,6 +945,7 @@ |
setState(EATEN_PAUSE); |
timerStart = tick; |
} else if (ghosts[i].isDangerous()) { |
audio.play("die"); |
setState(DYING); |
timerStart = tick; |
} |
@@ -905,6 +1004,7 @@ |
} |
|
function eatenPill() { |
audio.play("eatpill"); |
timerStart = tick; |
eatenCount = 0; |
for (i = 0; i < ghosts.length; i += 1) { |
@@ -940,6 +1040,7 @@ |
|
ctx = canvas.getContext('2d'); |
|
audio = new Pacman.Audio({"soundDisabled":soundDisabled}); |
map = new Pacman.Map(blockSize); |
user = new Pacman.User({ |
"completedLevel" : completedLevel, |
@@ -952,7 +1053,34 @@ |
} |
|
map.draw(ctx); |
dialog("Loading ..."); |
|
var extension = Modernizr.audio.ogg ? 'ogg' : 'mp3'; |
|
var audio_files = [ |
["start", root + "audio/opening_song." + extension], |
["die", root + "audio/die." + extension], |
["eatghost", root + "audio/eatghost." + extension], |
["eatpill", root + "audio/eatpill." + extension], |
["eating", root + "audio/eating.short." + extension], |
["eating2", root + "audio/eating.short." + extension] |
]; |
|
load(audio_files, function() { loaded(); }); |
}; |
|
function load(arr, callback) { |
|
if (arr.length === 0) { |
callback(); |
} else { |
var x = arr.pop(); |
audio.load(x[0], x[1], function() { load(arr, callback); }); |
} |
}; |
|
function loaded() { |
|
dialog("Press N to Start"); |
|
document.addEventListener("keydown", keyDown, true); |