Improve unlock notification

This commit is contained in:
tobspr 2020-05-23 10:30:54 +02:00
parent 3178974d78
commit dc6c20b8f0
11 changed files with 226 additions and 102 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}

View File

@ -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";

View File

@ -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
{

View File

@ -352,27 +352,77 @@ buildings:
storyRewards:
# Those are the rewards gained from completing the store
reward_cutter_and_trash: Cutting Shapes
reward_rotater: Rotating
reward_painter: Painting
reward_mixer: Color Mixing
reward_stacker: Combiner
reward_splitter: Splitter/Merger
reward_tunnel: Tunnel
reward_cutter_and_trash:
title: Cutting Shapes
desc: You just unlocked the <strong>cutter</strong> - it cuts shapes half from <strong>top to bottom</strong> regardless of its orientation!<br><br>Be sure to get rid of the waste, or otherwise <strong>it will stall</strong> - For this purpose I gave you a trash, which destroys everything you put into it!
reward_rotater_ccw: CCW Rotating
reward_miner_chainable: Chaining Extractor
reward_underground_belt_tier_2: Tunnel Tier II
reward_splitter_compact: Compact Balancer
reward_cutter_quad: Quad Cutting
reward_painter_double: Double Painting
reward_painter_quad: Quad Painting
reward_storage: Storage Buffer
reward_rotater:
title: Rotating
desc: The <strong>rotater</strong> has been unlocked! It rotates shapes clockwise by 90 degrees.
reward_freeplay: Freeplay
reward_painter:
title: Painting
desc: >-
The <strong>painter</strong> has been unlocked - Extract some color veins (just as you do with shapes) and combine it with a shape in the painter to color them!<br><br>PS: If you are colorblind, I'm working on a solution already!
reward_mixer:
title: Color Mixing
desc: The <strong>mixer</strong> has been unlocked - Combine two colors using <strong>additive blending</strong> with this building!
reward_stacker:
title: Combiner
desc: You can now combine shapes with the <strong>combiner</strong>! Both inputs are combined, and if they can be put next to each other, they will be <strong>fused</strong>. If not, the right input is <strong>stacked on top</strong> of the left input!
reward_splitter:
title: Splitter/Merger
desc: The multifunctional <strong>balancer</strong> has been unlocked - It can be used to build bigger factories by <strong>splitting and merging items</strong> onto multiple belts!<br><br>
reward_tunnel:
title: Tunnel
desc: The <strong>tunnel</strong> has been unlocked - You can now pipe items through belts and buildings with it!
reward_rotater_ccw:
title: CCW Rotating
desc: You have unlocked a variant of the <strong>rotater</strong> - It allows to rotate counter clockwise! To build it, select the rotater and <strong>press 'T' to cycle its variants</strong>!
reward_miner_chainable:
title: Chaining Extractor
desc: You have unlocked the <strong>chaining extractor</strong>! It can <strong>forward its resources</strong> to other extractors so you can more efficiently extract resources!
reward_underground_belt_tier_2:
title: Tunnel Tier II
desc: You have unlocked a new variant of the <strong>tunnel</strong> - It has a <strong>bigger range</strong>, and you can also mix-n-match those tunnels now!
reward_splitter_compact:
title: Compact Balancer
desc: >-
You have unlocked a compact variant of the <strong>balancer</strong> - It accepts two inputs and merges them into one!
reward_cutter_quad:
title: Quad Cutting
desc: You have unlocked a variant of the <strong>cutter</strong> - It allows you to cut shapes in <strong>four parts</strong> instead of just two!
reward_painter_double:
title: Double Painting
desc: You have unlocked a variant of the <strong>painter</strong> - It works as the regular painter but processes <strong>two shapes at once</strong> consuming just one color instead of two!
reward_painter_quad:
title: Quad Painting
desc: You have unlocked a variant of the <strong>painter</strong> - It allows to paint each part of the shape individually!
reward_storage:
title: Storage Buffer
desc: You have unlocked a variant of the <strong>trash</strong> - It allows to store items up to a given capacity!
reward_freeplay:
title: Freeplay
desc: You did it! You unlocked the <strong>free-play mode</strong>! This means that shapes are now randomly generated! (No worries, more content is planned for the standalone!)
# Special reward, which is shown when there is no reward actually
no_reward: Next level
no_reward:
title: Next level
desc: >-
This level gave you no reward, but the next one will! <br><br> PS: Better don't destroy your existing factory - You need <strong>all</strong> those shapes later again to <strong>unlock upgrades</strong>!
settings:
title: Settings