-
-
Notifications
You must be signed in to change notification settings - Fork 87
/
Trigger.js
163 lines (116 loc) · 3.51 KB
/
Trigger.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import { TriggerRegion } from './TriggerRegion.js';
import { RectangularTriggerRegion } from './regions/RectangularTriggerRegion.js';
import { SphericalTriggerRegion } from './regions/SphericalTriggerRegion.js';
import { GameEntity } from '../core/GameEntity.js';
import { Logger } from '../core/Logger.js';
/**
* Base class for representing triggers. A trigger generates an action if a game entity
* touches its trigger region, a predefine area in 3D space.
*
* @author {@link https://github.com/Mugen87|Mugen87}
* @augments GameEntity
*/
class Trigger extends GameEntity {
/**
* Constructs a new trigger with the given values.
*
* @param {TriggerRegion} region - The region of the trigger.
*/
constructor( region = new TriggerRegion() ) {
super();
/**
* The region of the trigger.
* @type {TriggerRegion}
*/
this.region = region;
//
this.canActivateTrigger = false; // triggers can't activate other triggers by default
this._typesMap = new Map(); // used for deserialization of custom trigger regions
}
/**
* This method is called per simulation step for all game entities. If the game
* entity touches the region of the trigger, the respective action is executed.
*
* @param {GameEntity} entity - The entity to test
* @return {Trigger} A reference to this trigger.
*/
check( entity ) {
if ( this.region.touching( entity ) === true ) {
this.execute( entity );
}
return this;
}
/**
* This method is called when the trigger should execute its action.
* Must be implemented by all concrete triggers.
*
* @param {GameEntity} entity - The entity that touched the trigger region.
* @return {Trigger} A reference to this trigger.
*/
execute( /* entity */ ) {}
/**
* Updates the region of this trigger. Called by the {@link EntityManager} per
* simulation step.
*
* @return {Trigger} A reference to this trigger.
*/
updateRegion() {
this.region.update( this );
return this;
}
/**
* Transforms this instance into a JSON object.
*
* @return {Object} The JSON object.
*/
toJSON() {
const json = super.toJSON();
json.region = this.region.toJSON();
return json;
}
/**
* Restores this instance from the given JSON object.
*
* @param {Object} json - The JSON object.
* @return {Trigger} A reference to this trigger.
*/
fromJSON( json ) {
super.fromJSON( json );
const regionJSON = json.region;
let type = regionJSON.type;
switch ( type ) {
case 'TriggerRegion':
this.region = new TriggerRegion().fromJSON( regionJSON );
break;
case 'RectangularTriggerRegion':
this.region = new RectangularTriggerRegion().fromJSON( regionJSON );
break;
case 'SphericalTriggerRegion':
this.region = new SphericalTriggerRegion().fromJSON( regionJSON );
break;
default:
// handle custom type
const ctor = this._typesMap.get( type );
if ( ctor !== undefined ) {
this.region = new ctor().fromJSON( regionJSON );
} else {
Logger.warn( 'YUKA.Trigger: Unsupported trigger region type:', regionJSON.type );
}
}
return this;
}
/**
* Registers a custom type for deserialization. When calling {@link Trigger#fromJSON}
* the trigger is able to pick the correct constructor in order to create custom
* trigger regions.
*
* @param {String} type - The name of the trigger region.
* @param {Function} constructor - The constructor function.
* @return {Trigger} A reference to this trigger.
*/
registerType( type, constructor ) {
this._typesMap.set( type, constructor );
return this;
}
}
export { Trigger };