mirror of
				https://github.com/tobspr/shapez.io.git
				synced 2025-06-13 13:04:03 +00:00 
			
		
		
		
	Initial support for themes, sound improvements
This commit is contained in:
		
							parent
							
								
									80ce2e1902
								
							
						
					
					
						commit
						709ff506c9
					
				| @ -9,7 +9,7 @@ function gulptasksSounds($, gulp, buildFolder) { | ||||
|         return gulp.src(builtSoundsDir).pipe($.clean({ force: true })); | ||||
|     }); | ||||
| 
 | ||||
|     const filters = ["loudnorm", "volume=0.2"]; | ||||
|     const filters = ["volume=0.2"]; | ||||
| 
 | ||||
|     const fileCache = new $.cache.Cache({ | ||||
|         cacheDirName: "shapezio-precompiled-sounds", | ||||
| @ -27,8 +27,8 @@ function gulptasksSounds($, gulp, buildFolder) { | ||||
|                             .audioBitrate(48) | ||||
|                             .audioChannels(1) | ||||
|                             .audioFrequency(22050) | ||||
|                             .audioCodec("libmp3lame"); | ||||
|                         // .audioFilters(["volume=0.25"])
 | ||||
|                             .audioCodec("libmp3lame") | ||||
|                             .audioFilters(["volume=0.3"]); | ||||
|                     }), | ||||
|                     { | ||||
|                         name: "music", | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								res_raw/sounds/music/menu.mp3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								res_raw/sounds/music/menu.mp3
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										3
									
								
								res_raw/sounds/ui/badge_notification.wav
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								res_raw/sounds/ui/badge_notification.wav
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| version https://git-lfs.github.com/spec/v1 | ||||
| oid sha256:dba7e859fb98713943890281a543e209d57c6633496090bd70d23dc58bed4405 | ||||
| size 743136 | ||||
| @ -37,7 +37,7 @@ export const globalConfig = { | ||||
| 
 | ||||
|     // Belt speeds
 | ||||
|     // NOTICE: Update webpack.production.config too!
 | ||||
|     beltSpeedItemsPerSecond: 1, | ||||
|     beltSpeedItemsPerSecond: 10, | ||||
|     itemSpacingOnBelts: 0.63, | ||||
|     minerSpeedItemsPerSecond: 0, // COMPUTED
 | ||||
| 
 | ||||
| @ -71,7 +71,7 @@ export const globalConfig = { | ||||
| 
 | ||||
|     debug: { | ||||
|         /* dev:start */ | ||||
|         // fastGameEnter: true,
 | ||||
|         fastGameEnter: true, | ||||
|         noArtificialDelays: true, | ||||
|         // disableSavegameWrite: true,
 | ||||
|         showEntityBounds: false, | ||||
|  | ||||
| @ -252,7 +252,7 @@ export class GameState { | ||||
|      * @returns {string|null} | ||||
|      */ | ||||
|     getThemeMusic() { | ||||
|         return null; | ||||
|         return MUSIC.menu; | ||||
|     } | ||||
| 
 | ||||
|     ////////////////////
 | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| import { DrawParameters } from "../core/draw_parameters"; | ||||
| import { BasicSerializableObject, types } from "../savegame/serialization"; | ||||
| import { THEME } from "./theme"; | ||||
| 
 | ||||
| /** | ||||
|  * Class for items on belts etc. Not an entity for performance reasons | ||||
| @ -28,6 +29,6 @@ export class BaseItem extends BasicSerializableObject { | ||||
|     draw(x, y, parameters, size) {} | ||||
| 
 | ||||
|     getBackgroundColorAsResource() { | ||||
|         return "#eaebec"; | ||||
|         abstract; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| import { BaseHUDPart } from "../base_hud_part"; | ||||
| import { makeDiv, randomInt } from "../../../core/utils"; | ||||
| import { SOUNDS } from "../../../platform/sound"; | ||||
| 
 | ||||
| export class HUDGameMenu extends BaseHUDPart { | ||||
|     initialize() {} | ||||
| @ -60,12 +61,13 @@ export class HUDGameMenu extends BaseHUDPart { | ||||
|         this.trackClicks(this.saveButton, this.startSave); | ||||
| 
 | ||||
|         this.musicButton.classList.toggle("muted", this.root.app.settings.getAllSettings().musicMuted); | ||||
|         this.sfxButton.classList.toggle("muted", this.root.app.settings.getAllSettings().musicMuted); | ||||
|         this.sfxButton.classList.toggle("muted", this.root.app.settings.getAllSettings().soundsMuted); | ||||
| 
 | ||||
|         this.root.signals.gameSaved.add(this.onGameSaved, this); | ||||
|     } | ||||
| 
 | ||||
|     update() { | ||||
|         let playSound = false; | ||||
|         for (let i = 0; i < this.badgesToUpdate.length; ++i) { | ||||
|             const { badge, button, badgeElement, lastRenderAmount } = this.badgesToUpdate[i]; | ||||
|             const amount = badge(); | ||||
| @ -73,10 +75,18 @@ export class HUDGameMenu extends BaseHUDPart { | ||||
|                 if (amount > 0) { | ||||
|                     badgeElement.innerText = amount; | ||||
|                 } | ||||
|                 // Check if the badge increased
 | ||||
|                 if (amount > lastRenderAmount) { | ||||
|                     playSound = true; | ||||
|                 } | ||||
|                 this.badgesToUpdate[i].lastRenderAmount = amount; | ||||
|                 button.classList.toggle("hasBadge", amount > 0); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (playSound) { | ||||
|             this.root.soundProxy.playUi(SOUNDS.badgeNotification); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     onGameSaved() { | ||||
|  | ||||
| @ -4,13 +4,7 @@ import { DrawParameters } from "../../core/draw_parameters"; | ||||
| import { types } from "../../savegame/serialization"; | ||||
| import { BaseItem } from "../base_item"; | ||||
| import { enumColors, enumColorsToHexCode } from "../colors"; | ||||
| 
 | ||||
| /** @enum {string} */ | ||||
| const enumColorToMapBackground = { | ||||
|     [enumColors.red]: "#ffbfc1", | ||||
|     [enumColors.green]: "#cbffc4", | ||||
|     [enumColors.blue]: "#bfdaff", | ||||
| }; | ||||
| import { THEME } from "../theme"; | ||||
| 
 | ||||
| export class ColorItem extends BaseItem { | ||||
|     static getId() { | ||||
| @ -39,7 +33,7 @@ export class ColorItem extends BaseItem { | ||||
|     } | ||||
| 
 | ||||
|     getBackgroundColorAsResource() { | ||||
|         return enumColorToMapBackground[this.color]; | ||||
|         return THEME.map.resources[this.color]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -75,8 +69,8 @@ export class ColorItem extends BaseItem { | ||||
|         context.scale((dpi * w) / 12, (dpi * h) / 12); | ||||
| 
 | ||||
|         context.fillStyle = enumColorsToHexCode[this.color]; | ||||
|         context.strokeStyle = "rgba(100,102, 110, 1)"; | ||||
|         context.lineWidth = 2; | ||||
|         context.strokeStyle = THEME.items.outline; | ||||
|         context.lineWidth = 2 * THEME.items.outlineWidth; | ||||
|         context.beginCircle(2, -1, 3); | ||||
|         context.stroke(); | ||||
|         context.fill(); | ||||
|  | ||||
| @ -2,6 +2,7 @@ import { DrawParameters } from "../../core/draw_parameters"; | ||||
| import { types } from "../../savegame/serialization"; | ||||
| import { BaseItem } from "../base_item"; | ||||
| import { ShapeDefinition } from "../shape_definition"; | ||||
| import { THEME } from "../theme"; | ||||
| 
 | ||||
| export class ShapeItem extends BaseItem { | ||||
|     static getId() { | ||||
| @ -33,6 +34,10 @@ export class ShapeItem extends BaseItem { | ||||
|         this.definition = definition; | ||||
|     } | ||||
| 
 | ||||
|     getBackgroundColorAsResource() { | ||||
|         return THEME.map.resources.shape; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param {number} x | ||||
|      * @param {number} y | ||||
|  | ||||
| @ -4,6 +4,7 @@ import { DrawParameters } from "../core/draw_parameters"; | ||||
| import { BaseMap } from "./map"; | ||||
| import { freeCanvas, makeOffscreenBuffer } from "../core/buffer_utils"; | ||||
| import { Entity } from "./entity"; | ||||
| import { THEME } from "./theme"; | ||||
| 
 | ||||
| /** | ||||
|  * This is the view of the map, it extends the map which is the raw model and allows | ||||
| @ -16,7 +17,7 @@ export class MapView extends BaseMap { | ||||
|         /** | ||||
|          * DPI of the background cache images, required in some places | ||||
|          */ | ||||
|         this.backgroundCacheDPI = 4; | ||||
|         this.backgroundCacheDPI = 2; | ||||
| 
 | ||||
|         /** | ||||
|          * The cached background sprite, containing the flat background | ||||
| @ -109,14 +110,16 @@ export class MapView extends BaseMap { | ||||
|         }); | ||||
|         context.scale(dpi, dpi); | ||||
| 
 | ||||
|         context.fillStyle = "#fff"; | ||||
|         context.fillStyle = THEME.map.background; | ||||
|         context.fillRect(0, 0, dims, dims); | ||||
| 
 | ||||
|         context.fillStyle = "#fafafa"; | ||||
|         context.fillRect(0, 0, dims, 1); | ||||
|         context.fillRect(0, 0, 1, dims); | ||||
|         context.fillRect(dims - 1, 0, 1, dims); | ||||
|         context.fillRect(0, dims - 1, dims, 1); | ||||
|         const borderWidth = THEME.map.gridLineWidth; | ||||
|         context.fillStyle = THEME.map.grid; | ||||
|         context.fillRect(0, 0, dims, borderWidth); | ||||
|         context.fillRect(0, borderWidth, borderWidth, dims); | ||||
| 
 | ||||
|         context.fillRect(dims - borderWidth, borderWidth, borderWidth, dims - 2 * borderWidth); | ||||
|         context.fillRect(borderWidth, dims - borderWidth, dims, borderWidth); | ||||
| 
 | ||||
|         this.cachedBackgroundCanvas = canvas; | ||||
|         this.cachedBackgroundContext = context; | ||||
|  | ||||
| @ -7,6 +7,7 @@ import { createLogger } from "../core/logging"; | ||||
| import { Vector } from "../core/vector"; | ||||
| import { BasicSerializableObject, types } from "../savegame/serialization"; | ||||
| import { enumColors, enumColorsToHexCode, enumColorToShortcode, enumShortcodeToColor } from "./colors"; | ||||
| import { THEME } from "./theme"; | ||||
| 
 | ||||
| const rusha = require("rusha"); | ||||
| 
 | ||||
| @ -274,8 +275,8 @@ export class ShapeDefinition extends BasicSerializableObject { | ||||
|                 context.rotate(rotation); | ||||
| 
 | ||||
|                 context.fillStyle = enumColorsToHexCode[color]; | ||||
|                 context.strokeStyle = "#555"; | ||||
|                 context.lineWidth = 1; | ||||
|                 context.strokeStyle = THEME.items.outline; | ||||
|                 context.lineWidth = THEME.items.outlineWidth; | ||||
| 
 | ||||
|                 const insetPadding = 0.0; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										7
									
								
								src/js/game/theme.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/js/game/theme.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| export const THEMES = { | ||||
|     dark: require("./themes/dark.json"), | ||||
|     light: require("./themes/light.json"), | ||||
| }; | ||||
| 
 | ||||
| // TODO: Make themes customizable
 | ||||
| export const THEME = THEMES.light; | ||||
							
								
								
									
										20
									
								
								src/js/game/themes/dark.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/js/game/themes/dark.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| { | ||||
|     "uiStyle": "dark", | ||||
|     "map": { | ||||
|         "background": "#2e2f37", | ||||
|         "grid": "rgba(255, 255, 255, 0.02)", | ||||
|         "gridLineWidth": 0.5, | ||||
| 
 | ||||
|         "resources": { | ||||
|             "shape": "#3d3f4a", | ||||
|             "red": "#4a3d3f", | ||||
|             "green": "#3e4a3d", | ||||
|             "blue": "#35384a" | ||||
|         } | ||||
|     }, | ||||
| 
 | ||||
|     "items": { | ||||
|         "outline": "#111418", | ||||
|         "outlineWidth": 0.75 | ||||
|     } | ||||
| } | ||||
							
								
								
									
										20
									
								
								src/js/game/themes/light.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/js/game/themes/light.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| { | ||||
|     "uiStyle": "light", | ||||
|     "map": { | ||||
|         "background": "#fff", | ||||
|         "grid": "#fafafa", | ||||
|         "gridLineWidth": 1, | ||||
| 
 | ||||
|         "resources": { | ||||
|             "shape": "#eaebec", | ||||
|             "red": "#ffbfc1", | ||||
|             "green": "#cbffc4", | ||||
|             "blue": "#bfdaff" | ||||
|         } | ||||
|     }, | ||||
| 
 | ||||
|     "items": { | ||||
|         "outline": "#55575a", | ||||
|         "outlineWidth": 0.75 | ||||
|     } | ||||
| } | ||||
| @ -74,10 +74,17 @@ class MusicInstance extends MusicInstanceInterface { | ||||
|                     autoplay: false, | ||||
|                     loop: true, | ||||
|                     html5: true, | ||||
|                     volume: 0.3, | ||||
|                     volume: 1, | ||||
|                     preload: true, | ||||
|                     pool: 2, | ||||
| 
 | ||||
|                     onunlock: () => { | ||||
|                         if (this.playing) { | ||||
|                             logger.log("Playing music after manual unlock"); | ||||
|                             this.play(); | ||||
|                         } | ||||
|                     }, | ||||
| 
 | ||||
|                     onload: () => { | ||||
|                         resolve(); | ||||
|                     }, | ||||
|  | ||||
| @ -18,6 +18,7 @@ export const SOUNDS = { | ||||
|     dialogOk: "ui/dialog_ok.mp3", | ||||
|     swishHide: "ui/ui_swish_hide.mp3", | ||||
|     swishShow: "ui/ui_swish_show.mp3", | ||||
|     badgeNotification: "ui/badge_notification.mp3", | ||||
| 
 | ||||
|     levelComplete: "ui/level_complete.mp3", | ||||
| 
 | ||||
| @ -27,6 +28,7 @@ export const SOUNDS = { | ||||
| 
 | ||||
| export const MUSIC = { | ||||
|     theme: "theme.mp3", | ||||
|     menu: "menu.mp3", | ||||
| }; | ||||
| 
 | ||||
| export class SoundInstanceInterface { | ||||
|  | ||||
| @ -6,6 +6,7 @@ import { ReadWriteProxy } from "../core/read_write_proxy"; | ||||
| import { BoolSetting, EnumSetting, BaseSetting } from "./setting_types"; | ||||
| import { createLogger } from "../core/logging"; | ||||
| import { ExplainedResult } from "../core/explained_result"; | ||||
| import { THEMES } from "../game/theme"; | ||||
| 
 | ||||
| const logger = createLogger("application_settings"); | ||||
| 
 | ||||
| @ -67,6 +68,18 @@ export const allApplicationSettings = [ | ||||
|         }, | ||||
|         G_IS_STANDALONE | ||||
|     ), | ||||
|     new EnumSetting("theme", { | ||||
|         options: Object.keys(THEMES), | ||||
|         valueGetter: theme => theme, | ||||
|         textGetter: theme => theme.substr(0, 1).toUpperCase() + theme.substr(1), | ||||
|         category: categoryApp, | ||||
|         restartRequired: false, | ||||
|         changeCb: | ||||
|             /** | ||||
|              * @param {Application} app | ||||
|              */ | ||||
|             (app, id) => document.body.setAttribute("data-theme", id), | ||||
|     }), | ||||
|     new BoolSetting( | ||||
|         "soundsMuted", | ||||
|         categoryApp, | ||||
| @ -100,6 +113,7 @@ class SettingsStorage { | ||||
| 
 | ||||
|         this.soundsMuted = false; | ||||
|         this.musicMuted = false; | ||||
|         this.theme = "light"; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -110,7 +124,17 @@ export class ApplicationSettings extends ReadWriteProxy { | ||||
| 
 | ||||
|     initialize() { | ||||
|         // Read and directly write latest data back
 | ||||
|         return this.readAsync().then(() => this.writeAsync()); | ||||
|         return this.readAsync() | ||||
|             .then(() => { | ||||
|                 // Apply default setting callbacks
 | ||||
|                 const settings = this.getAllSettings(); | ||||
|                 for (let i = 0; i < allApplicationSettings.length; ++i) { | ||||
|                     const handle = allApplicationSettings[i]; | ||||
|                     handle.apply(this.app, settings[handle.id]); | ||||
|                 } | ||||
|             }) | ||||
| 
 | ||||
|             .then(() => this.writeAsync()); | ||||
|     } | ||||
| 
 | ||||
|     save() { | ||||
| @ -208,7 +232,7 @@ export class ApplicationSettings extends ReadWriteProxy { | ||||
|     } | ||||
| 
 | ||||
|     getCurrentVersion() { | ||||
|         return 2; | ||||
|         return 3; | ||||
|     } | ||||
| 
 | ||||
|     migrate(data) { | ||||
|  | ||||
| @ -27,6 +27,16 @@ export class BaseSetting { | ||||
|         this.dialogs = null; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param {Application} app | ||||
|      * @param {any} value | ||||
|      */ | ||||
|     apply(app, value) { | ||||
|         if (this.changeCb) { | ||||
|             this.changeCb(app, value); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param {Application} app | ||||
|      * @param {Element} element | ||||
|  | ||||
| @ -99,17 +99,6 @@ export class PreloadState extends GameState { | ||||
|             .then(() => { | ||||
|                 return this.app.settings.initialize(); | ||||
|             }) | ||||
|             .then(() => { | ||||
|                 // Make sure the app pickups the right size
 | ||||
|                 this.app.updateAfterUiScaleChanged(); | ||||
|             }) | ||||
| 
 | ||||
|             .then(() => { | ||||
|                 // Initialize fullscreen
 | ||||
|                 if (this.app.platformWrapper.getSupportsFullscreen()) { | ||||
|                     this.app.platformWrapper.setFullscreen(this.app.settings.getIsFullScreen()); | ||||
|                 } | ||||
|             }) | ||||
| 
 | ||||
|             .then(() => this.setStatus("Initializing sounds")) | ||||
|             .then(() => { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 tobspr
						tobspr