Skip to content

Commit

Permalink
feat(achievements): achievement notifications (#65)
Browse files Browse the repository at this point in the history
Improved achievements feature by adding fancier notifications for it
Also improved the docs a bit
  • Loading branch information
liana-p committed Apr 12, 2023
1 parent fe9950f commit c6fe5b3
Show file tree
Hide file tree
Showing 16 changed files with 204 additions and 104 deletions.
49 changes: 33 additions & 16 deletions docs/examples/example-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,57 +21,74 @@ See the most up to date config [directly on GitHub](https://github.com/liana-p/n

```yaml
---
gameTitle: Narrat Demo
gameTitle: Narrat Default
saveFileName: Narrat Default
images:
narrat: img/backgrounds/narrat.webp
map: img/backgrounds/map.webp
shopButton: img/ui/shop-button.webp
parkButton: img/ui/park-button.webp
dialogPanel:
overlayMode: true
rightOffset: 100
bottomOffset: 50
width: 475
height: 680
dialoguePanel:
textSpeed: 30
animateText: true
timeBetweenLines: 100
layout:
dialogPanel:
overlayMode: true
rightOffset: 100
bottomOffset: 50
width: 475
height: 680
backgrounds:
# Default was 880 x 720
width: 1280
height: 720
dialogBottomPadding: 70
dialogBottomPadding: '2rem'
mobileDialogHeightPercentage: 60
verticalLayoutThreshold: 600
portraits:
width: 150
height: 225
offset:
landscape:
right: 10
bottom: 0
portrait:
right: 10
bottom: 0
saves:
mode: manual
slots: 10
screens: data/screens.yaml
buttons: data/buttons.yaml
skills: data/skills.yaml
scripts: data/scripts.yaml
audio: data/audio.yaml
tooltips: data/tooltips.yaml
characters: data/characters.yaml
notifications:
timeOnScreen: 1.5
alsoPrintInDialogue: true
items: data/items.yaml
quests: data/quests.yaml
hudStats:
money:
icon: img/ui/money.webp
name: Money
startingValue: 10
minValue: 0
maxValue: 99999
energy:
icon: img/ui/energy.webp
name: Energy
startingValue: 10
minValue: 0
maxValue: 10
saves:
mode: manual
slots: 10
items: data/items.yaml
achievements: data/achievements.yaml
interactionTags:
default:
onlyInteractOutsideOfScripts: true
quests: data/quests.yaml
menuButtons:
menu:
text: Menu
cssId: my-custom-id
```
:::
Expand Down
2 changes: 0 additions & 2 deletions docs/features/quests.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,3 @@ map_update:
```

:::

<!-- ![](../.gitbook/assets/Animation-2.webp) -->
4 changes: 4 additions & 0 deletions docs/guides/installing-narrat-in-a-web-app.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Installing Narrat in a web app

::: danger
This is for advanced use. It's unlikely you want to follow those instructions unless you know what you're doing
:::

## Install on a project

`npm install narrat`
Expand Down
Binary file not shown.
4 changes: 4 additions & 0 deletions packages/narrat/examples/games/default/data/achievements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ categories:
defaultAchievementIcon: img/achievements/trophy.png

achievements:
janken:
name: Janken
description: Win at Rock paper scissors Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec auctor, nisl eget ultricies tincidunt.
icon: img/achievements/janken.webp
win_game:
name: Won the game
description: Get this achievement by being a true ultimate pro gamer
Expand Down
64 changes: 58 additions & 6 deletions packages/narrat/examples/games/default/scripts/default.nar
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,64 @@ main:
// jump test_choice_conditions
// set config.characters.characters.player.name "Someone"
// talk player idle "I like @@bread"
talk player idle "hello world"
add global.counter 1
if (== $global.counter 2):
unlock_achievement win_game
talk player idle "Global counter is %{$global.counter}"
jump quest_demo
// talk player idle "hello world"
// add global.counter 1
// if (== $global.counter 2):
// unlock_achievement win_game
// talk player idle "Global counter is %{$global.counter}"
// jump quest_demo
jump achievements_demo

achievements_demo:
talk helper idle "Let's play rock paper scissors!"
talk helper idle "I will choose one of the three options before you, and once you choose yours I'll reveal mine."
jump janken

janken:
talk helper idle "It's time to duel!"
set data.janken (new Array "rock" "paper" "scissors")
choice:
"Choose your weapon"
"Rock":
set data.player_choice "rock"
"Paper":
set data.player_choice "paper"
"Scissors":
set data.player_choice "scissors"
set data.computer_choice (random_from_array $data.janken)
talk helper idle "I chose %{$data.computer_choice}"
if (== $data.player_choice $data.computer_choice):
talk player idle "It's a tie!"
else:
if (== $data.player_choice "rock"):
if (== $data.computer_choice "paper"):
run janken_lose
else:
run janken_win
if (== $data.player_choice "paper"):
if (== $data.computer_choice "scissors"):
run janken_lose
else:
run janken_win
if (== $data.player_choice "scissors"):
if (== $data.computer_choice "rock"):
run janken_lose
else:
run janken_win
choice:
"Play again?"
"Yes":
jump janken
"No":
talk player idle "Bye!"
jump main

janken_win:
talk helper idle "You won!"
unlock_achievement janken

janken_lose:
talk helper idle "You lost!"

test_choice_conditions:
set data.falseCondition false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="achievement-display" :id="`achievement-${achievement}`">
<div class="achievement-display tile" :id="`achievement-${achievement}`">
<div class="achievement-icon" :style="style"></div>
<p class="obtained-status">
{{ obtainedStatus }}
Expand Down Expand Up @@ -72,9 +72,6 @@ const obtainedStatus = computed(() => {
display: flex;
align-items: center;
flex-direction: column;
padding: 20px;
border-radius: 15px;
border-width: 2px;
border-color: var(--achievement-tile-border-color);
position: relative;
background: var(--achievement-tile-background);
Expand Down
66 changes: 51 additions & 15 deletions packages/narrat/src/components/notification-toast.vue
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
<template>
<transition-group name="notification" tag="div" class="notifications-holder">
<div
class="notification"
class="notification tile"
v-for="(notification, id) in notifications"
:key="id"
>
<h3 v-html="notification.text"></h3>
<img
:src="getAssetUrl(notification.icon)"
v-if="notification.icon"
class="notification-icon"
:style="notificationStyle(notification)"
/>
<span v-html="notification.text" class="notification-text"></span>
<p
v-html="notification.description"
v-if="notification.description"
class="notification-description"
></p>
</div>
</transition-group>
</template>

<script lang="ts">
import { useNotifications } from '@/stores/notification-store';
import { mapState } from 'pinia';
import { defineComponent } from 'vue';
<script lang="ts" setup>
import {
NotificationState,
useNotifications,
} from '@/stores/notification-store';
import { computed } from 'vue';
import { getAssetUrl } from '@/config';
export default defineComponent({
computed: {
...mapState(useNotifications, ['notifications']),
},
});
const notificationsStore = useNotifications();
const notifications = computed(() => notificationsStore.notifications);
const notificationStyle = (notification: NotificationState) => {
if (notification.description) {
return {
marginTop: '10px',
};
}
};
</script>

<style>
Expand All @@ -39,9 +57,27 @@ export default defineComponent({
margin-top: 10px;
margin-bottom: 10px;
border-radius: 10px;
padding: 15px;
background: var(--notifications-bg);
width: 40vh;
text-align: center;
padding: 9px;
width: 400px;
text-align: left;
}
.notification-icon {
float: left;
width: var(--notification-icon-size);
height: var(--notification-icon-size);
margin-right: 10px;
}
.notification-text {
color: var(--notifications-text-color);
font-size: 1.2rem;
font-weight: 600;
}
.notification-description {
margin-top: 10px;
color: var(--notifications-description-color);
font-size: 1rem;
font-style: italic;
}
</style>
6 changes: 4 additions & 2 deletions packages/narrat/src/components/screen-layer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { isViewportElementClickable } from '@/utils/viewport-utils';
const props = defineProps({
layer: String,
layerIndex: Number,
transitioning: {
type: Boolean,
default: false,
Expand All @@ -57,6 +58,9 @@ const main = useMain();
const screensStore = useScreens();
const screenObjectsStore = useScreenObjects();
const screenObjects = computed(() => {
return screenObjectsStore.tree.filter((o) => o.layer === props.layerIndex);
});
const layoutWidth = computed(() => {
return getConfig().layout.backgrounds.width;
});
Expand Down Expand Up @@ -278,8 +282,6 @@ function getSpriteStyle(sprite: SpriteState): CSSProperties {
.viewport-button.interactable {
cursor: pointer;
animation: pulse 0.8s infinite;
animation-timing-function: linear;
pointer-events: auto;
}
Expand Down
17 changes: 0 additions & 17 deletions packages/narrat/src/components/screen-objects/screen-object.vue
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,6 @@ const objectStyle = computed(() => {
.viewport-button.interactable {
cursor: pointer;
animation: pulse 0.8s infinite;
animation-timing-function: linear;
pointer-events: auto;
}
Expand Down Expand Up @@ -149,7 +147,6 @@ const objectStyle = computed(() => {
font-weight: bold;
background-size: cover;
background-repeat: no-repeat;
animation: object-appear 0.3s ease-in;
}
.viewport-object.interactable {
Expand All @@ -160,18 +157,4 @@ const objectStyle = computed(() => {
pointer-events: none;
user-select: none;
}
@keyframes object-appear {
/* Make an animation rotating the logo in 3d */
0% {
transform: perspective(10000px) rotateX(-120deg) scale(1);
}
80% {
transform: perspective(10000px) rotateX(10deg) scale(1.05, 1.05);
}
100% {
transform: perspective(10000px) rotateX(0deg) scale(1, 1);
}
}
</style>
2 changes: 2 additions & 0 deletions packages/narrat/src/components/screens.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
<Layer
v-if="layer.transition.oldScreen"
:layer="layer.transition.oldScreen"
:layerIndex="index"
:transitioning="true"
/>
</template>
<template v-slot:newElement>
<Layer
v-if="layer.screen"
:layer="layer.screen"
:layerIndex="index"
:transitioning="true"
/>
</template>
Expand Down
Loading

0 comments on commit c6fe5b3

Please sign in to comment.