const PADDING = 50; const PADDLE_SIZE = { width: 500, height: 30, } const BALL_SIZE = { width: 50, height: 30 } const PADDLE_POSITION = { x: (window.screen.availWidth / 2) - (PADDLE_SIZE.width/2), y: window.screen.availHeight - PADDLE_SIZE.height - PADDING } const TARGET_SIZE = { width: 300, height: 100 } const TARGET_GRID = { x: 4, y: 3 } const PADDLE_MOVE = 30; function shuffleArray(array) { return array.map(value => ({ value, sort: Math.random() })) .sort((a, b) => a.sort - b.sort) .map(({ value }) => value) } function plan_grid(){ let n_targets = TARGET_GRID.x * TARGET_GRID.y; let pages, page_objects; // get pages that are real pages pages = document.querySelectorAll('.page-metadata'); page_objects = Array.from(pages).map((page) => { return { url: page.getAttribute('url') } }) // pad end with blanks page_objects = Object.assign(new Array(n_targets).fill({url:'blank.html'}), page_objects); // shuffle array order page_objects = shuffleArray(page_objects) // arrange on a grid! page_objects = page_objects.map((page, idx) => { let col = idx % TARGET_GRID.x; let row = Math.floor(idx / TARGET_GRID.x); let col_grid_width = (window.screen.availWidth-(PADDING*2)) / TARGET_GRID.x return { ...page, x: (col_grid_width * col) + PADDING, y: (PADDING*2 + TARGET_SIZE.height) * row } }) return page_objects } function popupPosition(popup){ let pos = { left: popup.screenLeft, right: popup.screenLeft + popup.outerWidth, top: popup.screenTop, bottom: popup.screenTop + popup.outerHeight } pos.centerX = (pos.left + pos.right) / 2 pos.centerY = (pos.top + pos.bottom) / 2 return pos } function checkIntersect(a, b){ let pos_a = popupPosition(a); let pos_b = popupPosition(b); // console.log(pos_a,pos_b) // check if intersect let overlap = !( pos_a.right < pos_b.left || pos_a.left > pos_b.right || pos_a.bottom < pos_b.top || pos_a.top > pos_b.bottom ) if (overlap === false){ return false } // if overlap, check what side we are on if (Math.abs(pos_a.centerX-pos_b.centerX) > Math.abs(pos_a.centerY-pos_b.centerY)){ // more X difference than y difference, we are left or right if (pos_a.centerX > pos_b.centerX){ // a is to the right of b return('right') } else { return('left') } } else { if (pos_a.centerY > pos_b.centerY){ // a is below b return('bottom') } else { return('top') } } } function endGame(popups, ball, paddle){ for (let popup of popups){ popup.popup.close() } ball.popup.close(); paddle.close(); } function handleIntersect(popup, popups){ if (popup.url === "blank.html"){ popup.popup.close() let index = popups.indexOf(popup); if (index > -1){ popups.splice(index, 1); } console.log('closing popup') return false } else { window.location = popup.url console.log('going to new page!') return true; } } function updateBall(ball, popups, paddle){ let end_game = false; ball.position = popupPosition(ball.popup) // console.log(ball.position, popups.popup) // check bounce if (ball.position.right === window.screen.availWidth || ball.position.left === 0){ ball.velocity.x *= -1 } if (ball.position.top === screen.availTop){ ball.velocity.y *= -1 } // check intersections with other windows for (let popup of popups){ // console.log(popup.popup) let intersected = checkIntersect(ball.popup, popup.popup) if (intersected === 'top' || intersected === 'bottom'){ ball.velocity.y *= -1; } else if (intersected === 'left' || intersected === 'right'){ ball.velocity.x *= -1; } if (intersected){ console.log(intersected); end_game = handleIntersect(popup, popups); break } } if (checkIntersect(ball.popup, paddle) && ball.velocity.y < 0){ ball.velocity.y *= -1; } if (ball.position.bottom === window.screen.availHeight && ball.velocity.y < 0){ // ball died :( // end_game = true; ball.popup.close(); ball = init_ball(); } if (end_game){ endGame(popups, ball, paddle) } else { ball.popup.moveBy(ball.velocity.x, -ball.velocity.y) window.setTimeout(() => {updateBall(ball, popups, paddle)}, 100) } } function init_ball(){ let ball_popup = window.open('ball.html', 'ball', `popup=true,width=${BALL_SIZE.width},height=${BALL_SIZE.height},screenX=${PADDLE_POSITION.x},screenY=${PADDLE_POSITION.y-BALL_SIZE.height}`) ball_popup.moveTo(PADDLE_POSITION.x,PADDLE_POSITION.y) let ball = { popup: ball_popup, velocity: {x: 20, y: 20} }; return ball } function init_controller(){ let grid = plan_grid(); console.log(grid); let popups = grid.map((page, idx) => { return{ ...page, popup: window.open(page.url, `target-${idx}`, `popup=true,width=${TARGET_SIZE.width},height=${TARGET_SIZE.height},left=${page.x},top=${page.y}`) } }) let paddle = window.open('paddle.html', 'paddle', `popup=true,width=${PADDLE_SIZE.width},height=${PADDLE_SIZE.height},screenX=${PADDLE_POSITION.x},screenY=${PADDLE_POSITION.y}`) let ball = init_ball(); updateBall(ball, popups, paddle); } function init_paddle(){ window.resizeTo(PADDLE_SIZE.width, PADDLE_SIZE.height); window.moveTo( PADDLE_POSITION.x, PADDLE_POSITION.y ) document.addEventListener('keydown', (event) => { if (event.key == "ArrowLeft"){ if (window.screenX > PADDLE_MOVE) { window.moveBy(-PADDLE_MOVE, 0) } else { window.moveBy(-window.screenX, 0); } } else if (event.key == "ArrowRight"){ let right_edge = window.screenX + window.outerWidth; if (right_edge < window.screen.availWidth - PADDLE_MOVE){ window.moveBy(PADDLE_MOVE, 0) } else { window.moveBy(window.screen.availWidth - right_edge, 0) } } }) } export function init(){ let page_type = document.querySelector('main').getAttribute('page'); if (page_type === 'pong'){ init_controller(); } else if (page_type === "paddle"){ init_paddle(); } }