I’m trying to set up the Conway’s Game of Life using Phaser.
My question is this: how can I make a Rectangular
of the Phaser.geom
class contain a click event?
Class Dots:
JavaScript
x
47
47
1
import 'phaser';
2
3
const COLOUR_ALIVE = 0xffffff;
4
const COLOUR_DEAD = 0x00000;
5
export class Dots extends Phaser.Geom.Rectangle {
6
public alive: number;
7
public fillColor: number;
8
public id: string;
9
constructor(scene, x, y, width, height, alive, id?) {
10
super(x, y, width, height);
11
this.alive = alive;
12
if(this.alive == 1){
13
this.fillColor = COLOUR_ALIVE;
14
} else {
15
this.fillColor = COLOUR_DEAD;
16
}
17
this.id = id;
18
console.log(id);
19
}
20
21
public isAlive():boolean{
22
return (this.alive == 1);
23
}
24
25
public returnAliveValue():number{
26
return this.alive;
27
}
28
29
public getFillColor(): number{
30
return this.fillColor;
31
}
32
33
public dead(){
34
this.alive = 0;
35
this.fillColor = COLOUR_DEAD;
36
}
37
38
public setAlive(){
39
this.alive = 1;
40
this.fillColor = COLOUR_ALIVE;
41
}
42
43
public click(pointer, gameobject){
44
console.log(pointer, gameobject);
45
}
46
}
47
Class Game:
JavaScript
1
199
199
1
import 'phaser';
2
import {Dots} from './classes/Dots'
3
4
const square_size = 10;
5
const pixel_height = 600;
6
const pixel_width = 800;
7
const DOTS = 100;
8
export default class Demo extends Phaser.Scene
9
{
10
private alives: Dots[] = [];
11
private graphics:Phaser.GameObjects.Graphics = null;
12
public timeElapsed: number;
13
public maxTime: number;
14
public cont = 0;
15
16
constructor ()
17
{
18
super('demo');
19
this.timeElapsed = 0;
20
this.maxTime = 1;
21
}
22
23
preload ()
24
{
25
}
26
27
draw () {
28
this.graphics = this.add.graphics();
29
//Afegim les fitxes vives
30
let pointer = this.input.activePointer;
31
this.alives.forEach((rectangle:Dots) => {
32
this.graphics.fillStyle(rectangle.getFillColor(), 1);
33
this.graphics.fillRectShape(rectangle);
34
this.graphics.setInteractive({
35
hitArea: new Phaser.Geom.Rectangle(0, 22, 27, 29),
36
hitAreaCallback: Phaser.Geom.Rectangle.Contains,
37
useHandCursor: true
38
}, (evt, geom) => {
39
if(pointer.isDown){
40
console.log(evt, geom);
41
}
42
});
43
});
44
}
45
46
destroy(obj:Phaser.GameObjects.Graphics) {
47
obj.destroy();
48
}
49
50
intersects(object1:Dots, object2:Dots){
51
let x = object1.x;
52
let y = object1.y;
53
let intersects = false;
54
55
if(object2.x == x - square_size && y == object2.y){
56
//Bloque izquierda
57
intersects = true;
58
} else if( object2.x == x + square_size && y == object2.y){
59
//Bloque derecha
60
intersects = true;
61
}
62
63
if(object2.y == y - square_size && x == object2.x){
64
//Bloque superior
65
intersects = true;
66
} else if(object2.y == y + square_size && x == object2.x){
67
//Bloque inferior
68
intersects = true;
69
}
70
71
if(object2.x == x - square_size && object2.y == y - square_size){
72
// Bloque izquierda superior
73
intersects = true;
74
} else if (object2.x == x - square_size && object2.y == y + square_size){
75
// Bloque izquierda inferior
76
intersects = true;
77
}
78
79
if(object2.x == x + square_size && object2.y == y - square_size){
80
// Bloque derecha superior
81
intersects = true;
82
} else if (object2.x == x + square_size && object2.y == y + square_size){
83
// Bloque derecha inferior
84
intersects = true;
85
}
86
87
return intersects;
88
}
89
90
searchArrIntersect(){
91
this.alives.forEach((x) => {
92
if(x.alive == 1){
93
let intersections = 0;
94
this.alives.forEach((y) => {
95
if(x != y){
96
let intersects = this.intersects(x, y);
97
if(intersects){
98
intersections ++;
99
}
100
}
101
});
102
if(intersections == 2 || intersections == 3){
103
x.isAlive();
104
}
105
if(intersections >= 3){
106
x.dead();
107
}
108
} else{
109
//fichas muertas
110
let intersections = 0;
111
this.alives.forEach((y) => {
112
if(x != y){
113
let intersects = this.intersects(x, y);
114
if(intersects){
115
intersections ++;
116
}
117
}
118
});
119
if(intersections == 3){
120
x.isAlive();
121
}
122
}
123
});
124
}
125
126
castObjectIntersects(object_search:Dots):Dots{
127
let dot_intersect = null;
128
this.alives.forEach((x, index) => {
129
if(x.x == object_search.x && x.y == object_search.y){
130
dot_intersect = x;
131
}
132
});
133
return dot_intersect;
134
}
135
136
create ()
137
{
138
let positions = [
139
//cross
140
// {x: pixel_width/2 - square_size, y: pixel_height/2, alive:1, id:'left'},
141
// {x: pixel_width/2 + square_size, y: pixel_height/2, alive:1, id:'right'},
142
// {x: pixel_width/2, y: pixel_height/2, alive:1, id:'center'},
143
// {x: pixel_width/2, y: pixel_height/2 - square_size, alive:1, id:'up'},
144
// {x: pixel_width/2, y: pixel_height/2 + square_size, alive:1, id:'down'},
145
// //borders
146
// //left
147
// {x: pixel_width/2 - square_size, y: pixel_height/2 - square_size, alive: 1, id:'left_up'},
148
// {x: pixel_width/2 - square_size, y: pixel_height/2 + square_size, alive: 1, id:'left_down'},
149
// //right
150
// {x: pixel_width/2 + square_size, y: pixel_height/2 - square_size, alive:0, id:'right_up'},
151
// {x: pixel_width/2 + square_size, y: pixel_height/2 + square_size, alive:0, id:'right_down'},
152
];
153
for(let i = 0; i < pixel_width; i+=10){
154
for(let j = 0; j < pixel_height; j+=10){
155
positions.push({x: i, y: j, alive:0, id:`${i}-${j}`});
156
}
157
}
158
positions.forEach((obj) => {
159
this.alives.push(new Dots(this, obj.x, obj.y, square_size, square_size, obj.alive, obj.id));
160
});
161
for(let i = 0; i <= DOTS; i++){
162
let random_length = Math.floor(Math.random() * (this.alives.length - 1 + 1) + 1);
163
let dot = this.alives[random_length];
164
dot.setAlive();
165
}
166
this.draw();
167
}
168
169
update(time: number, delta: number): void {
170
let deltaInSecond = delta/1000; // convert it to second
171
this.timeElapsed = this.timeElapsed + deltaInSecond;
172
if(this.timeElapsed >= this.maxTime) // if the time elapsed already more than 1 second
173
{
174
this.searchArrIntersect();
175
this.destroy(this.graphics);
176
this.draw();
177
// this.maxTime = 1200;
178
this.timeElapsed = 0;
179
}
180
}
181
}
182
183
const config = {
184
type: Phaser.AUTO,
185
backgroundColor: '#000000',
186
width: pixel_width,
187
height: pixel_height,
188
render: {
189
pixelArt: true
190
},
191
scale: {
192
mode: Phaser.Scale.FIT,
193
autoCenter: Phaser.Scale.CENTER_BOTH
194
},
195
scene: Demo
196
};
197
198
const game = new Phaser.Game(config);
199
Advertisement
Answer
You are setting interactive on the graphics
serveral time, it the forEach-loop. I think this can be done only once, so you are overriding it, but I’m no expert.
I would set the interactivity once, for the whole region:
JavaScript
1
5
1
this.graphics.setInteractive({ useHandCursor: true,
2
hitArea: new Phaser.Geom.Rectangle(0, 0, pixel_width, pixel_height),
3
hitAreaCallback: Phaser.Geom.Rectangle.Contains,
4
})
5
And than in the “click event” select the Rectangle/Dot
JavaScript
1
4
1
this.graphics.on( 'pointerdown', function(){
2
// ...
3
});
4
To get the Rectangle/Dot clicked, there are many ways, here is one:
JavaScript
1
7
1
this.graphics.on( 'pointerdown', function(pointer){
2
let selected = this.alives.find( point => Phaser.Geom.Rectangle.Contains( new
3
Phaser.Geom.Rectangle(point.x, point.y, point.width, point.height), pointer.worldX, pointer.worldY
4
));
5
console.log('pointerover', pointer, selected);
6
}, this);
7
btw.:
I would add the graphics
once in the create
method:
JavaScript
1
14
14
1
create () {
2
// ...
3
this.graphics = this.add.graphics();
4
this.graphics.setInteractive({
5
// ...
6
});
7
8
this.graphics.on('pointerdown', () => {
9
// ...
10
});
11
12
this.draw();
13
}
14
and in the draw method just clear the graphics-object.
JavaScript
1
5
1
draw () {
2
this.graphics.clear();
3
// ...
4
}
5