How to make an object that can be picked up with a spacebar? Like this?
Same question here too…
The answer here is through custom extensions using the websocket API. You can use the spacebar input to trigger a check for what a player is standing nearest to, then add that image to their character as a held item. Then you do the reverse to put it down. There is not currently default support for spacebar interactions outside of the Escape Room.
Thanks Bill_Uncork-it! Where can I learn about the websocket api. Appreciate the pointers!
Here, the discord, and the API office hours are a good start. However, none of these are “beginner” level sources, as they all assume a level of understanding JS,TS, npm, etc.
Is there any sample can show how to useing the extension of the websocket API?
Or the document of official websocket API have any explane about it?
I cant exactly give you the actual code, as there are a lot of considerations as to player behavior, object preferences, etc, but from a pseudo-code standpoint, you would:
Connect to the space using game.connect()
Set up a subscription to the 'playerTriggersItem' event
Inside the event, code for if they are allowed to pick up the item. If they are, add it to their character.
Also check if they already have an item, and if they do, drop it, or maybe swap it with the other close one.
When they pick up an item, be sure to delete the object on the ground too. (Unless multiple can be picked up)
When they drop an item, create an item with the proper characteristics on the ground, somewhere.
Technically, those are all the parts you would need for spacebar interactions.
Edit: didnt expect the bolded words, those don’t mean anything specific.
Hi sir,
Is it possible to provide a little more hint for it?
Thanks!!
I’ll see what I can do to provide a more concrete example. It will likely not be a runnable script, due to all the decisions I referenced in my earlier post, but it should provide a little bit of a midpoint to get you there.
This is a very rough snippet for the process. I have not tested nor refined the calls, so some oddness may occur if you run this as written.
interface ObjectHolder{
[playerId:string]:{
mapId: string,
obj:MapObject|undefined
}
}
let objects:ObjectHolder = {};
game.subscribeToEvent("playerTriggersItem", async ({playerTriggersItem}, context) => {
if(context.player!.itemString && objects[context.playerId!]){
let temp = objects[context.playerId!]
let newObj = {...temp.obj,
key: Object.keys(game.completeMaps[temp.mapId].objects!).length,
x: context.player!.x!,
y: context.player!.y!
}
game.setObject(temp.mapId, temp.obj!.id!, newObj)
}
if(playerTriggersItem.closestObjectTemplate && playerTriggersItem.closestObjectTemplate === "Special Object"){
let {mapId, obj} = game.getObject(playerTriggersItem.closestObject!)!;
game.setItem(playerTriggersItem.closestObjectTemplate!, obj!.normal, context.playerId);
objects[context.playerId!] = {mapId, obj};
}
})
Hi sir,
I will try in later!
Thanks for your help!
Hi,
Sorry for the late reply…
I have tried using game.subscribeToEvent("playerTriggersItem",....)
before, but it gave an error below:
error TS2345: Argument of type '"playerTriggersItem"' is not assignable to parameter of type '"info" | "warn" | "error" | "ready" | "serverHeartbeat" | "disableV....
Seems it could not go furthur.
But if I change playerTriggersItem
to playerMoves
or playerInteracts
, then the code can run with some of the exmpla on the github.
Any suggestion? In the mean while, I will try to get more familiar with node.js.
Any help would be appreciated! Thanks!
I think you probably need to update your @gathertown/gather-game-client npm package. You can run npm i @gathertown/gather-game-client@latest
to update to the current one.
I managed to almost get this working, but not quite.
- The
playerTriggersItem
event seems to be gone. There’s aplayerTriggersInventoryItem
, but it doesn’t trigger on spacebar.playerTriggersObject
seems to work. - Picking up the item doesn’t seem to remove the previous item on the board. I’m not sure what the right event to send to remove the item from the map without also removing it from the player.
- When dropping the item, you have to still manually clear out the player
itemString
via some sketchyitemString: ''
event, or else the player still holds onto the item.
game.subscribeToEvent(
"playerTriggersObject",
async ({ playerTriggersObject }, context) => {
console.log("playerTriggersObject", playerTriggersObject);
// drop item if player has an item
if (
context.player?.itemString != null &&
context.player?.itemString !== ""
) {
const objectId: string | undefined = JSON.parse(
context.player.itemString
)?.id;
if (objectId != null) {
const object = game.getObject(objectId);
const map = context.player.map;
const x = context.player.x;
const y = context.player.y;
if (object != null && map != null && x != null && y != null) {
console.log("dropping balloon");
game.setObject(map, objectId, { x, y });
game.sendAction2("setItemString", {
itemString: "",
targetId: context.playerId,
});
}
}
} else {
// pickup item
const object = playerTriggersObject?.key
? context.map?.objects?.[playerTriggersObject?.key]
: null;
if (object != null && object.templateId === BALLOON_TEMPLATE_ID) {
const objectId = object.id;
if (objectId != null) {
console.log("picking up balloon");
game.setItem(objectId, object.normal, context.playerId);
}
}
}
}
);