🏞️ react.js Myst clone (point and click game - Part 1)
Myst is one of my favorites games of all times. The art itself was enough to draw me in as a kid, but the whole environment from the look and feel of rooms, to the world building and story had me hooked.
So let's make a clone! That is to say, let's make a react.js point and click game.
Planning the basics
The basics of any point and click game will be rooms and movement in and out of those rooms. The simplest way I could think of doing this was to use the Cartesian Coordinate system to give each room a x,y value.
For example on this chart the x,y pairs could be:
0,0 - the main starting area
-3,1 - an outdoor dock closet
2,3 - an indoor vault
-1.5,-2.5 - a zoom in view in a cave room
Moving forward with this idea meant we had to come up with a user state that updates room image display based on the current user x,y pair value.
To do this each cardinal direction (along with a few special extras) will either subtract or add to the current x,y value.
Forward: y + 1
Backward: y - 1
Left: x - 1
Right: x + 1
Now that we have moment, let's work on rooms. The quick and easy way for me to do this was via Midjourney. Custom art would have been more my speed, but I wanted to get a prototype up and running. After creating a few Myst style images of an outdoor area with a door, a hallway with a few doors, a radio room, and a doc it was time to put together an example.
Setting up the framework
Game.jxs
This file is the biggest and the most complex. I'll be breaking it down in to a few sections. The first section is the imports. These include two files Image and Navigation.
Image.jxs
This code displays the image using the rules for position and size and returns the image to Game.jsx
.
Navigation.jxs
This code is a little more intertwined with Game.jsx
, but basically Game.jsx
passes a value stored in onNavigate
to Navigation
to control the movement logic.
Game.jsx - Constants
After the imports, the constants are established for the game. This includes the useState currentPosition
value, useState values for found items and item interactions.
Game.jsx - Defining Rooms
The next section of Game.jsx is still defining constants, however these are more detailed in that this room
constant is for defining each room.
As you can see, each room contains an x,y pair along with a path to the image, as well as an item you can find or take with you in to this room.
ClickableAreas
are also included in this section to map on each image, where the user can click. along with defining the areas to click, we also define the name of the direction to move the player forward, backward, left or right.
// Define the rooms, their corresponding images, and clickable areas
const rooms = {
//The Cartesian room location
//The First area Porch
'0,0': {
imagePath: 'image.jpg',
item: {
name: 'Piece of Paper',
largeImage: 'largereadablepaper.png',
letterSprite: 'lettersprite.png', },
clickableAreas: [
// to entry
{ name: 'right', xStart: 0.825, xEnd: .95, yStart: .09, yEnd: .80 },
// to dock
{ name: 'left', xStart: 0.04, xEnd: 0.15, yStart: 0.1, yEnd: 0.52 },
// to overlook
{ name: 'forward', xStart: 0.35, xEnd: 0.56, yStart: 0.5, yEnd: 0.77 },
],
},
};
Game.jsx - Room Checks and Movement Logic
This section of the code is divided in to three sections.
- the movement logic, just like we said above we are getting the current position and calculating the next position based on the forward, backward, left and right directions and how they either add or subtract from the current number. One addition later on was the
rud
andldd
which are Right Upper Diagonal and Left Downward Diagonal respectively. I added these options to make room for "zoom in" rooms. That is, say a room has an item on a table, you simply want to zoom in on an area of the room.
- the next section simply checks to see if the next room is a valid room.
- the last section looks to see if an item is allowed in the current room. This is used later to gather items and add them to the screen.
Clickable events and Items
This project is continuing to grow, next time I will go over the items and the onClick
events that help give the game a little polish.