2015-02-11 18:55:27 -05:00
/**
* Module that registers spaaaaaaaaace!
*/
var Space = {
SHIP _SPEED : 3 ,
BASE _ASTEROID _DELAY : 500 ,
BASE _ASTEROID _SPEED : 1500 ,
FTB _SPEED : 60000 ,
STAR _WIDTH : 3000 ,
STAR _HEIGHT : 3000 ,
NUM _STARS : 200 ,
STAR _SPEED : 60000 ,
FRAME _DELAY : 100 ,
stars : null ,
backStars : null ,
ship : null ,
lastMove : null ,
done : false ,
shipX : null ,
shipY : null ,
hull : 0 ,
name : "Space" ,
init : function ( options ) {
this . options = $ . extend (
this . options ,
options
) ;
// Create the Space panel
this . panel = $ ( '<div>' ) . attr ( 'id' , "spacePanel" )
. addClass ( 'location' )
. appendTo ( '#outerSlider' ) ;
// Create the ship
Space . ship = $ ( '<div>' ) . text ( "@" ) . attr ( 'id' , 'ship' ) . appendTo ( this . panel ) ;
// Create the hull display
var h = $ ( '<div>' ) . attr ( 'id' , 'hullRemaining' ) . appendTo ( this . panel ) ;
$ ( '<div>' ) . addClass ( 'row_key' ) . text ( _ ( 'hull: ' ) ) . appendTo ( h ) ;
$ ( '<div>' ) . addClass ( 'row_val' ) . appendTo ( h ) ;
//subscribe to stateUpdates
$ . Dispatch ( 'stateUpdate' ) . subscribe ( Space . handleStateUpdates ) ;
} ,
options : { } , // Nothing for now
onArrival : function ( ) {
Space . done = false ;
Engine . keyLock = false ;
Space . hull = Ship . getMaxHull ( ) ;
Space . altitude = 0 ;
Space . setTitle ( ) ;
2020-05-28 19:10:09 -04:00
AudioEngine . playBackgroundMusic ( AudioLibrary . MUSIC _SPACE ) ;
2015-02-11 18:55:27 -05:00
Space . updateHull ( ) ;
Space . up =
Space . down =
Space . left =
Space . right = false ;
Space . ship . css ( {
top : '350px' ,
left : '350px'
} ) ;
Space . startAscent ( ) ;
Space . _shipTimer = setInterval ( Space . moveShip , 33 ) ;
2020-05-28 19:10:09 -04:00
Space . _volumeTimer = setInterval ( Space . lowerVolume , 1000 ) ;
AudioEngine . playBackgroundMusic ( AudioLibrary . MUSIC _SPACE ) ;
2015-02-11 18:55:27 -05:00
} ,
setTitle : function ( ) {
if ( Engine . activeModule == this ) {
var t ;
if ( Space . altitude < 10 ) {
t = _ ( "Troposphere" ) ;
} else if ( Space . altitude < 20 ) {
t = _ ( "Stratosphere" ) ;
} else if ( Space . altitude < 30 ) {
t = _ ( "Mesosphere" ) ;
} else if ( Space . altitude < 45 ) {
t = _ ( "Thermosphere" ) ;
} else if ( Space . altitude < 60 ) {
t = _ ( "Exosphere" ) ;
} else {
t = _ ( "Space" ) ;
}
document . title = t ;
}
} ,
getSpeed : function ( ) {
return Space . SHIP _SPEED + $SM . get ( 'game.spaceShip.thrusters' ) ;
} ,
updateHull : function ( ) {
$ ( 'div#hullRemaining div.row_val' , Space . panel ) . text ( Space . hull + '/' + Ship . getMaxHull ( ) ) ;
} ,
createAsteroid : function ( noNext ) {
var r = Math . random ( ) ;
var c ;
if ( r < 0.2 )
c = '#' ;
else if ( r < 0.4 )
c = '$' ;
else if ( r < 0.6 )
c = '%' ;
else if ( r < 0.8 )
c = '&' ;
else
c = 'H' ;
var x = Math . floor ( Math . random ( ) * 700 ) ;
var a = $ ( '<div>' ) . addClass ( 'asteroid' ) . text ( c ) . appendTo ( '#spacePanel' ) . css ( 'left' , x + 'px' ) ;
a . data ( {
xMin : x ,
xMax : x + a . width ( ) ,
height : a . height ( )
} ) ;
a . animate ( {
top : '740px'
} , {
duration : Space . BASE _ASTEROID _SPEED - Math . floor ( Math . random ( ) * ( Space . BASE _ASTEROID _SPEED * 0.65 ) ) ,
easing : 'linear' ,
progress : function ( ) {
// Collision detection
var t = $ ( this ) ;
if ( t . data ( 'xMin' ) <= Space . shipX && t . data ( 'xMax' ) >= Space . shipX ) {
var aY = t . css ( 'top' ) ;
aY = parseFloat ( aY . substring ( 0 , aY . length - 2 ) ) ;
if ( aY <= Space . shipY && aY + t . data ( 'height' ) >= Space . shipY ) {
// Collision
Engine . log ( 'collision' ) ;
t . remove ( ) ;
Space . hull -- ;
Space . updateHull ( ) ;
2020-05-28 19:10:09 -04:00
// play audio on asteroid hit
// higher altitudes play higher frequency hits
var r = Math . floor ( Math . random ( ) * 2 ) ;
if ( Space . altitude > 40 ) {
r += 6 ;
AudioEngine . playSound ( AudioLibrary [ 'ASTEROID_HIT_' + r ] ) ;
} else if ( Space . altitude > 20 ) {
r += 4 ;
AudioEngine . playSound ( AudioLibrary [ 'ASTEROID_HIT_' + r ] ) ;
} else {
r += 1 ;
AudioEngine . playSound ( AudioLibrary [ 'ASTEROID_HIT_' + r ] ) ;
}
2015-02-11 18:55:27 -05:00
if ( Space . hull === 0 ) {
Space . crash ( ) ;
}
}
}
} ,
complete : function ( ) {
$ ( this ) . remove ( ) ;
}
} ) ;
if ( ! noNext ) {
// Harder
if ( Space . altitude > 10 ) {
Space . createAsteroid ( true ) ;
}
// HARDER
if ( Space . altitude > 20 ) {
Space . createAsteroid ( true ) ;
Space . createAsteroid ( true ) ;
}
// HAAAAAARDERRRRR!!!!1
if ( Space . altitude > 40 ) {
Space . createAsteroid ( true ) ;
Space . createAsteroid ( true ) ;
}
if ( ! Space . done ) {
2017-06-16 15:22:42 -05:00
Engine . setTimeout ( Space . createAsteroid , 1000 - ( Space . altitude * 10 ) , true ) ;
2015-02-11 18:55:27 -05:00
}
}
} ,
moveShip : function ( ) {
var x = Space . ship . css ( 'left' ) ;
x = parseFloat ( x . substring ( 0 , x . length - 2 ) ) ;
var y = Space . ship . css ( 'top' ) ;
y = parseFloat ( y . substring ( 0 , y . length - 2 ) ) ;
var dx = 0 , dy = 0 ;
if ( Space . up ) {
dy -= Space . getSpeed ( ) ;
} else if ( Space . down ) {
dy += Space . getSpeed ( ) ;
}
if ( Space . left ) {
dx -= Space . getSpeed ( ) ;
} else if ( Space . right ) {
dx += Space . getSpeed ( ) ;
}
if ( dx !== 0 && dy !== 0 ) {
dx = dx / Math . sqrt ( 2 ) ;
dy = dy / Math . sqrt ( 2 ) ;
}
if ( Space . lastMove != null ) {
var dt = Date . now ( ) - Space . lastMove ;
dx *= dt / 33 ;
dy *= dt / 33 ;
}
x = x + dx ;
y = y + dy ;
if ( x < 10 ) {
x = 10 ;
} else if ( x > 690 ) {
x = 690 ;
}
if ( y < 10 ) {
y = 10 ;
} else if ( y > 690 ) {
y = 690 ;
}
Space . shipX = x ;
Space . shipY = y ;
Space . ship . css ( {
left : x + 'px' ,
top : y + 'px'
} ) ;
2020-05-28 19:10:09 -04:00
2015-02-11 18:55:27 -05:00
Space . lastMove = Date . now ( ) ;
} ,
startAscent : function ( ) {
var body _color ;
var to _color ;
if ( Engine . isLightsOff ( ) ) {
body _color = '#272823' ;
to _color = '#EEEEEE' ;
}
else {
body _color = '#FFFFFF' ;
to _color = '#000000' ;
}
$ ( 'body' ) . addClass ( 'noMask' ) . css ( { backgroundColor : body _color } ) . animate ( {
backgroundColor : to _color
} , {
duration : Space . FTB _SPEED ,
easing : 'linear' ,
progress : function ( ) {
var cur = $ ( 'body' ) . css ( 'background-color' ) ;
var s = 'linear-gradient(rgba' + cur . substring ( 3 , cur . length - 1 ) + ', 0) 0%, rgba' +
cur . substring ( 3 , cur . length - 1 ) + ', 1) 100%)' ;
$ ( '#notifyGradient' ) . attr ( 'style' , 'background-color:' + cur + ';background:-webkit-' + s + ';background:' + s ) ;
} ,
complete : Space . endGame
} ) ;
Space . drawStars ( ) ;
Space . _timer = setInterval ( function ( ) {
Space . altitude += 1 ;
if ( Space . altitude % 10 === 0 ) {
Space . setTitle ( ) ;
}
if ( Space . altitude > 60 ) {
clearInterval ( Space . _timer ) ;
}
} , 1000 ) ;
Space . _panelTimeout = Engine . setTimeout ( function ( ) {
if ( Engine . isLightsOff ( ) )
$ ( '#spacePanel, .menu, select.menuBtn' ) . animate ( { color : '#272823' } , 500 , 'linear' ) ;
else
$ ( '#spacePanel, .menu, select.menuBtn' ) . animate ( { color : 'white' } , 500 , 'linear' ) ;
2017-06-16 15:22:42 -05:00
} , Space . FTB _SPEED / 2 , true ) ;
2015-02-11 18:55:27 -05:00
Space . createAsteroid ( ) ;
} ,
drawStars : function ( duration ) {
var starsContainer = $ ( '<div>' ) . attr ( 'id' , 'starsContainer' ) . appendTo ( 'body' ) ;
Space . stars = $ ( '<div>' ) . css ( 'bottom' , '0px' ) . attr ( 'id' , 'stars' ) . appendTo ( starsContainer ) ;
var s1 = $ ( '<div>' ) . css ( {
width : Space . STAR _WIDTH + 'px' ,
height : Space . STAR _HEIGHT + 'px'
} ) ;
var s2 = s1 . clone ( ) ;
Space . stars . append ( s1 ) . append ( s2 ) ;
Space . drawStarAsync ( s1 , s2 , 0 ) ;
Space . stars . data ( 'speed' , Space . STAR _SPEED ) ;
Space . startAnimation ( Space . stars ) ;
Space . starsBack = $ ( '<div>' ) . css ( 'bottom' , '0px' ) . attr ( 'id' , 'starsBack' ) . appendTo ( starsContainer ) ;
s1 = $ ( '<div>' ) . css ( {
width : Space . STAR _WIDTH + 'px' ,
height : Space . STAR _HEIGHT + 'px'
} ) ;
s2 = s1 . clone ( ) ;
Space . starsBack . append ( s1 ) . append ( s2 ) ;
Space . drawStarAsync ( s1 , s2 , 0 ) ;
Space . starsBack . data ( 'speed' , Space . STAR _SPEED * 2 ) ;
Space . startAnimation ( Space . starsBack ) ;
} ,
startAnimation : function ( el ) {
el . animate ( { bottom : '-3000px' } , el . data ( 'speed' ) , 'linear' , function ( ) {
$ ( this ) . css ( 'bottom' , '0px' ) ;
Space . startAnimation ( $ ( this ) ) ;
} ) ;
} ,
drawStarAsync : function ( el , el2 , num ) {
var top = Math . floor ( Math . random ( ) * Space . STAR _HEIGHT ) + 'px' ;
var left = Math . floor ( Math . random ( ) * Space . STAR _WIDTH ) + 'px' ;
$ ( '<div>' ) . text ( '.' ) . addClass ( 'star' ) . css ( {
top : top ,
left : left
} ) . appendTo ( el ) ;
$ ( '<div>' ) . text ( '.' ) . addClass ( 'star' ) . css ( {
top : top ,
left : left
} ) . appendTo ( el2 ) ;
if ( num < Space . NUM _STARS ) {
Engine . setTimeout ( function ( ) { Space . drawStarAsync ( el , el2 , num + 1 ) ; } , 100 ) ;
}
} ,
crash : function ( ) {
if ( Space . done ) return ;
Engine . keyLock = true ;
Space . done = true ;
clearInterval ( Space . _timer ) ;
clearInterval ( Space . _shipTimer ) ;
2020-05-28 19:10:09 -04:00
clearInterval ( Space . _volumeTimer ) ;
2015-02-11 18:55:27 -05:00
clearTimeout ( Space . _panelTimeout ) ;
var body _color ;
if ( Engine . isLightsOff ( ) )
body _color = '#272823' ;
else
body _color = '#FFFFFF' ;
// Craaaaash!
$ ( 'body' ) . removeClass ( 'noMask' ) . stop ( ) . animate ( {
backgroundColor : body _color
} , {
duration : 300 ,
progress : function ( ) {
var cur = $ ( 'body' ) . css ( 'background-color' ) ;
var s = 'linear-gradient(rgba' + cur . substring ( 3 , cur . length - 1 ) + ', 0) 0%, rgba' +
cur . substring ( 3 , cur . length - 1 ) + ', 1) 100%)' ;
$ ( '#notifyGradient' ) . attr ( 'style' , 'background-color:' + cur + ';background:-webkit-' + s + ';background:' + s ) ;
} ,
complete : function ( ) {
Space . stars . remove ( ) ;
Space . starsBack . remove ( ) ;
Space . stars = Space . starsBack = null ;
$ ( '#starsContainer' ) . remove ( ) ;
$ ( 'body' ) . attr ( 'style' , '' ) ;
$ ( '#notifyGradient' ) . attr ( 'style' , '' ) ;
$ ( '#spacePanel' ) . attr ( 'style' , '' ) ;
}
} ) ;
$ ( '.menu, select.menuBtn' ) . animate ( { color : '#666' } , 300 , 'linear' ) ;
$ ( '#outerSlider' ) . animate ( { top : '0px' } , 300 , 'linear' ) ;
Engine . activeModule = Ship ;
Ship . onArrival ( ) ;
Button . cooldown ( $ ( '#liftoffButton' ) ) ;
Engine . event ( 'progress' , 'crash' ) ;
2020-05-28 19:10:09 -04:00
AudioEngine . playSound ( AudioLibrary . CRASH ) ;
2015-02-11 18:55:27 -05:00
} ,
endGame : function ( ) {
if ( Space . done ) return ;
Engine . event ( 'progress' , 'win' ) ;
Space . done = true ;
clearInterval ( Space . _timer ) ;
clearInterval ( Space . _shipTimer ) ;
2020-05-28 19:10:09 -04:00
clearInterval ( Space . _volumeTimer ) ;
2015-02-11 18:55:27 -05:00
clearTimeout ( Engine . _saveTimer ) ;
clearTimeout ( Outside . _popTimeout ) ;
clearTimeout ( Engine . _incomeTimeout ) ;
clearTimeout ( Events . _eventTimeout ) ;
clearTimeout ( Room . _fireTimer ) ;
clearTimeout ( Room . _tempTimer ) ;
2016-10-02 17:57:17 -03:00
for ( var j in Room . Craftables ) {
Room . Craftables [ j ] . button = null ;
2015-02-11 18:55:27 -05:00
}
for ( var k in Room . TradeGoods ) {
Room . TradeGoods [ k ] . button = null ;
}
delete Outside . _popTimeout ;
2020-05-28 19:10:09 -04:00
AudioEngine . playBackgroundMusic ( AudioLibrary . MUSIC _ENDING ) ;
2015-02-11 18:55:27 -05:00
$ ( '#hullRemaining' , Space . panel ) . animate ( { opacity : 0 } , 500 , 'linear' ) ;
Space . ship . animate ( {
top : '350px' ,
left : '240px'
} , 3000 , 'linear' , function ( ) {
Engine . setTimeout ( function ( ) {
Space . ship . animate ( {
top : '-100px'
} , 200 , 'linear' , function ( ) {
// Restart everything! Play FOREVER!
$ ( '#outerSlider' ) . css ( { 'left' : '0px' , 'top' : '0px' } ) ;
$ ( '#locationSlider, #worldPanel, #spacePanel, #notifications' ) . remove ( ) ;
$ ( '#header' ) . empty ( ) ;
Engine . setTimeout ( function ( ) {
$ ( 'body' ) . stop ( ) ;
var container _color ;
if ( Engine . isLightsOff ( ) )
container _color = '#EEE' ;
else
container _color = '#000' ;
$ ( '#starsContainer' ) . animate ( {
opacity : 0 ,
'background-color' : container _color
} , {
duration : 2000 ,
progress : function ( ) {
var cur = $ ( 'body' ) . css ( 'background-color' ) ;
var s = 'linear-gradient(rgba' + cur . substring ( 3 , cur . length - 1 ) + ', 0) 0%, rgba' +
cur . substring ( 3 , cur . length - 1 ) + ', 1) 100%)' ;
$ ( '#notifyGradient' ) . attr ( 'style' , 'background-color:' + cur + ';background:-webkit-' + s + ';background:' + s ) ;
} ,
complete : function ( ) {
Engine . GAME _OVER = true ;
Score . save ( ) ;
Prestige . save ( ) ;
$ ( '#starsContainer' ) . remove ( ) ;
$ ( '#content, #notifications' ) . remove ( ) ;
2023-06-09 12:38:16 -04:00
Space . showExpansionEnding ( ) . then ( ( ) => {
Space . showEndingOptions ( ) ;
Engine . options = { } ;
Engine . deleteSave ( true ) ;
} ) ;
2015-02-11 18:55:27 -05:00
}
} ) ;
} , 2000 ) ;
} ) ;
} , 2000 ) ;
} ) ;
} ,
2023-06-09 12:38:16 -04:00
showExpansionEnding : ( ) => {
return new Promise ( ( resolve ) => {
if ( ! $SM . get ( 'stores["fleet beacon"]' ) ) {
resolve ( ) ;
return ;
}
const c = $ ( '<div>' )
. addClass ( 'outroContainer' )
. appendTo ( 'body' ) ;
setTimeout ( ( ) => {
$ ( '<div>' )
. addClass ( 'outro' )
. html ( 'the beacon pulses gently as the ship glides through space.<br>coordinates are locked. nothing to do but wait.' )
. appendTo ( c )
. animate ( { opacity : 1 } , 500 ) ;
} , 2000 ) ;
setTimeout ( ( ) => {
$ ( '<div>' )
. addClass ( 'outro' )
. html ( 'the beacon glows a solid blue, and then goes dim. the ship slows.<br>gradually, the vast wanderer homefleet comes into view.<br>massive worldships drift unnaturally through clouds of debris, scarred and dead.' )
. appendTo ( c )
. animate ( { opacity : 1 } , 500 ) ;
} , 7000 ) ;
setTimeout ( ( ) => {
$ ( '<div>' )
. addClass ( 'outro' )
. text ( 'the air is running out.' )
. appendTo ( c )
. animate ( { opacity : 1 } , 500 ) ;
} , 14000 ) ;
setTimeout ( ( ) => {
$ ( '<div>' )
. addClass ( 'outro' )
. text ( 'the capsule is cold.' )
. appendTo ( c )
. animate ( { opacity : 1 } , 500 ) ;
} , 17000 ) ;
setTimeout ( ( ) => {
Button . Button ( {
id : 'wait-btn' ,
text : _ ( 'wait' ) ,
click : ( btn ) => {
btn . addClass ( 'disabled' ) ;
c . animate ( { opacity : 0 } , 5000 , 'linear' , ( ) => {
c . remove ( ) ;
setTimeout ( resolve , 3000 ) ;
} )
}
} ) . animate ( { opacity : 1 } , 500 ) . appendTo ( c ) ;
} , 19500 )
} ) ;
} ,
showEndingOptions : ( ) => {
$ ( '<center>' )
. addClass ( 'centerCont' )
. appendTo ( 'body' ) ;
$ ( '<span>' )
. addClass ( 'endGame' )
. text ( _ ( 'score for this game: {0}' , Score . calculateScore ( ) ) )
. appendTo ( '.centerCont' )
. animate ( { opacity : 1 } , 1500 ) ;
$ ( '<br />' )
. appendTo ( '.centerCont' ) ;
$ ( '<span>' )
. addClass ( 'endGame' )
. text ( _ ( 'total score: {0}' , Prestige . get ( ) . score ) )
. appendTo ( '.centerCont' )
. animate ( { opacity : 1 } , 1500 ) ;
$ ( '<br />' )
. appendTo ( '.centerCont' ) ;
$ ( '<br />' )
. appendTo ( '.centerCont' ) ;
$ ( '<span>' )
. addClass ( 'endGame endGameOption' )
. text ( _ ( 'restart.' ) )
. click ( Engine . confirmDelete )
. appendTo ( '.centerCont' )
. animate ( { opacity : 1 } , 1500 ) ;
$ ( '<br />' )
. appendTo ( '.centerCont' ) ;
$ ( '<br />' )
. appendTo ( '.centerCont' ) ;
$ ( '<span>' )
. addClass ( 'endGame' )
. text ( _ ( 'expanded story. alternate ending. behind the scenes commentary. get the app.' ) )
. appendTo ( '.centerCont' )
. animate ( { opacity : 1 } , 1500 ) ;
$ ( '<br />' )
. appendTo ( '.centerCont' ) ;
$ ( '<br />' )
. appendTo ( '.centerCont' ) ;
$ ( '<span>' )
. addClass ( 'endGame endGameOption' )
. text ( _ ( 'iOS.' ) )
. click ( function ( ) { window . open ( 'https://itunes.apple.com/app/apple-store/id736683061?pt=2073437&ct=gameover&mt=8' ) ; } )
. appendTo ( '.centerCont' )
. animate ( { opacity : 1 } , 1500 ) ;
$ ( '<br />' )
. appendTo ( '.centerCont' ) ;
$ ( '<span>' )
. addClass ( 'endGame endGameOption' )
. text ( _ ( 'android.' ) )
. click ( function ( ) { window . open ( 'https://play.google.com/store/apps/details?id=com.yourcompany.adarkroom' ) ; } )
. appendTo ( '.centerCont' )
. animate ( { opacity : 1 } , 1500 ) ;
} ,
2015-02-11 18:55:27 -05:00
keyDown : function ( event ) {
switch ( event . which ) {
case 38 : // Up
case 87 :
Space . up = true ;
Engine . log ( 'up on' ) ;
break ;
case 40 : // Down
case 83 :
Space . down = true ;
Engine . log ( 'down on' ) ;
break ;
case 37 : // Left
case 65 :
Space . left = true ;
Engine . log ( 'left on' ) ;
break ;
case 39 : // Right
case 68 :
Space . right = true ;
Engine . log ( 'right on' ) ;
break ;
}
} ,
keyUp : function ( event ) {
switch ( event . which ) {
case 38 : // Up
case 87 :
Space . up = false ;
Engine . log ( 'up off' ) ;
break ;
case 40 : // Down
case 83 :
Space . down = false ;
Engine . log ( 'down off' ) ;
break ;
case 37 : // Left
case 65 :
Space . left = false ;
Engine . log ( 'left off' ) ;
break ;
case 39 : // Right
case 68 :
Space . right = false ;
Engine . log ( 'right off' ) ;
break ;
}
} ,
handleStateUpdates : function ( e ) {
2020-05-28 19:10:09 -04:00
} ,
lowerVolume : function ( ) {
if ( Space . done ) return ;
// lower audio as ship gets further into space
var progress = Space . altitude / 60 ;
var newVolume = 1.0 - progress ;
AudioEngine . setBackgroundMusicVolume ( newVolume , 0.3 ) ;
2015-02-11 18:55:27 -05:00
}
} ;