-
Notifications
You must be signed in to change notification settings - Fork 0
navigation
For implementing the navigation, you need create rooms, loocations and maps.
The navigation system is designed in the following way:
- The player is placed in a room
- To be reachable, each room must be connected to a location and a map
- The player, from the current room, can move to another room at the same location.
- For move in another location the player need to use the map.
The rooms are the places where the player can interact. The rooms are part of a location.
For creating a room, you need to create a new instance of the RoomBaseModel
class and add it into a game rooms dictionary, when the game is initialized.
For create a new instance of RoomBaseModel
you need to pass:
-
id
: a unique identifier for the room. It is used to reference the room in the game (must be unique). -
location
: the location instance. -
props
: the room properties. The properties are:-
name
: the room name. -
renderImage
: the room image. It can be a string, anJSX.Element
,GraphicItemInterface
or aPixi'VN Canvas Item
. Or an object to manage multiple image types. For example to have a image based on time. -
defaultActivities
: the activities that are available in this room. -
disabled
: whether is disabled. You can also pass a Pixi'VN flag name. -
hidden
: whether is hidden. You can also pass a Pixi'VN flag name. -
renderIcon
: the room icon. It can be a string, anJSX.Element
,GraphicItemInterface
or aPixi'VN Canvas Item
. Or a function to manage multiple icon types. For example to have a icon based on time. -
isEntrance
: whether is an entrance room, so when the player enters in the location, it will be the first room to be shown.
-
export const mcRoom = new RoomBaseModel('mc_room', home, {
name: "MC room",
renderImage: 'https://images.com/myroom.webp',
defaultActivities: [sleepActivity, studyActivity],
})
saveRoom([mcRoom, bathroom, lounge]);
The room have 2 types of activities:
-
RoomBaseModel.defaultActivities
: This list can't edited in runtime, but only by code (the room properties). -
RoomBaseModel.activities
: This list can be edited in runtime. You can add or remove activities with theRoomBaseModel.addActivity()
andRoomBaseModel.removeActivity()
functions.
You can use RoomBaseModel.getRoutine()
to get the current room routine.
The entrance room is the first room that the player will see when enter in a location. You can set the RoomBaseModel.isEntrance
property to true
in the room properties. If a location has multiple entrance rooms, the first room that is added in the location will be the entrance room. If a location doesn't have an entrance room, the first room that is added in the location will be the entrance room.
The locations are the collection of rooms. The locations are part of a map.
For creating a location, you need to create a new instance of the LocationBaseModel
class.
For create a new instance of LocationBaseModel
you need to pass:
-
id
: a unique identifier for the location. It is used to reference the location in the game (must be unique). -
map
: the map instance. -
props
: the location properties. The properties are:-
name
: the location name. -
disabled
: whether is disabled. You can also pass a Pixi'VN flag name. -
hidden
: whether is hidden. You can also pass a Pixi'VN flag name. -
renderIcon
: the location icon. It can be a string, anJSX.Element
,GraphicItemInterface
or aPixi'VN Canvas Item
. Or a function to manage multiple icon types. For example to have a icon based on time.
-
const home = new LocationBaseModel('home', map, {
name: "Home",
renderIcon: 'https://images.com/homeicon.webp',
})
export const mcRoom = new RoomBaseModel('mc_room', home, {
name: "MC room",
renderImage: 'https://images.com/myroom.webp',
defaultActivities: [sleepActivity, studyActivity],
})
saveRoom([mcRoom, bathroom, lounge]);
You can use LocationBaseModel.getRooms()
to get the rooms of the location.
You can use LocationBaseModel.getEntrance()
to get the entrance room of the location.
The maps are the collection of locations. The maps are part of the navigation system.
For creating a map, you need to create a new instance of the MapBaseModel
class.
For create a new instance of MapBaseModel
you need to pass:
-
id
: a unique identifier for the map. It is used to reference the map in the game (must be unique). -
props
: the map properties. The properties are:-
name
: the map name. -
renderImage
: the map image. It can be a string, anJSX.Element
,GraphicItemInterface
or aPixi'VN Canvas Item
. Or an object to manage multiple image types. For example to have a image based on time. -
neighboringMaps
: the neighboring maps that are available in this map. For example, if the player is in the current map and want to move to another map, the player can use the neighboring maps. Read the Overriding the Neighboring Maps Interface section for more information. -
disabled
: whether is disabled. You can also pass a Pixi'VN flag name. -
hidden
: whether is hidden. You can also pass a Pixi'VN flag name.
-
You can override the NeighboringMapsInterface
to set required parameters for the neighboring maps.
For example:
// nqtr.types.ts
declare module '@drincs/nqtr/dist/override' {
interface NeighboringMapsInterface {
"north": string,
"south": string,
"east": string,
"west": string,
}
}
- cyberpunk map
- Hex Kit
- Village Generator
- Medieval Fantasy City Generator
- Tabletop RPG Map editor II
- Neighbourhood Generator
- Styling Wizard
The player can only move to another rooms. To move to another room you can use the setCurrentRoom()
function. Automatically the location and the real map changed based on the room. This function has 1 parameters:
-
room
: the room instance.
setCurrentRoom(mcRoom);
For get the current room you can use the getCurrentRoom()
function.
const currentRoom = getCurrentRoom();
// or if you have a custom room model
const currentRoom = getCurrentRoom<MyRoomModel>();
For get the current location you can use the getCurrentLocation()
function.
const currentLocation = getCurrentLocation();
// or if you have a custom location model
const currentLocation = getCurrentLocation<MyLocationModel>();
For get the current map you can use the getCurrentMap()
function.
const currentMap = getCurrentMap();
// or if you have a custom map model
const currentMap = getCurrentMap<MyMapModel>();
It recommend creating a subclass of RoomBaseModel
, LocationBaseModel
or MapBaseModel
to add new properties or methods to the class.
For example, you can create a subclass RoomBaseModel
to add a new property color
:
class RoomModel extends RoomBaseModel {
color: string;
constructor(id: string, location: LocationBaseModel, props: RoomProps) {
super(id, location, props);
this.color = props.color;
}
}
export default function RoomList() {
const [{ currentLocation, currentRoom }, setCurrentNavigationData] = useState({
currentLocation: getCurrentLocation(),
currentRoom: getCurrentRoom(),
})
useEffect(() => {
let room = getCurrentRoom()
let location = getCurrenrLocation()
setCurrentNavigationData((prev) => ({
currentLocation: location || prev.currentLocation,
currentRoom: room || prev.currentRoom,
}))
}, [hour])
useEffect(() => {
if (currentRoom.renderImage) {
let backgroundImage = currentRoom.renderImage({})
let container = new CanvasContainer()
if (backgroundImage instanceof CanvasBase) {
container.addChild(backgroundImage)
}
if (typeof backgroundImage === 'string') {
let image = new CanvasImage()
image.imageLink = backgroundImage
image.load()
container.addChild(image)
}
GameWindowManager.addCanvasElement(BACKGROUND_ID, container)
}
}, [currentRoom])
return (
<Stack
direction="row"
justifyContent="center"
alignItems="flex-end"
spacing={0.5}
>
{currentLocation.getRooms().map((room) => {
let renderImage = room.renderIcon || room.renderImage
let disabled = room.disabled
let selected = room.id === currentRoom?.id
if (!renderImage) {
return
}
let image = renderImage({})
if (typeof image === "string") {
return (
<IconButton
key={"room" + room.id}
disabled={disabled || selected}
selected={selected}
onClick={() => {
if (!disabled) {
setCurrentRoom(room)
let r = getCurrentRoom()
if (r && r.id !== currentRoom.id) {
setCurrentNavigationData((prev) => ({ ...prev, currentRoom: r }))
}
}
}}
ariaLabel={room.name}
>
{image && <img src={image} />}
</IconButton>
)
}
else if (isValidElement(image)) {
return image
}
})}
</Stack>
);
}