1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2026-03-02 03:39:21 +00:00

Add notifications when saving and new upgrades are available, minor improvements

This commit is contained in:
tobspr
2020-05-16 12:43:11 +02:00
parent 9f0435b51d
commit c1d720ca52
20 changed files with 183 additions and 43 deletions

View File

@@ -87,11 +87,6 @@ body {
// }
}
// Dirty hack
* {
@include TextShadow3DImpl;
}
img {
-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
}

View File

@@ -20,3 +20,10 @@ $upgrades: belt, miner, painting, processors;
background-image: uiResource("res/ui/upgrades/#{$upgrade}.png") !important;
}
}
$icons: notification_saved, notification_success, notification_upgrade;
@each $icon in $icons {
[data-icon="icons/#{$icon}.png"] {
background-image: uiResource("res/ui/icons/#{$icon}.png") !important;
}
}

View File

@@ -0,0 +1,44 @@
#ingame_HUD_Notifications {
position: absolute;
@include S(bottom, 60px);
@include S(right, 10px);
.notification {
background: rgba(#333438, 0.8);
@include S(border-radius, 2px);
@include S(margin-top, 3px);
color: #fff;
@include PlainText;
@include S(padding, 7px, 10px);
@include S(width, 200px);
&[data-icon] {
@include S(background-position-x, 8px);
background-position-y: center;
@include S(padding-left, 35px);
background-repeat: no-repeat;
@include S(background-size, 15px);
}
transform-origin: 100% 50%;
@include InlineAnimation(5s ease-in-out) {
0% {
opacity: 1;
}
87% {
opacity: 1;
transform: scale(1);
}
95% {
transform: scale(1.05);
}
100% {
opacity: 0;
transform: scale(0.5);
}
}
}
}

View File

@@ -36,11 +36,13 @@
@import "ingame_hud/vignette_overlay";
@import "ingame_hud/statistics";
@import "ingame_hud/pinned_shapes";
@import "ingame_hud/notifications";
// Z-Index
$elements: ingame_Canvas, ingame_VignetteOverlay, ingame_HUD_building_placer, ingame_HUD_PinnedShapes,
ingame_HUD_buildings_toolbar, ingame_HUD_GameMenu, ingame_HUD_KeybindingOverlay, ingame_HUD_Shop,
ingame_HUD_Statistics, ingame_HUD_BetaOverlay, ingame_HUD_MassSelector, ingame_HUD_UnlockNotification;
ingame_HUD_buildings_toolbar, ingame_HUD_GameMenu, ingame_HUD_KeybindingOverlay, ingame_HUD_Notifications,
ingame_HUD_Shop, ingame_HUD_Statistics, ingame_HUD_BetaOverlay, ingame_HUD_MassSelector,
ingame_HUD_UnlockNotification;
$zindex: 100;

View File

@@ -253,38 +253,9 @@ button,
}
@mixin TextShadow3D($color: rgb(222, 234, 238), $borderColor: #000) {
// @if $borderColor != #000 {
// @include TextShadow3DImpl($color: $color, $borderColor: $borderColor);
// }
color: $color;
}
@mixin TextShadow3DImpl(
$color: rgb(222, 234, 238),
$scale: 1,
$additionalShadowAlpha: 1,
$borderColor: #222428
) {
// color: $text3dColor;
$borderColor: rgba(15, 18, 23, 0.9);
// $shadowColor: darken($color, 40%);
$border: 0.07em;
$borderMid: $border * 1.14;
$drop1: $borderMid + 0.02;
$drop2: $borderMid + 0.06em;
// text-shadow: #{$border} #{$border} 0 $borderColor, #{-$border} #{$border} 0 $borderColor, #{$border} #{-$border} 0 $borderColor,
// #{-$border} #{-$border} 0 $borderColor, 0 #{$borderMid} 0 $borderColor, 0 #{-$borderMid} 0 $borderColor,
// #{$borderMid} 0 0 $borderColor, #{-$borderMid} 0 0 $borderColor, 0 #{$drop1} 0 $borderColor, #{$borderMid} #{$drop1} 0 $borderColor,
// #{-$borderMid} #{$drop1} 0 $borderColor, 0 #{$drop2} 0 $borderColor, #{$borderMid} #{$drop2} 0 $borderColor,
// #{-$borderMid} #{$drop2} 0 $borderColor, -0.2em 0.13em 0 rgba(#111, 0.25); // 0px 0.07em 0px $shadowColor,
// 0px 0.15em 0.09em rgba(#333539, $additionalShadowAlpha);;
}
// ----------------------------------------
/* Shine animation prefab, useful for buttons etc. Adds a bright shine which moves over
the button like a reflection. Performance heavy. */

View File

