pong


Direct Link

Source code

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>pong - interactive DHTML</title>
<meta name="Author" content="Gerard Ferrandez at http://www.dhteumeuleu.com">
<meta http-equiv="imagetoolbar" content="no">
<style type="text/css">
html {
overflow: hidden;
}
body {
margin: 0px;
padding: 0px;
background: #222;
width: 100%;
height: 100%;
cursor: crosshair;
}
#screen {
position:absolute;
left: 0%;
top: 0%;
width: 100%;
height: 100%;
background: #000;
overflow: hidden;
cursor: crosshair;
}
#screen div {
position: absolute;
}
#screen span {
position: absolute;
background: #FFF;
}
#credit {
position: absolute;
color: #888;
font-family: arial;
font-size: 0.7em;
width: 99%;
text-align: right;
bottom: 2px;
z-index: 10000;
}
a {text-decoration: none;color:#fff;}
a:hover {text-decoration: none;background:#ff8000;color:#fff;}
a:visited {text-decoration: none;color:#fff;}
a:visited:hover {text-decoration: none;background:#ff8000;color:#fff;}
</style>
<script type="text/javascript" src="soundmanager.js"></script>
<script type="text/javascript">
/*
=================================================================
script: pong.html (schizophrenic version)
author: Gerard Ferrandez - [Ge1doot]
date: May 12, 2008
site: http://www.dhteumeuleu.com
----------------------------------------------------------------
sound manager by Scott Schiller at http://www.schillmania.com
=================================================================
*/
var js = {
/* ===== crossbrowsers events ==== */
addEvent : function ( obj, type, fn ) {
if (obj.addEventListener) obj.addEventListener(type, fn, false);
else if (obj.attachEvent) obj.attachEvent('on' + type, function() { return fn.call(obj, window.event); });
},
/* ===== create JS Object ==== */
JSObject : function (att) {
var object = new Object();
for( var i in att) object[i] = att[i];
return object;
},
/* ===== append HTML Element ==== */
Append : function (tag, att, css) {
var object = document.createElement(tag);
for( var i in att) object[i] = att[i];
for( var i in css) object.style[i] = css[i];
this.appendChild(object);
object.append = js.Append;
return object;
},
/* ===== soundify a href links ==== */
soundifyLinks : function (container, over, clic){
if (container){
var l = container.getElementsByTagName('a');
for(var i = 0, n = l.length; i < n; i++){
this.addEvent(l[i], 'click', new Function("soundManager.play('"+clic+"');"));
this.addEvent(l[i], 'mouseover', new Function("soundManager.play('"+over+"');"));
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var pong = function() {
/* ==== private variables and methods ==== */
///////////////////////
var acc = 1.01;
var speed = .025;
var angle = 15;
///////////////////////
var screen = new js.JSObject({left:0, width:0, height:0, scale_x:0, scale_y:0});
var ball = new js.JSObject({vx:0, vy:0, x:0, y:0, w:0});
var pad = [
new js.JSObject({y:0, s:1, ping:Ping, x:function(){return screen.scale_x * 2;}}),
new js.JSObject({y:0, s:-1, ping:Ping, x:function(){return screen.width - screen.scale_x * 3;}})
];
var time_p = new Date();
var score = [
new js.JSObject({s:0, d:-1}),
new js.JSObject({s:0, d:1}),
new js.JSObject({s:0, d:-1}),
new js.JSObject({s:0, d:1})
];
var sp;
var player = 0;
/* ===== window resize ==== */
function resize () {
/* ---- screen position/size ---- */
var o = screen.div;
for (screen.left = 0; o != null; o = o.offsetParent) screen.left += o.offsetLeft;
screen.width = screen.div.offsetWidth;
screen.height = screen.div.offsetHeight;
/* ---- scale pixels size ---- */
screen.scale_x = screen.width * .03;
screen.scale_y = screen.height * .25;
/* ---- ball and pads position/size ---- */
ball.style.width = ball.style.height = Math.round(screen.scale_x) + 'px';
pad[0].style.width = pad[1].style.width = Math.round(screen.scale_x) + 'px';
pad[0].style.height = pad[1].style.height = Math.round(screen.scale_y) + 'px';
pad[0].style.left = Math.round(screen.scale_x) + "px";
pad[1].style.left = Math.round(screen.width - screen.scale_x * 2) + "px";
/* ---- scores ---- */
for (var i = 0; i < 4; i++) {
var o = score[i].div.style;
o.width = o.height = Math.round(3 * screen.scale_x) + 'px';
o.left = Math.round(score[i].d > 0 ? screen.width * .5 + 2 * screen.scale_x : screen.width * .4 - 2 * screen.scale_x) + 'px';
o.top = Math.round(i < 2 ? screen.scale_x : screen.height - 4 * screen.scale_x) + 'px';
}
/* ---- middle line ---- */
sp.style.width = Math.round(screen.scale_x) + 'px';
sp.style.left = Math.round(screen.width * .5 - screen.scale_x * .5) + 'px';
sp.innerHTML = "";
for (var i = 0; i < screen.height; i += screen.scale_x * 2)
sp.append('span', false, {
'top':Math.round(i) + 'px',
'width':Math.round(screen.scale_x) + 'px',
'height':Math.round(screen.scale_x) + 'px'
});
}
/* ---- bounce on pad ---- */
function Ping() {
if (ball.y + screen.scale_x > this.y && ball.y < this.y + screen.scale_y) {
/* ---- play sound first and return (mitigate latency) ---- */
if (!ball.sound) {
soundManager.play('pong1');
ball.sound = true;
ball.x = this.x();
return;
}
ball.sound = false;
/* ---- inc scores ---- */
score[2].s++;
chrono(score[2]);
if(score[2].s > score[3].s) {
score[3].s = score[2].s;
chrono(score[3]);
}
/* ---- reverse direction and accelerate ---- */
ball.vx = -ball.vx * acc;
ball.x = this.x();
/* ---- beware of the corners! ---- */
if (ball.y < this.y) ball.vy = ball.vx * -this.s * angle + Math.random() * .1;
else if (ball.y > this.y + screen.scale_y - screen.scale_x) ball.vy = ball.vx * this.s * angle + Math.random() * .1;
/* ---- angle ---- */
else ball.vy = (Math.random() - .5) * ball.vx * angle;
}
}
/* ---- player won ---- */
function win(p) {
soundManager.play('pong3');
score[1 - p].s++;
chrono(score[1 - p]);
score[2].s = 0;
chrono(score[2]);
player = p;
}
/* ---- draw numeric digits ---- */
function chrono(score) {
var dir = score.d;
var txt = score.s + '';
score.div.innerHTML = '';
var a = [119,36,93,109,46,107,123,37,127,111];
var s = {1:[0,0,99,20],2:[0,0,33,45],4:[67,0,33,45],8:[0,40,100,20],16:[0,40,33,60],32:[67,40,33,60],64:[0,80,99,20]};
for (var i = 0, n = txt.length; i < n; i++) {
var c = txt.charAt(dir > 0 ? i : n - i - 1);
var p = a[c];
if (p) {
var d = score.div.append('div', false, {'height':'100%','width':'100%','left':(120 * i * dir) + '%'});
for (var j in s) {
var k = s[j];
if (p & j) d.append('span', false, {'left':k[0]+'%','top':k[1]+'%','width':k[2]+'%','height':k[3]+'%'});
}
}
}
}
/* ==== public methods ==== */
return {
/* ---- initialize script ---- */
init : function (container) {
/* ---- container ---- */
screen.div = document.getElementById(container);
if (!screen.div) return false;
screen.div.append = js.Append;
/* ---- pads and ball ---- */
pad[0].style = screen.div.append('span').style;
pad[1].style = screen.div.append('span').style;
ball.style = screen.div.append('span').style;
/* ---- scores ---- */
for (var i = 0; i < 4; i++) {
score[i].div = screen.div.append('div');
chrono(score[i]);
}
/* ---- center line ---- */
sp = screen.div.append('div', false, {'height':'100%'});
/* ---- do resize ---- */
resize();
/* ---- move pads ---- */
js.addEvent(screen.div, 'mousemove', function(e) {
e = e || window.event;
var y = screen.height - screen.scale_y;
var x = (e.clientX - screen.left) / screen.width;
pad[0].y = x * y;
pad[1].y = (1 - x) * y;
return false;
});
/* ---- launch ball ---- */
js.addEvent(screen.div, 'click', function(e) {
if (player >= 0) {
soundManager.play('pong1');
ball.vx = screen.scale_x * speed;
ball.vy = (Math.random() - .5) * screen.height * .01;
if (player == 1) ball.vx = -ball.vx;
player = -1;
}
});
/* ---- window resize event ---- */
js.addEvent(window, 'resize', resize);
/* ---- launch script ---- */
setInterval(pong.run, 16);
},
/* ==== main loop ==== */
run : function () {
/* ---- ball movment ---- */
var time = new Date();
var vx = ball.vx * (time - time_p);
if (player < 0) {
/* ---- playing ---- */
ball.x += vx;
ball.y += ball.vy;
} else {
/* ---- waiting ---- */
ball.x = pad[player].x();
ball.y = pad[player].y + screen.scale_y * .5 - screen.scale_x * .5;
}
time_p = time;
/* ---- test collisions ---- */
if (ball.vx > 0) {
/* ---- right player lost ---- */
if (ball.x > screen.width + screen.scale_x) win(1);
/* ---- bounce pad ---- */
else if (ball.x > screen.width - screen.scale_x * 3) pad[1].ping();
} else {
/* ---- left player lost ---- */
if (ball.x < -screen.scale_x) win(0);
/* ---- bounce pad ---- */
else if (ball.x < screen.scale_x * 2) pad[0].ping();
}
/* ---- collision top / bottom ---- */
if (ball.y > screen.height - screen.scale_x || ball.y < 0) {
soundManager.play('pong2');
ball.vy = -ball.vy;
}
/* ---- animate HTML elements ---- */
pad[0].style.top = Math.round(pad[0].y) + 'px';
pad[1].style.top = Math.round(pad[1].y) + 'px';
ball.style.left = Math.round(ball.x) + 'px';
ball.style.top = Math.round(ball.y) + 'px';
}
}
}();
/* ==== global onload ==== */
onload = function () {
/* ---- init sounds ---- */
soundManagerInit();
js.soundifyLinks(document.body, 'link', 'select');
/* ---- init script ---- */
pong.init('screen');
}
</script>
</head>
<body>
<div id="screen"></div>
<div id="credit">
credits: <a href="http://www.dhteumeuleu.com/" target="_self" title="Interactive DHTML demos">www.dhteumeuleu.com </a>
· code: <a href="http://www.dhteumeuleu.com/colorsyntax/viewJS.php?src=pong.html" target="_self" title="source code">pong</a>
 ·
<a href="http://www.schillmania.com/projects/soundmanager2/" target="_self" title="soundManager">soundManager</a>
</div>
</body>
</html>

 

Feed updates subscription

Enter your email address:

Delivered by FeedBurner

Donate

Want to give me some extra encouragement ?

License

Creative Commons License

Except where otherwise noted, all Javascript code on this site is licensed under a Creative Commons License.