<!-- Copyright 2009, Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> <title>o3dPingPong</title> <script type="text/javascript" src="../o3djs/base.js"></script> <script type="text/javascript" id="o3dscript"> o3djs.require('o3djs.util'); o3djs.require('o3djs.math'); o3djs.require('o3djs.rendergraph'); o3djs.require('o3djs.event'); var shader='uniform float4x4 worldViewProjMatrix : WORLDVIEWPROJECTION;\n'+ 'void vs(\n'+ ' float4 pos: POSITION,\n'+ ' float4 col: COLOR,\n'+ '\n'+ ' out float4 oPos: POSITION,\n'+ ' out float4 color : COLOR0)\n'+ '{\n'+ ' oPos = mul(pos,worldViewProjMatrix);\n'+ '\n'+ ' color=col; //float4(1,0,0,1);\n'+ '}\n'+ '\n'+ 'void fs(\n'+ ' float4 color: COLOR,\n'+ ' out float4 oCol: COLOR)\n'+ '{\n'+ ' oCol=color;\n'+ '}\n'+ '// #o3d VertexShaderEntryPoint vs\n'+ '// #o3d PixelShaderEntryPoint fs\n'+ '// #o3d MatrixLoadOrder RowMajor\n'; var camera = {}; camera.eye = {}; camera.target = {}; camera.eye.x = 0; camera.eye.y = -100; camera.eye.z = 100; camera.target.x = 0; camera.target.y = 0; camera.target.z = 0; var on = false; var cube; var none; var view; var viewInfo; var g_material; var angleY=0; var angleX=0; var o3d; var math; var client; var pack; var g_finished = false; // for selenium var game = {}; function updateView() { var matrix = math.matrix4.identity(); math.matrix4.rotateZYX(matrix, [angleX, angleY, 0]); math.matrix4.scale(matrix, math.mulScalarVector(.25, [1, 1, 1])); view.localMatrix = matrix; } var key = {}; key.LEFT = 37; key.UP = 38; key.RIGHT = 39; key.DOWN = 40; key.A = 65 key.S = 83 key.D = 68 key.W = 87 function keyPressed(e) { /*if (e.keyCode == key.A) rotateY(-0.1); else if (e.keyCode == key.D) rotateY(0.1) else if (e.keyCode == key.W) rotateX(-0.1) else if (e.keyCode == key.S) rotateX(0.1)*/ } function move_instance(node, x, y, z, h) { node.identity(); node.translate(x, y, z); } var entityID = 0; var transformNodes = new Array(); var meshNodes = new Array(); function createBox(x, y, z, w, d, h, color, parentNode, fadeToColor) { var boxVerts = [ 0, 0, 0, // 0 w, 0, 0, // 1 w, 0, h, // 2 0, 0, h, // 3 0, d, 0, // 4 w, d, 0, // 5 w, d, h, // 6 0, d, h, // 7 0, 0, 0, // 0b w, 0, 0, // 1b w, 0, h, // 2b 0, 0, h, // 3b 0, d, 0, // 4b w, d, 0, // 5b w, d, h, // 6b 0, d, h // 7b ]; var boxIndices = [ 0, 1, 3, 1, 2, 3, // front 0+8, 3+8, 1+8, 1+8, 3+8, 2+8, // frontb 5+8, 4+8, 6+8, 4+8, 7+8, 6+8, // back 5+8, 6+8, 4+8, 4+8, 6+8, 7+8, // backb 4, 0, 7, 0, 3, 7, // left 4+8, 7+8, 0+8, 0+8, 7+8, 3+8, // leftb 1+8, 5+8, 2+8, 5+8, 6+8, 2+8, // right 1, 2+8, 5+8, 5+8, 2+8, 6+8, // rightb 4, 5, 0, 5, 1, 0, // top 4+8, 0+8, 5+8, 5+8, 0+8, 1+8, // top2 6+8, 7+8, 2+8, 7+8, 3+8, 2+8, // bottom 6+8, 2+8, 7+8, 7+8, 2+8, 3+8 // bottom2 ]; var boxIndicesOneSided = [ 0, 1, 3, 1, 2, 3, // front 5+8, 4+8, 6+8, 4+8, 7+8, 6+8, // back 4, 0, 7, 0, 3, 7, // left 1+8, 5+8, 2+8, 5+8, 6+8, 2+8, // right 4, 5, 0, 5, 1, 0, // top 6+8, 7+8, 2+8, 7+8, 3+8, 2+8 // bottom ]; if (color != undefined) { var r = color.r; var g = color.g; var b = color.b; var a = color.a; if (fadeToColor == color) { var boxColors = [ r, g, b, a, // 0 r, g, b, a, // 1 r, g, b, a, // 2 r, g, b, a, // 3 r, g, b, a, // 4 r, g, b, a, // 5 r, g, b, a, // 6 r, g, b, a, // 7 r, g, b, a, // 0b r, g, b, a, // 1b r, g, b, a, // 2b r, g, b, a, // 3b r, g, b, a, // 4b r, g, b, a, // 5b r, g, b, a, // 6b r, g, b, a // 7b ]; } else if (fadeToColor != undefined) { r2 = fadeToColor.r; g2 = fadeToColor.g; b2 = fadeToColor.b; var boxColors = [ r2, g2, b2, a, // 0 r2, g2, b2, a, // 1 r, g, b, a, // r, g, b, a, // 3 r2, g2, b2, a, // 4 r2, g2, b2, a, // 5 r, g, b, a, // 6 r, g, b, a, // 7 r2, g2, b2, a, // 0b r2, g2, b2, a, // 1b r, g, b, a, // 2b r, g, b, a, // 3b r2, g2, b2, a, // 4b r2, g2, b2, a, // 5b r, g, b, a, // 6b r, g, b, a // 7b ]; } else { var boxColors = [ r, g, b, a, // 0 r, g, b, a, // 1 r*.7, g*.7, b*.7, a, // 2 r*.7, g*.7, b*.7, a, // 3 r, g, b, a, // 4 r, g, b, a, // 5 r*.7, g*.7, b*.7, a, // 6 r*.7, g*.7, b*.7, a, // 7 r*.8, g*.8, b*.8, a, // 0b r*.8, g*.8, b*.8, a, // 1b r*.8, g*.8, b*.8, a, // 2b r*.8, g*.8, b*.8, a, // 3b r*.4, g*.4, b*.4, a, // 4b r*.4, g*.4, b*.4, a, // 5b r*.4, g*.4, b*.4, a, // 6b r*.4, g*.4, b*.4, a // 7b ]; } } else { var boxColors = [ 1, 0, 0, 1, // 0 1, 0, 0, 1, // 1 1, 0, 0, 1, // 2 1, 0, 0, 1, // 3 0, 1, 0, 1, // 4 0, 1, 0, 1, // 5 0, 1, 0, 1, // 6 0, 1, 0, 1, // 7 .5, 0, 0, 1, // 0b .5, 0, 0, 1, // 1b .5, 0, 0, 1, // 2b .5, 0, 0, 1, // 3b 0, .5, 0, 1, // 4b 0, .5, 0, 1, // 5b 0, .5, 0, 1, // 6b 0, .5, 0, 1 // 7b ]; } entityID++; transformName = 'transform' + entityID; shapeName = 'shape' + entityID; meshName = 'mesh' + entityID; transformNodes[entityID] = pack.createObject('Transform'); transformNodes[entityID].translate(x, y, z); meshNodes[entityID] = pack.createObject('Shape'); transformNodes[entityID].addShape(meshNodes[entityID]) var primitive = pack.createObject('Primitive'); var streamBank = pack.createObject('StreamBank'); primitive.owner = meshNodes[entityID]; primitive.streamBank = streamBank; primitive.material = g_material; var vertBuffer = pack.createObject('VertexBuffer'); var positionField = vertBuffer.createField('FloatField', 3); vertBuffer.set(boxVerts); var colorBuffer = pack.createObject('VertexBuffer'); var colorField = colorBuffer.createField('FloatField', 4); colorBuffer.set(boxColors); var indexBuffer = pack.createObject('IndexBuffer'); indexBuffer.set(boxIndices); streamBank.setVertexStream(o3d.Stream.POSITION, 0, positionField, 0); streamBank.setVertexStream(o3d.Stream.COLOR, 0, colorField, 0); primitive.indexBuffer = indexBuffer; primitive.primitiveType = o3d.Primitive.TRIANGLELIST; primitive.numberPrimitives = 24; primitive.numberVertices = 16; if (parentNode != undefined) { transformNodes[entityID].parent = parentNode; } else { transformNodes[entityID].parent = view; } primitive.createDrawElement(pack, null); return transformNodes[entityID]; } var Color = function(r, g, b, a) { if (r>1 || g>1 || b>1) { r = r/255; g = g/255; b = b/255; } this.r = r; this.g = g; this.b = b; this.a = a; } function scrollMe(e) { if (e.deltaY < 0) { camera.eye.x *= 11/12; camera.eye.y *= 11/12; camera.eye.z *= 11/12; } else { camera.eye.x *= (1+1/12); camera.eye.y *= (1+1/12); camera.eye.z *= (1+1/12); } } /** * Creates the client area. */ function init() { o3djs.util.makeClients(initStep2); } /** * Initializes O3D. * @param {Array} clientElements Array of o3d object elements. */ function initStep2(clientElements) { var o3dElement = clientElements[0]; o3dElement.id = 'o3dObj'; o3d = o3dElement.o3d; math = o3djs.math; client = o3dElement.client; pack = client.createPack(); // Create the render graph for a view. viewInfo = o3djs.rendergraph.createBasicView( pack, client.root, client.renderGraphRoot); var effect = pack.createObject('Effect'); effect.loadFromFXString(shader); g_material = pack.createObject('Material'); g_material.drawList = viewInfo.performanceDrawList; g_material.effect = effect; effect.createUniformParameters(g_material); view = pack.createObject('Transform'); view.parent = client.root; var root = client.root; var o3d_width = client.width; var o3d_height = client.height; viewInfo.drawContext.projection=math.matrix4.perspective( math.degToRad(30), o3d_width / o3d_height, 1, 5000); target = [0, 0, 0]; eye = [0, -100, 0]; up = [0, 0, 1]; viewInfo.drawContext.view = math.matrix4.lookAt(eye, target, up); bg = pack.createObject('Transform'); bg.translate(0, 0, 1); bg.parent = client.root; red = new Color(1, 0, 0, 1); blue = new Color(0, 0, 1, 1); wallColor = new Color(0, .8, .4, 1); green = new Color(0, .5, 0, 1); lineColor = new Color(0, .7, 0, 1); shadow = new Color(0, .3, 0, .5); silver = new Color(.8, .8, .8, 1); pink = new Color(1, .8, .8, 1); window.field = createBox(-120, -80, -10, 240, 160, 10, green) window.centerline = createBox(-3, -80, 0, 6, 160, .5, lineColor) window.paddle1 = createBox(-110, 0, 5, 10, 30, 30, silver); window.shadow1 = createBox(-107, 3, 1, 10, 30, 0, shadow); window.paddle2 = createBox(-110, 0, 5, 10, 30, 30, silver); window.shadow2 = createBox(-107, 3, 1, 10, 30, 0, shadow); window.ball = createBox(0, 0, 2, 10, 10, 10, pink); window.ballShadow = createBox(0, 0, 1, 10, 10, 0, shadow); window.bottomWall = createBox(-120, -90, -10, 240, 10, 15, wallColor); window.topWall = createBox(-120, 80, -10, 240, 10, 15, wallColor); suRed = new Color(.7, 0, 0, 1) suGreen = new Color(0, .7, 0, 1) suBlue = new Color(0, 0, .7, 1) suGround = new Color(210, 208, 185, 1); suSky = new Color(212*.8, 225*.8, 225*.8, 1); window.xaxis = createBox(0, 0, 0, 5000, .25, .25, suRed, undefined); window.yaxis = createBox(0, 0, 0, .25, 5000, .25, suGreen, undefined); window.zaxis = createBox(0, 0, 0, .25, .25, 5000, suBlue, undefined); white = new Color(1, 1, 1, 1); mybox3 = createBox(-1500, -1500, -1500, 3000, 3000, 3000, suSky, bg, suGround); bg_Ground1 = createBox(-1500, 1490, -1500, 3000, 10, 1500, suGround, bg, suGround); bg_GroundR = createBox(1490, -1500, -1500, 10, 3000, 1500, suGround, bg, suGround); bg_GroundL = createBox(-1490, -1500, -1500, 10, 3000, 1500, suGround, bg, suGround); bg_Sky = createBox(-1500, 1490, 0, 3000, 10, 1500, suSky, bg, white); bg_SkyR = createBox(1490, -1500, 0, 10, 3000, 1500, suSky, bg, white); bg_SkyL = createBox(-1490, -1500, 0, 10, 3000, 1500, suSky, bg, white); on=true; updateView(); o3djs.event.addEventListener(o3dElement, 'wheel', scrollMe); updateLayout(); g_finished = true; // for selenium } function rotateX(delta) { angleX=angleX+delta; updateView(); } function rotateY(delta) { angleY=angleY+delta; updateView(); } function toggle() { if (on) { cube.parentNode = none; } else { cube.parentNode = view; } on = !on; } function startGame() { if (window.gameStarted == true) { return } window.gameStarted = true; document.getElementById('o3d').style.visibility = 'visible'; // Wait until the plug-in has initialized before starting the game. var clearId = window.setInterval(function() { if (client) { client.setRenderCallback(nextFrame); } else { return; } window.clearInterval(clearId); }, 10); } function updateLayout() { document.getElementById('focusHolder').focus(); document.body.scrollTop = 0; } function uninit() { if (client) { client.cleanup(); } } window.onload = init; window.onunload = uninit; </script> <body style="overflow:hidden" onscroll="updateLayout();"> <table border=0 width=100% height=100% style="overflow:hidden" > <tr><td id="clientBanner" align=center style="cursor:pointer;background-image:url(logo.gif);background-position:center center;background-repeat:no-repeat" onclick="startGame();"> <div id="client" name="client" > <div id="o3d" style="width: 800px; height: 600px; visibility: hidden;"></div> <br/><img src="instructions.gif"></div> <form> <input id="focusHolder" style="position:absolute;top:-100px;"> </form> </td></tr></table> </body> <script> keyIsDown = new Array(); document.onkeydown = function(e) { var keyChar = o3djs.event.getEventKeyChar(e); keyIsDown[keyChar] = true; } document.onkeyup = function(e) { var keyChar = o3djs.event.getEventKeyChar(e); keyIsDown[keyChar] = false; } var x = 1000+10; var y = 1000+20; var z = 1; var BACKSPACE=8 var TAB=9 var ENTER=13 var SHIFT=16 var CTRL=17 var ALT=18 var ESCAPE=27 var PAGEUP=33 var PAGEDOWN=34 var END=35 var HOME=36 var LEFT=37 var UP=38 var RIGHT=39 var DOWN=40 var DELETE=46 var SPACE=32 var spriteInfo = new Array(); var leftID = 0 var rightID = 1 var ballID = 2 var myPaddleID = leftID var enemyPaddleID = rightID var nextServeDirection = -1 var isServing = true; var loop = 0; spriteInfo[leftID] = new Array(); spriteInfo[rightID] = new Array(); spriteInfo[ballID] = new Array(); spriteInfo[leftID].velocityY = 0; spriteInfo[leftID].velocityX = 0; spriteInfo[leftID].x = 10; spriteInfo[leftID].y = 80; spriteInfo[rightID].velocityY = 0; spriteInfo[rightID].velocityX = 0; spriteInfo[rightID].x = 230; spriteInfo[rightID].y = 80; spriteInfo[ballID].velocityY = 0; spriteInfo[ballID].velocityX = 0; spriteInfo[ballID].x = 120; spriteInfo[ballID].y = 80; var SCREENHEIGHT = 160; var SCREENWIDTH = 240; var PADDLE var BALLWIDTH = 30 var BALLHEIGHT = 32 var BALLPAD = 20 var PADDLEHEIGHT = 30 var PADDLEWIDTH = 10 var PADDLEACCELY = 10 // acceleration rate of the paddle var PADDLEACCELX = 10 // acceleration rate of the paddle var SCREENWIDTH = 240 var SCREENHEIGHT = 160 var SCREENCENTERX = 120 var SCREENCENTERY = 80 var COMPUTERACCURACYX=90 // accuracy in pixels that the computer tries to get its paddle within var COMPUTERACCURACYY=10 var points = [0, 0, 0]; function ScorePoint(playerNumber) { if (playerNumber == myPaddleID) { //alert('You Score!'); } else { //alert('You Suck!'); } spriteInfo[ballID].velocityX = 0; spriteInfo[ballID].velocityY = 0; spriteInfo[ballID].x = SCREENWIDTH/2; spriteInfo[ballID].y = SCREENHEIGHT/2; points[playerNumber]++; pts = points[playerNumber]; ptBox = createBox(-140 + playerNumber*280, -80+pts*15, 0, 10, 10, 3, red); } function nextFrame(render_event) { var elapsedTime = render_event.elapsedTime; spriteInfo[ballID].x += spriteInfo[ballID].velocityX * elapsedTime; spriteInfo[ballID].y += spriteInfo[ballID].velocityY * elapsedTime; spriteInfo[leftID].x += spriteInfo[leftID].velocityX * elapsedTime; spriteInfo[leftID].y += spriteInfo[leftID].velocityY * elapsedTime; spriteInfo[rightID].x += spriteInfo[rightID].velocityX * elapsedTime; spriteInfo[rightID].y += spriteInfo[rightID].velocityY * elapsedTime; // move my paddle if (keyIsDown[UP]) { spriteInfo[myPaddleID].velocityY -= PADDLEACCELY; } else if (keyIsDown[DOWN]) { spriteInfo[myPaddleID].velocityY += PADDLEACCELY; } else { spriteInfo[myPaddleID].velocityY -= spriteInfo[myPaddleID].velocityY * elapsedTime; } if (keyIsDown[LEFT]) { spriteInfo[myPaddleID].velocityX -= PADDLEACCELX; } else if (keyIsDown[RIGHT]) { spriteInfo[myPaddleID].velocityX += PADDLEACCELX; } else { spriteInfo[myPaddleID].velocityX -= spriteInfo[myPaddleID].velocityX * elapsedTime; } if (keyIsDown[key.A]) camera.eye.x -= 100 * elapsedTime; if (keyIsDown[key.D]) camera.eye.x += 100 * elapsedTime; if (keyIsDown[key.W]) camera.eye.z += 100 * elapsedTime; if (keyIsDown[key.S]) camera.eye.z -= 100 * elapsedTime; target = [0, 0, 0]; eye = [camera.eye.x, camera.eye.y, camera.eye.z]; up = [0, 0, 1]; viewInfo.drawContext.view = math.matrix4.lookAt(eye, target, up); // make sure my paddle can't go off the top & bottom of screen if (spriteInfo[myPaddleID].y < PADDLEHEIGHT/2) { spriteInfo[myPaddleID].y = PADDLEHEIGHT/2; spriteInfo[myPaddleID].velocityY = 0; } else if (spriteInfo[myPaddleID].y > SCREENHEIGHT-PADDLEHEIGHT/2) { spriteInfo[myPaddleID].y = SCREENHEIGHT-PADDLEHEIGHT/2; spriteInfo[myPaddleID].velocityY = 0; } if (spriteInfo[myPaddleID].x < PADDLEWIDTH) { spriteInfo[myPaddleID].x = PADDLEWIDTH; spriteInfo[myPaddleID].velocityX = 0; } else if (spriteInfo[myPaddleID].x > SCREENWIDTH/2-BALLPAD) { spriteInfo[myPaddleID].x = SCREENWIDTH/2-BALLPAD; spriteInfo[myPaddleID].velocityX = 0; } // handle bouncing MoveComputer(); if ( spriteInfo[ballID].x + BALLWIDTH/2 > spriteInfo[rightID].x && spriteInfo[ballID].x + BALLWIDTH/2 < spriteInfo[rightID].x + PADDLEWIDTH && spriteInfo[ballID].y > spriteInfo[rightID].y-PADDLEHEIGHT/2 && spriteInfo[ballID].y < spriteInfo[rightID].y+PADDLEHEIGHT/2 && spriteInfo[ballID].velocityX > 0) { spriteInfo[ballID].velocityX *= -1; spriteInfo[ballID].velocityY += spriteInfo[rightID].velocityY/2 if (spriteInfo[rightID].velocityX < 0) { spriteInfo[ballID].velocityX += spriteInfo[rightID].velocityX; } } else if (spriteInfo[ballID].x - BALLWIDTH/2 < spriteInfo[leftID].x && spriteInfo[ballID].x - BALLWIDTH/2 > spriteInfo[leftID].x - PADDLEWIDTH && spriteInfo[ballID].y > spriteInfo[leftID].y-PADDLEHEIGHT/2 && spriteInfo[ballID].y < spriteInfo[leftID].y+PADDLEHEIGHT/2 && spriteInfo[ballID].velocityX < 0) { spriteInfo[ballID].velocityX *= -1; spriteInfo[ballID].velocityY += spriteInfo[leftID].velocityY/2; if (spriteInfo[leftID].velocityX > 0) { spriteInfo[ballID].velocityX += spriteInfo[leftID].velocityX; } } if (isServing) { loop++; if (loop > 20) { loop=0; spriteInfo[ballID].isVisible = true; spriteInfo[ballID].velocityY = ((Math.random()*4)-2)*20; spriteInfo[ballID].velocityX = (((Math.random()*1)+2) * nextServeDirection)*20; isServing = false; } } // bounce along top or bottom if ((spriteInfo[ballID].y > SCREENHEIGHT-10 || spriteInfo[ballID].y < 10) && isServing == false) { spriteInfo[ballID].velocityY *= -1; } if (spriteInfo[ballID].x < -50) { // right player scores a point! ScorePoint(rightID); nextServeDirection = -1; isServing = true; } if (spriteInfo[ballID].x > SCREENWIDTH+50) { // left player scores a point! ScorePoint(leftID); nextServeDirection = -1; isServing = true; } move_instance(paddle1, -120+spriteInfo[myPaddleID].x-PADDLEWIDTH/2, 80-spriteInfo[myPaddleID].y-PADDLEHEIGHT/2, 5, 30); move_instance(shadow1, -120+spriteInfo[myPaddleID].x+5-PADDLEWIDTH/2, 80-spriteInfo[myPaddleID].y-PADDLEHEIGHT/2+5, 1, 0); move_instance(paddle2, -120+spriteInfo[rightID].x-PADDLEWIDTH/2, 80-spriteInfo[rightID].y-PADDLEHEIGHT/2, 5, 30); move_instance(shadow2, -120+spriteInfo[rightID].x+5-PADDLEWIDTH/2, 80-spriteInfo[rightID].y-PADDLEHEIGHT/2+5, 1, 0); move_instance(ball, -120+spriteInfo[ballID].x-5, 80-(spriteInfo[ballID].y+5), 10, 10); move_instance(ballShadow, -120+spriteInfo[ballID].x-5+5, 80-(spriteInfo[ballID].y+0), 1, 0); } function MoveComputer() { // calculate where the AI wants to be if (spriteInfo[ballID].velocityX > 0) { // if the ball is coming our way, calculate where it will go targetX = spriteInfo[ballID].x; targetY = spriteInfo[ballID].y; } else { // else return to center targetX = 220; targetY = 80; } if (ComputerDistanceX() < COMPUTERACCURACYX) { spriteInfo[rightID].velocityX = spriteInfo[rightID].velocityX/2; } else { if (targetX < spriteInfo[rightID].x) { spriteInfo[rightID].velocityX -= PADDLEACCELX; } else if (targetX > spriteInfo[rightID].x) { spriteInfo[rightID].velocityX += PADDLEACCELX; } else { spriteInfo[rightID].velocityX = spriteInfo[rightID].velocityX/2; } } if (ComputerDistanceY() < COMPUTERACCURACYY) { spriteInfo[rightID].velocityY = spriteInfo[rightID].velocityY/2; } else { if (targetY < spriteInfo[rightID].y) { spriteInfo[rightID].velocityY -= PADDLEACCELY; } else if (targetY > spriteInfo[rightID].y) { spriteInfo[rightID].velocityY += PADDLEACCELY; } else { spriteInfo[rightID].velocityY = spriteInfo[rightID].velocityY/2; } } // make sure paddle can't go off the top & bottom of screen if (spriteInfo[rightID].y < PADDLEHEIGHT/2) { spriteInfo[rightID].y = PADDLEHEIGHT/2; spriteInfo[rightID].velocityY = 0; } else if (spriteInfo[rightID].y > SCREENHEIGHT-PADDLEHEIGHT/2) { spriteInfo[rightID].y = SCREENHEIGHT-PADDLEHEIGHT/2; spriteInfo[rightID].velocityY = 0; } if (spriteInfo[rightID].x > SCREENWIDTH) { spriteInfo[rightID].x = SCREENWIDTH-PADDLEWIDTH; spriteInfo[rightID].velocityX = 0; } else if (spriteInfo[rightID].x < SCREENWIDTH/2+BALLPAD) { spriteInfo[rightID].x = SCREENWIDTH/2+BALLPAD; spriteInfo[rightID].velocityX = 0; } } function ComputerDistanceX() { var distanceX; distanceX = spriteInfo[rightID].x - spriteInfo[ballID].x; if (distanceX < 0) { distanceX = distanceX * -1; } return distanceX; } function ComputerDistanceY() { var distanceY; distanceY = spriteInfo[ballID].y - spriteInfo[rightID].y; if (distanceY < 0) { distanceY = distanceY * -1; } return distanceY; } </script>