@@ -19,6 +19,7 @@ import { HUDStatistics } from "./parts/statistics";
import { MetaBuilding } from "../meta_building";
import { HUDPinnedShapes } from "./parts/pinned_shapes";
import { ShapeDefinition } from "../shape_definition";
import { HUDNotifications, enumNotificationType } from "./parts/notifications";
export class GameHUD {
/**
@@ -51,12 +52,15 @@ export class GameHUD {
pinnedShapes: new HUDPinnedShapes(this.root),
notifications: new HUDNotifications(this.root),
// betaOverlay: new HUDBetaOverlay(this.root),
};
this.signals = {
selectedPlacementBuildingChanged: /** @type {TypedSignal<[MetaBuilding|null]>} */ (new Signal()),
shapePinRequested: /** @type {TypedSignal<[ShapeDefinition, number]>} */ (new Signal()),
notification: /** @type {TypedSignal<[string, enumNotificationType]>} */ (new Signal()),
};
if (!IS_MOBILE) {

View File

@@ -1,6 +1,7 @@
import { BaseHUDPart } from "../base_hud_part";
import { makeDiv, randomInt } from "../../../core/utils";
import { SOUNDS } from "../../../platform/sound";
import { enumNotificationType } from "./notifications";
export class HUDGameMenu extends BaseHUDPart {
initialize() {}
@@ -14,6 +15,10 @@ export class HUDGameMenu extends BaseHUDPart {
handler: () => this.root.hud.parts.shop.show(),
keybinding: "menu_open_shop",
badge: () => this.root.hubGoals.getAvailableUpgradeCount(),
notification: /** @type {[string, enumNotificationType]} */ ([
"A new upgrade is available!",
enumNotificationType.upgrade,
]),
},
{
id: "stats",
@@ -23,10 +28,16 @@ export class HUDGameMenu extends BaseHUDPart {
},
];
/** @type {Array<{ badge: function, button: HTMLElement, badgeElement: HTMLElement, lastRenderAmount: number }>} */
/** @type {Array<{
* badge: function,
* button: HTMLElement,
* badgeElement: HTMLElement,
* lastRenderAmount: number,
* notification: [string, enumNotificationType]
* }>} */
this.badgesToUpdate = [];
buttons.forEach(({ id, label, handler, keybinding, badge }) => {
buttons.forEach(({ id, label, handler, keybinding, badge, notification }) => {
const button = document.createElement("button");
button.setAttribute("data-button-id", id);
this.element.appendChild(button);
@@ -45,6 +56,7 @@ export class HUDGameMenu extends BaseHUDPart {
lastRenderAmount: 0,
button,
badgeElement,
notification,
});
}
});
@@ -68,8 +80,9 @@ export class HUDGameMenu extends BaseHUDPart {
update() {
let playSound = false;
let notifications = new Set();
for (let i = 0; i < this.badgesToUpdate.length; ++i) {
const { badge, button, badgeElement, lastRenderAmount } = this.badgesToUpdate[i];
const { badge, button, badgeElement, lastRenderAmount, notification } = this.badgesToUpdate[i];
const amount = badge();
if (lastRenderAmount !== amount) {
if (amount > 0) {
@@ -78,6 +91,9 @@ export class HUDGameMenu extends BaseHUDPart {
// Check if the badge increased
if (amount > lastRenderAmount) {
playSound = true;
if (notification) {
notifications.add(notification);
}
}
this.badgesToUpdate[i].lastRenderAmount = amount;
button.classList.toggle("hasBadge", amount > 0);
@@ -87,6 +103,9 @@ export class HUDGameMenu extends BaseHUDPart {
if (playSound) {
this.root.soundProxy.playUi(SOUNDS.badgeNotification);
}
notifications.forEach(([notification, type]) => {
this.root.hud.signals.notification.dispatch(notification, type);
});
}
onGameSaved() {

View File

@@ -13,13 +13,18 @@ const logger = createLogger("hud/mass_selector");
export class HUDMassSelector extends BaseHUDPart {
createElements(parent) {
const removalKeybinding = this.root.gameState.keyActionMapper
.getBinding("confirm_mass_delete")
.getKeyCodeString();
const abortKeybinding = this.root.gameState.keyActionMapper.getBinding("back").getKeyCodeString();
this.element = makeDiv(
parent,
"ingame_HUD_MassSelector",
[],
`
Press <code class="keybinding">DEL</code> to remove selected buildings
and <code class="keybinding">ESC</code> to cancel.
Press <code class="keybinding">${removalKeybinding}</code> to remove selected buildings
and <code class="keybinding">${abortKeybinding}</code> to cancel.
`
);
}

View File

@@ -0,0 +1,52 @@
import { BaseHUDPart } from "../base_hud_part";
import { makeDiv } from "../../../core/utils";
/** @enum {string} */
export const enumNotificationType = {
saved: "saved",
upgrade: "upgrade",
success: "success",
};
export class HUDNotifications extends BaseHUDPart {
createElements(parent) {
this.element = makeDiv(parent, "ingame_HUD_Notifications", [], ``);
}
initialize() {
this.root.hud.signals.notification.add(this.onNotification, this);
/** @type {Array<{ element: HTMLElement, expireAt: number}>} */
this.notificationElements = [];
// Automatic notifications
this.root.signals.gameSaved.add(() =>
this.onNotification("Your game has been saved.", enumNotificationType.saved)
);
}
/**
* @param {string} message
* @param {enumNotificationType} type
*/
onNotification(message, type) {
const element = makeDiv(this.element, null, ["notification", "type-" + type], message);
element.setAttribute("data-icon", "icons/notification_" + type + ".png");
this.notificationElements.push({
element,
expireAt: this.root.time.realtimeNow() + 5,
});
}
update() {
const now = this.root.time.realtimeNow();
for (let i = 0; i < this.notificationElements.length; ++i) {
const handle = this.notificationElements[i];
if (handle.expireAt <= now) {
handle.element.remove();
this.notificationElements.splice(i, 1);
}
}
}
}

View File

@@ -29,7 +29,7 @@ export const defaultKeybindings = {
menu_open_shop: { keyCode: key("F") },
menu_open_stats: { keyCode: key("G") },
confirm_mass_delete: { keyCode: 46 }, // DEL
confirm_mass_delete: { keyCode: key("X") }, // DEL
toggle_hud: { keyCode: 113 }, // F2
},

View File