Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 494 lines (410 sloc) 16.348 kB
0784201 @AdmTal initial upload
authored
1 <!--
2
3 By Adam Tal
4 AdmTal@gmail.com
5
6 -->
7
8 <!DOCTYPE html>
9 <html lang="en">
10 <head>
11 <meta charset="utf-8" />
12 <meta name="apple-mobile-web-app-capable" content="yes" />
13 <link href="icon.png" rel="apple-touch-icon" />
14 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
15 <meta name="viewport" content="width=device-width,user-scalable=no"> <title>3D Pong</title>
16
17 <script>
18 function blockMove() {
19 event.preventDefault() ;
20 }
21 </script>
22
23 <style>
24 html, body { position:relative; height: 100%; background-color:black;}
25
26 body {
27 background-color: white;
28 margin: 0px;
29 padding: 0px;
30 overflow: hidden;
31 }
32
33 .box1 {
34 -webkit-transition: all .4s ease-in-out;
35 }
36
37 .box1 .front { background: rgba(0,0,0,0); border:1px solid; border-color:black;}
38 .box1 .back { background: rgba(0,0,0,0.3); border:1px solid; border-color:black;}
39 .box1 .left { background: rgba(0,0,0,0.5); border:1px solid; border-color:black;}
40 .box1 .right { background: rgba(0,0,0,0.5); border:1px solid; border-color:black;}
41 .box1 .bottom { background: rgba(0,0,0,0.7); border:1px solid; border-color:black }
42 .box1 .top { background: rgba(0,0,0,0.7); border:1px solid; border-color:black;}
43
44 .marker .front { background: rgba(0,0,0,0); }
45 .marker .back { background: rgba(0,0,0,0); }
46 .marker .left { background: rgba(0,0,0,.2); }
47 .marker .right { background: rgba(0,0,0,.2); }
48 .marker .bottom { background: rgba(0,0,0,.2); }
49 .marker .top { background: rgba(0,0,0,.2); }
50
51 .paddle_marker .front { background: rgba(0,0,0,0); }
52 .paddle_marker .back { background: rgba(0,0,0,0); }
53 .paddle_marker .left { background: rgba(0,0,0,8); }
54 .paddle_marker .right { background: rgba(0,0,0,8); }
55 .paddle_marker .bottom { background: rgba(0,0,0,8); }
56 .paddle_marker .top { background: rgba(0,0,0,8); }
57
58 .ball .front{
59 -webkit-border-radius: 50px;
60 -moz-border-radius: 50px;
61 border-radius: 50px;
62 background: white;
63 border-color:black;
64 border:3px solid;
65 }
66
67 .paddle .front { background: rgba(255,255,255,.5); border:2px solid; border-color:black; }
68 .paddle .back { background: rgba(255,255,255,.5); border:2px solid; border-color:black; }
69 .paddle .left { background: rgba(255,255,255,.5); border:2px solid; border-color:black; }
70 .paddle .right { background: rgba(255,255,255,.5); border:2px solid; border-color:black; }
71 .paddle .bottom { background: rgba(255,255,255,.5); border:2px solid; border-color:black; }
72 .paddle .top { background: rgba(255,255,255,.5); border:2px solid; border-color:black; }
73
74 .npc_paddle .front { background: rgba(0,0,0,.5); border:3px solid; border-color:white; }
75 .npc_paddle .back { background: rgba(0,0,0,.5); border:3px solid; border-color:white; }
76 .npc_paddle .left { background: rgba(0,0,0,.5); border:3px solid; border-color:white; }
77 .npc_paddle .right { background: rgba(0,0,0,.5); border:3px solid; border-color:white; }
78 .npc_paddle .bottom { background: rgba(0,0,0,.5); border:3px solid; border-color:white; }
79 .npc_paddle .top { background: rgba(0,0,0,.5); border:3px solid; border-color:white; }
80
81 #score{
82 text-align:center;
83 font-size:55px;
84 font-weight:bold;
85 -webkit-text-stroke-width: 1.5px;
86 -webkit-text-stroke-color: black;
87 }
88 .begin{
89 position:absolute;
90 width:30%;
91 height:30%;
92 top:75%;
93 left:35%;
94 opacity:0.0;
95 -webkit-transition: .3s linear;
96 -moz-transition: .3s linear;
97 -o-transition: .3s linear;
98 transition: .3s linear;
99 }
100 .middle{
101 position:absolute;
102 width:30%;
103 height:30%;
104 top:25%;
105 left:35%;
106 opacity:1.0;
107 -webkit-transition: .7s linear;
108 -moz-transition: .7s linear;
109 -o-transition: .7s linear;
110 transition: .7s linear;
111 }
112 .end{
113 position:absolute;
114 width:30%;
115 height:30%;
116 top:0%;
117 left:35%;
118 opacity:0.0;
119 -webkit-transition: .3s linear;
120 -moz-transition: .3s linear;
121 -o-transition: .3s linear;
122 transition: .3s linear
123 }
124
125 </style>
126 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
127 <script>
128 var state = 1;
129 function show_score(){
130 if (state == 1){
131 $('#score').removeClass('end');
132 $('#score').toggleClass('begin');
133 document.getElementById('score').addEventListener('webkitTransitionEnd',show_score,true)
134 state = 2;
135 } else if (state == 2){
136 $('#score').removeClass('begin');
137 $('#score').toggleClass('middle');
138 state = 3;
139 } else if (state == 3) {
140 $('#score').removeClass('middle');
141 $('#score').toggleClass('end');
142 state = 1;
143 document.getElementById('score').removeEventListener('webkitTransitionEnd',show_score,true)
144 }
145 }
146 </script>
147
148 </head>
149
150 <body ontouchmove="blockMove()">
151
152 <script src="Sprite3D.js" type="text/javascript"></script>
153 <script>
154
155 document.body.style.cursor = 'none';
156
157 var buzz = new Audio("buzz.wav");
158 var bounce = new Audio("beep.wav");
159 var ding = new Audio("ding.wav");
160 buzz.volume = .1; // buzz is annoying!!!
161
162 var window_width = document.body.offsetWidth;
163 var window_height = document.body.offsetHeight;
164
165 var window_depth = window_width * 1.25;
166 var paddle_width = window_width * .15;
167 var paddle_height = window_height * .15;
168 var paddle_thickness = paddle_width * .7;
169 var ball_thickness = paddle_width * .25;
170
171 var half_paddle_width = paddle_width/2;
172 var half_paddle_height = paddle_height/2;
173
174 var paddle_x_speed = 0, paddle_y_speed = 0;
175 var npc_paddle_x_speed = 0, npc_paddle_y_speed = 0;
176
177 // create the main container
178 var stage = Sprite3D.stage();
179
180 var box = Sprite3D.box( window_width, window_height, window_depth, ".box1" );
181 var marker = Sprite3D.box( window_width, window_height, ball_thickness, ".marker" );
182 var npc_paddle = Sprite3D.box( paddle_width, paddle_height, paddle_thickness, ".npc_paddle" );
183 var paddle_marker = Sprite3D.box( window_width, window_height, paddle_thickness*.5, ".paddle_marker" );
184 var paddle = Sprite3D.box( paddle_width, paddle_height, paddle_thickness, ".paddle" );
185 var ball = Sprite3D.box( ball_thickness, ball_thickness, ball_thickness, ".ball" );
186
187 // max speed is the screen diagonal length divided by (some number... was origionally 10)
188 // The paddle speed is its diagonal displacement during the most recent event call
189
190 function pythag(a,b){
191 return Math.sqrt((a*a)+(b*b));
192 }
193
194 max_speed = pythag(window_width,window_depth)/1;
195
196 function reset_paddle(){
197 paddle.position(0,0,0);
198 paddle.update();
199 }
200
201 npc_paddle.position(0,0,(-window_depth + (paddle_thickness/2)));
202 npc_paddle.update();
203
204 box.z(-(window_depth/2));
205 box.update();
206
207 paddle_marker.update();
208
209 stage.appendChild(box);
210 stage.appendChild(marker);
211 stage.appendChild(paddle_marker);
212 stage.appendChild(npc_paddle);
213 stage.appendChild(ball);
214 stage.appendChild(paddle);
215
216 function move_paddle(e){
217 var x = e.pageX;
218 var y = e.pageY;
219
220 e.target.ontouchmove = function(evt){
221 var offx = evt.pageX - x;
222 var offy = evt.pageY - y;
223 paddle.move(offx,offy,0);
224 paddle.update();
225 x = evt.pageX;
226 y = evt.pageY;
227
228 paddle_x_speed = offx;
229 paddle_y_speed = offy;
230 };
231 }
232
233 // the /2 doesnt need to be done everytime, should be its own variable!
234 function paddle_ball_collide(){
235 var p_left = paddle.x() - half_paddle_width;
236 var p_right = paddle.x() + half_paddle_width;
237 var p_top = paddle.y() + half_paddle_height;
238 var p_bottom = paddle.y() - half_paddle_height;
239
240 var b_left = ball.x() - ball_width/2;
241 var b_right = ball.x() + ball_width/2;
242 var b_top = ball.y() + ball_height/2;
243 var b_bottom = ball.y() - ball_height/2;
244 var b_front = ball.z() + ball_thickness/2;
245
246 if ( b_front >= (-paddle_thickness))
247 if (((p_right >= b_left) && (p_left <= b_right)) && ((p_top >= b_bottom) && (p_bottom <= b_top)))
248 return true
249 return false;
250 }
251
252 function npc_paddle_ball_collide(){
253 var p_left = npc_paddle.x() - half_paddle_width;
254 var p_right = npc_paddle.x() + half_paddle_width;
255 var p_top = npc_paddle.y() + half_paddle_height;
256 var p_bottom = npc_paddle.y() - half_paddle_height;
257
258 var b_left = ball.x() - ball_width/2;
259 var b_right = ball.x() + ball_width/2;
260 var b_top = ball.y() + ball_height/2;
261 var b_bottom = ball.y() - ball_height/2;
262 var b_back = ball.z() - ball_thickness/2;
263
264 if (b_back < -(window_depth-paddle_thickness))
265 if (((p_right >= b_left) && (p_left <= b_right)) && ((p_top >= b_bottom) && (p_bottom <= b_top)))
266 return true
267 return false;
268 }
269
270 var x_prev = 0, y_prev = 0;
271
272 function move_paddle_mouse(e){
273 var x,y = 0;
274 if (e.pageX >= window_width/2)
275 x = e.pageX - (window_width/2);
276 else
277 x = -((window_width/2)- e.pageX);
278
279 if (e.pageY <= window_height/2)
280 y = -((window_height/2) - e.pageY);
281 else
282 y = (e.pageY - (window_height/2));
283
284 paddle.x(x);
285 paddle.y(y);
286
287 paddle_x_speed = x_prev = x-x_prev;
288 paddle_y_speed = y_prev = y-y_prev;
289
290 x_prev = x;
291 y_prev = y;
292
293 paddle.update();
294 }
295
296 function move_npc_paddle_mouse(e){
297 var x = 0,y = 0;
298 if (e.pageX >= window_width/2)
299 x = e.pageX - (window_width/2);
300 else
301 x = -((window_width/2)- e.pageX);
302
303 if (e.pageY <= window_height/2)
304 y = -((window_height/2) - e.pageY);
305 else
306 y = (e.pageY - (window_height/2));
307
308 npc_paddle.x(x);
309 npc_paddle.y(y);
310
311 npc_paddle_x_speed = x_prev = x-x_prev;
312 npc_paddle_y_speed = y_prev = y-y_prev;
313
314 x_prev = x;
315 y_prev = y;
316
317 npc_paddle.update();
318 }
319
320 function is_touch_device() {
321 return !!('ontouchstart' in window) // works on most browsers
322 || !!('onmsgesturechange' in window); // works on ie10
323 }
324
325 if(is_touch_device())
326 paddle.addEventListener("touchstart",move_paddle,true);
327 else
328 stage.addEventListener("mousemove", move_paddle_mouse, true);
329
330 // Ball velocities
331
332 var x_velocity;
333 var y_velocity;
334 var z_velocity;
335 var ball_width = 50;
336 var ball_height = 50;
337
338 function reset_ball(){
339 x_velocity = Math.random() * 10;
340 if (Math.random() > .5)
341 x_velocity = -x_velocity;
342 y_velocity = Math.random() * 10;
343 if (Math.random() > .5)
344 y_velocity = -y_velocity;
345 z_velocity = window_depth * .007;
346
347 ball.position(0,0,window_depth/-2);
348 marker.z(ball.z());
349 marker.update();
350 ball.update();
351 //buzz.play();
352 }
353
354 var player_score = 0;
355 var npc_score = 0;
356
357 function move_ball(){
358 if (ball.x() < -(window_width/2)){
359 x_velocity = -x_velocity;
360 bounce.play();
361 }
362 if (ball.x() >= (window_width/2)-(ball_width)){
363 x_velocity = -x_velocity;
364 bounce.play();
365 }
366
367 if (ball.y() < -(window_height/2)){
368 y_velocity = -y_velocity;
369 bounce.play();
370 }
371 if (ball.y() >= (window_height/2)-(ball_height)){
372 y_velocity = -y_velocity;
373 bounce.play();
374 }
375
376 if (ball.z() < -(window_depth)){
377 ding.play();
378 player_score++;
379 $("#score").css({'color':'yellow'});
380 $("#score").html("You : " + player_score + "<br />Computer : " + npc_score);
381 reset_ball(); // switch to computer serve
382 show_score();
383 }
384 if (ball.z() > 0){
385 reset_ball();
386 buzz.play();
387 npc_score++;
388 $("#score").css({'color':'red'});
389 $("#score").html("You : " + player_score + "<br />Computer : " + npc_score);
390 show_score();
391 }
392
393 ball.move(x_velocity,y_velocity,z_velocity)
394 marker.z(ball.z());
395
396 ball.update();
397 marker.update();
398
399 if (paddle_ball_collide()){
400 // move ball away from paddle here... needs to be done so ball doesnt bounce back again.
401 // paddle speed is /5 and then added to the xy axis
402
403 z_velocity = -(window_depth * z_speed(paddle_x_speed, paddle_y_speed));
404 x_velocity += (paddle_x_speed/10);
405 if (x_velocity > 20)
406 x_velocity = 20;
407 y_velocity += (paddle_y_speed/10);
408 if (y_velocity > 20)
409 y_velocity = 20;
410
411 bounce.play();
412 }
413
414 if (npc_paddle_ball_collide()){
415 // move ball away from npc_paddle here... needs to be done so ball doesnt bounce back again.
416 ball.z(-window_depth + paddle_thickness + (ball_thickness/2));
417 // npc_paddle speed is /5 and then added to the xy axis
418 z_velocity = (window_depth * z_speed(npc_paddle_x_speed, npc_paddle_y_speed));
419 x_velocity += (npc_paddle_x_speed/10);
420 if (x_velocity > 20)
421 x_velocity = 20;
422 y_velocity += (npc_paddle_y_speed/10);
423 if (y_velocity > 20)
424 y_velocity = 20;
425
426 bounce.play();
427 }
428 paddle_x_speed = paddle_y_speed = 0;
429 npc_paddle_x_speed = npc_paddle_y_speed = 0;
430 }
431
432 function z_speed(){
433 //min speed is .005 of window_depth
434 //max speed is .025 of window_depth
435
436 var paddle_speed = pythag(paddle_x_speed, paddle_y_speed);
437
438 var speed_percent = pythag(paddle_x_speed, paddle_y_speed)/max_speed;
439 if (speed_percent < .007)
440 return .007;
441 else if (speed_percent > .02)
442 return .02;
443 else
444 return speed_percent;
445 }
446
447 function npc_ai(){
448 basic_defense();
449 }
450
451 function basic_defense(){
452 if (ball.z() >= -(window_depth/2) || z_velocity > 0){
453 if (ball.x() > npc_paddle.x()){
454 npc_paddle.move(1,0,0);
455 }
456 if (ball.x() < npc_paddle.x()){
457 npc_paddle.move(-1,0,0);
458 }
459 if (ball.y() > npc_paddle.y()){
460 npc_paddle.move(0,1,0);
461 }
462 if (ball.y() < npc_paddle.y()){
463 npc_paddle.move(0,-1,0);
464 }
465 } else {
466 if (ball.x() > npc_paddle.x()){
467 npc_paddle.move(4,0,0);
468 }
469 if (ball.x() < npc_paddle.x()){
470 npc_paddle.move(-4,0,0);
471 }
472 if (ball.y() > npc_paddle.y()){
473 npc_paddle.move(0,4,0);
474 }
475 if (ball.y() < npc_paddle.y()){
476 npc_paddle.move(0,-4,0);
477 }
478 }
479 npc_paddle.update();
480 }
481
482 reset_paddle();
483 reset_ball();
484
485 setInterval(function () {move_ball()},17);
486 setInterval(function () {npc_ai()},1);
487
488 </script>
489
490 <div id="score" class="end">SCORE BITCH</div>
491
492 </body>
493 </html>
Something went wrong with that request. Please try again.