mirror of
https://github.com/tobspr-games/shapez.io.git
synced 2025-12-28 04:41:39 -08:00
Improve unlock notification
This commit is contained in:
parent
3178974d78
commit
dc6c20b8f0
11 changed files with 226 additions and 102 deletions
|
|
@ -9,6 +9,7 @@
|
|||
justify-content: center;
|
||||
align-items: center;
|
||||
pointer-events: all;
|
||||
|
||||
@include InlineAnimation(0.1s ease-in-out) {
|
||||
0% {
|
||||
opacity: 0;
|
||||
|
|
@ -16,7 +17,7 @@
|
|||
}
|
||||
|
||||
.dialog {
|
||||
background: rgba(#222428, 0.5);
|
||||
// background: rgba(#222428, 0.5);
|
||||
@include S(border-radius, $globalBorderRadius);
|
||||
@include S(padding, 30px);
|
||||
|
||||
|
|
@ -32,7 +33,7 @@
|
|||
.subTitle {
|
||||
@include SuperHeading;
|
||||
text-transform: uppercase;
|
||||
@include S(font-size, 50px);
|
||||
@include S(font-size, 40px);
|
||||
|
||||
@include InlineAnimation(0.5s ease-in-out) {
|
||||
0% {
|
||||
|
|
@ -48,11 +49,10 @@
|
|||
}
|
||||
|
||||
.subTitle {
|
||||
@include Heading;
|
||||
background: $colorGreenBright;
|
||||
@include PlainText;
|
||||
display: inline-block;
|
||||
@include S(padding, 1px, 6px);
|
||||
@include S(margin, 20px, 0, 20px);
|
||||
@include S(margin, 0px, 0, 20px);
|
||||
color: $colorGreenBright;
|
||||
|
||||
@include S(border-radius, $globalBorderRadius);
|
||||
@include InlineAnimation(0.5s ease-in-out) {
|
||||
|
|
@ -82,14 +82,15 @@
|
|||
transform: translateX(-2vw);
|
||||
}
|
||||
}
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@include S(grid-gap, 10px);
|
||||
|
||||
.reward {
|
||||
.rewardName {
|
||||
grid-column: 1 / 3;
|
||||
display: none;
|
||||
@include InlineAnimation(0.5s ease-in-out) {
|
||||
0% {
|
||||
transform: translateX(200vw);
|
||||
|
|
@ -104,29 +105,63 @@
|
|||
}
|
||||
}
|
||||
|
||||
.buildingExplanation {
|
||||
@include S(width, 200px);
|
||||
@include S(height, 200px);
|
||||
display: inline-block;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
@include S(border-radius, $globalBorderRadius);
|
||||
box-shadow: #{D(2px)} #{D(3px)} 0 0 rgba(0, 0, 0, 0.15);
|
||||
.rewardDesc {
|
||||
grid-column: 1 / 3;
|
||||
@include PlainText;
|
||||
@include S(margin-bottom, 15px);
|
||||
color: #aaacaf;
|
||||
@include S(width, 400px);
|
||||
text-align: left;
|
||||
strong {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.images {
|
||||
display: flex;
|
||||
.buildingExplanation {
|
||||
@include S(width, 200px);
|
||||
@include S(height, 200px);
|
||||
display: inline-block;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
@include S(border-radius, $globalBorderRadius);
|
||||
box-shadow: #{D(2px)} #{D(3px)} 0 0 rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button.close {
|
||||
border: 0;
|
||||
@include InlineAnimation(2s ease-in-out) {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
95% {
|
||||
opacity: 0;
|
||||
position: relative;
|
||||
@include S(margin-top, 30px);
|
||||
|
||||
&:not(.unlocked) {
|
||||
pointer-events: none;
|
||||
opacity: 0.8;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: " ";
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 100%;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 10, 20, 0.8);
|
||||
|
||||
@include InlineAnimation(10s linear) {
|
||||
0% {
|
||||
left: 0;
|
||||
}
|
||||
100% {
|
||||
left: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@include S(margin-top, 30px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,18 +2,11 @@ import { globalConfig } from "../../../core/config";
|
|||
import { gMetaBuildingRegistry } from "../../../core/global_registries";
|
||||
import { makeDiv } from "../../../core/utils";
|
||||
import { SOUNDS } from "../../../platform/sound";
|
||||
import { MetaCutterBuilding } from "../../buildings/cutter";
|
||||
import { MetaMixerBuilding } from "../../buildings/mixer";
|
||||
import { MetaPainterBuilding } from "../../buildings/painter";
|
||||
import { MetaRotaterBuilding } from "../../buildings/rotater";
|
||||
import { MetaSplitterBuilding } from "../../buildings/splitter";
|
||||
import { MetaStackerBuilding } from "../../buildings/stacker";
|
||||
import { MetaTrashBuilding } from "../../buildings/trash";
|
||||
import { MetaUndergroundBeltBuilding } from "../../buildings/underground_belt";
|
||||
import { enumHubGoalRewards } from "../../tutorial_goals";
|
||||
import { T } from "../../../translations";
|
||||
import { defaultBuildingVariant } from "../../meta_building";
|
||||
import { enumHubGoalRewards, enumHubGoalRewardsToContentUnlocked } from "../../tutorial_goals";
|
||||
import { BaseHUDPart } from "../base_hud_part";
|
||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||
import { T } from "../../../translations";
|
||||
|
||||
export class HUDUnlockNotification extends BaseHUDPart {
|
||||
initialize() {
|
||||
|
|
@ -26,6 +19,8 @@ export class HUDUnlockNotification extends BaseHUDPart {
|
|||
if (!(G_IS_DEV && globalConfig.debug.disableUnlockDialog)) {
|
||||
this.root.signals.storyGoalCompleted.add(this.showForLevel, this);
|
||||
}
|
||||
|
||||
this.buttonShowTimeout = null;
|
||||
}
|
||||
|
||||
shouldPauseGame() {
|
||||
|
|
@ -60,63 +55,50 @@ export class HUDUnlockNotification extends BaseHUDPart {
|
|||
("" + level).padStart(2, "0")
|
||||
);
|
||||
|
||||
const rewardText = T.storyRewards[reward];
|
||||
const rewardName = T.storyRewards[reward].title;
|
||||
|
||||
let html =
|
||||
"<span class='reward'>" +
|
||||
T.ingame.levelCompleteNotification.unlockText.replace("<reward>", rewardText) +
|
||||
"</span>";
|
||||
let html = `
|
||||
<div class="rewardName">
|
||||
${T.ingame.levelCompleteNotification.unlockText.replace("<reward>", rewardName)}
|
||||
</div>
|
||||
|
||||
<div class="rewardDesc">
|
||||
${T.storyRewards[reward].desc}
|
||||
</div>
|
||||
|
||||
const addBuildingExplanation = metaBuildingClass => {
|
||||
const metaBuilding = gMetaBuildingRegistry.findByClass(metaBuildingClass);
|
||||
html += `<div class="buildingExplanation" data-icon="building_tutorials/${metaBuilding.getId()}.png"></div>`;
|
||||
};
|
||||
`;
|
||||
|
||||
switch (reward) {
|
||||
case enumHubGoalRewards.reward_cutter_and_trash: {
|
||||
addBuildingExplanation(MetaCutterBuilding);
|
||||
addBuildingExplanation(MetaTrashBuilding);
|
||||
break;
|
||||
}
|
||||
case enumHubGoalRewards.reward_mixer: {
|
||||
addBuildingExplanation(MetaMixerBuilding);
|
||||
break;
|
||||
}
|
||||
|
||||
case enumHubGoalRewards.reward_painter: {
|
||||
addBuildingExplanation(MetaPainterBuilding);
|
||||
break;
|
||||
}
|
||||
|
||||
case enumHubGoalRewards.reward_rotater: {
|
||||
addBuildingExplanation(MetaRotaterBuilding);
|
||||
break;
|
||||
}
|
||||
|
||||
case enumHubGoalRewards.reward_splitter: {
|
||||
addBuildingExplanation(MetaSplitterBuilding);
|
||||
break;
|
||||
}
|
||||
|
||||
case enumHubGoalRewards.reward_stacker: {
|
||||
addBuildingExplanation(MetaStackerBuilding);
|
||||
break;
|
||||
}
|
||||
|
||||
case enumHubGoalRewards.reward_tunnel: {
|
||||
addBuildingExplanation(MetaUndergroundBeltBuilding);
|
||||
break;
|
||||
}
|
||||
html += "<div class='images'>";
|
||||
const gained = enumHubGoalRewardsToContentUnlocked[reward];
|
||||
if (gained) {
|
||||
gained.forEach(([metaBuildingClass, variant]) => {
|
||||
const metaBuilding = gMetaBuildingRegistry.findByClass(metaBuildingClass);
|
||||
html += `<div class="buildingExplanation" data-icon="building_tutorials/${
|
||||
metaBuilding.getId() + (variant === defaultBuildingVariant ? "" : "-" + variant)
|
||||
}.png"></div>`;
|
||||
});
|
||||
}
|
||||
|
||||
// addBuildingExplanation(MetaSplitterBuilding);
|
||||
// addBuildingExplanation(MetaCutterBuilding);
|
||||
html += "</div>";
|
||||
|
||||
this.elemContents.innerHTML = html;
|
||||
|
||||
this.visible = true;
|
||||
|
||||
this.root.soundProxy.playUi(SOUNDS.levelComplete);
|
||||
|
||||
if (this.buttonShowTimeout) {
|
||||
clearTimeout(this.buttonShowTimeout);
|
||||
}
|
||||
|
||||
this.buttonShowTimeout = setTimeout(
|
||||
() => this.element.querySelector("button.close").classList.add("unlocked"),
|
||||
G_IS_DEV ? 1000 : 10000
|
||||
);
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
if (this.buttonShowTimeout) {
|
||||
clearTimeout(this.buttonShowTimeout);
|
||||
this.buttonShowTimeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
requestClose() {
|
||||
|
|
@ -126,10 +108,18 @@ export class HUDUnlockNotification extends BaseHUDPart {
|
|||
}
|
||||
|
||||
close() {
|
||||
if (this.buttonShowTimeout) {
|
||||
clearTimeout(this.buttonShowTimeout);
|
||||
this.buttonShowTimeout = null;
|
||||
}
|
||||
this.visible = false;
|
||||
}
|
||||
|
||||
update() {
|
||||
this.domAttach.update(this.visible);
|
||||
if (!this.visible && this.buttonShowTimeout) {
|
||||
clearTimeout(this.buttonShowTimeout);
|
||||
this.buttonShowTimeout = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ export class HubSystem extends GameSystemWithFilter {
|
|||
context.font = "bold 11px GameFont";
|
||||
context.fillStyle = "#fd0752";
|
||||
context.textAlign = "center";
|
||||
context.fillText(T.storyRewards[goals.reward].toUpperCase(), pos.x, pos.y + 46);
|
||||
context.fillText(T.storyRewards[goals.reward].title.toUpperCase(), pos.x, pos.y + 46);
|
||||
|
||||
// Level
|
||||
context.font = "bold 11px GameFont";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,18 @@
|
|||
import { ShapeDefinition } from "./shape_definition";
|
||||
import { finalGameShape } from "./upgrades";
|
||||
import { MetaBuilding, defaultBuildingVariant } from "./meta_building";
|
||||
import { MetaCutterBuilding, enumCutterVariants } from "./buildings/cutter";
|
||||
import { MetaRotaterBuilding, enumRotaterVariants } from "./buildings/rotater";
|
||||
import { MetaPainterBuilding, enumPainterVariants } from "./buildings/painter";
|
||||
import { MetaMixerBuilding } from "./buildings/mixer";
|
||||
import { MetaStackerBuilding } from "./buildings/stacker";
|
||||
import { MetaSplitterBuilding, enumSplitterVariants } from "./buildings/splitter";
|
||||
import { MetaUndergroundBeltBuilding, enumUndergroundBeltVariants } from "./buildings/underground_belt";
|
||||
import { MetaMinerBuilding, enumMinerVariants } from "./buildings/miner";
|
||||
import { MetaTrashBuilding, enumTrashVariants } from "./buildings/trash";
|
||||
|
||||
/**
|
||||
* Don't forget to also update unlock_notification.js as well as the translations!
|
||||
* @enum {string}
|
||||
*/
|
||||
export const enumHubGoalRewards = {
|
||||
|
|
@ -27,6 +38,44 @@ export const enumHubGoalRewards = {
|
|||
no_reward: "no_reward",
|
||||
};
|
||||
|
||||
/** @typedef {Array<[typeof MetaBuilding, string]>} TutorialGoalReward */
|
||||
|
||||
/**
|
||||
* Helper method for proper types
|
||||
* @returns {TutorialGoalReward}
|
||||
*/
|
||||
const typed = x => x;
|
||||
|
||||
/**
|
||||
* Stores which reward unlocks what
|
||||
* @enum {TutorialGoalReward?}
|
||||
*/
|
||||
export const enumHubGoalRewardsToContentUnlocked = {
|
||||
[enumHubGoalRewards.reward_cutter_and_trash]: typed([[MetaCutterBuilding, defaultBuildingVariant]]),
|
||||
[enumHubGoalRewards.reward_rotater]: typed([[MetaRotaterBuilding, defaultBuildingVariant]]),
|
||||
[enumHubGoalRewards.reward_painter]: typed([[MetaPainterBuilding, defaultBuildingVariant]]),
|
||||
[enumHubGoalRewards.reward_mixer]: typed([[MetaMixerBuilding, defaultBuildingVariant]]),
|
||||
[enumHubGoalRewards.reward_stacker]: typed([[MetaStackerBuilding, defaultBuildingVariant]]),
|
||||
[enumHubGoalRewards.reward_splitter]: typed([[MetaSplitterBuilding, defaultBuildingVariant]]),
|
||||
[enumHubGoalRewards.reward_tunnel]: typed([[MetaUndergroundBeltBuilding, defaultBuildingVariant]]),
|
||||
|
||||
[enumHubGoalRewards.reward_rotater_ccw]: typed([[MetaRotaterBuilding, enumRotaterVariants.ccw]]),
|
||||
[enumHubGoalRewards.reward_miner_chainable]: typed([[MetaMinerBuilding, enumMinerVariants.chainable]]),
|
||||
[enumHubGoalRewards.reward_underground_belt_tier_2]: typed([
|
||||
[MetaUndergroundBeltBuilding, enumUndergroundBeltVariants.tier2],
|
||||
]),
|
||||
[enumHubGoalRewards.reward_splitter_compact]: typed([
|
||||
[MetaSplitterBuilding, enumSplitterVariants.compact],
|
||||
]),
|
||||
[enumHubGoalRewards.reward_cutter_quad]: typed([[MetaCutterBuilding, enumCutterVariants.quad]]),
|
||||
[enumHubGoalRewards.reward_painter_double]: typed([[MetaPainterBuilding, enumPainterVariants.double]]),
|
||||
[enumHubGoalRewards.reward_painter_quad]: typed([[MetaPainterBuilding, enumPainterVariants.quad]]),
|
||||
[enumHubGoalRewards.reward_storage]: typed([[MetaTrashBuilding, enumTrashVariants.storage]]),
|
||||
|
||||
[enumHubGoalRewards.reward_freeplay]: null,
|
||||
[enumHubGoalRewards.no_reward]: null,
|
||||
};
|
||||
|
||||
export const tutorialGoals = [
|
||||
// Circle
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue