UNPKG

hytopia

Version:

The HYTOPIA SDK makes it easy for developers to create massively multiplayer games using JavaScript or TypeScript.

94 lines (77 loc) 3.08 kB
import { startServer, Audio, Player, PlayerEntity, PlayerEvent, PlayerUIEvent, } from 'hytopia'; import worldMap from './assets/map.json'; // Simple map for player -> singular controlled entity const playerEntityMap = new Map<Player, PlayerEntity>(); startServer(world => { world.loadMap(worldMap); world.on(PlayerEvent.JOINED_WORLD, ({ player }) => { // Load the UI for the player. // This is loaded directly into a sandboxed iframe // overlaying the game. As long as it's an HTML file, // it can be loaded. You can bundle React, Svelte, or // any other framework into the UI you want to serve, // or just use plain HTML like in this example. player.ui.load('ui/index.html'); const playerEntity = new PlayerEntity({ player, name: 'Player', modelUri: 'models/players/player.gltf', modelLoopedAnimations: [ 'idle' ], modelScale: 0.5, }); playerEntity.spawn(world, { x: 0, y: 10, z: 0 }); // Set the player entity on our map for when // we do player list updates. playerEntityMap.set(player, playerEntity); // Handle data sent from player to server by client UI interactions we define. // See the ui/index.html file for the UI code that sends the data. player.ui.on(PlayerUIEvent.DATA, ({ playerUI, data }) => { console.log('data', data); if (data.type === 'teleport') { const randomX = Math.random() * 40 - 20; // Random between -20 and 20 const randomY = Math.random() * 13 + 2; // Random between 2 and 15 const randomZ = Math.random() * 40 - 20; // Random between -20 and 20 playerEntity.setPosition({ x: randomX, y: randomY, z: randomZ }); } }); }); world.on(PlayerEvent.LEFT_WORLD, ({ player }) => { world.entityManager.getPlayerEntitiesByPlayer(player).forEach(entity => entity.despawn()); // Remove the player entity from our map for our list. playerEntityMap.delete(player); }); // Update the player list every 1 second, no need to send too frequently. // We want to balance not sending too much UI data too frequently, because // it is currently sent over the same connection as game packets and will // compete for critical game packet bandwidth on slower player connections. setInterval(updatePlayerList, 1000); new Audio({ uri: 'audio/music/hytopia-main.mp3', loop: true, volume: 0.2, }).play(world); }); function updatePlayerList() { // Create a list of all connected players and their positions const playerListData = Array.from(playerEntityMap).map(([ player, entity ]) => { // For each player, return their username and current position return { username: player.username, position: entity.position, // Gets x,y,z coordinate }; }); // Send the updated player list to every connected player's UI for (const [ player ] of playerEntityMap) { player.ui.sendData({ type: 'playerList', // Message type for UI to handle list: playerListData, // List of all players and positions }); } }