Todos o casi todos hemos echado unas partiditas al 'Comecocos', creado alla por principios de los 80 (ay, que jovencico era yo entonces). Pues bien, en una web/foro de programacion vi este codigo que publico un usuario del que desconozco sus datos. Este codigo realizado con Javascript (y un poquillo de CSS) reproduce fielmente el mitico juego de Pacman, con sonido incluido, la melodia del original, asi como los efectos de sonido. Para jugarlo, presionas Enter, lo mueves con las teclas de direccion y para pausarlo pulsa Escape. Si te gusta y quieres ponerlo en tu blog o web, copia el codigo de abajo o si lo prefieres tambien puedes descargartelo.
descargar ver codigo
<div id="pacman"></div>
<script>
Object.prototype.clone = function () {
var i, newObj = (this instanceof Array) ? [] : {};
for (i in this) {
if (i === 'clone') {
continue;
}
if (this[i] && typeof this[i] === "object") {
newObj[i] = this[i].clone();
} else {
newObj[i] = this[i];
}
}
return newObj;
};
var NONE = 4,
UP = 3,
LEFT = 2,
DOWN = 1,
RIGHT = 0,
WAITING = 5,
PAUSE = 6,
PLAYING = 7,
COUNTDOWN = 8,
EATEN_PAUSE = 9,
DYING = 10,
Pacman = {};
Pacman.WALL = 0;
Pacman.BISCUIT = 1;
Pacman.EMPTY = 2;
Pacman.BLOCK = 3;
Pacman.PILL = 4;
Pacman.MAP = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 4, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 4, 0],
[0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0],
[0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0],
[2, 2, 2, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 2, 2, 2],
[0, 0, 0, 0, 1, 0, 1, 0, 0, 3, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[2, 2, 2, 2, 1, 1, 1, 0, 3, 3, 3, 0, 1, 1, 1, 2, 2, 2, 2],
[0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[2, 2, 2, 0, 1, 0, 1, 1, 1, 2, 1, 1, 1, 0, 1, 0, 2, 2, 2],
[0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0],
[0, 4, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 4, 0],
[0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0],
[0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
];
Pacman.WALLS = [
[{"move": [0, 9.5]}, {"line": [3, 9.5]},
{"curve": [3.5, 9.5, 3.5, 9]}, {"line": [3.5, 8]},
{"curve": [3.5, 7.5, 3, 7.5]}, {"line": [1, 7.5]},
{"curve": [0.5, 7.5, 0.5, 7]}, {"line": [0.5, 1]},
{"curve": [0.5, 0.5, 1, 0.5]}, {"line": [9, 0.5]},
{"curve": [9.5, 0.5, 9.5, 1]}, {"line": [9.5, 3.5]}],
[{"move": [9.5, 1]},
{"curve": [9.5, 0.5, 10, 0.5]}, {"line": [18, 0.5]},
{"curve": [18.5, 0.5, 18.5, 1]}, {"line": [18.5, 7]},
{"curve": [18.5, 7.5, 18, 7.5]}, {"line": [16, 7.5]},
{"curve": [15.5, 7.5, 15.5, 8]}, {"line": [15.5, 9]},
{"curve": [15.5, 9.5, 16, 9.5]}, {"line": [19, 9.5]}],
[{"move": [2.5, 5.5]}, {"line": [3.5, 5.5]}],
[{"move": [3, 2.5]},
{"curve": [3.5, 2.5, 3.5, 3]},
{"curve": [3.5, 3.5, 3, 3.5]},
{"curve": [2.5, 3.5, 2.5, 3]},
{"curve": [2.5, 2.5, 3, 2.5]}],
[{"move": [15.5, 5.5]}, {"line": [16.5, 5.5]}],
[{"move": [16, 2.5]}, {"curve": [16.5, 2.5, 16.5, 3]},
{"curve": [16.5, 3.5, 16, 3.5]}, {"curve": [15.5, 3.5, 15.5, 3]},
{"curve": [15.5, 2.5, 16, 2.5]}],
[{"move": [6, 2.5]}, {"line": [7, 2.5]}, {"curve": [7.5, 2.5, 7.5, 3]},
{"curve": [7.5, 3.5, 7, 3.5]}, {"line": [6, 3.5]},
{"curve": [5.5, 3.5, 5.5, 3]}, {"curve": [5.5, 2.5, 6, 2.5]}],
[{"move": [12, 2.5]}, {"line": [13, 2.5]}, {"curve": [13.5, 2.5, 13.5, 3]},
{"curve": [13.5, 3.5, 13, 3.5]}, {"line": [12, 3.5]},
{"curve": [11.5, 3.5, 11.5, 3]}, {"curve": [11.5, 2.5, 12, 2.5]}],
[{"move": [7.5, 5.5]}, {"line": [9, 5.5]}, {"curve": [9.5, 5.5, 9.5, 6]},
{"line": [9.5, 7.5]}],
[{"move": [9.5, 6]}, {"curve": [9.5, 5.5, 10.5, 5.5]},
{"line": [11.5, 5.5]}],
[{"move": [5.5, 5.5]}, {"line": [5.5, 7]}, {"curve": [5.5, 7.5, 6, 7.5]},
{"line": [7.5, 7.5]}],
[{"move": [6, 7.5]}, {"curve": [5.5, 7.5, 5.5, 8]}, {"line": [5.5, 9.5]}],
[{"move": [13.5, 5.5]}, {"line": [13.5, 7]},
{"curve": [13.5, 7.5, 13, 7.5]}, {"line": [11.5, 7.5]}],
[{"move": [13, 7.5]}, {"curve": [13.5, 7.5, 13.5, 8]},
{"line": [13.5, 9.5]}],
[{"move": [0, 11.5]}, {"line": [3, 11.5]}, {"curve": [3.5, 11.5, 3.5, 12]},
{"line": [3.5, 13]}, {"curve": [3.5, 13.5, 3, 13.5]}, {"line": [1, 13.5]},
{"curve": [0.5, 13.5, 0.5, 14]}, {"line": [0.5, 17]},
{"curve": [0.5, 17.5, 1, 17.5]}, {"line": [1.5, 17.5]}],
[{"move": [1, 17.5]}, {"curve": [0.5, 17.5, 0.5, 18]}, {"line": [0.5, 21]},
{"curve": [0.5, 21.5, 1, 21.5]}, {"line": [18, 21.5]},
{"curve": [18.5, 21.5, 18.5, 21]}, {"line": [18.5, 18]},
{"curve": [18.5, 17.5, 18, 17.5]}, {"line": [17.5, 17.5]}],
[{"move": [18, 17.5]}, {"curve": [18.5, 17.5, 18.5, 17]},
{"line": [18.5, 14]}, {"curve": [18.5, 13.5, 18, 13.5]},
{"line": [16, 13.5]}, {"curve": [15.5, 13.5, 15.5, 13]},
{"line": [15.5, 12]}, {"curve": [15.5, 11.5, 16, 11.5]},
{"line": [19, 11.5]}],
[{"move": [5.5, 11.5]}, {"line": [5.5, 13.5]}],
[{"move": [13.5, 11.5]}, {"line": [13.5, 13.5]}],
[{"move": [2.5, 15.5]}, {"line": [3, 15.5]},
{"curve": [3.5, 15.5, 3.5, 16]}, {"line": [3.5, 17.5]}],
[{"move": [16.5, 15.5]}, {"line": [16, 15.5]},
{"curve": [15.5, 15.5, 15.5, 16]}, {"line": [15.5, 17.5]}],
[{"move": [5.5, 15.5]}, {"line": [7.5, 15.5]}],
[{"move": [11.5, 15.5]}, {"line": [13.5, 15.5]}],
[{"move": [2.5, 19.5]}, {"line": [5, 19.5]},
{"curve": [5.5, 19.5, 5.5, 19]}, {"line": [5.5, 17.5]}],
[{"move": [5.5, 19]}, {"curve": [5.5, 19.5, 6, 19.5]},
{"line": [7.5, 19.5]}],
[{"move": [11.5, 19.5]}, {"line": [13, 19.5]},
{"curve": [13.5, 19.5, 13.5, 19]}, {"line": [13.5, 17.5]}],
[{"move": [13.5, 19]}, {"curve": [13.5, 19.5, 14, 19.5]},
{"line": [16.5, 19.5]}],
[{"move": [7.5, 13.5]}, {"line": [9, 13.5]},
{"curve": [9.5, 13.5, 9.5, 14]}, {"line": [9.5, 15.5]}],
[{"move": [9.5, 14]}, {"curve": [9.5, 13.5, 10, 13.5]},
{"line": [11.5, 13.5]}],
[{"move": [7.5, 17.5]}, {"line": [9, 17.5]},
{"curve": [9.5, 17.5, 9.5, 18]}, {"line": [9.5, 19.5]}],
[{"move": [9.5, 18]}, {"curve": [9.5, 17.5, 10, 17.5]},
{"line": [11.5, 17.5]}],
[{"move": [8.5, 9.5]}, {"line": [8, 9.5]}, {"curve": [7.5, 9.5, 7.5, 10]},
{"line": [7.5, 11]}, {"curve": [7.5, 11.5, 8, 11.5]},
{"line": [11, 11.5]}, {"curve": [11.5, 11.5, 11.5, 11]},
{"line": [11.5, 10]}, {"curve": [11.5, 9.5, 11, 9.5]},
{"line": [10.5, 9.5]}]
];
Pacman.Ghost = function (game, map, colour) {
var position = null,
direction = null,
eatable = null,
eaten = null,
due = null;
function getNewCoord(dir, current) {
var speed = isVunerable() ? 1 : isHidden() ? 4 : 2;
return {
"x": addWithBounds(current.x,
(dir === LEFT && -speed ||
dir === RIGHT && speed || 0)),
"y": addWithBounds(current.y,
(dir === DOWN && speed ||
dir === UP && -speed || 0))
};
}
function addWithBounds(x1, x2) {
var rem = x1 % 10, result = rem + x2;
if (rem !== 0 && result > 10) {
return x1 + (10 - rem);
} else if(rem > 0 && result < 0) {
return x1 - rem;
}
return x1 + x2;
};
function isVunerable() {
return eatable !== null;
};
function isDangerous() {
return eaten === null;
};
function isHidden() {
return eatable === null && eaten !== null;
};
function getRandomDirection() {
var moves = (direction === LEFT || direction === RIGHT) ?
[UP, DOWN] : [LEFT, RIGHT];
return moves[Math.floor(Math.random() * 2)];
};
function reset() {
eaten = null;
eatable = null;
position = {"x": 90, "y": 80};
direction = getRandomDirection();
due = getRandomDirection();
};
function onWholeSquare(x) {
return x % 10 === 0;
};
function makeEatable() {
direction = (direction === LEFT) ? RIGHT :
(direction === RIGHT) ? LEFT :
(direction === UP) ? DOWN : UP;
eatable = game.getTick();
};
function eat() {
eatable = null;
eaten = game.getTick();
};
function pointToCoord(x) {
return Math.round(x/10);
};
function nextSquare(x, dir) {
var rem = x % 10;
if (rem === 0) {
return x;
} else if (dir === RIGHT || dir === DOWN) {
return x + (10 - rem);
} else {
return x - rem;
}
};
function onGridSquare(pos) {
return onWholeSquare(pos.y) && onWholeSquare(pos.x);
};
function secondsAgo(tick) {
return (game.getTick() - tick) / 30;
};
function getColour() {
if (eatable) {
if (secondsAgo(eatable) > 5) {
return game.getTick() % 20 > 10 ? "#FFF" : "#0000BB";
} else {
return "#0000BB";
}
} else if(eaten) {
return "#222";
}
return colour;
};
function draw(ctx) {
var top = (position.y/10) * map.blockSize,
left = (position.x/10) * map.blockSize;
if (eatable && secondsAgo(eatable) > 8) {
eatable = null;
}
if (eaten && secondsAgo(eaten) > 3) {
eaten = null;
}
var tl = left+map.blockSize;
var base = top+map.blockSize-3;
var s = map.blockSize;
var inc = map.blockSize / 10;
var high = game.getTick() % 10 > 5 ? 3 : -3;
var low = game.getTick() % 10 > 5 ? -3 : 3;
ctx.fillStyle = getColour();
ctx.beginPath();
ctx.moveTo(left, base);
ctx.quadraticCurveTo(left, top, left + (s/2), top);
ctx.quadraticCurveTo(left+s, top, left+s, base);
// Wavy things at the bottom
ctx.quadraticCurveTo(tl-(inc*1), base+high, tl-(inc*2), base);
ctx.quadraticCurveTo(tl-(inc*3), base+low, tl-(inc*4), base);
ctx.quadraticCurveTo(tl-(inc*5), base+high, tl-(inc*6), base);
ctx.quadraticCurveTo(tl-(inc*7), base+low, tl-(inc*8), base);
ctx.quadraticCurveTo(tl-(inc*9), base+high, tl-(inc*10), base);
ctx.closePath();
ctx.fill();
ctx.beginPath();
ctx.fillStyle = "#FFF";
ctx.arc(left+6,top+6, map.blockSize / 6, 0, 300, false);
ctx.arc((left+s)-6,top+6, map.blockSize / 6, 0, 300, false);
ctx.closePath();
ctx.fill();
var f = map.blockSize / 12;
var off = {};
off[RIGHT] = [f, 0];
off[LEFT] = [-f, 0];
off[UP] = [0, -f];
off[DOWN] = [0, f];
ctx.beginPath();
ctx.fillStyle = "#000";
ctx.arc(left+6+off[direction][0], top+6+off[direction][1],
map.blockSize / 15, 0, 300, false);
ctx.arc((left+s)-6+off[direction][0], top+6+off[direction][1],
map.blockSize / 15, 0, 300, false);
ctx.closePath();
ctx.fill();
};
function pane(pos) {
if (pos.y === 100 && pos.x >= 190 && direction === RIGHT) {
return {"y": 100, "x": -10};
}
if (pos.y === 100 && pos.x <= -10 && direction === LEFT) {
return position = {"y": 100, "x": 190};
}
return false;
};
function move(ctx) {
var oldPos = position,
onGrid = onGridSquare(position),
npos = null;
if (due !== direction) {
npos = getNewCoord(due, position);
if (onGrid &&
map.isFloorSpace(pointToCoord(nextSquare(npos.y, due)),
pointToCoord(nextSquare(npos.x, due)))) {
direction = due;
} else {
npos = null;
}
}
if (npos === null) {
npos = getNewCoord(direction, position);
}
if (onGrid &&
map.isWallSpace(pointToCoord(nextSquare(npos.y, direction)),
pointToCoord(nextSquare(npos.x, direction)))) {
due = getRandomDirection();
return move(ctx);
}
position = npos;
var tmp = pane(position);
if (tmp) {
position = tmp;
}
due = getRandomDirection();
return {
"new" : position,
"old" : oldPos
};
};
return {
"eat" : eat,
"isVunerable" : isVunerable,
"isDangerous" : isDangerous,
"makeEatable" : makeEatable,
"reset" : reset,
"move" : move,
"draw" : draw
};
};
Pacman.User = function (game, map) {
var position = null,
direction = null,
eaten = null,
due = null,
lives = null,
score = 5,
keyMap = {};
keyMap[37] = LEFT;
keyMap[38] = UP;
keyMap[39] = RIGHT;
keyMap[40] = DOWN;
function addScore(nScore) {
score += nScore;
if (score >= 10000 && score - nScore < 10000) {
lives += 1;
}
};
function theScore() {
return score;
};
function loseLife() {
lives -= 1;
};
function getLives() {
return lives;
};
function initUser() {
score = 0;
lives = 3;
newLevel();
}
function newLevel() {
resetPosition();
eaten = 0;
};
function resetPosition() {
position = {"x": 90, "y": 120};
direction = LEFT;
due = LEFT;
};
function reset() {
initUser();
resetPosition();
};
function keyDown(e) {
if (typeof keyMap[e.keyCode] !== "undefined") {
due = keyMap[e.keyCode];
e.preventDefault();
e.stopPropagation();
return false;
}
return true;
};
function getNewCoord(dir, current) {
return {
"x": current.x + (dir === LEFT && -2 || dir === RIGHT && 2 || 0),
"y": current.y + (dir === DOWN && 2 || dir === UP && -2 || 0)
};
};
function onWholeSquare(x) {
return x % 10 === 0;
};
function pointToCoord(x) {
return Math.round(x/10);
};
function nextSquare(x, dir) {
var rem = x % 10;
if (rem === 0) {
return x;
} else if (dir === RIGHT || dir === DOWN) {
return x + (10 - rem);
} else {
return x - rem;
}
};
function onGridSquare(pos) {
return onWholeSquare(pos.y) && onWholeSquare(pos.x);
};
function isOnSamePlane(due, dir) {
return ((due === LEFT || due === RIGHT) &&
(dir === LEFT || dir === RIGHT)) ||
((due === UP || due === DOWN) &&
(dir === UP || dir === DOWN));
};
function move(ctx) {
var npos = null;
if (due !== direction) {
npos = getNewCoord(due, position);
if (isOnSamePlane(due, direction) ||
(onGridSquare(position) &&
map.isFloorSpace(pointToCoord(nextSquare(npos.y, due)),
pointToCoord(nextSquare(npos.x, due))))) {
direction = due;
} else {
npos = null;
}
}
if (npos === null) {
npos = getNewCoord(direction, position);
}
if (onGridSquare(position) &&
map.isWallSpace(pointToCoord(nextSquare(npos.y, direction)),
pointToCoord(nextSquare(npos.x, direction)))) {
direction = NONE;
}
if (direction === NONE) {
return {"new" : position, "old" : position};
}
if (npos.y === 100 && npos.x >= 190 && direction === RIGHT) {
position = {"y": 100, "x": -10};
return {"new" : position, "old" : position};
}
if (npos.y === 100 && npos.x <= -12 && direction === LEFT) {
position = {"y": 100, "x": 190};
return {"new" : position, "old" : position};
}
var oldPosition = position;
position = npos;
var block = map.block(pointToCoord(nextSquare(position.y, direction)),
pointToCoord(nextSquare(position.x, direction)));
if ((isMidSquare(position.y) || isMidSquare(position.x)) &&
block === Pacman.BISCUIT || block === Pacman.PILL) {
map.setBlock(pointToCoord(nextSquare(position.y, direction)),
pointToCoord(nextSquare(position.x, direction)),
Pacman.EMPTY);
addScore(10);
eaten += 1;
if (eaten === 182) {
game.completedLevel();
}
if (block === Pacman.PILL) {
game.eatenPill();
}
}
return {
"new" : position,
"old" : oldPosition
};
};
function isMidSquare(x) {
var rem = x % 10;
return rem > 3 || rem < 7;
};
function calcAngle(dir, pos) {
if (dir == RIGHT && (pos.x % 10 < 5)) {
return {"start":0.25, "end":1.75, "direction": false};
} else if (dir === DOWN && (pos.y % 10 < 5)) {
return {"start":0.75, "end":2.25, "direction": false};
} else if (dir === UP && (pos.y % 10 < 5)) {
return {"start":1.25, "end":1.75, "direction": true};
} else if (dir === LEFT && (pos.x % 10 < 5)) {
return {"start":0.75, "end":1.25, "direction": true};
}
return {"start":0, "end":2, "direction": false};
};
function drawDead(ctx, amount) {
var size = map.blockSize,
half = size / 2;
if (amount >= 1) {
return;
}
ctx.fillStyle = "#FFFF00";
ctx.beginPath();
ctx.moveTo(((position.x/10) * size) + half,
((position.y/10) * size) + half);
ctx.arc(((position.x/10) * size) + half,
((position.y/10) * size) + half,
half, 0, Math.PI * 2 * amount, true);
ctx.fill();
};
function draw(ctx) {
var angle = calcAngle(direction, position);
ctx.fillStyle = "#FFFF00";
ctx.beginPath();
ctx.moveTo(((position.x/10) * map.blockSize) + map.blockSize / 2,
((position.y/10) * map.blockSize) + map.blockSize / 2);
ctx.arc(((position.x/10) * map.blockSize) + map.blockSize / 2,
((position.y/10) * map.blockSize) + map.blockSize / 2,
map.blockSize / 2,
Math.PI * angle.start,
Math.PI * angle.end, angle.direction);
ctx.fill();
};
initUser();
return {
"draw" : draw,
"drawDead" : drawDead,
"loseLife" : loseLife,
"getLives" : getLives,
"score" : score,
"addScore" : addScore,
"theScore" : theScore,
"keyDown" : keyDown,
"move" : move,
"newLevel" : newLevel,
"reset" : reset,
"resetPosition" : resetPosition
};
};
Pacman.Map = function (size) {
var height = null,
width = null,
blockSize = size,
pillSize = 0,
map = null;
function withinBounds(y, x) {
return y >= 0 && y < height && x >= 0 && x < width;
}
function isWall(y, x) {
return withinBounds(y, x) && map[y][x] === Pacman.WALL;
}
function isFloorSpace(y, x) {
if (!withinBounds(y, x)) {
return false;
}
var peice = map[y][x];
return peice === Pacman.EMPTY ||
peice === Pacman.BISCUIT ||
peice === Pacman.PILL;
}
function drawWall(ctx) {
var i, j, p, line;
ctx.strokeStyle = "#0000FF";
ctx.lineWidth = 5;
ctx.lineCap = "round";
for (i = 0; i < Pacman.WALLS.length; i += 1) {
line = Pacman.WALLS[i];
ctx.beginPath();
for (j = 0; j < line.length; j += 1) {
p = line[j];
if (p.move) {
ctx.moveTo(p.move[0] * blockSize, p.move[1] * blockSize);
} else if (p.line) {
ctx.lineTo(p.line[0] * blockSize, p.line[1] * blockSize);
} else if (p.curve) {
ctx.quadraticCurveTo(p.curve[0] * blockSize,
p.curve[1] * blockSize,
p.curve[2] * blockSize,
p.curve[3] * blockSize);
}
}
ctx.stroke();
}
}
function reset() {
map = Pacman.MAP.clone();
height = map.length;
width = map[0].length;
};
function block(y, x) {
return map[y][x];
};
function setBlock(y, x, type) {
map[y][x] = type;
};
function drawPills(ctx) {
if (++pillSize > 30) {
pillSize = 0;
}
for (i = 0; i < height; i += 1) {
for (j = 0; j < width; j += 1) {
if (map[i][j] === Pacman.PILL) {
ctx.beginPath();
ctx.fillStyle = "#000";
ctx.fillRect((j * blockSize), (i * blockSize),
blockSize, blockSize);
ctx.fillStyle = "#FFF";
ctx.arc((j * blockSize) + blockSize / 2,
(i * blockSize) + blockSize / 2,
Math.abs(5 - (pillSize/3)),
0,
Math.PI * 2, false);
ctx.fill();
ctx.closePath();
}
}
}
};
function draw(ctx) {
var i, j, size = blockSize;
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, width * size, height * size);
drawWall(ctx);
for (i = 0; i < height; i += 1) {
for (j = 0; j < width; j += 1) {
drawBlock(i, j, ctx);
}
}
};
function drawBlock(y, x, ctx) {
var layout = map[y][x];
if (layout === Pacman.PILL) {
return;
}
ctx.beginPath();
if (layout === Pacman.EMPTY ||
layout === Pacman.BLOCK ||
layout === Pacman.BISCUIT) {
ctx.fillStyle = "#000";
ctx.fillRect((x * blockSize), (y * blockSize),
blockSize, blockSize);
if (layout === Pacman.BISCUIT) {
ctx.fillStyle = "#FFF";
ctx.fillRect((x * blockSize) + (blockSize / 2.5),
(y * blockSize) + (blockSize / 2.5),
blockSize / 6, blockSize / 6);
}
}
ctx.closePath();
};
reset();
return {
"draw" : draw,
"drawBlock" : drawBlock,
"drawPills" : drawPills,
"block" : block,
"setBlock" : setBlock,
"reset" : reset,
"isWallSpace" : isWall,
"isFloorSpace" : isFloorSpace,
"height" : height,
"width" : width,
"blockSize" : blockSize
};
};
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,
level = 0,
tick = 0,
ghostPos, userPos,
stateChanged = true,
timerStart = null,
lastTime = 0,
ctx = null,
timer = null,
map = null,
user = null,
stored = null;
function getTick() {
return tick;
};
function drawScore(text, position) {
ctx.fillStyle = "#FFFFFF";
ctx.font = "12px BDCartoonShoutRegular";
ctx.fillText(text,
(position["new"]["x"] / 10) * map.blockSize,
((position["new"]["y"] + 5) / 10) * map.blockSize);
}
function dialog(text) {
ctx.fillStyle = "#FFFF00";
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();
for (var i = 0; i < ghosts.length; i += 1) {
ghosts[i].reset();
}
audio.play("start");
timerStart = tick;
setState(COUNTDOWN);
}
function startNewGame() {
setState(WAITING);
level = 1;
user.reset();
map.reset();
map.draw(ctx);
startLevel();
}
function keyDown(e) {
if (e.keyCode === 13) {
startNewGame();
} else if (e.keyCode === 83) {
audio.disableSound();
localStorage["soundDisabled"] = !soundDisabled();
} else if (e.keyCode === 27 && state === PAUSE) {
audio.resume();
map.draw(ctx);
setState(stored);
} else if (e.keyCode === 27) {
stored = state;
setState(PAUSE);
audio.pause();
map.draw(ctx);
dialog("PAUSA");
} else if (state !== PAUSE) {
return user.keyDown(e);
}
return true;
}
function loseLife() {
setState(WAITING);
user.loseLife();
if (user.getLives() > 0) {
startLevel();
}
}
function setState(nState) {
state = nState;
stateChanged = true;
};
function collided(user, ghost) {
return (Math.sqrt(Math.pow(ghost.x - user.x, 2) +
Math.pow(ghost.y - user.y, 2))) < 10;
};
function drawFooter() {
var topLeft = (map.height * map.blockSize),
textBase = topLeft + 17;
ctx.fillStyle = "#000000";
ctx.fillRect(0, topLeft, (map.width * map.blockSize), 30);
ctx.fillStyle = "#FFFF00";
for (var i = 0, len = user.getLives(); i < len; i++) {
ctx.fillStyle = "#FFFF00";
ctx.beginPath();
ctx.moveTo(150 + (25 * i) + map.blockSize / 2,
(topLeft+1) + map.blockSize / 2);
ctx.arc(150 + (25 * i) + map.blockSize / 2,
(topLeft+1) + map.blockSize / 2,
map.blockSize / 2, Math.PI * 0.25, Math.PI * 1.75, false);
ctx.fill();
}
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 BDCartoonShoutRegular";
ctx.fillText("Puntos: " + user.theScore(), 30, textBase);
ctx.fillText("Nivel: " + level, 260, textBase);
}
function redrawBlock(pos) {
map.drawBlock(Math.floor(pos.y/10), Math.floor(pos.x/10), ctx);
map.drawBlock(Math.ceil(pos.y/10), Math.ceil(pos.x/10), ctx);
}
function mainDraw() {
var diff, u, i, len, nScore;
ghostPos = [];
for (i = 0, len = ghosts.length; i < len; i += 1) {
ghostPos.push(ghosts[i].move(ctx));
}
u = user.move(ctx);
for (i = 0, len = ghosts.length; i < len; i += 1) {
redrawBlock(ghostPos[i].old);
}
redrawBlock(u.old);
for (i = 0, len = ghosts.length; i < len; i += 1) {
ghosts[i].draw(ctx);
}
user.draw(ctx);
userPos = u["new"];
for (i = 0, len = ghosts.length; i < len; i += 1) {
if (collided(userPos, ghostPos[i]["new"])) {
if (ghosts[i].isVunerable()) {
audio.play("eatghost");
ghosts[i].eat();
eatenCount += 1;
nScore = eatenCount * 50;
drawScore(nScore, ghostPos[i]);
user.addScore(nScore);
setState(EATEN_PAUSE);
timerStart = tick;
} else if (ghosts[i].isDangerous()) {
audio.play("die");
setState(DYING);
timerStart = tick;
}
}
}
};
function mainLoop() {
var diff;
if (state !== PAUSE) {
++tick;
}
map.drawPills(ctx);
if (state === PLAYING) {
mainDraw();
} else if (state === WAITING && stateChanged) {
stateChanged = false;
map.draw(ctx);
dialog("ENTER para comenzar a jugar");
} else if (state === EATEN_PAUSE && tick - timerStart > 11) {
map.draw(ctx);
setState(PLAYING);
} else if (state === DYING) {
if (tick - timerStart > 60) {
loseLife();
} else {
redrawBlock(userPos);
for (i = 0, len = ghosts.length; i < len; i += 1) {
redrawBlock(ghostPos[i].old);
ghostPos.push(ghosts[i].draw(ctx));
}
user.drawDead(ctx, (tick - timerStart) / 60);
}
} else if (state === COUNTDOWN) {
diff = 5 + Math.floor((timerStart - tick) / 30);
if (diff === 0) {
map.draw(ctx);
setState(PLAYING);
} else {
if (diff !== lastTime) {
lastTime = diff;
map.draw(ctx);
dialog("Comenzando en: " + diff);
}
}
}
drawFooter();
}
function eatenPill() {
audio.play("eatpill");
timerStart = tick;
eatenCount = 0;
for (i = 0; i < ghosts.length; i += 1) {
ghosts[i].makeEatable(ctx);
}
};
function completedLevel() {
setState(WAITING);
level += 1;
map.reset();
user.newLevel();
startLevel();
};
function keyPress(e) {
if (state !== WAITING && state !== PAUSE) {
e.preventDefault();
e.stopPropagation();
}
};
function init(wrapper, root) {
var i, len, ghost,
maxHeight = (wrapper.offsetHeight - 30) / 22,
maxWidth = wrapper.offsetWidth / 19,
blockSize = Math.floor(Math.min(maxWidth, maxHeight)),
canvas = document.createElement("canvas");
canvas.setAttribute("width", (blockSize * 19) + "px");
canvas.setAttribute("height", (blockSize * 22) + 30 + "px");
wrapper.appendChild(canvas);
ctx = canvas.getContext('2d');
audio = new Pacman.Audio({"soundDisabled":soundDisabled});
map = new Pacman.Map(blockSize);
user = new Pacman.User({
"completedLevel" : completedLevel,
"eatenPill" : eatenPill
}, map);
for (i = 0, len = ghostSpecs.length; i < len; i += 1) {
ghost = new Pacman.Ghost({"getTick":getTick}, map, ghostSpecs[i]);
ghosts.push(ghost);
}
map.draw(ctx);
dialog("Cargando ...");
var myAudio = document.createElement('audio');
var canPlayOGG = !!(myAudio.canPlayType('audio/ogg').replace(/no/, ''));
var canPlayMP3 = !!(myAudio.canPlayType('audio/mpeg').replace(/no/, ''));
var extension = canPlayOGG ? '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 load(arr) {
if (arr.length === 0) {
loaded();
} else {
var x = arr.pop();
audio.load(x[0], x[1], function() { load(arr); });
}
};
function loaded() {
dialog("ENTER PARA JUGAR");
document.addEventListener("keydown", keyDown, true);
document.addEventListener("keypress", keyPress, true);
timer = window.setInterval(mainLoop, 35);
};
return {
"init" : init
};
}());
</script>
<script>
var el = document.getElementById("pacman");
function supportsOggAudio() {
var myAudio = document.createElement("audio");
return typeof myAudio.canPlayType === "function" &&
("no" != myAudio.canPlayType("audio/ogg")) &&
("" != myAudio.canPlayType("audio/ogg"));
};
function supports_canvas() {
return !!document.createElement('canvas').getContext;
};
function supports_local_storage() {
return ('localStorage' in window) && window['localStorage'] !== null;
};
function supports_audio() {
var myAudio = document.createElement('audio');
var canPlayOGG = typeof myAudio.canPlayType === "function" &&
!!(myAudio.canPlayType('audio/ogg').replace(/no/, ''));
var canPlayMP3 = typeof myAudio.canPlayType === "function" &&
!!(myAudio.canPlayType('audio/mpeg').replace(/no/, ''));
return canPlayOGG || canPlayMP3;
};
if (supports_canvas() && supports_local_storage() && supports_audio()) {
window.setTimeout(function () { PACMAN.init(el, "http://arandomurl.com/random/pacman/"); }, 0);
} else {
el.innerHTML = "Tu navegador no es compatible";
}
</script>
<style>
@font-face {
font-family: 'BDCartoonShoutRegular';
src: url('BD_Cartoon_Shout-webfont.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
#shim {
font-family: BDCartoonShoutRegular;
position:absolute;
visibility:hidden;
}
#pacman {
width:412px;
height:450px;
margin:20px auto;
}
</style>
<script>
Object.prototype.clone = function () {
var i, newObj = (this instanceof Array) ? [] : {};
for (i in this) {
if (i === 'clone') {
continue;
}
if (this[i] && typeof this[i] === "object") {
newObj[i] = this[i].clone();
} else {
newObj[i] = this[i];
}
}
return newObj;
};
var NONE = 4,
UP = 3,
LEFT = 2,
DOWN = 1,
RIGHT = 0,
WAITING = 5,
PAUSE = 6,
PLAYING = 7,
COUNTDOWN = 8,
EATEN_PAUSE = 9,
DYING = 10,
Pacman = {};
Pacman.WALL = 0;
Pacman.BISCUIT = 1;
Pacman.EMPTY = 2;
Pacman.BLOCK = 3;
Pacman.PILL = 4;
Pacman.MAP = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 4, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 4, 0],
[0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0],
[0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0],
[2, 2, 2, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 2, 2, 2],
[0, 0, 0, 0, 1, 0, 1, 0, 0, 3, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[2, 2, 2, 2, 1, 1, 1, 0, 3, 3, 3, 0, 1, 1, 1, 2, 2, 2, 2],
[0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[2, 2, 2, 0, 1, 0, 1, 1, 1, 2, 1, 1, 1, 0, 1, 0, 2, 2, 2],
[0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0],
[0, 4, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 4, 0],
[0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0],
[0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
];
Pacman.WALLS = [
[{"move": [0, 9.5]}, {"line": [3, 9.5]},
{"curve": [3.5, 9.5, 3.5, 9]}, {"line": [3.5, 8]},
{"curve": [3.5, 7.5, 3, 7.5]}, {"line": [1, 7.5]},
{"curve": [0.5, 7.5, 0.5, 7]}, {"line": [0.5, 1]},
{"curve": [0.5, 0.5, 1, 0.5]}, {"line": [9, 0.5]},
{"curve": [9.5, 0.5, 9.5, 1]}, {"line": [9.5, 3.5]}],
[{"move": [9.5, 1]},
{"curve": [9.5, 0.5, 10, 0.5]}, {"line": [18, 0.5]},
{"curve": [18.5, 0.5, 18.5, 1]}, {"line": [18.5, 7]},
{"curve": [18.5, 7.5, 18, 7.5]}, {"line": [16, 7.5]},
{"curve": [15.5, 7.5, 15.5, 8]}, {"line": [15.5, 9]},
{"curve": [15.5, 9.5, 16, 9.5]}, {"line": [19, 9.5]}],
[{"move": [2.5, 5.5]}, {"line": [3.5, 5.5]}],
[{"move": [3, 2.5]},
{"curve": [3.5, 2.5, 3.5, 3]},
{"curve": [3.5, 3.5, 3, 3.5]},
{"curve": [2.5, 3.5, 2.5, 3]},
{"curve": [2.5, 2.5, 3, 2.5]}],
[{"move": [15.5, 5.5]}, {"line": [16.5, 5.5]}],
[{"move": [16, 2.5]}, {"curve": [16.5, 2.5, 16.5, 3]},
{"curve": [16.5, 3.5, 16, 3.5]}, {"curve": [15.5, 3.5, 15.5, 3]},
{"curve": [15.5, 2.5, 16, 2.5]}],
[{"move": [6, 2.5]}, {"line": [7, 2.5]}, {"curve": [7.5, 2.5, 7.5, 3]},
{"curve": [7.5, 3.5, 7, 3.5]}, {"line": [6, 3.5]},
{"curve": [5.5, 3.5, 5.5, 3]}, {"curve": [5.5, 2.5, 6, 2.5]}],
[{"move": [12, 2.5]}, {"line": [13, 2.5]}, {"curve": [13.5, 2.5, 13.5, 3]},
{"curve": [13.5, 3.5, 13, 3.5]}, {"line": [12, 3.5]},
{"curve": [11.5, 3.5, 11.5, 3]}, {"curve": [11.5, 2.5, 12, 2.5]}],
[{"move": [7.5, 5.5]}, {"line": [9, 5.5]}, {"curve": [9.5, 5.5, 9.5, 6]},
{"line": [9.5, 7.5]}],
[{"move": [9.5, 6]}, {"curve": [9.5, 5.5, 10.5, 5.5]},
{"line": [11.5, 5.5]}],
[{"move": [5.5, 5.5]}, {"line": [5.5, 7]}, {"curve": [5.5, 7.5, 6, 7.5]},
{"line": [7.5, 7.5]}],
[{"move": [6, 7.5]}, {"curve": [5.5, 7.5, 5.5, 8]}, {"line": [5.5, 9.5]}],
[{"move": [13.5, 5.5]}, {"line": [13.5, 7]},
{"curve": [13.5, 7.5, 13, 7.5]}, {"line": [11.5, 7.5]}],
[{"move": [13, 7.5]}, {"curve": [13.5, 7.5, 13.5, 8]},
{"line": [13.5, 9.5]}],
[{"move": [0, 11.5]}, {"line": [3, 11.5]}, {"curve": [3.5, 11.5, 3.5, 12]},
{"line": [3.5, 13]}, {"curve": [3.5, 13.5, 3, 13.5]}, {"line": [1, 13.5]},
{"curve": [0.5, 13.5, 0.5, 14]}, {"line": [0.5, 17]},
{"curve": [0.5, 17.5, 1, 17.5]}, {"line": [1.5, 17.5]}],
[{"move": [1, 17.5]}, {"curve": [0.5, 17.5, 0.5, 18]}, {"line": [0.5, 21]},
{"curve": [0.5, 21.5, 1, 21.5]}, {"line": [18, 21.5]},
{"curve": [18.5, 21.5, 18.5, 21]}, {"line": [18.5, 18]},
{"curve": [18.5, 17.5, 18, 17.5]}, {"line": [17.5, 17.5]}],
[{"move": [18, 17.5]}, {"curve": [18.5, 17.5, 18.5, 17]},
{"line": [18.5, 14]}, {"curve": [18.5, 13.5, 18, 13.5]},
{"line": [16, 13.5]}, {"curve": [15.5, 13.5, 15.5, 13]},
{"line": [15.5, 12]}, {"curve": [15.5, 11.5, 16, 11.5]},
{"line": [19, 11.5]}],
[{"move": [5.5, 11.5]}, {"line": [5.5, 13.5]}],
[{"move": [13.5, 11.5]}, {"line": [13.5, 13.5]}],
[{"move": [2.5, 15.5]}, {"line": [3, 15.5]},
{"curve": [3.5, 15.5, 3.5, 16]}, {"line": [3.5, 17.5]}],
[{"move": [16.5, 15.5]}, {"line": [16, 15.5]},
{"curve": [15.5, 15.5, 15.5, 16]}, {"line": [15.5, 17.5]}],
[{"move": [5.5, 15.5]}, {"line": [7.5, 15.5]}],
[{"move": [11.5, 15.5]}, {"line": [13.5, 15.5]}],
[{"move": [2.5, 19.5]}, {"line": [5, 19.5]},
{"curve": [5.5, 19.5, 5.5, 19]}, {"line": [5.5, 17.5]}],
[{"move": [5.5, 19]}, {"curve": [5.5, 19.5, 6, 19.5]},
{"line": [7.5, 19.5]}],
[{"move": [11.5, 19.5]}, {"line": [13, 19.5]},
{"curve": [13.5, 19.5, 13.5, 19]}, {"line": [13.5, 17.5]}],
[{"move": [13.5, 19]}, {"curve": [13.5, 19.5, 14, 19.5]},
{"line": [16.5, 19.5]}],
[{"move": [7.5, 13.5]}, {"line": [9, 13.5]},
{"curve": [9.5, 13.5, 9.5, 14]}, {"line": [9.5, 15.5]}],
[{"move": [9.5, 14]}, {"curve": [9.5, 13.5, 10, 13.5]},
{"line": [11.5, 13.5]}],
[{"move": [7.5, 17.5]}, {"line": [9, 17.5]},
{"curve": [9.5, 17.5, 9.5, 18]}, {"line": [9.5, 19.5]}],
[{"move": [9.5, 18]}, {"curve": [9.5, 17.5, 10, 17.5]},
{"line": [11.5, 17.5]}],
[{"move": [8.5, 9.5]}, {"line": [8, 9.5]}, {"curve": [7.5, 9.5, 7.5, 10]},
{"line": [7.5, 11]}, {"curve": [7.5, 11.5, 8, 11.5]},
{"line": [11, 11.5]}, {"curve": [11.5, 11.5, 11.5, 11]},
{"line": [11.5, 10]}, {"curve": [11.5, 9.5, 11, 9.5]},
{"line": [10.5, 9.5]}]
];
Pacman.Ghost = function (game, map, colour) {
var position = null,
direction = null,
eatable = null,
eaten = null,
due = null;
function getNewCoord(dir, current) {
var speed = isVunerable() ? 1 : isHidden() ? 4 : 2;
return {
"x": addWithBounds(current.x,
(dir === LEFT && -speed ||
dir === RIGHT && speed || 0)),
"y": addWithBounds(current.y,
(dir === DOWN && speed ||
dir === UP && -speed || 0))
};
}
function addWithBounds(x1, x2) {
var rem = x1 % 10, result = rem + x2;
if (rem !== 0 && result > 10) {
return x1 + (10 - rem);
} else if(rem > 0 && result < 0) {
return x1 - rem;
}
return x1 + x2;
};
function isVunerable() {
return eatable !== null;
};
function isDangerous() {
return eaten === null;
};
function isHidden() {
return eatable === null && eaten !== null;
};
function getRandomDirection() {
var moves = (direction === LEFT || direction === RIGHT) ?
[UP, DOWN] : [LEFT, RIGHT];
return moves[Math.floor(Math.random() * 2)];
};
function reset() {
eaten = null;
eatable = null;
position = {"x": 90, "y": 80};
direction = getRandomDirection();
due = getRandomDirection();
};
function onWholeSquare(x) {
return x % 10 === 0;
};
function makeEatable() {
direction = (direction === LEFT) ? RIGHT :
(direction === RIGHT) ? LEFT :
(direction === UP) ? DOWN : UP;
eatable = game.getTick();
};
function eat() {
eatable = null;
eaten = game.getTick();
};
function pointToCoord(x) {
return Math.round(x/10);
};
function nextSquare(x, dir) {
var rem = x % 10;
if (rem === 0) {
return x;
} else if (dir === RIGHT || dir === DOWN) {
return x + (10 - rem);
} else {
return x - rem;
}
};
function onGridSquare(pos) {
return onWholeSquare(pos.y) && onWholeSquare(pos.x);
};
function secondsAgo(tick) {
return (game.getTick() - tick) / 30;
};
function getColour() {
if (eatable) {
if (secondsAgo(eatable) > 5) {
return game.getTick() % 20 > 10 ? "#FFF" : "#0000BB";
} else {
return "#0000BB";
}
} else if(eaten) {
return "#222";
}
return colour;
};
function draw(ctx) {
var top = (position.y/10) * map.blockSize,
left = (position.x/10) * map.blockSize;
if (eatable && secondsAgo(eatable) > 8) {
eatable = null;
}
if (eaten && secondsAgo(eaten) > 3) {
eaten = null;
}
var tl = left+map.blockSize;
var base = top+map.blockSize-3;
var s = map.blockSize;
var inc = map.blockSize / 10;
var high = game.getTick() % 10 > 5 ? 3 : -3;
var low = game.getTick() % 10 > 5 ? -3 : 3;
ctx.fillStyle = getColour();
ctx.beginPath();
ctx.moveTo(left, base);
ctx.quadraticCurveTo(left, top, left + (s/2), top);
ctx.quadraticCurveTo(left+s, top, left+s, base);
// Wavy things at the bottom
ctx.quadraticCurveTo(tl-(inc*1), base+high, tl-(inc*2), base);
ctx.quadraticCurveTo(tl-(inc*3), base+low, tl-(inc*4), base);
ctx.quadraticCurveTo(tl-(inc*5), base+high, tl-(inc*6), base);
ctx.quadraticCurveTo(tl-(inc*7), base+low, tl-(inc*8), base);
ctx.quadraticCurveTo(tl-(inc*9), base+high, tl-(inc*10), base);
ctx.closePath();
ctx.fill();
ctx.beginPath();
ctx.fillStyle = "#FFF";
ctx.arc(left+6,top+6, map.blockSize / 6, 0, 300, false);
ctx.arc((left+s)-6,top+6, map.blockSize / 6, 0, 300, false);
ctx.closePath();
ctx.fill();
var f = map.blockSize / 12;
var off = {};
off[RIGHT] = [f, 0];
off[LEFT] = [-f, 0];
off[UP] = [0, -f];
off[DOWN] = [0, f];
ctx.beginPath();
ctx.fillStyle = "#000";
ctx.arc(left+6+off[direction][0], top+6+off[direction][1],
map.blockSize / 15, 0, 300, false);
ctx.arc((left+s)-6+off[direction][0], top+6+off[direction][1],
map.blockSize / 15, 0, 300, false);
ctx.closePath();
ctx.fill();
};
function pane(pos) {
if (pos.y === 100 && pos.x >= 190 && direction === RIGHT) {
return {"y": 100, "x": -10};
}
if (pos.y === 100 && pos.x <= -10 && direction === LEFT) {
return position = {"y": 100, "x": 190};
}
return false;
};
function move(ctx) {
var oldPos = position,
onGrid = onGridSquare(position),
npos = null;
if (due !== direction) {
npos = getNewCoord(due, position);
if (onGrid &&
map.isFloorSpace(pointToCoord(nextSquare(npos.y, due)),
pointToCoord(nextSquare(npos.x, due)))) {
direction = due;
} else {
npos = null;
}
}
if (npos === null) {
npos = getNewCoord(direction, position);
}
if (onGrid &&
map.isWallSpace(pointToCoord(nextSquare(npos.y, direction)),
pointToCoord(nextSquare(npos.x, direction)))) {
due = getRandomDirection();
return move(ctx);
}
position = npos;
var tmp = pane(position);
if (tmp) {
position = tmp;
}
due = getRandomDirection();
return {
"new" : position,
"old" : oldPos
};
};
return {
"eat" : eat,
"isVunerable" : isVunerable,
"isDangerous" : isDangerous,
"makeEatable" : makeEatable,
"reset" : reset,
"move" : move,
"draw" : draw
};
};
Pacman.User = function (game, map) {
var position = null,
direction = null,
eaten = null,
due = null,
lives = null,
score = 5,
keyMap = {};
keyMap[37] = LEFT;
keyMap[38] = UP;
keyMap[39] = RIGHT;
keyMap[40] = DOWN;
function addScore(nScore) {
score += nScore;
if (score >= 10000 && score - nScore < 10000) {
lives += 1;
}
};
function theScore() {
return score;
};
function loseLife() {
lives -= 1;
};
function getLives() {
return lives;
};
function initUser() {
score = 0;
lives = 3;
newLevel();
}
function newLevel() {
resetPosition();
eaten = 0;
};
function resetPosition() {
position = {"x": 90, "y": 120};
direction = LEFT;
due = LEFT;
};
function reset() {
initUser();
resetPosition();
};
function keyDown(e) {
if (typeof keyMap[e.keyCode] !== "undefined") {
due = keyMap[e.keyCode];
e.preventDefault();
e.stopPropagation();
return false;
}
return true;
};
function getNewCoord(dir, current) {
return {
"x": current.x + (dir === LEFT && -2 || dir === RIGHT && 2 || 0),
"y": current.y + (dir === DOWN && 2 || dir === UP && -2 || 0)
};
};
function onWholeSquare(x) {
return x % 10 === 0;
};
function pointToCoord(x) {
return Math.round(x/10);
};
function nextSquare(x, dir) {
var rem = x % 10;
if (rem === 0) {
return x;
} else if (dir === RIGHT || dir === DOWN) {
return x + (10 - rem);
} else {
return x - rem;
}
};
function onGridSquare(pos) {
return onWholeSquare(pos.y) && onWholeSquare(pos.x);
};
function isOnSamePlane(due, dir) {
return ((due === LEFT || due === RIGHT) &&
(dir === LEFT || dir === RIGHT)) ||
((due === UP || due === DOWN) &&
(dir === UP || dir === DOWN));
};
function move(ctx) {
var npos = null;
if (due !== direction) {
npos = getNewCoord(due, position);
if (isOnSamePlane(due, direction) ||
(onGridSquare(position) &&
map.isFloorSpace(pointToCoord(nextSquare(npos.y, due)),
pointToCoord(nextSquare(npos.x, due))))) {
direction = due;
} else {
npos = null;
}
}
if (npos === null) {
npos = getNewCoord(direction, position);
}
if (onGridSquare(position) &&
map.isWallSpace(pointToCoord(nextSquare(npos.y, direction)),
pointToCoord(nextSquare(npos.x, direction)))) {
direction = NONE;
}
if (direction === NONE) {
return {"new" : position, "old" : position};
}
if (npos.y === 100 && npos.x >= 190 && direction === RIGHT) {
position = {"y": 100, "x": -10};
return {"new" : position, "old" : position};
}
if (npos.y === 100 && npos.x <= -12 && direction === LEFT) {
position = {"y": 100, "x": 190};
return {"new" : position, "old" : position};
}
var oldPosition = position;
position = npos;
var block = map.block(pointToCoord(nextSquare(position.y, direction)),
pointToCoord(nextSquare(position.x, direction)));
if ((isMidSquare(position.y) || isMidSquare(position.x)) &&
block === Pacman.BISCUIT || block === Pacman.PILL) {
map.setBlock(pointToCoord(nextSquare(position.y, direction)),
pointToCoord(nextSquare(position.x, direction)),
Pacman.EMPTY);
addScore(10);
eaten += 1;
if (eaten === 182) {
game.completedLevel();
}
if (block === Pacman.PILL) {
game.eatenPill();
}
}
return {
"new" : position,
"old" : oldPosition
};
};
function isMidSquare(x) {
var rem = x % 10;
return rem > 3 || rem < 7;
};
function calcAngle(dir, pos) {
if (dir == RIGHT && (pos.x % 10 < 5)) {
return {"start":0.25, "end":1.75, "direction": false};
} else if (dir === DOWN && (pos.y % 10 < 5)) {
return {"start":0.75, "end":2.25, "direction": false};
} else if (dir === UP && (pos.y % 10 < 5)) {
return {"start":1.25, "end":1.75, "direction": true};
} else if (dir === LEFT && (pos.x % 10 < 5)) {
return {"start":0.75, "end":1.25, "direction": true};
}
return {"start":0, "end":2, "direction": false};
};
function drawDead(ctx, amount) {
var size = map.blockSize,
half = size / 2;
if (amount >= 1) {
return;
}
ctx.fillStyle = "#FFFF00";
ctx.beginPath();
ctx.moveTo(((position.x/10) * size) + half,
((position.y/10) * size) + half);
ctx.arc(((position.x/10) * size) + half,
((position.y/10) * size) + half,
half, 0, Math.PI * 2 * amount, true);
ctx.fill();
};
function draw(ctx) {
var angle = calcAngle(direction, position);
ctx.fillStyle = "#FFFF00";
ctx.beginPath();
ctx.moveTo(((position.x/10) * map.blockSize) + map.blockSize / 2,
((position.y/10) * map.blockSize) + map.blockSize / 2);
ctx.arc(((position.x/10) * map.blockSize) + map.blockSize / 2,
((position.y/10) * map.blockSize) + map.blockSize / 2,
map.blockSize / 2,
Math.PI * angle.start,
Math.PI * angle.end, angle.direction);
ctx.fill();
};
initUser();
return {
"draw" : draw,
"drawDead" : drawDead,
"loseLife" : loseLife,
"getLives" : getLives,
"score" : score,
"addScore" : addScore,
"theScore" : theScore,
"keyDown" : keyDown,
"move" : move,
"newLevel" : newLevel,
"reset" : reset,
"resetPosition" : resetPosition
};
};
Pacman.Map = function (size) {
var height = null,
width = null,
blockSize = size,
pillSize = 0,
map = null;
function withinBounds(y, x) {
return y >= 0 && y < height && x >= 0 && x < width;
}
function isWall(y, x) {
return withinBounds(y, x) && map[y][x] === Pacman.WALL;
}
function isFloorSpace(y, x) {
if (!withinBounds(y, x)) {
return false;
}
var peice = map[y][x];
return peice === Pacman.EMPTY ||
peice === Pacman.BISCUIT ||
peice === Pacman.PILL;
}
function drawWall(ctx) {
var i, j, p, line;
ctx.strokeStyle = "#0000FF";
ctx.lineWidth = 5;
ctx.lineCap = "round";
for (i = 0; i < Pacman.WALLS.length; i += 1) {
line = Pacman.WALLS[i];
ctx.beginPath();
for (j = 0; j < line.length; j += 1) {
p = line[j];
if (p.move) {
ctx.moveTo(p.move[0] * blockSize, p.move[1] * blockSize);
} else if (p.line) {
ctx.lineTo(p.line[0] * blockSize, p.line[1] * blockSize);
} else if (p.curve) {
ctx.quadraticCurveTo(p.curve[0] * blockSize,
p.curve[1] * blockSize,
p.curve[2] * blockSize,
p.curve[3] * blockSize);
}
}
ctx.stroke();
}
}
function reset() {
map = Pacman.MAP.clone();
height = map.length;
width = map[0].length;
};
function block(y, x) {
return map[y][x];
};
function setBlock(y, x, type) {
map[y][x] = type;
};
function drawPills(ctx) {
if (++pillSize > 30) {
pillSize = 0;
}
for (i = 0; i < height; i += 1) {
for (j = 0; j < width; j += 1) {
if (map[i][j] === Pacman.PILL) {
ctx.beginPath();
ctx.fillStyle = "#000";
ctx.fillRect((j * blockSize), (i * blockSize),
blockSize, blockSize);
ctx.fillStyle = "#FFF";
ctx.arc((j * blockSize) + blockSize / 2,
(i * blockSize) + blockSize / 2,
Math.abs(5 - (pillSize/3)),
0,
Math.PI * 2, false);
ctx.fill();
ctx.closePath();
}
}
}
};
function draw(ctx) {
var i, j, size = blockSize;
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, width * size, height * size);
drawWall(ctx);
for (i = 0; i < height; i += 1) {
for (j = 0; j < width; j += 1) {
drawBlock(i, j, ctx);
}
}
};
function drawBlock(y, x, ctx) {
var layout = map[y][x];
if (layout === Pacman.PILL) {
return;
}
ctx.beginPath();
if (layout === Pacman.EMPTY ||
layout === Pacman.BLOCK ||
layout === Pacman.BISCUIT) {
ctx.fillStyle = "#000";
ctx.fillRect((x * blockSize), (y * blockSize),
blockSize, blockSize);
if (layout === Pacman.BISCUIT) {
ctx.fillStyle = "#FFF";
ctx.fillRect((x * blockSize) + (blockSize / 2.5),
(y * blockSize) + (blockSize / 2.5),
blockSize / 6, blockSize / 6);
}
}
ctx.closePath();
};
reset();
return {
"draw" : draw,
"drawBlock" : drawBlock,
"drawPills" : drawPills,
"block" : block,
"setBlock" : setBlock,
"reset" : reset,
"isWallSpace" : isWall,
"isFloorSpace" : isFloorSpace,
"height" : height,
"width" : width,
"blockSize" : blockSize
};
};
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,
level = 0,
tick = 0,
ghostPos, userPos,
stateChanged = true,
timerStart = null,
lastTime = 0,
ctx = null,
timer = null,
map = null,
user = null,
stored = null;
function getTick() {
return tick;
};
function drawScore(text, position) {
ctx.fillStyle = "#FFFFFF";
ctx.font = "12px BDCartoonShoutRegular";
ctx.fillText(text,
(position["new"]["x"] / 10) * map.blockSize,
((position["new"]["y"] + 5) / 10) * map.blockSize);
}
function dialog(text) {
ctx.fillStyle = "#FFFF00";
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();
for (var i = 0; i < ghosts.length; i += 1) {
ghosts[i].reset();
}
audio.play("start");
timerStart = tick;
setState(COUNTDOWN);
}
function startNewGame() {
setState(WAITING);
level = 1;
user.reset();
map.reset();
map.draw(ctx);
startLevel();
}
function keyDown(e) {
if (e.keyCode === 13) {
startNewGame();
} else if (e.keyCode === 83) {
audio.disableSound();
localStorage["soundDisabled"] = !soundDisabled();
} else if (e.keyCode === 27 && state === PAUSE) {
audio.resume();
map.draw(ctx);
setState(stored);
} else if (e.keyCode === 27) {
stored = state;
setState(PAUSE);
audio.pause();
map.draw(ctx);
dialog("PAUSA");
} else if (state !== PAUSE) {
return user.keyDown(e);
}
return true;
}
function loseLife() {
setState(WAITING);
user.loseLife();
if (user.getLives() > 0) {
startLevel();
}
}
function setState(nState) {
state = nState;
stateChanged = true;
};
function collided(user, ghost) {
return (Math.sqrt(Math.pow(ghost.x - user.x, 2) +
Math.pow(ghost.y - user.y, 2))) < 10;
};
function drawFooter() {
var topLeft = (map.height * map.blockSize),
textBase = topLeft + 17;
ctx.fillStyle = "#000000";
ctx.fillRect(0, topLeft, (map.width * map.blockSize), 30);
ctx.fillStyle = "#FFFF00";
for (var i = 0, len = user.getLives(); i < len; i++) {
ctx.fillStyle = "#FFFF00";
ctx.beginPath();
ctx.moveTo(150 + (25 * i) + map.blockSize / 2,
(topLeft+1) + map.blockSize / 2);
ctx.arc(150 + (25 * i) + map.blockSize / 2,
(topLeft+1) + map.blockSize / 2,
map.blockSize / 2, Math.PI * 0.25, Math.PI * 1.75, false);
ctx.fill();
}
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 BDCartoonShoutRegular";
ctx.fillText("Puntos: " + user.theScore(), 30, textBase);
ctx.fillText("Nivel: " + level, 260, textBase);
}
function redrawBlock(pos) {
map.drawBlock(Math.floor(pos.y/10), Math.floor(pos.x/10), ctx);
map.drawBlock(Math.ceil(pos.y/10), Math.ceil(pos.x/10), ctx);
}
function mainDraw() {
var diff, u, i, len, nScore;
ghostPos = [];
for (i = 0, len = ghosts.length; i < len; i += 1) {
ghostPos.push(ghosts[i].move(ctx));
}
u = user.move(ctx);
for (i = 0, len = ghosts.length; i < len; i += 1) {
redrawBlock(ghostPos[i].old);
}
redrawBlock(u.old);
for (i = 0, len = ghosts.length; i < len; i += 1) {
ghosts[i].draw(ctx);
}
user.draw(ctx);
userPos = u["new"];
for (i = 0, len = ghosts.length; i < len; i += 1) {
if (collided(userPos, ghostPos[i]["new"])) {
if (ghosts[i].isVunerable()) {
audio.play("eatghost");
ghosts[i].eat();
eatenCount += 1;
nScore = eatenCount * 50;
drawScore(nScore, ghostPos[i]);
user.addScore(nScore);
setState(EATEN_PAUSE);
timerStart = tick;
} else if (ghosts[i].isDangerous()) {
audio.play("die");
setState(DYING);
timerStart = tick;
}
}
}
};
function mainLoop() {
var diff;
if (state !== PAUSE) {
++tick;
}
map.drawPills(ctx);
if (state === PLAYING) {
mainDraw();
} else if (state === WAITING && stateChanged) {
stateChanged = false;
map.draw(ctx);
dialog("ENTER para comenzar a jugar");
} else if (state === EATEN_PAUSE && tick - timerStart > 11) {
map.draw(ctx);
setState(PLAYING);
} else if (state === DYING) {
if (tick - timerStart > 60) {
loseLife();
} else {
redrawBlock(userPos);
for (i = 0, len = ghosts.length; i < len; i += 1) {
redrawBlock(ghostPos[i].old);
ghostPos.push(ghosts[i].draw(ctx));
}
user.drawDead(ctx, (tick - timerStart) / 60);
}
} else if (state === COUNTDOWN) {
diff = 5 + Math.floor((timerStart - tick) / 30);
if (diff === 0) {
map.draw(ctx);
setState(PLAYING);
} else {
if (diff !== lastTime) {
lastTime = diff;
map.draw(ctx);
dialog("Comenzando en: " + diff);
}
}
}
drawFooter();
}
function eatenPill() {
audio.play("eatpill");
timerStart = tick;
eatenCount = 0;
for (i = 0; i < ghosts.length; i += 1) {
ghosts[i].makeEatable(ctx);
}
};
function completedLevel() {
setState(WAITING);
level += 1;
map.reset();
user.newLevel();
startLevel();
};
function keyPress(e) {
if (state !== WAITING && state !== PAUSE) {
e.preventDefault();
e.stopPropagation();
}
};
function init(wrapper, root) {
var i, len, ghost,
maxHeight = (wrapper.offsetHeight - 30) / 22,
maxWidth = wrapper.offsetWidth / 19,
blockSize = Math.floor(Math.min(maxWidth, maxHeight)),
canvas = document.createElement("canvas");
canvas.setAttribute("width", (blockSize * 19) + "px");
canvas.setAttribute("height", (blockSize * 22) + 30 + "px");
wrapper.appendChild(canvas);
ctx = canvas.getContext('2d');
audio = new Pacman.Audio({"soundDisabled":soundDisabled});
map = new Pacman.Map(blockSize);
user = new Pacman.User({
"completedLevel" : completedLevel,
"eatenPill" : eatenPill
}, map);
for (i = 0, len = ghostSpecs.length; i < len; i += 1) {
ghost = new Pacman.Ghost({"getTick":getTick}, map, ghostSpecs[i]);
ghosts.push(ghost);
}
map.draw(ctx);
dialog("Cargando ...");
var myAudio = document.createElement('audio');
var canPlayOGG = !!(myAudio.canPlayType('audio/ogg').replace(/no/, ''));
var canPlayMP3 = !!(myAudio.canPlayType('audio/mpeg').replace(/no/, ''));
var extension = canPlayOGG ? '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 load(arr) {
if (arr.length === 0) {
loaded();
} else {
var x = arr.pop();
audio.load(x[0], x[1], function() { load(arr); });
}
};
function loaded() {
dialog("ENTER PARA JUGAR");
document.addEventListener("keydown", keyDown, true);
document.addEventListener("keypress", keyPress, true);
timer = window.setInterval(mainLoop, 35);
};
return {
"init" : init
};
}());
</script>
<script>
var el = document.getElementById("pacman");
function supportsOggAudio() {
var myAudio = document.createElement("audio");
return typeof myAudio.canPlayType === "function" &&
("no" != myAudio.canPlayType("audio/ogg")) &&
("" != myAudio.canPlayType("audio/ogg"));
};
function supports_canvas() {
return !!document.createElement('canvas').getContext;
};
function supports_local_storage() {
return ('localStorage' in window) && window['localStorage'] !== null;
};
function supports_audio() {
var myAudio = document.createElement('audio');
var canPlayOGG = typeof myAudio.canPlayType === "function" &&
!!(myAudio.canPlayType('audio/ogg').replace(/no/, ''));
var canPlayMP3 = typeof myAudio.canPlayType === "function" &&
!!(myAudio.canPlayType('audio/mpeg').replace(/no/, ''));
return canPlayOGG || canPlayMP3;
};
if (supports_canvas() && supports_local_storage() && supports_audio()) {
window.setTimeout(function () { PACMAN.init(el, "http://arandomurl.com/random/pacman/"); }, 0);
} else {
el.innerHTML = "Tu navegador no es compatible";
}
</script>
<style>
@font-face {
font-family: 'BDCartoonShoutRegular';
src: url('BD_Cartoon_Shout-webfont.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
#shim {
font-family: BDCartoonShoutRegular;
position:absolute;
visibility:hidden;
}
#pacman {
width:412px;
height:450px;
margin:20px auto;
}
</style>