/* * ScrollShooter * ------------------ * iio.js version 1.4 */ ScrollShooter = function( app, s ){ // Arrays for holding references to objects created var meteors = []; var stars = []; var lasers = []; // The player object var player; // Number of space objects var numSmallStars = 50; var numBigStars = 26; var numSmallMeteors = 20; var numBigMeteors = 10; // But cut back if it's only a preview version if( s && s.preview ){ numSmallMeteors /= 2; numBigStars /= 2; numSmallMeteors /= 2; numBigMeteors /= 2; } else app.set({ color:'black' }); // callback function for bringing and object up to top of screen // once its scrolled off the bottom function bringToTop(o){ o.pos.y = -100; o.pos.x = iio.random( 0, app.width ); } // Callback function for creating space objects, scrolling in a random down angle // On reaching the bottom, bring it back to the top with bringToTop function createScrollObjects(num, arr, props){ for ( var i=0; i<num; i++ ) arr.push( app.add( new iio.Quad({ z: props.z, img: props.img, health: props.health, rotation: iio.random( props.rotation.min, props.rotation.max ), pos: [ iio.random( 0, app.width ), iio.random( -100, app.height ) ], vel:[ iio.random( props.vel.x.min, props.vel.x.max ), iio.random( props.vel.y.min, props.vel.y.max ) ], rVel: iio.random( props.rVel.min, props.rVel.max ), bounds: { bottom: { bound: app.height + 100, callback: bringToTop } } }))); } // Create a loader with a base path at ".assets" var loader = new iio.Loader('assets'); // Define assets in a hash, with each asset associated with a asset ID. // in the form: // assetId: 'path/to/asset' var assets = { starSmall: 'images/starSmall.png', starBig: 'images/starBig.png', meteorBig: 'images/meteorBig.png', meteorSmall: 'images/meteorSmall.png', laserSound: 'sounds/laser.wav', explode: 'sounds/explode.wav', player: 'images/player.png', playerLeft: 'images/playerleft.png', playerRight: 'images/playerRight.png', laser: 'images/laserRed.png', laserFlash: 'images/laserRedShot.png', theme: 'sounds/theme.mp3', } // The main body of this app // This will be the callback function to the loader // which will be called once all assets are completely loaded (or failed) var main = function(assets) { // Play the theme if not preview if(assets.theme && !( s && s.preview )) assets.theme.play(0, {loop: true}); // Create a bunch of small stars createScrollObjects( numSmallStars, stars, { img: assets.starSmall, rotation: { min: 0, max: 0 }, rVel: { min: 0, max: 0 }, vel: { x: { min: 0, max: 0 }, y: { min: 1, max: 2 } } }); // Create a bunch of big stars createScrollObjects( numBigStars, stars, { z: 10, img: assets.starBig, rotation: { min: 0, max: 0 }, rVel: { min: 0, max: 0 }, vel: { x: { min: 0, max: 0 }, y: { min: 2, max: 3 } } }); // Shared by both big and small meteors var meteorProps = { z: 25, rotation: { min: -7, max: 7 }, rVel: { min: -.04, max: .04 }, vel: { x: { min: -3, max: 3 }, y: { min: 4, max: 6 } } } // Create a bunch of big meteors createScrollObjects( numBigMeteors, meteors, iio.merge({ img: assets.meteorBig, health: 5 }, meteorProps)); // Create a bunch of small meteors createScrollObjects( numSmallMeteors, meteors, iio.merge({ img: assets.meteorSmall, z: 25 }, meteorProps)); // Define references to the sounds for laser firing if(!( s && s.preview )) { if (assets.laserSound){ var laserSound = assets.laserSound; laserSound.set({gain: 0.125}); } if (assets.explode){ var explode = assets.explode; explode.set({gain: 0.25}); } } // Laser functions. Add a new object showing the laser firing var laser = assets.laser; var laserFlash = assets.laserFlash; fireLaser = function(x,y,s){ lasers.push(app.add(new iio.Quad({ pos: [ x, y ], z: 50, img: laser, vel: [ 0, -s ], bounds: { top: -100 } }))); // Play laser sound if not preview if(laserSound && !( s && s.preview )) laserSound.play(); } // Set up controller var controller = { LEFT: 0, RIGHT: 0, UP: 0, DOWN: 0, SPACE: 0 } updateController=function(k,bool){ if( k === 'left arrow' || k === 'a' ) controller.LEFT = bool; else if( k === 'right arrow' || k === 'd' ) controller.RIGHT = bool; else if( k === 'up arrow' || k === 'w' ) controller.UP = bool; else if( k === 'down arrow' || k === 's' ) controller.DOWN = bool; else if( k === 'space' || k === 'ctrl' ) controller.SPACE = bool; } // Create player object, and hook it up to the controller var player = assets.player; var playerLeft = assets.playerLeft; var playerRight = assets.playerRight; var playerObj = app.add(new iio.Quad({ pos: [ app.center.x, app.height-100 ], z:100, vel: [0,0], img: player, xSpeed:8, fSpeed:9, bSpeed:5, laserCooldown:20, laserTimer:20, laserSpeed:20, onUpdate:function(){ if( controller.RIGHT && this.right() < app.width ){ this.vel.x = this.xSpeed; this.img = playerRight; } else if( controller.LEFT && this.left() > 0 ){ this.vel.x = -this.xSpeed; this.img = playerLeft; } else { this.vel.x = 0; this.img = player; } if( controller.UP && this.top() > 0 ) this.vel.y = -this.fSpeed; else if( controller.DOWN && this.bottom() < app.height ) this.vel.y = this.bSpeed; else this.vel.y = 0; if( controller.SPACE && this.laserTimer === 20 ){ fireLaser( this.pos.x - this.width/3, this.pos.y + 10, this.laserSpeed ); fireLaser( this.pos.x + this.width/3, this.pos.y + 10, this.laserSpeed ); this.laserTimer--; } else if( this.laserTimer < 20 ){ if( !controller.SPACE ) this.laserTimer -= 2; else this.laserTimer--; if( this.laserTimer < 0 ) this.laserTimer = this.laserCooldown; } } })); // For updating direction on key presses app.onKeyDown = function(e,k){ updateController(k,true) } app.onKeyUp = function(e,k){ updateController(k,false) } app.onResize=function(){ if(playerObj.right > app.width) playerObj.pos.x = app.width - playerObj.width/2 } // Set up collisions on laser hit app.collision( lasers, meteors, function( laser, meteor ){ // Large meteors have health if( typeof( meteor.health ) !== 'undefined' ){ // Decrement meteor health on hit if not completely depleted if( meteor.health > 0 ) meteor.health--; else { // Break it for 5 small meteors for ( var i=0; i<5; i++ ) meteors.push( app.add( new iio.Quad({ pos: [ iio.random( meteor.pos.x-30, meteor.pos.x+30 ), iio.random( meteor.pos.y-30, meteor.pos.y+30 ) ], img: assets.meteorSmall, z: 25, vel: [ iio.random( -1, 2 ), iio.random( 4, 6 ) ], rVel: iio.random( -.2, .2 ), rot: iio.random( -7, 7 ), bounds: { bottom: { bound: app.height + 100, callback: bringToTop } } }))); app.rmv(meteor); } } else { // Otherwise is small meteor, so just remove it app.rmv(meteor) } // Add in flashes on contact with a meteor app.add(new iio.Quad({ z: 75, pos: [ laser.pos.x, laser.pos.y-20 ], img: assets.laserFlash, vel: meteor.vel, shrink: .2 })); // Play the explosion sound if not preview if(explode && !( s && s.preview )) explode.play(); app.rmv(laser); }); } // Load the assets, and run the main body of ScrollShooter loader.load(assets, main); }; // start the app full screen iio.start( ScrollShooter );