summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
authorluchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-17 22:53:23 +0000
committerluchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-17 22:53:23 +0000
commitcf54865e9baedb5e2590a33f7f316e7c8d4e46d5 (patch)
treeee9035d28ef73e8e7df86269cd3b49d7b9a112ac /o3d
parent37b30e20d1503c14929699049f78ae35c2164ac5 (diff)
downloadchromium_src-cf54865e9baedb5e2590a33f7f316e7c8d4e46d5.zip
chromium_src-cf54865e9baedb5e2590a33f7f316e7c8d4e46d5.tar.gz
chromium_src-cf54865e9baedb5e2590a33f7f316e7c8d4e46d5.tar.bz2
o3d-webgl: Adding WebGL version of the pingpong game.
Review URL: http://codereview.chromium.org/2857002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50156 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
-rw-r--r--o3d/samples/o3d-webgl-samples/pingpong/instructions.gifbin0 -> 3439 bytes
-rw-r--r--o3d/samples/o3d-webgl-samples/pingpong/logo.gifbin0 -> 6958 bytes
-rw-r--r--o3d/samples/o3d-webgl-samples/pingpong/pingpong.html846
3 files changed, 846 insertions, 0 deletions
diff --git a/o3d/samples/o3d-webgl-samples/pingpong/instructions.gif b/o3d/samples/o3d-webgl-samples/pingpong/instructions.gif
new file mode 100644
index 0000000..d142083
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/pingpong/instructions.gif
Binary files differ
diff --git a/o3d/samples/o3d-webgl-samples/pingpong/logo.gif b/o3d/samples/o3d-webgl-samples/pingpong/logo.gif
new file mode 100644
index 0000000..379d196
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/pingpong/logo.gif
Binary files differ
diff --git a/o3d/samples/o3d-webgl-samples/pingpong/pingpong.html b/o3d/samples/o3d-webgl-samples/pingpong/pingpong.html
new file mode 100644
index 0000000..443d824
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/pingpong/pingpong.html
@@ -0,0 +1,846 @@
+<!--
+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="../../o3d-webgl/base.js"></script>
+<script type="text/javascript" src="../../o3djs/base.js"></script>
+<script type="text/javascript" id="o3dscript">
+o3djs.base.o3d = o3d;
+o3djs.require('o3djs.webgl');
+o3djs.require('o3djs.math');
+o3djs.require('o3djs.rendergraph');
+o3djs.require('o3djs.event');
+
+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.webgl.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 shader = document.getElementById('shader').value;
+ 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>
+
+<textarea style="display: none;" id="shader" name="shader">
+uniform mat4 worldViewProjection;
+attribute vec4 position;
+attribute vec4 color;
+varying vec4 pcolor;
+void main() {
+ gl_Position = worldViewProjection * position;
+ pcolor = color;
+}
+// #o3d SplitMarker
+varying vec4 pcolor;
+void main() {
+ gl_FragColor = pcolor;
+}
+// #o3d MatrixLoadOrder RowMajor
+</textarea>
+
+</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>
+