// Example of porting physics World unchanged to AB using plain physics API// World from "3D Game Programming for Kids", Second Edition// "Purple Fruit Monster" from Chapter 14// https://pragprog.com/titles/csjava2/source_code// basically unchanged
AB.headerLHS();// === scoreboard.js ================================================================================================// https://www.code3dgames.com/scoreboard.js// unchanged // "Purple Fruit Monster" includes it with <script> // We can include it like this:// start of include scoreboard.js
$.getScript ("https://www.code3dgames.com/scoreboard.js",function(){// === purple_fruit_monster/code.html ================================================================================================// from:// https://pragprog.com/titles/csjava2/source_code// unchanged (only because we matched paths of our images with image paths in this code) /*
<!--
! Excerpted from "3D Game Programming for Kids, Second Edition",
! published by The Pragmatic Bookshelf.
! Copyrights apply to this code. It may not be used to create training material,
! courses, books, articles, and the like. Contact us if you are in doubt.
! We make no guarantees that this code is fit for any purpose.
! Visit http://www.pragmaticprogrammer.com/titles/csjava2 for more book information.
-->
*/// The "scene" is where stuff in our game will happen:var scene =newPhysijs.Scene();
scene.setGravity(new THREE.Vector3(0,-250,0));var flat ={flatShading:true};var light =new THREE.AmbientLight('white',0.8);
scene.add(light);// The "camera" is what sees the stuff:var w = window.innerWidth /2;var h = window.innerHeight /2;var camera =new THREE.OrthographicCamera(-w, w, h,-h,1,10000);
camera.position.z =500;
scene.add(camera);// The "renderer" draws what the camera sees onto the screen:var renderer =new THREE.WebGLRenderer({antialias:true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor('skyblue');
document.body.appendChild(renderer.domElement);// ******** START CODING ON THE NEXT LINE ********var gameOver =false;var ground = addGround();var avatar = addAvatar();var scoreboard = addScoreboard();
reset();function addGround(){var shape =new THREE.BoxGeometry(2*w, h,10);var cover =new THREE.MeshBasicMaterial({color:'lawngreen'});var ground =newPhysijs.BoxMesh(shape, cover,0);
ground.position.y =-h/2;
scene.add(ground);return ground;}function addAvatar(){var shape =new THREE.CubeGeometry(100,100,1);var cover =new THREE.MeshBasicMaterial({visible:false});var avatar =newPhysijs.BoxMesh(shape, cover,1);
scene.add(avatar);var image =new THREE.TextureLoader().load("/images/monster.png");var material =new THREE.SpriteMaterial({map: image});var sprite =new THREE.Sprite(material);
sprite.scale.set(100,100,1);
avatar.add(sprite);
avatar.setLinearFactor(new THREE.Vector3(1,1,0));
avatar.setAngularFactor(new THREE.Vector3(0,0,0));return avatar;}function addScoreboard(){var scoreboard =newScoreboard();
scoreboard.score();
scoreboard.help("Use arrow keys to move and the space bar to jump. "+"Don't let the fruit get past you!!!");return scoreboard;}function reset(){
avatar.__dirtyPosition =true;
avatar.position.set(-0.6*w,200,0);
avatar.setLinearVelocity(new THREE.Vector3(0,250,0));
scoreboard.score(0);
scoreboard.message('');var last = scene.children.length -1;for(var i=last; i>=0; i--){var obj = scene.children[i];if(obj.isFruit) scene.remove(obj);}if(gameOver){
gameOver =false;
animate();}}function launchFruit(){if(gameOver)return;var speed =500+(10*Math.random()* scoreboard.getScore());var fruit = makeFruit();
fruit.setLinearVelocity(new THREE.Vector3(-speed,0,0));
fruit.setAngularVelocity(new THREE.Vector3(0,0,10));}
launchFruit();
setInterval(launchFruit,3*1000);function makeFruit(){var shape =new THREE.SphereGeometry(40,16,24);var cover =new THREE.MeshBasicMaterial({visible:false});var fruit =newPhysijs.SphereMesh(shape, cover);
fruit.position.set(w,40,0);
scene.add(fruit);var image =new THREE.TextureLoader().load("/images/fruit.png");
cover =new THREE.MeshBasicMaterial({map: image, transparent:true});
shape =new THREE.PlaneGeometry(80,80);var picturePlane =new THREE.Mesh(shape, cover);
fruit.add(picturePlane);
fruit.setAngularFactor(new THREE.Vector3(0,0,1));
fruit.setLinearFactor(new THREE.Vector3(1,1,0));
fruit.isFruit =true;return fruit;}function checkMissedFruit(){var count=0;for(var i=0; i<scene.children.length; i++){var obj = scene.children[i];if(obj.isFruit && obj.position.x <-w) count++;}if(count >10){
gameOver =true;
scoreboard.message('Purple Fruit Monster missed too much fruit! '+'Press R to try again.');}}function gameStep(){
scene.simulate();
setTimeout(gameStep,1000/30);}
gameStep();var clock =new THREE.Clock();function animate(){if(gameOver)return;
requestAnimationFrame(animate);var t = clock.getElapsedTime();// Animation code goes here...
renderer.render(scene, camera);}
animate();
document.addEventListener("keydown", sendKeyDown);function sendKeyDown(event){var code = event.code;if(code =='ArrowLeft') left();if(code =='ArrowRight') right();if(code =='ArrowUp') up();if(code =='ArrowDown') down();if(code =='Space') up();if(code =='KeyR') reset();}function left(){ move(-100,0);}function right(){ move(100,0);}function up(){ move(0,250);}function down(){ move(0,-50);}function move(x, y){if(x >0) avatar.scale.x =1;if(x <0) avatar.scale.x =-1;var dir =new THREE.Vector3(x, y,0);
avatar.applyCentralImpulse(dir);}
avatar.addEventListener('collision', sendCollision);function sendCollision(object){if(gameOver)return;if(object.isFruit){
scoreboard.addPoints(10);
avatar.setLinearVelocity(new THREE.Vector3(0,250,0));
scene.remove(object);}if(object == ground){
gameOver =true;
scoreboard.message("Purple Fruit Monster crashed! "+"Press R to try again.");}}// end of include scoreboard.js});