hytopia 0.1.93 → 0.1.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/examples/zombies-fps/assets/maps/terrain.json +13494 -0
- package/examples/zombies-fps/assets/models/environment/barbedfence.gltf +1 -0
- package/examples/zombies-fps/assets/models/environment/binoculars.gltf +1 -0
- package/examples/zombies-fps/assets/models/environment/mattifest.json +9 -0
- package/examples/zombies-fps/assets/models/environment/metalshelf.gltf +1 -0
- package/examples/zombies-fps/assets/models/environment/weaponbox.gltf +1 -0
- package/examples/zombies-fps/assets/models/players/soldier-player.gltf +1 -0
- package/examples/zombies-fps/assets/skyboxes/partly-cloudy/+x.png +0 -0
- package/examples/zombies-fps/assets/skyboxes/partly-cloudy/+y.png +0 -0
- package/examples/zombies-fps/assets/skyboxes/partly-cloudy/+z.png +0 -0
- package/examples/zombies-fps/assets/skyboxes/partly-cloudy/-x.png +0 -0
- package/examples/zombies-fps/assets/skyboxes/partly-cloudy/-y.png +0 -0
- package/examples/zombies-fps/assets/skyboxes/partly-cloudy/-z.png +0 -0
- package/examples/zombies-fps/classes/EnemyEntity.ts +20 -0
- package/examples/zombies-fps/classes/GamePlayerEntity.ts +30 -0
- package/examples/zombies-fps/classes/PurchaseBarrierEntity.ts +74 -0
- package/examples/zombies-fps/classes/WeaponCrateEntity.ts +0 -0
- package/examples/zombies-fps/gameConfig.ts +126 -0
- package/examples/zombies-fps/index.ts +49 -0
- package/examples/zombies-fps/package.json +16 -0
- package/package.json +1 -1
- package/server.js +1 -1
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import {
|
2
|
+
Entity,
|
3
|
+
EntityOptions,
|
4
|
+
} from 'hytopia';
|
5
|
+
|
6
|
+
export interface EnemyEntityOptions extends EntityOptions {
|
7
|
+
health: number;
|
8
|
+
damage: number;
|
9
|
+
}
|
10
|
+
|
11
|
+
export class EnemyEntity extends Entity {
|
12
|
+
public health: number;
|
13
|
+
public damage: number;
|
14
|
+
|
15
|
+
public constructor(options: EnemyEntityOptions) {
|
16
|
+
super(options);
|
17
|
+
this.health = options.health;
|
18
|
+
this.damage = options.damage;
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import {
|
2
|
+
Player,
|
3
|
+
PlayerEntity,
|
4
|
+
PlayerCameraMode,
|
5
|
+
} from 'hytopia';
|
6
|
+
|
7
|
+
const BASE_HEALTH = 100;
|
8
|
+
|
9
|
+
export default class GamePlayerEntity extends PlayerEntity {
|
10
|
+
public health: number;
|
11
|
+
public maxHealth: number;
|
12
|
+
|
13
|
+
public constructor(player: Player) {
|
14
|
+
super({
|
15
|
+
player,
|
16
|
+
name: 'Player',
|
17
|
+
modelUri: 'models/players/soldier-player.gltf',
|
18
|
+
modelLoopedAnimations: [ 'idle' ],
|
19
|
+
modelScale: 0.5,
|
20
|
+
});
|
21
|
+
|
22
|
+
// this.player.camera.setMode(PlayerCameraMode.FIRST_PERSON);
|
23
|
+
// this.player.camera.setModelHiddenNodes([ 'head' ]);
|
24
|
+
// this.player.camera.setOffset({ x: 0, y: 0.4, z: 0 });
|
25
|
+
// this.player.camera.setForwardOffset(0.4);
|
26
|
+
|
27
|
+
this.health = BASE_HEALTH;
|
28
|
+
this.maxHealth = BASE_HEALTH;
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
import {
|
2
|
+
ColliderOptions,
|
3
|
+
ColliderShape,
|
4
|
+
Entity,
|
5
|
+
RigidBodyType,
|
6
|
+
QuaternionLike,
|
7
|
+
Vector3Like,
|
8
|
+
World,
|
9
|
+
} from 'hytopia';
|
10
|
+
|
11
|
+
const WALL_COLLIDER_OPTIONS: ColliderOptions = {
|
12
|
+
shape: ColliderShape.BLOCK,
|
13
|
+
halfExtents: {
|
14
|
+
x: 0.5,
|
15
|
+
y: 0, //5,
|
16
|
+
z: 0.5,
|
17
|
+
},
|
18
|
+
};
|
19
|
+
|
20
|
+
export interface PurchaseBarrierEntityOptions {
|
21
|
+
name: string;
|
22
|
+
removalPrice: number;
|
23
|
+
width: number;
|
24
|
+
}
|
25
|
+
|
26
|
+
export default class PurchaseBarrierEntity extends Entity {
|
27
|
+
public removalPrice: number;
|
28
|
+
private _width: number;
|
29
|
+
|
30
|
+
public constructor(options: PurchaseBarrierEntityOptions) {
|
31
|
+
super({
|
32
|
+
name: options.name,
|
33
|
+
modelUri: 'models/environment/barbedfence.gltf',
|
34
|
+
rigidBodyOptions: {
|
35
|
+
type: RigidBodyType.FIXED,
|
36
|
+
colliders: [ WALL_COLLIDER_OPTIONS ],
|
37
|
+
},
|
38
|
+
});
|
39
|
+
|
40
|
+
this.removalPrice = options.removalPrice;
|
41
|
+
this._width = options.width;
|
42
|
+
}
|
43
|
+
|
44
|
+
public get width(): number {
|
45
|
+
return this._width;
|
46
|
+
}
|
47
|
+
|
48
|
+
public override spawn(world: World, position: Vector3Like, rotation?: QuaternionLike): void {
|
49
|
+
super.spawn(world, position, rotation);
|
50
|
+
|
51
|
+
if (this._width > 1) {
|
52
|
+
const offset = Math.floor((this._width - 1) / 2);
|
53
|
+
for (let i = -offset; i <= offset; i++) {
|
54
|
+
if (i === 0) continue; // Skip center since parent barrier is there
|
55
|
+
|
56
|
+
const barrier = new Entity({
|
57
|
+
name: `${this.name} (${Math.abs(i)})`,
|
58
|
+
modelUri: 'models/environment/barbedfence.gltf',
|
59
|
+
rigidBodyOptions: {
|
60
|
+
type: RigidBodyType.FIXED,
|
61
|
+
colliders: [ WALL_COLLIDER_OPTIONS ],
|
62
|
+
},
|
63
|
+
});
|
64
|
+
|
65
|
+
barrier.spawn(world, {
|
66
|
+
x: position.x + (rotation?.w === 1 ? i : 0),
|
67
|
+
y: position.y,
|
68
|
+
z: position.z + (rotation?.w === 1 ? 0 : i),
|
69
|
+
}, rotation);
|
70
|
+
}
|
71
|
+
};
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
File without changes
|
@@ -0,0 +1,126 @@
|
|
1
|
+
import { Quaternion } from 'hytopia';
|
2
|
+
|
3
|
+
export const INVISIBLE_WALLS = [
|
4
|
+
{ // Main entrance (south door)
|
5
|
+
position: { x: 2.5, y: 1, z: 25},
|
6
|
+
halfExtents: { x: 1, y: 5, z: 0.5 },
|
7
|
+
},
|
8
|
+
{ // Main entrance (south window)
|
9
|
+
position: { x: -4, y: 1, z: 25},
|
10
|
+
halfExtents: { x: 1, y: 5, z: 0.5 },
|
11
|
+
},
|
12
|
+
{ // Main entrance (east window)
|
13
|
+
position: { x: 13, y: 1, z: 22 },
|
14
|
+
halfExtents: { x: 0.5, y: 5, z: 1 },
|
15
|
+
},
|
16
|
+
{ // Main entrance (north window)
|
17
|
+
position: { x: 8, y: 1, z: 15 },
|
18
|
+
halfExtents: { x: 1, y: 5, z: 0.5 },
|
19
|
+
},
|
20
|
+
{ // Theater (south window)
|
21
|
+
position: { x: -8, y: 1, z: 12},
|
22
|
+
halfExtents: { x: 1, y: 5, z: 0.5 },
|
23
|
+
},
|
24
|
+
{ // Parlor (south window)
|
25
|
+
position: { x: -21, y: 1, z: 16},
|
26
|
+
halfExtents: { x: 1, y: 5, z: 0.5 },
|
27
|
+
},
|
28
|
+
{ // Parlor (north window)
|
29
|
+
position: { x: -26, y: 1, z: -2},
|
30
|
+
halfExtents: { x: 1, y: 5, z: 0.5 },
|
31
|
+
},
|
32
|
+
{ // Dining Hall (south window)
|
33
|
+
position: { x: 31, y: 1, z: 15},
|
34
|
+
halfExtents: { x: 1, y: 5, z: 0.5 },
|
35
|
+
},
|
36
|
+
{ // Dining Hall (north window)
|
37
|
+
position: { x: 31, y: 1, z: -2},
|
38
|
+
halfExtents: { x: 1.5, y: 5, z: 0.5 },
|
39
|
+
},
|
40
|
+
{ // Art Gallery (north window)
|
41
|
+
position: { x: 26, y: 1, z: -26},
|
42
|
+
halfExtents: { x: 2.5, y: 5, z: 0.5 },
|
43
|
+
},
|
44
|
+
{ // Kitchen (west window 1)
|
45
|
+
position: { x: -29, y: 1, z: -18 },
|
46
|
+
halfExtents: { x: 0.5, y: 5, z: 1.5 },
|
47
|
+
},
|
48
|
+
{ // Kitchen (west window 2)
|
49
|
+
position: { x: -29, y: 1, z: -23 },
|
50
|
+
halfExtents: { x: 0.5, y: 5, z: 1.5 },
|
51
|
+
}
|
52
|
+
|
53
|
+
]
|
54
|
+
|
55
|
+
export const PURCHASE_BARRIERS = [
|
56
|
+
{
|
57
|
+
name: 'Unlock Theater Room (South)',
|
58
|
+
removalPrice: 100,
|
59
|
+
position: { x: 2, y: 1.5, z: 15 },
|
60
|
+
rotation: Quaternion.fromEuler(0, 0, 0),
|
61
|
+
width: 5,
|
62
|
+
},
|
63
|
+
{
|
64
|
+
name: 'Unlock Parlor (South)',
|
65
|
+
removalPrice: 25,
|
66
|
+
position: { x: -8, y: 1.5, z: 19 },
|
67
|
+
rotation: Quaternion.fromEuler(0, 90, 0),
|
68
|
+
width: 3,
|
69
|
+
},
|
70
|
+
{
|
71
|
+
name: 'Unlock Dining Hall (South)',
|
72
|
+
removalPrice: 50,
|
73
|
+
position: { x: 12, y: 1.5, z: 19 },
|
74
|
+
rotation: Quaternion.fromEuler(0, 90, 0),
|
75
|
+
width: 3,
|
76
|
+
},
|
77
|
+
{
|
78
|
+
name: 'Unlock Theater Room (West)',
|
79
|
+
removalPrice: 75,
|
80
|
+
position: { x: -15, y: 1.5, z: 3 },
|
81
|
+
rotation: Quaternion.fromEuler(0, 90, 0),
|
82
|
+
width: 5,
|
83
|
+
},
|
84
|
+
{
|
85
|
+
name: 'Unlock Theater Room (East)',
|
86
|
+
removalPrice: 75,
|
87
|
+
position: { x: 19, y: 1.5, z: 3 },
|
88
|
+
rotation: Quaternion.fromEuler(0, 90, 0),
|
89
|
+
width: 5,
|
90
|
+
},
|
91
|
+
{
|
92
|
+
name: 'Unlock Art Gallery (South)',
|
93
|
+
removalPrice: 200,
|
94
|
+
position: { x: 26, y: 1.5, z: -2 },
|
95
|
+
rotation: Quaternion.fromEuler(0, 0, 0),
|
96
|
+
width: 5,
|
97
|
+
},
|
98
|
+
{
|
99
|
+
name: 'Unlock Kitchen (South)',
|
100
|
+
removalPrice: 200,
|
101
|
+
position: { x: -23, y: 1.5, z: -2 },
|
102
|
+
rotation: Quaternion.fromEuler(0, 0, 0),
|
103
|
+
width: 5,
|
104
|
+
},
|
105
|
+
{
|
106
|
+
name: 'Unlock Vault',
|
107
|
+
removalPrice: 200,
|
108
|
+
position: { x: 0, y: 1.5, z: -26 },
|
109
|
+
rotation: Quaternion.fromEuler(0, 0, 0),
|
110
|
+
width: 3,
|
111
|
+
},
|
112
|
+
{
|
113
|
+
name: 'Unlock Treasure Room (West)',
|
114
|
+
removalPrice: 75,
|
115
|
+
position: { x: -16, y: 1.5, z: -18 },
|
116
|
+
rotation: Quaternion.fromEuler(0, 90, 0),
|
117
|
+
width: 5,
|
118
|
+
},
|
119
|
+
{
|
120
|
+
name: 'Unlock Treasure Room (East)',
|
121
|
+
removalPrice: 75,
|
122
|
+
position: { x: 20, y: 1.5, z: -18 },
|
123
|
+
rotation: Quaternion.fromEuler(0, 90, 0),
|
124
|
+
width: 5,
|
125
|
+
},
|
126
|
+
]
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import { startServer, Collider, ColliderShape } from 'hytopia';
|
2
|
+
import GamePlayerEntity from './classes/GamePlayerEntity';
|
3
|
+
import PurchaseBarrierEntity from './classes/PurchaseBarrierEntity';
|
4
|
+
import { INVISIBLE_WALLS, PURCHASE_BARRIERS } from './gameConfig';
|
5
|
+
import worldMap from './assets/maps/terrain.json';
|
6
|
+
|
7
|
+
startServer(world => {
|
8
|
+
// Load map.
|
9
|
+
world.loadMap(worldMap);
|
10
|
+
|
11
|
+
// Setup lighting
|
12
|
+
world.setAmbientLightIntensity(0.3);
|
13
|
+
world.setAmbientLightColor({ r: 255, g: 192, b: 192 });
|
14
|
+
world.setDirectionalLightIntensity(0.8);
|
15
|
+
|
16
|
+
// Setup invisible walls that only enemies can pass through
|
17
|
+
INVISIBLE_WALLS.forEach(wall => {
|
18
|
+
const wallCollider = new Collider({
|
19
|
+
shape: ColliderShape.BLOCK,
|
20
|
+
halfExtents: wall.halfExtents,
|
21
|
+
relativePosition: wall.position, // since this is not attached to a rigid body, relative position is realtive to the world global coordinate space.
|
22
|
+
});
|
23
|
+
|
24
|
+
wallCollider.addToSimulation(world.simulation);
|
25
|
+
});
|
26
|
+
|
27
|
+
// Setup purchase barriers
|
28
|
+
PURCHASE_BARRIERS.forEach(barrier => {
|
29
|
+
const purchaseBarrier = new PurchaseBarrierEntity({
|
30
|
+
name: barrier.name,
|
31
|
+
removalPrice: barrier.removalPrice,
|
32
|
+
width: barrier.width,
|
33
|
+
});
|
34
|
+
|
35
|
+
purchaseBarrier.spawn(world, barrier.position, barrier.rotation);
|
36
|
+
});
|
37
|
+
|
38
|
+
// Spawn a player entity when a player joins the game.
|
39
|
+
world.onPlayerJoin = player => {
|
40
|
+
const playerEntity = new GamePlayerEntity(player);
|
41
|
+
|
42
|
+
playerEntity.spawn(world, { x: 2, y: 10, z: 19 });
|
43
|
+
};
|
44
|
+
|
45
|
+
// Despawn all player entities when a player leaves the game.
|
46
|
+
world.onPlayerLeave = player => {
|
47
|
+
world.entityManager.getPlayerEntitiesByPlayer(player).forEach(entity => entity.despawn());
|
48
|
+
};
|
49
|
+
});
|
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"name": "zombies-fps",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "",
|
5
|
+
"main": "index.js",
|
6
|
+
"scripts": {
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
8
|
+
},
|
9
|
+
"keywords": [],
|
10
|
+
"author": "",
|
11
|
+
"license": "ISC",
|
12
|
+
"dependencies": {
|
13
|
+
"@hytopia.com/assets": "^0.2.5",
|
14
|
+
"hytopia": "^0.1.93"
|
15
|
+
}
|
16
|
+
}
|