As you may have been following, I've recently been blogging about my efforts working with the rpg-js framework, check out my profile if you've missed out on this content.
Today's tutorial covers several areas - the initial player gui, sprites and inventory items!
Enabling the user to select a character sprite!
So, up until now the user has just been allocated a default hero character sprite, this works well but it distinctly lacks personalization, so by letting the user select their preferred looks hopefully they feel a greater personal attachment with their in game character, even though there's no real gameplay going on right now..
So, after sourcing some additional sprites for the user to pick between, I added this step after the user has selected the new account they want to use:
<div v-if="chain && method === 'sprite'">
<h3>Choose how your character appears</h3>
<sl-radio-group :value="spriteType" @sl-change="spriteType = $event.target.value" size="medium" label="Select a sprite type" name="gender">
<sl-radio-button style="margin-top: 10px;" pill value="male">Male</sl-radio-button>
<sl-radio-button style="margin-top: 10px;" pill value="female">Female</sl-radio-button>
</sl-radio-group>
// image removed for hive - check github for full code
<p>Viewing {{ spriteValue }} of {{ spriteTypeQty }} {{ spriteType }} sprites</p>
<div class="smallGrid">
<sl-button
variant="neutral"
@click="spriteValue > 0 ? (spriteValue -= 1) : (spriteValue = spriteTypeQty - 1)"
size="small"
pill
>
Previous
</sl-button>
<sl-button
variant="neutral"
@click="spriteValue < spriteTypeQty - 1 ? (spriteValue += 1) : (spriteValue = 0)"
size="small"
pill
>Next</sl-button
>
</div>
<div class="microGrid">
<sl-button
variant="primary"
@click="
setCurrentUser(
searchResult.name,
searchResult.id,
searchResult.referrer,
`${spriteType}-${spriteValue}`,
chain
);
closeGUI();
"
size="small"
pill
>Use this sprite</sl-button
>
</div>
</div>
.
This code lets the user easily peruse the available sprites, and when ready will save the additional sprite info to the persistent user nanostore!
Let's see how this looks in action!
Once we've stored our recently used Bitshares account to persistent nanostore state, we can look up our previously used accounts and the sprite will now be shown alongside a new "delete" button, to erase your historical account usage in game.
<div v-if="chain && method === 'existing'">
<p>
{{
chain === "bitshares"
? "Selecting a previously used Bitshares (BTS) account"
: "Selecting a previously used Bitshares testnet (TEST) account"
}}
</p>
<div
v-if="
storedUsers &&
storedUsers.users &&
storedUsers.users.length > 0 &&
storedUsers.users.filter((user) => user.chain === chain)
"
>
<p>Choose an account from the list below:</p>
<div style="max-height: 200px; overflow-y: scroll;" class="microGrid">
<div v-for="user in storedUsers.users.filter((user) => user.chain === chain)">
<sl-button
variant="default"
@click="
setCurrentUser(user.username, user.id, user.referrer, user.sprite, chain);
closeGUI();
"
:key="user.id"
style="margin: 5px; width: 80%;"
>
<div class="parent">
<div
:style="{
width: '32px',
height: '32px',
backgroundImage: `url(/main/spritesheets/characters/${user.sprite}.png)`,
backgroundPosition: '-32px 0px',
backgroundSize: '96px 128px'
}"
></div>
<div>
{{ user.username }} ({{ user.id }})
</div>
</div>
</sl-button>
<sl-button
variant="default"
@click="removeUser(user.id)"
:key="`${user.id}_remove`"
style="margin: 5px;"
>
❌
</sl-button>
</div>
</div>
</div>
<div v-else>
<p>No previously used accounts found, please use a new account.</p>
<sl-button slot="footer" variant="primary" @click="method = 'new'" style="margin-bottom: 10px;">
Find account
</sl-button>
</div>
<sl-button slot="footer" variant="neutral" @click="method = null;" style="margin-top:15px;">Back</sl-button>
</div>
.
Let's see it in action!
Enabling the user to switch between accounts without refreshing
Rather than have to refresh the app to be able to switch to another blockchain or to another account on the same blockchain, why not offer the user an item which allows them to do just that?
Introducing - the account switcher!
import { RpgPlayer } from '@rpgjs/server'
import { Item } from '@rpgjs/database'
import { $currentUser, eraseCurrentUser } from '../nanostores/users';
import { playerGold } from '../common/player';
@Item({
id: 'accountChanger',
name: 'Account changer',
description: 'Switch between accounts and blockchains with this tool.',
price: 0,
consumable: true // Must be true for GUI to launch
})
export default class Book {
async onUse(player: RpgPlayer) {
await player.gui("intro").open({}, {waitingAction: true, blockPlayerInput: true});
const usr = $currentUser.get();
await playerGold(player, usr);
player.setGraphic(usr.sprite);
player.items = [];
player.addItem("accountChanger", 1); // default user item
player.changeMap('map');
}
onRemove(player: RpgPlayer) {
player.addItem('accountChanger', 1); // avoid selling the tool
}
}
.
It does what it says on the tin, this item when selected from the user's inventory will launch the initial intro
GUI, from where the user can select a chain and blockchain account to proceed with.
When will the user be given this item? Immediately after the user selects their account!
async onJoinMap(player: RpgPlayer) {
// User selects an account here
player.addItem("accountChanger", 1); // give item to user
},
.
And finally, let's see the account changer item in action!
Awesome stuff! Several quick coding wins resulting in greatly improved potential user experience in game!
Have any questions? Comment below!
These developments were brought to you by the NFTEA Gallery.
Consider collecting an NFTEA NFT to or donate to the following BTS or EOS blockchain accounts directly, to fund continued developments.
Don't have a Bitshares account? Make one today!
It's so interesting how it's structured and connected and how well it all seems to work.
From what I understand, the framework itself doesn't yet offer 100% support for running on blockchain or something like Web3, but you can easily create an MMORPG with it in JS.
This is a great project, and I'll be following it further.
Yeah I was really impressed by how the rpg-js compiler works, there's so much you can build with just tiled and limited programming skills, it's still a lot more free and open source than propriatery rpg maker software alternatives currently out there
Thanks for your contribution to the STEMsocial community. Feel free to join us on discord to get to know the rest of us!
Please consider delegating to the @stemsocial account (85% of the curation rewards are returned).
You may also include @stemsocial as a beneficiary of the rewards of this post to get a stronger support.
Your level lowered and you are now a Red Fish!
Check out our last posts: