Skip to content

Instantly share code, notes, and snippets.

@dmirtyisme
Created February 11, 2016 05:58
Show Gist options
  • Save dmirtyisme/f4912a89cde48e39b432 to your computer and use it in GitHub Desktop.
Save dmirtyisme/f4912a89cde48e39b432 to your computer and use it in GitHub Desktop.
self pong
<div id="screen"></div>
!function() {
"use strict";
// variables
var acc = 1.01;
var speed = 0.025;
var angle = 15;
var pong1, pong2, pong3;
var timeP = new Date();
// def audio
if (window.Audio) {
var base = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/222599/";
var notlogical = new Audio(base + 'Door_entry_notification.mp3');
notlogical.play();
pong1 = new Audio(base + 'pong1.mp3');
pong2 = new Audio(base + 'pong2.mp3');
pong3 = new Audio(base + 'pong3.mp3');
}
// def screen
var screen = {
elem: document.getElementById('screen'),
left: 0,
width: 0,
height: 0,
scaleX: 0,
scaleY: 0
}
// append html elements helper
screen.elem.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 = screen.elem.append;
return object;
}
// resize
screen.resize = function () {
// screen size and position
var o = screen.elem;
for (screen.left = 0; o != null; o = o.offsetParent) screen.left += o.offsetLeft;
screen.width = screen.elem.offsetWidth;
screen.height = screen.elem.offsetHeight;
// scale pixels size
screen.scaleX = screen.width * 0.03;
screen.scaleY = screen.height * 0.25;
// ball and pads
ball.style.width = ball.style.height = Math.round(screen.scaleX) + 'px';
pad[0].style.width = pad[1].style.width = Math.round(screen.scaleX) + 'px';
pad[0].style.height = pad[1].style.height = Math.round(screen.scaleY) + 'px';
pad[0].style.left = Math.round(screen.scaleX) + "px";
pad[1].style.left = Math.round(screen.width - screen.scaleX * 2) + "px";
// scores
for (var i = 0; i < 4; i++) {
var o = score[i].elem.style;
o.width = o.height = Math.round(3 * screen.scaleX) + 'px';
o.left = Math.round(score[i].d > 0 ? screen.width * 0.5 + 2 * screen.scaleX : screen.width * 0.4 - 2 * screen.scaleX) + 'px';
o.top = Math.round(i < 2 ? screen.scaleX : screen.height - 4 * screen.scaleX) + 'px';
}
// separation
sp.style.width = Math.round(screen.scaleX) + 'px';
sp.style.left = Math.round(screen.width * 0.5 - screen.scaleX * 0.5) + 'px';
sp.innerHTML = "";
for (var i = 0; i < screen.height; i += screen.scaleX * 2) {
sp.append('span', false, {
'top': Math.round(i) + 'px',
'width': Math.round(screen.scaleX) + 'px',
'height': Math.round(screen.scaleX) + 'px'
});
}
}
// move pads
screen.move = function (e, touch) {
e.preventDefault();
var pointer = touch ? e.touches[0] : e;
var y = screen.height - screen.scaleY;
var x = (pointer.clientX - screen.left) / screen.width;
pad[0].y = Math.min(screen.height - screen.scaleY, Math.max(0, x * y * 2 - y * 0.5));
pad[1].y = Math.min(screen.height - screen.scaleY, Math.max(0, (1 - x) * y * 2 - y * 0.5));
}
// launch new ball
screen.down = function (e, touch) {
e.preventDefault();
if (player >= 0) {
pong1 && pong1.play();
ball.vx = screen.scaleX * speed;
ball.vy = (Math.random() - 0.5) * screen.height * 0.01;
if (player === 1) ball.vx = -ball.vx;
player = -1;
}
}
// def scores
var score = [
{s:0, d:-1},
{s:0, d: 1},
{s:0, d:-1},
{s:0, d: 1}
];
score.chrono = function (score) {
var dir = score.d;
var txt = score.s + "";
score.elem.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.elem.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] + '%'
});
}
}
}
}
score.forEach(function (s) {
s.elem = screen.elem.append('div');
score.chrono(s);
});
// pads
var pad = [];
pad.ping = function () {
if (ball.y + screen.scaleX > this.y && ball.y < this.y + screen.scaleY) {
pong1 && pong1.play();
// inc scores
score[2].s++;
score.chrono(score[2]);
if(score[2].s > score[3].s) {
score[3].s = score[2].s;
score.chrono(score[3]);
}
// bounce
ball.vx = -ball.vx * acc;
ball.x = this.x;
if (ball.y < this.y) {
ball.vy = ball.vx * -this.s * angle + Math.random() * 0.1;
} else if (ball.y > this.y + screen.scaleY - screen.scaleX) {
ball.vy = ball.vx * this.s * angle + Math.random() * 0.1;
} else {
ball.vy = (Math.random() - 0.5) * ball.vx * angle;
}
}
}
// first pad
pad.push({
y: 0,
s: 1,
ping: pad.ping,
get x () {
return screen.scaleX * 2;
}
});
// second pad
pad.push({
y: 0,
s:-1,
ping: pad.ping,
get x () {
return screen.width - screen.scaleX * 3;
}
});
pad[0].style = screen.elem.append('span').style;
pad[1].style = screen.elem.append('span').style;
// ball
var ball = {
vx: 0,
vy: 0,
x: 0,
y: 0,
w: 0
}
ball.style = screen.elem.append('span').style;
// separation line
var sp = screen.elem.append('div', false, {
'height': '100%'
});
var player = 0;
// mouse/touch events
if ('ontouchstart' in window) {
screen.elem.ontouchstart = function(e) { screen.down(e, true); };
screen.elem.ontouchmove = function(e) { screen.move(e, true); };
}
window.addEventListener("mousemove", function(e) { screen.move(e, false); }, false );
screen.elem.addEventListener("click", function(e) { screen.down(e, false); }, false);
// screen resize
window.addEventListener("resize", screen.resize, false );
screen.resize();
// player wins
function win (p) {
pong3 && pong3.play();
score[1 - p].s++;
score.chrono(score[1 - p]);
score[2].s = 0;
score.chrono(score[2]);
player = p;
}
// main loop
function run () {
requestAnimationFrame(run);
var time = new Date();
var vx = ball.vx * (time - timeP);
// playing
if (player < 0) {
ball.x += vx;
ball.y += ball.vy;
} else {
ball.x = pad[player].x;
ball.y = pad[player].y + screen.scaleY * 0.5 - screen.scaleX * 0.5;
}
timeP = time;
// collisions
if (ball.vx > 0) {
if (ball.x > screen.width + screen.scaleX) win(1);
else if (ball.x > screen.width - screen.scaleX * 3) pad[1].ping();
} else {
if (ball.x < -screen.scaleX) win(0);
else if (ball.x < screen.scaleX * 2) pad[0].ping();
}
if (ball.y > screen.height - screen.scaleX || ball.y < 0) {
pong2 && pong2.play();
ball.vy = -ball.vy;
}
// DOM animation
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';
}
// go go go !
run();
}();
html {
overflow: hidden;
touch-action: none;
content-zooming: none;
}
body {
position: absolute;
margin: 0;
padding: 0;
background: #222;
width: 100%;
height: 100%;
}
#screen {
width: 100vw;
height: 56.25vw; /* 100/56.25 = 1.778 */
background: #000;
max-height: 100vh;
max-width: 177.78vh; /* 16/9 = 1.778 */
margin: auto;
position: absolute;
top:0; /* vertical center */
bottom:0;
left:0; /* horizontal center */
right:0;
overflow: hidden;
cursor: crosshair;
}
#screen div {
position: absolute;
overflow: hidden;
}
#screen span {
position: absolute;
background: #FFF;
overflow:hidden;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment