diff --git a/Games/OutRun_Offline_Game/assets/sounds/music/music-0.wav b/Games/OutRun_Offline_Game/assets/sounds/music/music-0.wav new file mode 100644 index 0000000000..905ab756c8 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sounds/music/music-0.wav differ diff --git a/Games/OutRun_Offline_Game/assets/sounds/music/music-1.wav b/Games/OutRun_Offline_Game/assets/sounds/music/music-1.wav new file mode 100644 index 0000000000..cc05e2aabe Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sounds/music/music-1.wav differ diff --git a/Games/OutRun_Offline_Game/assets/sounds/music/music-2.wav b/Games/OutRun_Offline_Game/assets/sounds/music/music-2.wav new file mode 100644 index 0000000000..93a779377c Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sounds/music/music-2.wav differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/background/alps/back.png b/Games/OutRun_Offline_Game/assets/sprites/background/alps/back.png new file mode 100644 index 0000000000..7bb02245f0 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/background/alps/back.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/background/alps/front.png b/Games/OutRun_Offline_Game/assets/sprites/background/alps/front.png new file mode 100644 index 0000000000..7f2582cef5 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/background/alps/front.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/background/wilderness/back.png b/Games/OutRun_Offline_Game/assets/sprites/background/wilderness/back.png new file mode 100644 index 0000000000..ee97c15332 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/background/wilderness/back.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/background/wilderness/front.png b/Games/OutRun_Offline_Game/assets/sprites/background/wilderness/front.png new file mode 100644 index 0000000000..b20d4ec219 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/background/wilderness/front.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/0.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/0.png new file mode 100644 index 0000000000..acbeca69b9 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/0.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/1.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/1.png new file mode 100644 index 0000000000..80c2413548 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/1.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/2.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/2.png new file mode 100644 index 0000000000..4a0e3adad5 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/2.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/3.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/3.png new file mode 100644 index 0000000000..9913bef47a Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/3.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/4.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/4.png new file mode 100644 index 0000000000..2da8d7d809 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/4.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/5.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/5.png new file mode 100644 index 0000000000..445370d1a7 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/5.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/6.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/6.png new file mode 100644 index 0000000000..844accdaf9 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/6.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/7.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/7.png new file mode 100644 index 0000000000..ede5dc45f0 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/7.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/8.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/8.png new file mode 100644 index 0000000000..65cf613440 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/8.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/digits/9.png b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/9.png new file mode 100644 index 0000000000..4cb152cb43 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/digits/9.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/kmh.png b/Games/OutRun_Offline_Game/assets/sprites/hud/kmh.png new file mode 100644 index 0000000000..7f320b8996 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/kmh.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/alps.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/alps.png new file mode 100644 index 0000000000..856e53cedd Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/alps.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/autobahn.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/autobahn.png new file mode 100644 index 0000000000..758ee467f9 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/autobahn.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/cloudy-mountain.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/cloudy-mountain.png new file mode 100644 index 0000000000..e561192919 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/cloudy-mountain.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/coconut-beach.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/coconut-beach.png new file mode 100644 index 0000000000..9e432b2ae3 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/coconut-beach.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/death-valley.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/death-valley.png new file mode 100644 index 0000000000..9eabcc3deb Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/death-valley.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/desert.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/desert.png new file mode 100644 index 0000000000..39f64ffbc6 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/desert.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/desolation-hill.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/desolation-hill.png new file mode 100644 index 0000000000..6574f14a83 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/desolation-hill.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/devils-canyon.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/devils-canyon.png new file mode 100644 index 0000000000..38eedb4da8 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/devils-canyon.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/gateaway.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/gateaway.png new file mode 100644 index 0000000000..c58b5eed53 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/gateaway.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/lakeside.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/lakeside.png new file mode 100644 index 0000000000..5764480695 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/lakeside.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/old-capital.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/old-capital.png new file mode 100644 index 0000000000..e80f8cc595 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/old-capital.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/seaside-town.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/seaside-town.png new file mode 100644 index 0000000000..0695c9c6de Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/seaside-town.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/vineyard.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/vineyard.png new file mode 100644 index 0000000000..392f57d79f Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/vineyard.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/wheat-field.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/wheat-field.png new file mode 100644 index 0000000000..80a2075f99 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/wheat-field.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/hud/map/wilderness.png b/Games/OutRun_Offline_Game/assets/sprites/hud/map/wilderness.png new file mode 100644 index 0000000000..b70e42c114 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/hud/map/wilderness.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/loading/loading-box.png b/Games/OutRun_Offline_Game/assets/sprites/loading/loading-box.png new file mode 100644 index 0000000000..ed79517a89 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/loading/loading-box.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/loading/loading-text.png b/Games/OutRun_Offline_Game/assets/sprites/loading/loading-text.png new file mode 100644 index 0000000000..f9b54e8eef Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/loading/loading-text.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/menu/logo-bg-5.png b/Games/OutRun_Offline_Game/assets/sprites/menu/logo-bg-5.png new file mode 100644 index 0000000000..55ac44dfd9 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/menu/logo-bg-5.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/menu/logo-car.png b/Games/OutRun_Offline_Game/assets/sprites/menu/logo-car.png new file mode 100644 index 0000000000..572b8af2cd Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/menu/logo-car.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/menu/logo-road.png b/Games/OutRun_Offline_Game/assets/sprites/menu/logo-road.png new file mode 100644 index 0000000000..ee208de922 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/menu/logo-road.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/radio/radio-car.png b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-car.png new file mode 100644 index 0000000000..780dadbcf7 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-car.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/radio/radio-dot-green.png b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-dot-green.png new file mode 100644 index 0000000000..29de76dfeb Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-dot-green.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/radio/radio-dot-red.png b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-dot-red.png new file mode 100644 index 0000000000..7236d58274 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-dot-red.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/radio/radio-freq-1.png b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-freq-1.png new file mode 100644 index 0000000000..dfe907253b Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/radio/radio-freq-1.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/radio/radio.png b/Games/OutRun_Offline_Game/assets/sprites/radio/radio.png new file mode 100644 index 0000000000..d94a6e71ea Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/radio/radio.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/text/music-0.png b/Games/OutRun_Offline_Game/assets/sprites/text/music-0.png new file mode 100644 index 0000000000..627e8159a8 Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/text/music-0.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/text/music-1.png b/Games/OutRun_Offline_Game/assets/sprites/text/music-1.png new file mode 100644 index 0000000000..7ecd846fda Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/text/music-1.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/text/music-2.png b/Games/OutRun_Offline_Game/assets/sprites/text/music-2.png new file mode 100644 index 0000000000..31ebaaff1f Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/text/music-2.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/text/press-enter.png b/Games/OutRun_Offline_Game/assets/sprites/text/press-enter.png new file mode 100644 index 0000000000..2a6fe34aac Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/text/press-enter.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/text/select-music.png b/Games/OutRun_Offline_Game/assets/sprites/text/select-music.png new file mode 100644 index 0000000000..e211e7f55b Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/text/select-music.png differ diff --git a/Games/OutRun_Offline_Game/assets/sprites/vehicles/vehicle-0/left-0.png b/Games/OutRun_Offline_Game/assets/sprites/vehicles/vehicle-0/left-0.png new file mode 100644 index 0000000000..4bab6609ff Binary files /dev/null and b/Games/OutRun_Offline_Game/assets/sprites/vehicles/vehicle-0/left-0.png differ diff --git a/Games/OutRun_Offline_Game/index.html b/Games/OutRun_Offline_Game/index.html new file mode 100644 index 0000000000..f9ba4f6848 --- /dev/null +++ b/Games/OutRun_Offline_Game/index.html @@ -0,0 +1,30 @@ + + + + Outrun + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Assets.js b/Games/OutRun_Offline_Game/main/Assets.js new file mode 100644 index 0000000000..e5753b6609 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Assets.js @@ -0,0 +1,585 @@ +let sprites = {}; +let sounds = {}; +let colors = {}; +let dimensions = {}; + +var loading = 0; +var maxLoading = 0; + +function loadAssets() { + //\\//\\ LOADING //\\//\\ + sprites['loading-text'] = loadSprite('loading/loading-text'); + sprites['loading-box'] = loadSprite('loading/loading-box'); + Outrun.drawLoading(); + //\\//\\ MENU ASSETS //\\//\\ + // LOADING MENU SPRITES + sprites['logo-bg-0'] = loadSprite('menu/logo-bg-0'); + sprites['logo-bg-1'] = loadSprite('menu/logo-bg-1'); + sprites['logo-bg-2'] = loadSprite('menu/logo-bg-2'); + sprites['logo-bg-3'] = loadSprite('menu/logo-bg-3'); + sprites['logo-bg-4'] = loadSprite('menu/logo-bg-4'); + sprites['logo-bg-5'] = loadSprite('menu/logo-bg-5'); + sprites['logo-road'] = loadSprite('menu/logo-road'); + sprites['logo-car'] = loadSprite('menu/logo-car'); + sprites['logo-tree-0'] = loadSprite('menu/logo-tree-0'); + sprites['logo-tree-1'] = loadSprite('menu/logo-tree-1'); + sprites['logo-tree-2'] = loadSprite('menu/logo-tree-2'); + sprites['logo-text'] = loadSprite('menu/logo-text'); + //\\//\\ RADIO ASSETS //\\//\\ + // LOADING RADIO SPRITES + sprites['radio-car'] = loadSprite('radio/radio-car'); + sprites['radio'] = loadSprite('radio/radio'); + sprites['radio-freq-0'] = loadSprite('radio/radio-freq-0'); + sprites['radio-freq-1'] = loadSprite('radio/radio-freq-1'); + sprites['radio-freq-2'] = loadSprite('radio/radio-freq-2'); + sprites['radio-dot-red'] = loadSprite('radio/radio-dot-red'); + sprites['radio-dot-green'] = loadSprite('radio/radio-dot-green'); + sprites['radio-hand-0'] = loadSprite('radio/radio-hand-0'); + sprites['radio-hand-1'] = loadSprite('radio/radio-hand-1'); + sprites['radio-hand-2'] = loadSprite('radio/radio-hand-2'); + // LOADING RADIO SAMPLES + sounds['wave'] = loadSound('sample/wave'); + sounds['coin'] = loadSound('sample/coin'); + sounds['signal-0'] = loadSound('sample/signal-0'); + sounds['signal-1'] = loadSound('sample/signal-1'); + Outrun.drawLoading(); + //\\//\\ IN-GAME ASSETS //\\//\\ + // LOADING IN-GAME SPRITES + var tunnel = loadSprite('environment/tunnel'); + sprites['coconut-beach'] = { + back: loadSprite('background/coconut-beach/back'), + front: loadSprite('background/coconut-beach/front'), + tunnel: tunnel, + terrain: loadSprite('environment/coconut-beach/terrain'), + left1: loadSprite('environment/coconut-beach/sail-1'), + left2: loadSprite('environment/coconut-beach/sail-2'), + right1: loadSprite('environment/coconut-beach/tree'), + right2: loadSprite('environment/coconut-beach/bush'), + start0: loadSprite('environment/start-flag-0'), + start1: loadSprite('environment/start-flag-1'), + start2: loadSprite('environment/start-flag-2'), + start3: loadSprite('environment/start-flag-3') + }; + dimensions['coconut-beach'] = { + tunnel: createDimension(4800, 2000, 0), + terrain: createDimension(9760, 320, -9500), + left1: createDimension(765, 1500, -8000), + left2: createDimension(765, 1500, -9000), + right1: createDimension(1170, 2520, 5000), + right2: createDimension(1280, 790, 5000), + start0: createDimension(4720, 1760, -2000), + start1: createDimension(4720, 1760, -2000), + start2: createDimension(4720, 1760, -2000), + start3: createDimension(4720, 1760, -2000), + }; + sprites['gateaway'] = { + back: loadSprite('background/gateaway/back'), + front: loadSprite('background/gateaway/front'), + tunnel: tunnel, + terrain: loadSprite('environment/gateaway/terrain'), + left1: loadSprite('environment/gateaway/arcade-sign'), + left2: loadSprite('environment/gateaway/motorcycle-sign'), + right1: loadSprite('environment/gateaway/castle'), + right2: loadSprite('environment/gateaway/castle') + }; + dimensions['gateaway'] = { + tunnel: createDimension(4800, 2000, 0), + terrain: createDimension(9760, 320, -9500), + left1: createDimension(1250, 1690, -6000), + left2: createDimension(1080, 1030, -6000), + right1: createDimension(1230, 1830, 5000), + right2: createDimension(1230, 1830, 5000) + }; + sprites['devils-canyon'] = { + back: loadSprite('background/devils-canyon/back'), + front: loadSprite('background/devils-canyon/front'), + tunnel: tunnel, + terrain: loadSprite('environment/devils-canyon/terrain'), + left1: loadSprite('environment/devils-canyon/sega-sign'), + left2: loadSprite('environment/devils-canyon/diving-sign'), + right1: loadSprite('environment/devils-canyon/rock'), + right2: loadSprite('environment/devils-canyon/rock') + }; + dimensions['devils-canyon'] = { + tunnel: createDimension(4800, 2000, 0), + terrain: createDimension(9760, 320, -9500), + left1: createDimension(1440, 920, -6000), + left2: createDimension(1160, 800, -6000), + right1: createDimension(1720, 1780, 5000), + right2: createDimension(1720, 1780, 5000) + }; + sprites['desert'] = { + back: loadSprite('background/desert/back'), + front: loadSprite('background/desert/front'), + tunnel: tunnel, + left1: loadSprite('environment/desert/dry-tree'), + left2: loadSprite('environment/desert/dry-tree'), + right1: loadSprite('environment/desert/terrain'), + right2: loadSprite('environment/desert/terrain') + }; + dimensions['desert'] = { + tunnel: createDimension(4800, 2000, 0), + left1: createDimension(440, 760, -5000), + left2: createDimension(440, 760, 5000), + right1: createDimension(9760, 320, -9500), + right2: createDimension(9760, 320, 9500) + }; + Outrun.drawLoading(); + sprites['alps'] = { + back: loadSprite('background/alps/back'), + front: loadSprite('background/alps/front'), + tunnel: tunnel, + left1: loadSprite('environment/alps/mill-1'), + left2: loadSprite('environment/alps/mill-2'), + right1: loadSprite('environment/alps/terrain-1'), + right2: loadSprite('environment/alps/terrain-2') + }; + dimensions['alps'] = { + tunnel: createDimension(4800, 2000, 0), + left1: createDimension(1080, 1400, 6000), + left2: createDimension(1080, 1400, -6000), + right1: createDimension(9760, 320, -9500), + right2: createDimension(9760, 320, 9500) + }; + sprites['cloudy-mountain'] = { + back: loadSprite('background/cloudy-mountain/back'), + front: loadSprite('background/cloudy-mountain/front'), + tunnel: tunnel, + terrain: loadSprite('environment/cloudy-mountain/clouds'), + right1: loadSprite('environment/cloudy-mountain/tree'), + right2: loadSprite('environment/cloudy-mountain/tree') + }; + dimensions['cloudy-mountain'] = { + tunnel: createDimension(4800, 2000, 0), + terrain: createDimension(19250, 3000, 0), + right1: createDimension(2480, 2480, -6000), + right2: createDimension(2480, 2480, 6000) + }; + sprites['wilderness'] = { + back: loadSprite('background/wilderness/back'), + front: loadSprite('background/wilderness/front'), + tunnel: tunnel, + left1: loadSprite('environment/wilderness/rock-1'), + left2: loadSprite('environment/wilderness/rock-2'), + right1: loadSprite('environment/wilderness/cut-tree'), + right2: loadSprite('environment/wilderness/dry-tree') + }; + dimensions['wilderness'] = { + tunnel: createDimension(4800, 2000, 0), + left1: createDimension(1160, 420, 6000), + left2: createDimension(1160, 550, -6000), + right1: createDimension(885, 660, 6000), + right2: createDimension(880, 1530, -5000) + }; + sprites['old-capital'] = { + back: loadSprite('background/old-capital/back'), + front: loadSprite('background/old-capital/front'), + tunnel: tunnel, + left1: loadSprite('environment/old-capital/tower'), + left2: loadSprite('environment/old-capital/hut'), + right1: loadSprite('environment/old-capital/tree-1'), + right2: loadSprite('environment/old-capital/tree-2') + }; + dimensions['old-capital'] = { + tunnel: createDimension(4800, 2000, 0), + left1: createDimension(720, 1640, -5000), + left2: createDimension(1200, 860, -6000), + right1: createDimension(945, 2400, 5500), + right2: createDimension(1740, 1980, 6000) + }; + sprites['wheat-field'] = { + back: loadSprite('background/wheat-field/back'), + front: loadSprite('background/wheat-field/front'), + tunnel: tunnel, + left1: loadSprite('environment/wheat-field/motorcycle-sign'), + left2: loadSprite('environment/wheat-field/tree'), + right1: loadSprite('environment/wheat-field/terrain'), + right2: loadSprite('environment/wheat-field/terrain'), + }; + dimensions['wheat-field'] = { + tunnel: createDimension(4800, 2000, 0), + left1: createDimension(1080, 1030, -6000), + left2: createDimension(1740, 1980, -6000), + right1: createDimension(9760, 320, 9500), + right2: createDimension(9760, 320, 9500) + }; + Outrun.drawLoading(); + sprites['seaside-town'] = { + back: loadSprite('background/seaside-town/back'), + front: loadSprite('background/seaside-town/front'), + tunnel: tunnel, + terrain: loadSprite('environment/seaside-town/terrain'), + right1: loadSprite('environment/seaside-town/tower'), + right2: loadSprite('environment/seaside-town/hut') + }; + dimensions['seaside-town'] = { + tunnel: createDimension(4800, 2000, 0), + terrain: createDimension(9760, 320, -9500), + right1: createDimension(720, 1640, 5000), + right2: createDimension(1200, 860, 5500) + }; + sprites['vineyard'] = { + back: loadSprite('background/vineyard/back'), + front: loadSprite('background/vineyard/front'), + tunnel: tunnel, + right1: loadSprite('environment/vineyard/terrain'), + right2: loadSprite('environment/vineyard/terrain'), + goal: loadSprite('environment/goal') + }; + dimensions['vineyard'] = { + tunnel: createDimension(4800, 2000, 0), + right1: createDimension(6600, 650, 7700), + right2: createDimension(6600, 650, -7700), + goal: createDimension(9010, 1760, 0) + }; + sprites['death-valley'] = { + back: loadSprite('background/death-valley/back'), + front: loadSprite('background/death-valley/front'), + tunnel: tunnel, + left1: loadSprite('environment/death-valley/danke-sign'), + left2: loadSprite('environment/death-valley/rock'), + right1: loadSprite('environment/death-valley/pebbles'), + right2: loadSprite('environment/death-valley/pebbles'), + goal: loadSprite('environment/goal') + }; + dimensions['death-valley'] = { + tunnel: createDimension(4800, 2000, 0), + left1: createDimension(1120, 730, -6000), + left2: createDimension(440, 970, -5000), + right1: createDimension(2420, 160, 7000), + right2: createDimension(2420, 160, -7000), + goal: createDimension(9010, 1760, 0) + }; + sprites['desolation-hill'] = { + back: loadSprite('background/desolation-hill/back'), + front: loadSprite('background/desolation-hill/front'), + tunnel: tunnel, + right1: loadSprite('environment/desolation-hill/rock-1'), + right2: loadSprite('environment/desolation-hill/rock-2'), + goal: loadSprite('environment/goal') + }; + dimensions['desolation-hill'] = { + tunnel: createDimension(4800, 2000, 0), + right1: createDimension(1160, 420, 6000), + right2: createDimension(1160, 420, -6000), + goal: createDimension(9010, 1760, 0) + }; + sprites['autobahn'] = { + back: loadSprite('background/autobahn/back'), + front: loadSprite('background/autobahn/front'), + tunnel: tunnel, + left1: loadSprite('environment/autobahn/bush-1'), + left2: loadSprite('environment/autobahn/bush-2'), + right1: loadSprite('environment/autobahn/tree'), + right2: loadSprite('environment/autobahn/tree'), + goal: loadSprite('environment/goal') + }; + dimensions['autobahn'] = { + tunnel: createDimension(4800, 2000, 0), + left1: createDimension(840, 560, -5000), + left2: createDimension(1260, 530, -5500), + right1: createDimension(2480, 2480, 6000), + right2: createDimension(2480, 2480, 6000), + goal: createDimension(9010, 1760, 0) + }; + sprites['lakeside'] = { + back: loadSprite('background/lakeside/back'), + front: loadSprite('background/lakeside/front'), + tunnel: tunnel, + right1: loadSprite('environment/lakeside/tree'), + right2: loadSprite('environment/lakeside/tree'), + goal: loadSprite('environment/goal') + }; + dimensions['lakeside'] = { + tunnel: createDimension(4800, 2000, 0), + right1: createDimension(1800, 1890, 6000), + right2: createDimension(1800, 1890, -6000), + goal: createDimension(9010, 1760, 0) + }; + Outrun.drawLoading(); + // LOADING FERRARI SPRITES + for (var i = 0; i < 2; i++) { + sprites['down-hardleft-' + i] = loadSprite('ferrari/down-hardleft-' + i); + sprites['down-hardright-' + i] = loadSprite('ferrari/down-hardright-' + i); + sprites['down-left-' + i] = loadSprite('ferrari/down-left-' + i); + sprites['down-right-' + i] = loadSprite('ferrari/down-right-' + i); + sprites['down-straight-' + i] = loadSprite('ferrari/down-straight-' + i); + + sprites['hardleft-' + i] = loadSprite('ferrari/hardleft-' + i); + sprites['hardright-' + i] = loadSprite('ferrari/hardright-' + i); + sprites['left-' + i] = loadSprite('ferrari/left-' + i); + sprites['right-' + i] = loadSprite('ferrari/right-' + i); + sprites['straight-' + i] = loadSprite('ferrari/straight-' + i); + + sprites['up-hardleft-' + i] = loadSprite('ferrari/up-hardleft-' + i); + sprites['up-hardright-' + i] = loadSprite('ferrari/up-hardright-' + i); + sprites['up-left-' + i] = loadSprite('ferrari/up-left-' + i); + sprites['up-right-' + i] = loadSprite('ferrari/up-right-' + i); + sprites['up-straight-' + i] = loadSprite('ferrari/up-straight-' + i); + + + sprites['down-hardleft-brake-' + i] = loadSprite('ferrari/down-hardleft-brake-' + i); + sprites['down-hardright-brake-' + i] = loadSprite('ferrari/down-hardright-brake-' + i); + sprites['down-left-brake-' + i] = loadSprite('ferrari/down-left-brake-' + i); + sprites['down-right-brake-' + i] = loadSprite('ferrari/down-right-brake-' + i); + sprites['down-straight-brake-' + i] = loadSprite('ferrari/down-straight-brake-' + i); + + sprites['hardleft-brake-' + i] = loadSprite('ferrari/hardleft-brake-' + i); + sprites['hardright-brake-' + i] = loadSprite('ferrari/hardright-brake-' + i); + sprites['left-brake-' + i] = loadSprite('ferrari/left-brake-' + i); + sprites['right-brake-' + i] = loadSprite('ferrari/right-brake-' + i); + sprites['straight-brake-' + i] = loadSprite('ferrari/straight-brake-' + i); + + sprites['up-hardleft-brake-' + i] = loadSprite('ferrari/up-hardleft-brake-' + i); + sprites['up-hardright-brake-' + i] = loadSprite('ferrari/up-hardright-brake-' + i); + sprites['up-left-brake-' + i] = loadSprite('ferrari/up-left-brake-' + i); + sprites['up-right-brake-' + i] = loadSprite('ferrari/up-right-brake-' + i); + sprites['up-straight-brake-' + i] = loadSprite('ferrari/up-straight-brake-' + i); + } + Outrun.drawLoading(); + // LOADING IN-GAME MUSIC + sounds['music-0'] = loadSound('music/music-0'); + sounds['music-1'] = loadSound('music/music-1'); + sounds['music-2'] = loadSound('music/music-2'); + //\\//\\ TEXT ASSETS //\\//\\ + sprites['press-enter'] = loadSprite('text/press-enter'); + sprites['select-music'] = loadSprite('text/select-music'); + sprites['music-0'] = loadSprite('text/music-0'); + sprites['music-1'] = loadSprite('text/music-1'); + sprites['music-2'] = loadSprite('text/music-2'); + //\\//\\ VEHICLES //\\//\\ + for (var i = 0; i < 11; i++) { + sprites['vehicle-' + i] = { + right0: loadSprite('vehicles/vehicle-' + i + '/right-0'), + right1: loadSprite('vehicles/vehicle-' + i + '/right-1'), + left0: loadSprite('vehicles/vehicle-' + i + '/left-0'), + left1: loadSprite('vehicles/vehicle-' + i + '/left-1') + }; + } + dimensions['vehicle-0'] = createDimension(945, 525); + dimensions['vehicle-1'] = dimensions['vehicle-0']; + dimensions['vehicle-2'] = dimensions['vehicle-0']; + dimensions['vehicle-3'] = createDimension(1420, 620); + dimensions['vehicle-4'] = dimensions['vehicle-3']; + dimensions['vehicle-5'] = createDimension(570, 600); + dimensions['vehicle-6'] = createDimension(1460, 1100); + dimensions['vehicle-7'] = dimensions['vehicle-6']; + dimensions['vehicle-8'] = dimensions['vehicle-6']; + dimensions['vehicle-9'] = createDimension(920, 450); + dimensions['vehicle-10'] = dimensions['vehicle-9']; + Outrun.drawLoading(); + //\\//\\ HUD //\\//\\ + for(var i = 0; i < 10; i++){ + sprites['hud-'+i] = loadSprite('hud/digits/'+i); + } + sprites['hud-kmh'] = loadSprite('hud/kmh'); + sprites['hud-coconut-beach'] = loadSprite('hud/map/coconut-beach'); + sprites['hud-gateaway'] = loadSprite('hud/map/gateaway'); + sprites['hud-devils-canyon'] = loadSprite('hud/map/devils-canyon'); + sprites['hud-desert'] = loadSprite('hud/map/desert'); + sprites['hud-alps'] = loadSprite('hud/map/alps'); + sprites['hud-cloudy-mountain'] = loadSprite('hud/map/cloudy-mountain'); + sprites['hud-wilderness'] = loadSprite('hud/map/wilderness'); + sprites['hud-old-capital'] = loadSprite('hud/map/old-capital'); + sprites['hud-wheat-field'] = loadSprite('hud/map/wheat-field'); + sprites['hud-seaside-town'] = loadSprite('hud/map/seaside-town'); + sprites['hud-vineyard'] = loadSprite('hud/map/vineyard'); + sprites['hud-death-valley'] = loadSprite('hud/map/death-valley'); + sprites['hud-desolation-hill'] = loadSprite('hud/map/desolation-hill'); + sprites['hud-autobahn'] = loadSprite('hud/map/autobahn'); + sprites['hud-lakeside'] = loadSprite('hud/map/lakeside'); + //\\//\\ COLORS //\\//\\ + colors['coconut-beach'] = { + skyColor: '#008BFF', + darkOffroadColor: '#D3C0B2', + lightOffroadColor: '#E1CDBF', + darkAsphaltColor: '#7F7D7D', + lightAsphaltColor: '#8B898A', + darkSideColor: '#7F7D7D', + lightSideColor: '#E5DCDD', + darkLineColor: '#7F7D7D', + lightLineColor: '#E5DCDD' + }; + colors['gateaway'] = { + skyColor: '#00BEDA', + darkOffroadColor: '#959E6B', + lightOffroadColor: '#A2AA75', + darkAsphaltColor: '#767475', + lightAsphaltColor: '#838081', + darkSideColor: '#767475', + lightSideColor: '#CECACD', + darkLineColor: '#767475', + lightLineColor: '#CECACD' + }; + colors['devils-canyon'] = { + skyColor: '#FFC25E', + darkOffroadColor: '#809473', + lightOffroadColor: '#8CA17F', + darkAsphaltColor: '#89857A', + lightAsphaltColor: '#9A958D', + darkSideColor: '#8E0C00', + lightSideColor: '#CAC6C7', + darkLineColor: '#89857A', + lightLineColor: '#CAC6C7' + }; + colors['desert'] = { + skyColor: '#000FFF', + darkOffroadColor: '#CEBCA2', + lightOffroadColor: '#DAC9AE', + darkAsphaltColor: '#AB9C8F', + lightAsphaltColor: '#B8A89B', + darkSideColor: '#AB9C8F', + lightSideColor: '#B8A89B', + darkLineColor: '#AB9C8F', + lightLineColor: '#B8A89B' + }; + colors['alps'] = { + skyColor: '#005AFF', + darkOffroadColor: '#8BA17D', + lightOffroadColor: '#95AC87', + darkAsphaltColor: '#7E7C7E', + lightAsphaltColor: '#8A878A', + darkSideColor: '#7E7C7E', + lightSideColor: '#C9C9C3', + darkLineColor: '#7E7C7E', + lightLineColor: '#C9C9C3' + }; + colors['cloudy-mountain'] = { + skyColor: '#938BFA', + darkOffroadColor: '#959D6C', + lightOffroadColor: '#A2AA75', + darkAsphaltColor: '#777576', + lightAsphaltColor: '#817F80', + darkSideColor: '#777576', + lightSideColor: '#C4C2C5', + darkLineColor: '#777576', + lightLineColor: '#C4C2C5' + }; + colors['wilderness'] = { + skyColor: '#D8C2A3', + darkOffroadColor: '#B18F73', + lightOffroadColor: '#BE9C7E', + darkAsphaltColor: '#B8987B', + lightAsphaltColor: '#C7A687', + darkSideColor: '#B8987B', + lightSideColor: '#C7A687', + darkLineColor: '#B8987B', + lightLineColor: '#C7A687' + }; + colors['old-capital'] = { + skyColor: '#7642FD', + darkOffroadColor: '#523627', + lightOffroadColor: '#5B3F2F', + darkAsphaltColor: '#4E3F3F', + lightAsphaltColor: '#574848', + darkSideColor: '#4E3F3F', + lightSideColor: '#C29E82', + darkLineColor: '#4E3F3F', + lightLineColor: '#C29E82' + }; + colors['wheat-field'] = { + skyColor: '#FFC25E', + darkOffroadColor: '#825E00', + lightOffroadColor: '#866404', + darkAsphaltColor: '#646365', + lightAsphaltColor: '#6F6E70', + darkSideColor: '#646365', + lightSideColor: '#C2C0C2', + darkLineColor: '#646365', + lightLineColor: '#C2C0C2' + }; + colors['seaside-town'] = { + skyColor: '#3C74FE', + darkOffroadColor: '#D2A479', + lightOffroadColor: '#DAAF82', + darkAsphaltColor: '#868277', + lightAsphaltColor: '#979288', + darkSideColor: '#868277', + lightSideColor: '#CDC9CE', + darkLineColor: '#868277', + lightLineColor: '#CDC9CE' + }; + colors['vineyard'] = { + skyColor: '#0BA1FF', + darkOffroadColor: '#A3A95C', + lightOffroadColor: '#B0B566', + darkAsphaltColor: '#7F7D7E', + lightAsphaltColor: '#898687', + darkSideColor: '#7F7D7E', + lightSideColor: '#ACAAAC', + darkLineColor: '#7F7D7E', + lightLineColor: '#ACAAAC' + }; + colors['death-valley'] = { + skyColor: '#6255FE', + darkOffroadColor: '#AA7B5D', + lightOffroadColor: '#AD7E5E', + darkAsphaltColor: '#6C5D5D', + lightAsphaltColor: '#776868', + darkSideColor: '#6C5D5D', + lightSideColor: '#C6C0C4', + darkLineColor: '#6C5D5D', + lightLineColor: '#C6C0C4' + }; + colors['desolation-hill'] = { + skyColor: '#EFECDC', + darkOffroadColor: '#CEBEB1', + lightOffroadColor: '#D9CABE', + darkAsphaltColor: '#848284', + lightAsphaltColor: '#908D90', + darkSideColor: '#848284', + lightSideColor: '#CFCCCF', + darkLineColor: '#848284', + lightLineColor: '#CFCCCF' + }; + colors['autobahn'] = { + skyColor: '#7642FD', + darkOffroadColor: '#839876', + lightOffroadColor: '#8EA481', + darkAsphaltColor: '#696B86', + lightAsphaltColor: '#747592', + darkSideColor: '#8C0C00', + lightSideColor: '#C5C4C5', + darkLineColor: '#696B86', + lightLineColor: '#C5C4C5' + }; + colors['lakeside'] = { + skyColor: '#FEAAA4', + darkOffroadColor: '#B8A79B', + lightOffroadColor: '#C6B4A8', + darkAsphaltColor: '#7D7569', + lightAsphaltColor: '#877F72', + darkSideColor: '#7D7569', + lightSideColor: '#C8C1C2', + darkLineColor: '#7D7569', + lightLineColor: '#C8C1C2' + }; +} + +function loadSprite(fileName) { + maxLoading++; + var sprite = new Image(); + sprite.onload = function () { + loading++; + } + sprite.src = "./assets/sprites/" + fileName + ".png"; + return sprite; +} + +function loadSound(fileName) { + maxLoading++; + var sample = new Audio(); + sample.isLoaded = false; + sample.oncanplay = function () { + if (!this.isLoaded) { + this.isLoaded = true; + loading++; + } + } + sample.src = "./assets/sounds/" + fileName + ".wav"; + return sample; +} + +function createDimension(width, height, offset) { + return { width: width, height: height, offset: offset }; +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/AudioManager.js b/Games/OutRun_Offline_Game/main/AudioManager.js new file mode 100644 index 0000000000..680776678e --- /dev/null +++ b/Games/OutRun_Offline_Game/main/AudioManager.js @@ -0,0 +1,62 @@ +function AudioManager() { + this.delay = 0; + this.music = 1; + this.dots = 3; + this.background = 0; + this.tree = 0; + this.flash = 0; +} + +const radioDelay = 6; + +AudioManager.prototype.update = function () { + if (Outrun.scene == MENU_SCENE | Outrun.scene == RADIO_SCENE) { + this.delay = (this.delay + 1) % radioDelay; + if (!this.delay) { + this.dots--; + if (this.dots < 0) { + this.dots = 3 + Math.random() * 4; + } + this.background = (this.background + 1) % 6; + this.tree = (this.tree + 1) % 3; + this.flash = (this.flash + 1) % 10; + } + if (sounds['wave'].paused) + sounds['wave'].play(); + } else if (Outrun.scene == IN_GAME_SCENE) { + if (sounds['music-' + this.music].paused) + sounds['music-' + this.music].play(); + } +} + +AudioManager.prototype.draw = function () { + Canvas.fill('#008BFF'); + Canvas.drawStaticImage(sprites['radio-car'], 0, 0, Canvas.width, Canvas.height); + Canvas.drawStaticImage(sprites['radio'], 127, 166, 126, 30); + Canvas.drawStaticImage(sprites['radio-freq-' + this.music], 143, 173, 24, 7); + for (var i = 0; i < this.dots; i++) { + Canvas.drawStaticImage(sprites['radio-dot-' + (i < 4 ? 'green' : 'red')], 156 + i * 3, 187, 2, 2); + Canvas.drawStaticImage(sprites['radio-dot-' + (i < 4 ? 'green' : 'red')], 156 + i * 3, 190, 2, 2); + } + Canvas.drawStaticImage(sprites['radio-hand-' + this.music], 117, 165, 133, 59); + if (Outrun.scene == MENU_SCENE) { + Canvas.drawStaticImage(sprites['logo-bg-' + this.background], 72, 18, 176, 88); + Canvas.drawStaticImage(sprites['logo-road'], 81, 80, 95, 25); + Canvas.drawStaticImage(sprites['logo-car'], 127, 66, 64, 39); + Canvas.drawStaticImage(sprites['logo-tree-' + this.tree], 75, 30, 46, 57); + Canvas.drawStaticImage(sprites['logo-text'], 109, 33, 135, 36); + if (this.flash < 5) + Canvas.drawStaticImage(sprites['press-enter'], 111, 123, 97, 8); + } else { + Canvas.drawStaticImage(sprites['select-music'], 65, 67, 191, 14); + if (this.music == 0) { + Canvas.drawStaticImage(sprites['music-0'], 72, 88, 175, 16); + } else if (this.music == 1) { + Canvas.drawStaticImage(sprites['music-1'], 96, 88, 127, 16); + } else { + Canvas.drawStaticImage(sprites['music-2'], 108, 88, 103, 16); + } + } +} + +let Radio = new AudioManager(); \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Camera.js b/Games/OutRun_Offline_Game/main/Camera.js new file mode 100644 index 0000000000..c801b78eed --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Camera.js @@ -0,0 +1,9 @@ +function Camera(width, height, altitude, fov) { + this.width = width; + this.height = height; + this.altitude = altitude; + this.fov = fov; + this.gap = this.width / (2 * Math.tan(this.fov * Math.PI / 360)); + this.rotation = 0; + this.position = new Vector3(-1.5 * (laneWidth + lineWidth), this.altitude + this.height / 2, 0); +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Canvas.js b/Games/OutRun_Offline_Game/main/Canvas.js new file mode 100644 index 0000000000..6990a423e4 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Canvas.js @@ -0,0 +1,97 @@ +function Canvas2D() { + this.canvas = document.getElementById('screen'); + this.canvasContext = this.canvas.getContext('2d'); + this.canvas.width = 320; + this.canvas.height = 224; + if (window.innerWidth / window.innerHeight <= canvasRatio) { + this.canvas.width = window.innerWidth; + this.canvas.height = window.innerWidth / canvasRatio; + } else { + this.canvas.width = window.innerHeight * canvasRatio; + this.canvas.height = window.innerHeight; + } + this.width = 320; + this.height = 224; + this.gradient = this.canvasContext.createLinearGradient(0, 0, 0, 200); + this.gradient.addColorStop(1, "white"); +} + +const canvasRatio = 1.42857142857; + +Canvas2D.prototype.clear = function () { + this.canvasContext.clearRect(0, 0, this.width, this.height); +} + +Canvas2D.prototype.fill = function (color) { + this.canvasContext.fillStyle = color; + this.canvasContext.fillRect(0, 0, this.width, this.height); +} + +Canvas2D.prototype.fillGradient = function (color) { + this.gradient.addColorStop(0, color); + this.canvasContext.fillStyle = this.gradient; + this.canvasContext.fillRect(0, 0, this.width, this.height); +} + +Canvas2D.prototype.drawImage = function (image, center, width, height) { + this.canvasContext.drawImage(image, center.xScreen - width / 2, center.yScreen - height, width, height); +} + +Canvas2D.prototype.drawStaticImage = function (image, x, y, width, height) { + this.canvasContext.drawImage(image, x, y, width, height); +} + +Canvas2D.prototype.drawShape = function (point1, point2, point3, point4, color) { + this.canvasContext.beginPath(); + this.canvasContext.moveTo(point1.xScreen, point1.yScreen); + this.canvasContext.lineTo(point2.xScreen, point2.yScreen); + this.canvasContext.lineTo(point3.xScreen, point3.yScreen); + this.canvasContext.lineTo(point4.xScreen, point4.yScreen); + this.canvasContext.fillStyle = color; + this.canvasContext.fill(); + this.canvasContext.strokeStyle = color; + this.canvasContext.stroke(); +} + +Canvas2D.prototype.drawText = function (text) { + for (var i = 0; i < text.length; i++) { + console.log(text.charAt(text.length - i - 1)); + this.drawStaticImage(sprites['hud-' + text.charAt(text.length - i - 1)], 19 - i * 8, 209, 7, 12); + } + +} + +/* + PROBABLY NOT GOING TO BE USED IN THE FUTURE +Canvas2D.prototype.pixelize = function (pixelSize) { + this.canvasContext.drawImage(this.canvas, 0, 0, this.width, this.height, 0, 0, this.width / pixelSize, this.height / pixelSize); + this.canvasContext.mozImageSmoothingEnabled = false; + this.canvasContext.imageSmoothingEnabled = false; + this.canvasContext.drawImage(this.canvas, 0, 0, this.width / pixelSize, this.height / pixelSize, 0, 0, this.width, this.height); +} +*/ + +Canvas2D.prototype.fix = function () { + this.canvasContext.mozImageSmoothingEnabled = false; + this.canvasContext.imageSmoothingEnabled = false; + this.canvasContext.drawImage(this.canvas, 0, 0, this.width, this.height, 0, 0, this.canvas.width, this.canvas.height); +} + +Canvas2D.prototype.mix = function (base, target, step) { + if (base == target) + return base; + var resHex = '#'; + for (var i = 1; i <= 5; i += 2) { + var diff = parseInt(target.substring(i, i + 2), 16) - parseInt(base.substring(i, i + 2), 16); + var add = null; + if (Math.abs(diff) >= step) { + add = (parseInt(base.substring(i, i + 2), 16) + step * Math.sign(diff)).toString(16).toUpperCase(); + } else { + add = target.substring(i, i + 2); + } + resHex += (add.length == 1 ? '0' : '') + add; + } + return resHex; +} + +let Canvas = new Canvas2D(); \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/EventListener.js b/Games/OutRun_Offline_Game/main/EventListener.js new file mode 100644 index 0000000000..5433b052f4 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/EventListener.js @@ -0,0 +1,62 @@ +function EventListener() { + document.onkeydown = keyDown; + document.onkeyup = keyUp; +} + +let KEY_W = 87; +let KEY_A = 65; +let KEY_S = 83; +let KEY_D = 68; +let KEY_ENTER = 13; +let KEY_SPACE = 32; +let KEY_UP = 38; +let KEY_LEFT = 37; +let KEY_DOWN = 40; +let KEY_RIGHT = 39; + +function keyDown(event) { + if (loading == maxLoading) { + if (Outrun.scene == MENU_SCENE) { + if (event.which == KEY_ENTER) { + Outrun.scene = RADIO_SCENE; + sounds['coin'].play(); + } + } else if (Outrun.scene == RADIO_SCENE) { + if (event.which == KEY_A | event.which == KEY_LEFT) { + if (Radio.music != 0) + Radio.music--; + } else if (event.which == KEY_D | event.which == KEY_RIGHT) { + if (Radio.music != 2) + Radio.music++; + } else if (event.which == KEY_ENTER) { + sounds['wave'].pause(); + Outrun.newGame(); + Outrun.scene = IN_GAME_SCENE; + } + } else if (Outrun.scene == IN_GAME_SCENE) { + if (event.which == KEY_W | event.which == KEY_UP) { + Driver.accelerate = true; + } else if (event.which == KEY_S | event.which == KEY_DOWN) { + Driver.decelerate = true; + } else if (event.which == KEY_A | event.which == KEY_LEFT) { + Driver.steerLeft = true; + } else if (event.which == KEY_D | event.which == KEY_RIGHT) { + Driver.steerRight = true; + } + } + } +} + +function keyUp(event) { + if (Outrun.scene == IN_GAME_SCENE) { + if (event.which == KEY_W | event.which == KEY_UP) { + Driver.accelerate = false; + } else if (event.which == KEY_S | event.which == KEY_DOWN) { + Driver.decelerate = false; + } else if (event.which == KEY_A | event.which == KEY_LEFT) { + Driver.steerLeft = false; + } else if (event.which == KEY_D | event.which == KEY_RIGHT) { + Driver.steerRight = false; + } + } +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Game.js b/Games/OutRun_Offline_Game/main/Game.js new file mode 100644 index 0000000000..a43af468f8 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Game.js @@ -0,0 +1,72 @@ +function Game() { + this.scene = MENU_SCENE; + this.renderSize = 300; + this.playable = false; + this.startDelay = 0; +} + +var controlCount = 0; + +const MENU_SCENE = 'menu'; +const RADIO_SCENE = 'radio'; +const IN_GAME_SCENE = 'drive'; + +const FPS = 60; + +var time = null; +var currentTime = null; + +Game.prototype.init = function () { + time = new Date().getTime(); + loadAssets(); + this.eventListener = new EventListener(); +} + +Game.prototype.newGame = function () { + this.gameWorld = new GameWorld(); +} + +Game.prototype.start = function () { + Outrun.init(); + Outrun.mainLoop(); +} + +Game.prototype.mainLoop = function () { + currentTime = new Date().getTime(); + var milliseconds = currentTime - time; + if (milliseconds >= 1000 / FPS) { + time = currentTime; + if (loading < maxLoading) { + Outrun.drawLoading(); + } else { + Radio.update(); + if (Outrun.scene == MENU_SCENE | Outrun.scene == RADIO_SCENE) { + Radio.draw(); + } else if (Outrun.scene == IN_GAME_SCENE) { + if(!Outrun.playable){ + Outrun.startDelay = (Outrun.startDelay + 1) % FPS; + if(!Outrun.startDelay) + Outrun.gameWorld.road.nextLight(); + } + Outrun.gameWorld.play(); + Outrun.gameWorld.update(); + Outrun.gameWorld.draw(); + } + } + Canvas.fix(); + } + + requestAnimationFrame(Outrun.mainLoop); +} + +Game.prototype.drawLoading = function () { + Canvas.fill('#008BFF'); + Canvas.canvasContext.fillStyle = "#000000"; + Canvas.canvasContext.fillRect(99, 126, 121, 12); + Canvas.canvasContext.fillStyle = "#F7F700"; + Canvas.canvasContext.fillRect(99, 126, 121 * (loading / maxLoading), 12); + Canvas.drawStaticImage(sprites['loading-box'], 98, 125, 124, 15); + Canvas.drawStaticImage(sprites['loading-text'], 106, 84, 109, 28); +} + +let Outrun = new Game(); diff --git a/Games/OutRun_Offline_Game/main/GameWorld.js b/Games/OutRun_Offline_Game/main/GameWorld.js new file mode 100644 index 0000000000..06c74b84b2 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/GameWorld.js @@ -0,0 +1,134 @@ +function GameWorld() { + this.road = new Road(new Vector3(0, 0, 0), 0, 0, trackNumLanes); + this.route = 'coconut-beach'; + this.currentColor = colors['coconut-beach']; + this.backParallax = 0; + this.frontParallax = 0; +} + +const backSpeed = 0.000001; +const frontSpeed = 0.000002; +const backWidth = 1536; +const frontWidth = 2048; +const backgroundHeight = 256; +const backgroundOffset = -135; + +GameWorld.prototype.play = function () { + if (this.road.endSegment != null && this.road.findIndex(this.road.endSegment.highCenter.z) < this.road.findIndex(Driver.camera.position.z)) + Outrun.playable = false; + if (Outrun.playable) + Driver.play(); + for (var i = 0; i < this.road.vehicles.length; i++) { + this.road.vehicles[i].play(); + } +} + +GameWorld.prototype.update = function () { + var currentIndex = this.road.findIndex(Driver.camera.position.z); + for (var i = currentIndex, size = Math.min(this.road.segments.length, currentIndex + Outrun.renderSize); i < size; i++) { + this.road.segments[i].project(); + } + Driver.project(); + for (var i = 0; i < this.road.vehicles.length; i++) { + this.road.vehicles[i].project(); + } + this.route = this.road.findRoute(); + for (var i = 0; i < 9; i++) { + var key = Object.keys(this.currentColor)[i]; + this.currentColor[key] = Canvas.mix(this.currentColor[key], colors[this.route][key], 1); + } + var parallaxAmount = Driver.speed * Math.sign(Driver.curveDirection); + this.backParallax -= backSpeed * parallaxAmount; + this.frontParallax -= frontSpeed * parallaxAmount; + if (Math.abs(this.backParallax) > 1) { + this.backParallax = 0; + } + if (Math.abs(this.frontParallax) > 1) { + this.frontParallax = 0; + } +} + +GameWorld.prototype.draw = function () { + Canvas.fillGradient(this.currentColor.skyColor); + Canvas.drawStaticImage(sprites[this.route].back, backWidth * (this.backParallax - 1), backgroundOffset, backWidth, backgroundHeight); + Canvas.drawStaticImage(sprites[this.route].back, backWidth * (this.backParallax), backgroundOffset, backWidth, backgroundHeight); + Canvas.drawStaticImage(sprites[this.route].back, backWidth * (this.backParallax + 1), backgroundOffset, backWidth, backgroundHeight); + Canvas.drawStaticImage(sprites[this.route].front, frontWidth * (this.frontParallax - 1), backgroundOffset, frontWidth, backgroundHeight); + Canvas.drawStaticImage(sprites[this.route].front, frontWidth * (this.frontParallax), backgroundOffset, frontWidth, backgroundHeight); + Canvas.drawStaticImage(sprites[this.route].front, frontWidth * (this.frontParallax + 1), backgroundOffset, frontWidth, backgroundHeight); + var currentIndex = this.road.findIndex(Driver.camera.position.z); + var maxRendered = Math.min(this.road.segments.length, currentIndex + Outrun.renderSize) - 1; + for (var i = maxRendered; i >= currentIndex; i--) { + var segment = this.road.segments[i]; + var color = segment.isDark ? this.currentColor.darkOffroadColor : this.currentColor.lightOffroadColor; + if (segment instanceof Segment) { + Canvas.drawShape(segment.offroad.upLeft, segment.offroad.upRight, segment.offroad.downRight, segment.offroad.downLeft, color); + } else { + var subSegment = segment.leftJunction; + Canvas.drawShape(subSegment.offroad.upLeft, subSegment.offroad.upRight, subSegment.offroad.downRight, subSegment.offroad.downLeft, color); + subSegment = segment.rightJunction; + Canvas.drawShape(subSegment.offroad.upLeft, subSegment.offroad.upRight, subSegment.offroad.downRight, subSegment.offroad.downLeft, color); + } + } + for (var i = maxRendered; i >= currentIndex; i--) { + var segment = this.road.segments[i]; + var asphaltColor = segment.isDark ? this.currentColor.darkAsphaltColor : this.currentColor.lightAsphaltColor; + var sideColor = segment.isDark ? this.currentColor.darkSideColor : this.currentColor.lightSideColor; + var lineColor = segment.isDark ? this.currentColor.darkLineColor : this.currentColor.lightLineColor; + if (segment instanceof Segment) { + Canvas.drawShape(segment.asphalt.upLeft, segment.asphalt.upRight, segment.asphalt.downRight, segment.asphalt.downLeft, asphaltColor); + Canvas.drawShape(segment.leftSide.upLeft, segment.leftSide.upRight, segment.leftSide.downRight, segment.leftSide.downLeft, sideColor); + Canvas.drawShape(segment.rightSide.upLeft, segment.rightSide.upRight, segment.rightSide.downRight, segment.rightSide.downLeft, sideColor); + for (var j = 0; j < segment.numLanes - 1; j++) { + Canvas.drawShape(segment.lines[j].upLeft, segment.lines[j].upRight, segment.lines[j].downRight, segment.lines[j].downLeft, lineColor); + } + for (var j = 0; j < segment.objects.length; j++) { + var object = segment.objects[j]; + if (sprites[this.route][object.fileName] != undefined) + Canvas.drawImage(sprites[this.route][object.fileName], object.center, object.relWidth, object.relHeight); + } + } else { + var subSegment = segment.leftJunction; + Canvas.drawShape(subSegment.asphalt.upLeft, subSegment.asphalt.upRight, subSegment.asphalt.downRight, subSegment.asphalt.downLeft, asphaltColor); + Canvas.drawShape(subSegment.leftSide.upLeft, subSegment.leftSide.upRight, subSegment.leftSide.downRight, subSegment.leftSide.downLeft, sideColor); + Canvas.drawShape(subSegment.rightSide.upLeft, subSegment.rightSide.upRight, subSegment.rightSide.downRight, subSegment.rightSide.downLeft, sideColor); + for (var j = 0; j < subSegment.numLanes - 1; j++) { + Canvas.drawShape(subSegment.lines[j].upLeft, subSegment.lines[j].upRight, subSegment.lines[j].downRight, subSegment.lines[j].downLeft, lineColor); + } + for (var j = 0; j < subSegment.objects.length; j++) { + var object = subSegment.objects[j]; + if (sprites[this.route][object.fileName] != undefined) + Canvas.drawImage(sprites[this.route][object.fileName], object.center, object.relWidth, object.relHeight); + } + subSegment = segment.rightJunction; + Canvas.drawShape(subSegment.asphalt.upLeft, subSegment.asphalt.upRight, subSegment.asphalt.downRight, subSegment.asphalt.downLeft, asphaltColor); + Canvas.drawShape(subSegment.leftSide.upLeft, subSegment.leftSide.upRight, subSegment.leftSide.downRight, subSegment.leftSide.downLeft, sideColor); + Canvas.drawShape(subSegment.rightSide.upLeft, subSegment.rightSide.upRight, subSegment.rightSide.downRight, subSegment.rightSide.downLeft, sideColor); + for (var j = 0; j < subSegment.numLanes - 1; j++) { + Canvas.drawShape(subSegment.lines[j].upLeft, subSegment.lines[j].upRight, subSegment.lines[j].downRight, subSegment.lines[j].downLeft, lineColor); + } + for (var j = 0; j < subSegment.objects.length; j++) { + var object = subSegment.objects[j]; + if (sprites[this.route][object.fileName] != undefined) + Canvas.drawImage(sprites[this.route][object.fileName], object.center, object.relWidth, object.relHeight); + } + } + } + for (var i = this.road.vehicles.length - 1; i >= 0; i--) { + var vehicle = this.road.vehicles[i]; + var position = this.road.findIndex(vehicle.car.center.z); + if (position > currentIndex & position < maxRendered) + Canvas.drawImage(sprites[vehicle.vehicleType][vehicle.car.fileName], vehicle.car.center, vehicle.car.relWidth, vehicle.car.relHeight); + } + Canvas.drawImage(sprites[Driver.car.fileName], Driver.car.center, Driver.car.relWidth, Driver.car.relHeight); + + Canvas.drawStaticImage(sprites['hud-' + this.route], 301, 210, 16, 11); + Canvas.drawStaticImage(sprites['hud-kmh'], 27, 210, 18, 13); + Canvas.drawText(Math.floor(Driver.speed / 3).toString()); + + if (this.road.segments.length - currentIndex < Outrun.renderSize) { + this.road.addSegments(true); + } +} + +let Driver = new Player(); \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Junction.js b/Games/OutRun_Offline_Game/main/Junction.js new file mode 100644 index 0000000000..1e28df37af --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Junction.js @@ -0,0 +1,12 @@ +function Junction(prevJunction, curve, hill, index, isInitial) { + this.numLanes = prevJunction.numLanes; + this.isDark = index % (2 * invisSegment) < invisSegment; + this.leftJunction = new Segment(prevJunction.leftJunction, -curve, hill, index, isInitial, true); + this.rightJunction = new Segment(prevJunction.rightJunction, curve, hill, index, isInitial, true); + this.isInitial = isInitial; +} + +Junction.prototype.project = function () { + this.leftJunction.project(); + this.rightJunction.project(); +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Player.js b/Games/OutRun_Offline_Game/main/Player.js new file mode 100644 index 0000000000..83b838e6ca --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Player.js @@ -0,0 +1,131 @@ +function Player() { + this.camera = new Camera(window.innerWidth, window.innerHeight, 300, 120); + this.car = new WorldObject(new Vector3(0, 0, carDistance), 'straight'); + this.car.width = 810; + this.car.height = 460; + this.car.project = function (measure2) { + this.center.project(); + this.relWidth = Vector3.calculate(this.width, Driver.camera.gap, measure2); + this.relHeight = Vector3.calculate(this.height, Driver.camera.gap, measure2); + } + this.lastSegment = null; + this.curve = 0; + this.hill = 0; + this.curveDirection = 0; + this.hillDirection = 0; + this.speed = 0; + this.accelerate = false; + this.decelerate = false; + this.steerLeft = false; + this.steerRight = false; +} + +const maxSpeed = 900; + +const carDistance = 5000; + +const curveSense = 0.2; +const hillSense = 10; +const speedSense = 250; + +Player.prototype.play = function () { + if (this.accelerate) { + this.speed += 4; + } else if (this.decelerate) { + this.speed -= 16; + } else { + this.speed -= 2; + } + this.speed = this.speed < 0 ? 0 : this.speed > maxSpeed ? maxSpeed : this.speed; + + var carIndex = Outrun.gameWorld.road.findIndex(this.car.center.z); + var segment = Outrun.gameWorld.road.segments[carIndex]; + if (segment instanceof Segment) { + this.lastSegment = segment; + this.curve = segment.curve; + this.hill = segment.hill; + if (Outrun.gameWorld.road.segments[carIndex - 1] instanceof Segment) { + this.curveDirection = this.curve - Outrun.gameWorld.road.segments[carIndex - 1].curve; + this.hillDirection = this.hill - Outrun.gameWorld.road.segments[carIndex - 1].hill; + } else { + this.curveDirection = 0; + this.hillDirection = 0; + } + } else { + if (Outrun.gameWorld.road.trackCount > Outrun.gameWorld.road.chosenPath.length) { + Outrun.gameWorld.road.chosenPath.push(this.car.center.x >= this.lastSegment.highCenter.x); + } + if (Outrun.gameWorld.road.chosenPath[Outrun.gameWorld.road.chosenPath.length - 1]) { + this.curve = segment.rightJunction.curve; + this.hill = segment.rightJunction.hill; + if (Outrun.gameWorld.road.segments[carIndex - 1] instanceof Junction) { + this.curveDirection = this.curve - Outrun.gameWorld.road.segments[carIndex - 1].rightJunction.curve; + this.hillDirection = this.hill - Outrun.gameWorld.road.segments[carIndex - 1].rightJunction.hill; + } else { + this.curveDirection = 0; + this.hillDirection = 0; + } + } else { + this.curve = segment.leftJunction.curve; + this.hill = segment.leftJunction.hill; + if (Outrun.gameWorld.road.segments[carIndex - 1] instanceof Junction) { + this.curveDirection = this.curve - Outrun.gameWorld.road.segments[carIndex - 1].leftJunction.curve; + this.hillDirection = this.hill - Outrun.gameWorld.road.segments[carIndex - 1].leftJunction.hill; + } else { + this.curveDirection = 0; + this.hillDirection = 0; + } + } + } + + zMove = this.speed * (this.steerLeft | this.steerRight ? 0.99 : 1); + xMove = this.speed * ((this.steerLeft ? -0.08 : this.steerRight ? 0.08 : 0) - this.curveDirection / 25); + + this.camera.position.z += zMove; + this.camera.position.x += xMove; + this.camera.position.y = this.hill + this.camera.altitude + this.camera.height / 2; +} + +Player.prototype.project = function () { + this.car.center.x = this.camera.position.x; + this.car.center.z = this.camera.position.z + carDistance; + this.car.center.y = this.hill; + this.car.project(this.car.center.z - this.camera.position.z); + + this.car.fileName = ''; + if (this.hillDirection > hillSense) { + this.car.fileName = 'up-'; + } else if (this.hillDirection < -hillSense) { + this.car.fileName = 'down-'; + } + if (this.curveDirection < -curveSense) { + if (this.steerLeft & this.speed != 0) + this.car.fileName += 'hardleft-'; + else if (this.steerRight & this.speed != 0) + this.car.fileName += 'straight-'; + else + this.car.fileName += 'left-'; + } else if (this.curveDirection > curveSense) { + if (this.steerLeft & this.speed != 0) + this.car.fileName += 'straight-'; + else if (this.steerRight & this.speed != 0) + this.car.fileName += 'hardright-'; + else + this.car.fileName += 'right-'; + } else { + if (this.steerLeft & this.speed != 0) + this.car.fileName += 'left-'; + else if (this.steerRight & this.speed != 0) + this.car.fileName += 'right-'; + else + this.car.fileName += 'straight-'; + } + if (this.decelerate) { + this.car.fileName += 'brake-'; + } + if (this.speed > speedSense) { + this.car.fileName += Math.floor(Math.random() * 2); + } else { + this.car.fileName += '0'; + } +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Road.js b/Games/OutRun_Offline_Game/main/Road.js new file mode 100644 index 0000000000..40fa36ff0b --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Road.js @@ -0,0 +1,274 @@ +function Road(center, curve, hill, numLanes) { + this.trackRemain = trackLength - 1; + this.chosenPath = []; + this.vehicles = []; + this.trackCount = 0; + this.segments = [new Segment(Road.prepareInitial(center, curve, hill, numLanes), curve, hill, 0, true)]; + this.addSegments(false); + this.segments[0].offroad.downLeft.project(); + this.segments[0].offroad.downRight.project(); + this.segments[0].asphalt.downLeft.project(); + this.segments[0].asphalt.downRight.project(); + this.segments[0].leftSide.downLeft.project(); + this.segments[0].leftSide.downRight.project(); + this.segments[0].rightSide.downLeft.project(); + this.segments[0].rightSide.downRight.project(); + for (var i = 0; i < numLanes - 1; i++) { + this.segments[0].lines[i].downLeft.project(); + this.segments[0].lines[i].downRight.project(); + } + this.startSegment = this.segments[13]; + this.endSegment = null; + this.startSegment.objects.push(new WorldObject(new Vector3(this.startSegment.highCenter.x, this.startSegment.highCenter.y, this.startSegment.highCenter.z), 'start0')); +} + +const trackLength = 2000; +const junctionLength = 400; + +const trackNumLanes = 6; +const junctNumLanes = 3; + +const vehicleSpawn = 5; + +const MAX_CURVE = 1; +const MAX_HILL = 10; + +Road.prototype.addSegments = function (canCurve) { + var curved = canCurve & Math.random() < 0.4; + if (this.segments[this.segments.length - 1] instanceof Segment) { + if (curved & this.trackRemain > 400 + Outrun.renderSize) { + var curveLength = Math.random() < 0.5 ? 200 : 400; + if (Math.random() < 0.7) { + this.addCurves(curveLength); + } else { + this.addHills(curveLength); + } + this.trackRemain -= curveLength; + } else if (this.trackRemain != 0) { + var length = Math.min(this.trackRemain, Outrun.renderSize); + this.addStraights(length); + this.trackRemain -= length; + } else { + if (this.chosenPath.length < 4) { + this.addJunctions(junctionLength); + this.trackRemain = trackLength; + } else { + Outrun.finished = true; + this.endSegment = this.segments[this.segments.length - 1]; + this.endSegment.objects.push(new WorldObject(new Vector3(this.endSegment.highCenter.x, this.endSegment.highCenter.y, this.endSegment.highCenter.z), 'goal')); + this.addStraights(Outrun.renderSize * 2); + } + } + } else { + var lastJunction = null; + if (this.chosenPath[this.chosenPath.length - 1]) { + lastJunction = this.segments[this.segments.length - 1].rightJunction; + var newCenter = new Vector3(lastJunction.highCenter.x + (laneWidth * 1.5 + sideLineWidth / 2 + lineWidth / 2), lastJunction.highCenter.y, lastJunction.highCenter.z); + this.segments.push(new Segment(Road.prepareInitial(newCenter, lastJunction.curve, lastJunction.hill, trackNumLanes), 0, 0, this.segments.length, true)); + } else { + lastJunction = this.segments[this.segments.length - 1].leftJunction; + var newCenter = new Vector3(lastJunction.highCenter.x - (laneWidth * 1.5 + sideLineWidth / 2 + lineWidth / 2), lastJunction.highCenter.y, lastJunction.highCenter.z); + this.segments.push(new Segment(Road.prepareInitial(newCenter, lastJunction.curve, lastJunction.hill, trackNumLanes), 0, 0, this.segments.length, true)); + } + this.addStraights(Outrun.renderSize); + } +} + +Road.prototype.addCurves = function (length) { + var direction = Math.random() < 0.5 ? -1 : 1; + var part = length / 3; + var vehicle = 0; + for (var i = 0; i < part; i++) { + this.segments.push(new Segment(this.segments[this.segments.length - 1], MAX_CURVE * (i / part) * direction, 0, this.segments.length, false)); + if (vehicle < vehicleSpawn & Math.random() < 0.01) { + vehicle++; + this.addVehicles(this.segments[this.segments.length - 1]); + } + } + for (var i = 0; i < part; i++) { + this.segments.push(new Segment(this.segments[this.segments.length - 1], MAX_CURVE * direction, 0, this.segments.length, false)); + if (vehicle < vehicleSpawn & Math.random() < 0.01) { + vehicle++; + this.addVehicles(this.segments[this.segments.length - 1]); + } + } + for (var i = 0; i < part; i++) { + this.segments.push(new Segment(this.segments[this.segments.length - 1], MAX_CURVE * (1 - i / part) * direction, 0, this.segments.length, false)); + if (vehicle < vehicleSpawn & Math.random() < 0.01) { + vehicle++; + this.addVehicles(this.segments[this.segments.length - 1]); + } + } +} + +Road.prototype.addHills = function (length) { + var part = length / 3; + var vehicle = 0; + for (var i = 0; i < part; i++) { + this.segments.push(new Segment(this.segments[this.segments.length - 1], 0, MAX_HILL * (Math.cos((2 * i / part - 1) * Math.PI) + 1), this.segments.length, false)); + if (vehicle < vehicleSpawn & Math.random() < 0.01) { + vehicle++; + this.addVehicles(this.segments[this.segments.length - 1]); + } + } + for (var i = 0; i < part; i++) { + this.segments.push(new Segment(this.segments[this.segments.length - 1], 0, 0, this.segments.length, false)); + if (vehicle < vehicleSpawn & Math.random() < 0.01) { + vehicle++; + this.addVehicles(this.segments[this.segments.length - 1]); + } + } + for (var i = 0; i < part; i++) { + this.segments.push(new Segment(this.segments[this.segments.length - 1], 0, MAX_HILL * (-Math.cos((2 * i / part - 1) * Math.PI) - 1), this.segments.length, false)); + if (vehicle < vehicleSpawn & Math.random() < 0.01) { + vehicle++; + this.addVehicles(this.segments[this.segments.length - 1]); + } + } +} + +Road.prototype.addStraights = function (length) { + var vehicle = 0; + for (var i = 0; i < length; i++) { + this.segments.push(new Segment(this.segments[this.segments.length - 1], 0, 0, this.segments.length, false)); + if (vehicle < vehicleSpawn & Math.random() < 0.01) { + vehicle++; + this.addVehicles(this.segments[this.segments.length - 1]); + } + } +} + +Road.prototype.addJunctions = function (length) { + this.trackCount++; + var lastSegment = this.segments[this.segments.length - 1]; + var initial = { + numLanes: junctNumLanes, + leftJunction: Road.prepareInitial(new Vector3(lastSegment.highCenter.x - (lastSegment.asphalt.width / 4 - sideLineWidth / 2 + lineWidth / 4), lastSegment.highCenter.y, lastSegment.highCenter.z), lastSegment.curve, lastSegment.hill, junctNumLanes), + rightJunction: Road.prepareInitial(new Vector3(lastSegment.highCenter.x + (lastSegment.asphalt.width / 4 - sideLineWidth / 2 + lineWidth / 4), lastSegment.highCenter.y, lastSegment.highCenter.z), lastSegment.curve, lastSegment.hill, junctNumLanes) + }; + this.segments.push(new Junction(initial, 0, 0, this.segments.length, true)); + var part = (length - 1) / 3; + for (var i = 0; i < part; i++) { + this.segments.push(new Junction(this.segments[this.segments.length - 1], MAX_CURVE * (i / part), 0, this.segments.length, false)); + } + for (var i = 0; i < part; i++) { + this.segments.push(new Junction(this.segments[this.segments.length - 1], MAX_CURVE, 0, this.segments.length, false)); + } + for (var i = 0; i < part; i++) { + this.segments.push(new Junction(this.segments[this.segments.length - 1], MAX_CURVE * (1 - i / part), 0, this.segments.length, false)); + } + for (var i = 0; i < Outrun.renderSize; i++) { + this.segments.push(new Junction(this.segments[this.segments.length - 1], 0, 0, this.segments.length, false)); + } +} + +Road.prototype.addVehicles = function (segment) { + var shift = (Math.floor(Math.random() * (segment.numLanes / 2)) + 0.5) * (Math.random() < 0.5 ? 1 : -1); + this.vehicles.push(new Vehicle(new Vector3(segment.highCenter.x, segment.highCenter.y, segment.highCenter.z), shift, 'vehicle-' + Math.floor(Math.random() * 11))); +} + +Road.prototype.nextLight = function () { + var currentFile = this.startSegment.objects[this.startSegment.objects.length - 1].fileName; + if (currentFile == 'start0') + this.startSegment.objects[this.startSegment.objects.length - 1].fileName = 'start1'; + else if (currentFile == 'start1') + this.startSegment.objects[this.startSegment.objects.length - 1].fileName = 'start2'; + else if (currentFile == 'start2') + this.startSegment.objects[this.startSegment.objects.length - 1].fileName = 'start3'; + if (currentFile == 'start2') { + sounds['signal-1'].play(); + Outrun.playable = true; + } + else + sounds['signal-0'].play(); +} + +Road.prototype.findIndex = function (position) { + return Math.floor(position / segmentDepth) % this.segments.length; +} + +Road.prepareInitial = function (center, curve, hill, numLanes) { + var asphaltWidth = laneWidth * numLanes + lineWidth * (numLanes - 1) + sideLineWidth * 2; + var initial = { + numLanes: numLanes, + curve: curve, + hill: hill, + highCenter: center, + offroad: { + upLeft: new Vector3(center.x - offroadWidth / 2, center.y, center.z), + upRight: new Vector3(center.x + offroadWidth / 2, center.y, center.z), + highCenter: center, + space: 0, + width: offroadWidth + }, + asphalt: { + upLeft: new Vector3(center.x - asphaltWidth / 2, center.y, center.z), + upRight: new Vector3(center.x + asphaltWidth / 2, center.y, center.z), + highCenter: center, + space: 0, + width: asphaltWidth + }, + leftSide: { + upLeft: new Vector3(center.x - asphaltWidth / 2, center.y, center.z), + upRight: new Vector3(center.x - asphaltWidth / 2 + sideLineWidth, center.y, center.z), + highCenter: center, + space: (sideLineWidth - asphaltWidth) / 2, + width: sideLineWidth + }, + rightSide: { + upLeft: new Vector3(center.x + asphaltWidth / 2 - sideLineWidth, center.y, center.z), + upRight: new Vector3(center.x + asphaltWidth / 2, center.y, center.z), + highCenter: center, + space: (asphaltWidth - sideLineWidth) / 2, + width: sideLineWidth + }, + lines: [] + }; + var leftSide = initial.leftSide; + for (var i = 0; i < numLanes - 1; i++) { + initial.lines.push( + { + upLeft: new Vector3(leftSide.upRight.x + laneWidth + (laneWidth + lineWidth) * i, center.y, center.z), + upRight: new Vector3(leftSide.upRight.x + (laneWidth + lineWidth) * (i + 1), center.y, center.z), + highCenter: center, + space: leftSide.space + (sideLineWidth + lineWidth) / 2 + laneWidth + (laneWidth + lineWidth) * i, + width: lineWidth + } + ); + } + return initial; +} + +Road.prototype.findRoute = function () { + var length = this.chosenPath.length; + var sum = this.chosenPath.reduce((a, b) => a + b, 0); + switch (length) { + case 0: return 'coconut-beach'; + case 1: + switch (sum) { + case 0: return 'gateaway'; + case 1: return 'devils-canyon'; + } + case 2: + switch (sum) { + case 0: return 'desert'; + case 1: return 'alps'; + case 2: return 'cloudy-mountain'; + } + case 3: + switch (sum) { + case 0: return 'wilderness'; + case 1: return 'old-capital'; + case 2: return 'wheat-field'; + case 3: return 'seaside-town'; + } + case 4: + switch (sum) { + case 0: return 'vineyard'; + case 1: return 'death-valley'; + case 2: return 'desolation-hill'; + case 3: return 'autobahn'; + case 4: return 'lakeside'; + } + } +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Segment.js b/Games/OutRun_Offline_Game/main/Segment.js new file mode 100644 index 0000000000..99c7195d20 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Segment.js @@ -0,0 +1,79 @@ +function Segment(prevSegment, curve, hill, index, isInitial, isTunnel) { + this.numLanes = prevSegment.numLanes; + this.isInitial = isInitial; + this.curve = prevSegment.curve + curve; + this.hill = prevSegment.hill + hill; + this.lowCenter = prevSegment.highCenter; + this.highCenter = new Vector3(this.lowCenter.x + curve, this.lowCenter.y + hill, this.lowCenter.z + segmentDepth); + this.isDark = index % (2 * invisSegment) < invisSegment; + this.offroad = new Tile(prevSegment.offroad, this.highCenter); + this.asphalt = new Tile(prevSegment.asphalt, this.highCenter); + this.leftSide = new Tile(prevSegment.leftSide, this.highCenter); + this.rightSide = new Tile(prevSegment.rightSide, this.highCenter); + this.lines = []; + for (var i = 0; i < this.numLanes - 1; i++) { + this.lines.push(new Tile(prevSegment.lines[i], this.highCenter)); + } + this.objects = []; + if (!isTunnel) { + if (!(index % (objectDistance / 4))) { + this.objects.push(new WorldObject(new Vector3(this.highCenter.x, this.highCenter.y, this.highCenter.z), 'terrain')); + if (Math.random() < 0.1) { + this.objects.push(new WorldObject(new Vector3(this.highCenter.x, this.highCenter.y, this.highCenter.z), 'left' + (Math.random() < 0.5 ? '1' : '2'))); + } + } + if (!(index % objectDistance)) { + this.objects.push(new WorldObject(new Vector3(this.highCenter.x, this.highCenter.y, this.highCenter.z), 'right' + (Math.random() < 0.5 ? '1' : '2'))); + } + } else if (!(index % tunnelDistance)) { + this.objects.push(new WorldObject(new Vector3(this.highCenter.x, this.highCenter.y, this.highCenter.z), 'tunnel')); + } +} + +const invisSegment = 5; +const sideLineWidth = 300; +const lineWidth = 150; +const laneWidth = 1200; +const offroadWidth = 70000; +const segmentDepth = 600; +const objectDistance = 20; +const tunnelDistance = 6; + +Segment.prototype.project = function () { + if (this.isInitial & this.lowCenter.z > Driver.camera.position.z) { + this.offroad.downLeft.project(); + this.offroad.downRight.project(); + this.asphalt.downLeft.project(); + this.asphalt.downRight.project(); + this.leftSide.downLeft.project(); + this.leftSide.downRight.project(); + this.rightSide.downLeft.project(); + this.rightSide.downRight.project(); + for (var i = 0; i < this.numLanes - 1; i++) { + this.lines[i].downLeft.project(); + this.lines[i].downRight.project(); + } + } + this.highCenter.x = this.lowCenter.x + (this.curve - Driver.curve); + this.highCenter.project(); + var measure2 = this.highCenter.z - Driver.camera.position.z; + this.offroad.project(measure2); + this.asphalt.project(measure2); + this.leftSide.project(measure2); + this.rightSide.project(measure2); + for (var i = 0, size = this.numLanes / 2; i < size; i++) { + var relSpace = Vector3.calculate(this.lines[i].space, Driver.camera.gap, measure2); + var relWidth = Vector3.calculate(this.lines[i].width, Driver.camera.gap, measure2); + this.lines[i].calculate(relSpace, relWidth); + this.lines[this.numLanes - 2 - i].calculate(-relSpace, relWidth); + } + if (this.numLanes % 2 == 0) { + this.lines[this.numLanes / 2 + 1].project(measure2); + } + for (var i = 0; i < this.objects.length; i++) { + if (dimensions[Outrun.gameWorld.route][this.objects[i].fileName] != undefined) { + this.objects[i].center.x = this.highCenter.x + dimensions[Outrun.gameWorld.route][this.objects[i].fileName].offset; + this.objects[i].project(measure2); + } + } +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Tile.js b/Games/OutRun_Offline_Game/main/Tile.js new file mode 100644 index 0000000000..d750d8cec2 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Tile.js @@ -0,0 +1,26 @@ +function Tile(prevTile, highCenter) { + this.lowCenter = prevTile.highCenter; + this.highCenter = highCenter; + this.space = prevTile.space; + this.width = prevTile.width; + this.downLeft = prevTile.upLeft; + this.downRight = prevTile.upRight; + this.upLeft = new Vector3(); + this.upRight = new Vector3(); +} + +Tile.prototype.project = function (measure2) { + var relSpace = Vector3.calculate(this.space, Driver.camera.gap, measure2); + var relWidth = Vector3.calculate(this.width, Driver.camera.gap, measure2); + this.upLeft.xScreen = this.highCenter.xScreen + relSpace - relWidth / 2; + this.upLeft.yScreen = this.highCenter.yScreen; + this.upRight.xScreen = this.highCenter.xScreen + relSpace + relWidth / 2; + this.upRight.yScreen = this.highCenter.yScreen; +} + +Tile.prototype.calculate = function (relSpace, relWidth) { + this.upLeft.xScreen = this.highCenter.xScreen + relSpace - relWidth / 2; + this.upLeft.yScreen = this.highCenter.yScreen; + this.upRight.xScreen = this.highCenter.xScreen + relSpace + relWidth / 2; + this.upRight.yScreen = this.highCenter.yScreen; +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Vector3.js b/Games/OutRun_Offline_Game/main/Vector3.js new file mode 100644 index 0000000000..20629928de --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Vector3.js @@ -0,0 +1,17 @@ +function Vector3(x, y, z) { + this.x = x; + this.y = y; + this.z = z; + this.xScreen = 0; + this.yScreen = 0; +} + +Vector3.prototype.project = function () { + zDiff = this.z - Driver.camera.position.z; + this.xScreen = Canvas.width / 2 + Driver.camera.gap * (this.x - Driver.camera.position.x) / zDiff; + this.yScreen = Canvas.height / 2 + Driver.camera.gap * (Driver.camera.position.y - this.y) / zDiff; +} + +Vector3.calculate = function (length, measure1, measure2) { + return length * measure1 / measure2; +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/Vehicle.js b/Games/OutRun_Offline_Game/main/Vehicle.js new file mode 100644 index 0000000000..037d5a91d0 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/Vehicle.js @@ -0,0 +1,85 @@ +function Vehicle(center, shift, vehicleType) { + this.vehicleType = vehicleType; + this.shift = shift; + this.car = new WorldObject(center, 'right0'); + this.car.width = 810; + this.car.height = 460; + this.car.project = function (measure2, dimension) { + this.center.project(); + this.relWidth = Vector3.calculate(dimension.width, Driver.camera.gap, measure2); + this.relHeight = Vector3.calculate(dimension.height, Driver.camera.gap, measure2); + } + this.lastSegment = null; + this.chosenPath = []; + this.curveDirection = 0; + this.hasStopped = false; +} + +const speed = 400; + +Vehicle.prototype.play = function () { + if (!this.hasStopped) { + this.car.center.z += speed; + } + + var carIndex = Outrun.gameWorld.road.findIndex(this.car.center.z); + var segment = Outrun.gameWorld.road.segments[carIndex]; + if (segment instanceof Segment) { + this.hasStopped = false; + this.lastSegment = segment; + if (Outrun.gameWorld.road.segments[carIndex - 1] instanceof Segment) { + this.curveDirection = segment.curve - Outrun.gameWorld.road.segments[carIndex - 1].curve; + } else { + this.curveDirection = 0; + this.shift += 1.5 * (this.chosenPath[this.chosenPath.length - 1] ? -1 : 1); + } + } else if (segment instanceof Junction) { + this.hasStopped = false; + if (Outrun.gameWorld.road.trackCount > this.chosenPath.length) { + this.chosenPath.push(this.car.center.x >= this.lastSegment.highCenter.x); + this.shift += 1.5 * (this.chosenPath[this.chosenPath.length - 1] ? -1 : 1); + } + if (this.chosenPath[this.chosenPath.length - 1]) { + segment = segment.rightJunction; + if (Outrun.gameWorld.road.segments[carIndex - 1] instanceof Junction) { + this.curveDirection = segment.curve - Outrun.gameWorld.road.segments[carIndex - 1].rightJunction.curve; + } else { + this.curveDirection = 0; + } + } else { + segment = segment.leftJunction; + if (Outrun.gameWorld.road.segments[carIndex - 1] instanceof Junction) { + this.curveDirection = segment.curve - Outrun.gameWorld.road.segments[carIndex - 1].leftJunction.curve; + } else { + this.curveDirection = 0; + } + } + } else { + this.hasStopped = true; + } + + this.car.center.x = segment.highCenter.x + this.shift * (laneWidth + lineWidth); + this.car.center.y = segment.highCenter.y; +} + +Vehicle.prototype.project = function () { + this.car.project(this.car.center.z - Driver.camera.position.z, dimensions[this.vehicleType]); + + if (this.curveDirection < 0) { + if (this.car.center.x < Driver.car.center.x) + this.car.fileName = 'left1'; + else + this.car.fileName = 'left0'; + } else if (this.curveDirection > 0) { + if (this.car.center.x > Driver.car.center.x) + this.car.fileName = 'right1'; + else + this.car.fileName = 'right0'; + } else { + if (this.car.center.x < Driver.car.center.x) { + this.car.fileName = 'right0'; + } else { + this.car.fileName = 'left0'; + } + } +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/main/WorldObject.js b/Games/OutRun_Offline_Game/main/WorldObject.js new file mode 100644 index 0000000000..ca9cdee988 --- /dev/null +++ b/Games/OutRun_Offline_Game/main/WorldObject.js @@ -0,0 +1,12 @@ +function WorldObject(center, fileName) { + this.center = center; + this.fileName = fileName; + this.relHeight = 0; + this.relWidth = 0; +} + +WorldObject.prototype.project = function (measure2) { + this.center.project(); + this.relWidth = Vector3.calculate(dimensions[Outrun.gameWorld.route][this.fileName].width, Driver.camera.gap, measure2); + this.relHeight = Vector3.calculate(dimensions[Outrun.gameWorld.route][this.fileName].height, Driver.camera.gap, measure2); +} \ No newline at end of file diff --git a/Games/OutRun_Offline_Game/style.css b/Games/OutRun_Offline_Game/style.css new file mode 100644 index 0000000000..8f3d69218f --- /dev/null +++ b/Games/OutRun_Offline_Game/style.css @@ -0,0 +1,17 @@ +html, body { + width: 100%; + height: 100%; + margin: 0; + background-color: #3d3d3d; +} + +canvas { + padding: 0; + margin: auto; + display: block; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} \ No newline at end of file diff --git a/README.md b/README.md index 9ab59ff0c0..06c603e536 100644 --- a/README.md +++ b/README.md @@ -818,7 +818,12 @@ This repository also provides one such platforms where contributers come over an |[Math_Race_Game](https://github.com/kunjgit/GameZone/tree/main/Games/Math_Race_Game)| | [Bunny is Lost](https://github.com/kunjgit/GameZone/tree/main/Games/Bunny_is_Lost)| |[Steam_Punk](https://github.com/kunjgit/GameZone/tree/main/Games/Steam_Punk)| + +|[OutRun_Offline_Game](https://github.com/kunjgit/GameZone/tree/main/Games/OutRun_Offline_Game)| +|[Tower Defence Game](https://github.com/Will2Jacks/GameZoneForked/tree/Task/Games/Tower_Defence_Game)| + | [Jigsaw_Puzzle](https://github.com/kunjgit/GameZone/tree/main/Games/Jigsaw_Puzzle) | + | [Mathematics Escape Room](https://github.com/kunjgit/GameZone/tree/main/Games/MathematicsEscapeRoom) | |[Tower Defence Game](https://github.com/Will2Jacks/GameZoneForked/tree/Task/Games/Tower_Defence_Game) | | [Ant Smasher Game](https://github.com/kunjgit/GameZone/tree/main/Games/Ant_Smasher)| |[Mario Matching Game](https://github.com/ananyag309/GameZone_ggsoc/tree/main/Games/MarioMatchingGame)| diff --git a/assets/images/Outrun.png b/assets/images/Outrun.png new file mode 100644 index 0000000000..de9810dfcd Binary files /dev/null and b/assets/images/Outrun.png differ