-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsignEntity4.js
More file actions
360 lines (300 loc) · 13 KB
/
Copy pathsignEntity4.js
File metadata and controls
360 lines (300 loc) · 13 KB
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
/**
* SignEntity4.js - Ceiling sign entity for Circuit Sanctum Arcade
* Handles loading and rendering of ceiling-mounted sign entities
*/
import { Entity } from './entity.js';
import assetLoader from './assetLoader.js';
import { debug } from './utils.js';
import { getAssetPath } from './pathResolver.js';
class SignEntity4 extends Entity {
/**
* Create a new ceiling sign entity
* @param {number} x - Grid X position
* @param {number} y - Grid Y position
* @param {number} width - Width in grid units
* @param {number} height - Height in grid units
* @param {string} signKey - Key for the sign asset in the asset loader
*/
constructor(x, y, width = 4.0, height = 4.0, signKey = 'sign4') {
super(x, y, width, height);
debug(`SignEntity4: Creating new ceiling sign at (${x}, ${y}) with key ${signKey}`);
// Sign specific properties
this.signKey = signKey; // Key for the sign asset
this.zHeight = 60; // Higher z-height for ceiling mounting
this.signImage = null; // Will hold the loaded image
this.loadAttempts = 0; // Track loading attempts
this.maxLoadAttempts = 3; // Maximum loading attempts
// Ensure sign has no velocity
this.velocityX = 0;
this.velocityY = 0;
this.isStatic = true; // Make sign static so it doesn't move
this.collidable = false; // Disable collision for ceiling sign so player can walk beneath it
// Check asset loader first
const existingAsset = assetLoader.getAsset(signKey);
if (existingAsset) {
debug(`SignEntity4: Found existing asset for ${signKey} in asset loader`);
this.signImage = existingAsset;
} else {
debug(`SignEntity4: No existing asset found for ${signKey}, will load directly`);
}
// Directly try to load the sign image
this.directLoadSignImage();
}
/**
* Directly load the sign image without relying on asset loader
*/
directLoadSignImage() {
if (this.signImage) {
debug(`SignEntity4: Sign image already loaded, skipping direct load`);
return;
}
debug(`SignEntity4: Directly loading sign image (attempt ${this.loadAttempts + 1}/${this.maxLoadAttempts})`);
// Create a new image directly
const img = new Image();
img.onload = () => {
debug(`SignEntity4: Successfully loaded sign image directly (${img.width}x${img.height})`);
this.signImage = img;
// Also store in asset loader for other components
assetLoader.assets[this.signKey] = img;
debug(`SignEntity4: Stored sign image in asset loader with key ${this.signKey}`);
};
img.onerror = (err) => {
console.error(`SignEntity4: Failed to load sign image directly`, err);
this.loadAttempts++;
if (this.loadAttempts < this.maxLoadAttempts) {
debug(`SignEntity4: Will try alternative path (attempt ${this.loadAttempts + 1})`);
// Try again with a slightly different path
setTimeout(() => this.tryAlternativePath(), 200);
} else {
debug(`SignEntity4: All ${this.maxLoadAttempts} attempts failed, creating fallback`);
this.createFallbackImage();
}
};
// Use exact path with proper path resolution
const exactPath = 'assets/decor/Sign_4.png';
const resolvedPath = getAssetPath(exactPath);
debug(`SignEntity4: Setting image src to resolved path: ${resolvedPath}`);
img.src = resolvedPath;
}
/**
* Try loading from alternative paths
*/
tryAlternativePath() {
debug(`SignEntity4: Trying alternative path for sign image`);
const alternativePaths = [
'assets/decor/Sign_4.png',
'../assets/decor/Sign_4.png',
'./assets/decor/Sign_4.png',
'/assets/decor/Sign_4.png',
'Sign_4.png'
];
// Use an appropriate path from the list based on current attempt
const pathIndex = this.loadAttempts % alternativePaths.length;
const alternativePath = alternativePaths[pathIndex];
debug(`SignEntity4: Trying alternative path: ${alternativePath}`);
const img = new Image();
img.onload = () => {
debug(`SignEntity4: Successfully loaded sign image from alternative path: ${alternativePath}`);
this.signImage = img;
// Also store in asset loader
assetLoader.assets[this.signKey] = img;
};
img.onerror = (err) => {
console.error(`SignEntity4: Failed to load sign image from alternative path: ${alternativePath}`, err);
this.loadAttempts++;
if (this.loadAttempts < this.maxLoadAttempts) {
debug(`SignEntity4: Will try another path (attempt ${this.loadAttempts + 1})`);
// Try again with a slightly different path
setTimeout(() => this.tryAlternativePath(), 300);
} else {
debug(`SignEntity4: All ${this.maxLoadAttempts} attempts failed, creating fallback`);
this.createFallbackImage();
}
};
img.src = alternativePath;
}
/**
* Create a fallback canvas-based image for the sign
*/
createFallbackImage() {
debug(`SignEntity4: Creating fallback sign image`);
// Create a canvas for the fallback image
const canvas = document.createElement('canvas');
canvas.width = 256;
canvas.height = 192;
const ctx = canvas.getContext('2d');
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw stylized fallback sign - cyberpunk style for ceiling sign
// Background gradient
const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
gradient.addColorStop(0, '#440044');
gradient.addColorStop(1, '#000044');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Neon-like border
ctx.strokeStyle = '#FF00FF';
ctx.lineWidth = 5;
ctx.strokeRect(10, 10, canvas.width - 20, canvas.height - 20);
// Inner glow
ctx.shadowColor = '#FF00FF';
ctx.shadowBlur = 15;
ctx.strokeStyle = '#8800FF';
ctx.lineWidth = 2;
ctx.strokeRect(20, 20, canvas.width - 40, canvas.height - 40);
// Circuit-like lines
ctx.beginPath();
ctx.moveTo(30, 40);
ctx.lineTo(80, 40);
ctx.lineTo(80, 70);
ctx.lineTo(canvas.width - 30, 70);
ctx.strokeStyle = '#00FFFF';
ctx.lineWidth = 2;
ctx.shadowColor = '#00FFFF';
ctx.shadowBlur = 8;
ctx.stroke();
// Text
ctx.fillStyle = '#FFFFFF';
ctx.font = 'bold 28px "Courier New", monospace';
ctx.textAlign = 'center';
ctx.shadowColor = '#FF00FF';
ctx.shadowBlur = 10;
ctx.fillText('CEILING SIGN', canvas.width / 2, canvas.height / 2);
// Secondary text
ctx.fillStyle = '#00FFFF';
ctx.font = '18px Arial, sans-serif';
ctx.fillText('Circuit Sanctum', canvas.width / 2, canvas.height / 2 + 30);
// Create an image from the canvas
const fallbackImg = new Image();
// Store the fallback image
fallbackImg.onload = () => {
debug(`SignEntity4: Fallback image created successfully`);
this.signImage = fallbackImg;
assetLoader.assets[this.signKey] = fallbackImg;
};
fallbackImg.src = canvas.toDataURL('image/png');
}
/**
* Draw a fallback sign when the image fails to load
* @param {CanvasRenderingContext2D} ctx - Canvas context
* @param {number} screenX - Screen X position
* @param {number} screenY - Screen Y position
* @param {number} width - Render width
* @param {number} height - Render height
* @param {number} zOffset - Z offset for rendering height
*/
drawFallbackSign(ctx, screenX, screenY, width, height, zOffset) {
debug(`SignEntity4: Drawing fallback ceiling sign`);
// Save context for restoration later
ctx.save();
// Calculate sign dimensions
const signWidth = width * 1.2;
const signHeight = height * 1.6;
// Position sign (higher z-offset for ceiling mounting)
const signX = screenX - signWidth / 2;
const signY = screenY - signHeight - zOffset - this.zHeight;
// Draw sign background - darker for ceiling sign
ctx.fillStyle = '#220033';
ctx.fillRect(
signX,
signY,
signWidth,
signHeight
);
// Add glow effect
ctx.shadowColor = '#FF00FF';
ctx.shadowBlur = 10;
ctx.strokeStyle = '#FF00FF';
ctx.lineWidth = 2;
ctx.strokeRect(
signX,
signY,
signWidth,
signHeight
);
// Add tech circuit lines
ctx.beginPath();
ctx.moveTo(signX + signWidth * 0.2, signY + signHeight * 0.1);
ctx.lineTo(signX + signWidth * 0.4, signY + signHeight * 0.1);
ctx.lineTo(signX + signWidth * 0.4, signY + signHeight * 0.2);
ctx.lineTo(signX + signWidth * 0.6, signY + signHeight * 0.2);
ctx.strokeStyle = '#00FFFF';
ctx.stroke();
// Add text to the sign with glow
ctx.shadowColor = '#FF00FF';
ctx.shadowBlur = 8;
ctx.fillStyle = '#FFFFFF';
ctx.font = 'bold 14px "Courier New", monospace';
ctx.textAlign = 'center';
ctx.fillText(
'CEILING',
screenX,
signY + signHeight / 3
);
ctx.fillText(
'SIGN',
screenX,
signY + signHeight / 2
);
// Add decorative elements
ctx.font = '10px serif';
ctx.fillStyle = '#00FFFF';
ctx.fillText(
'⚡ ✧ ⚡',
screenX,
signY + signHeight * 0.7
);
// No mounting chain/rope for cleaner visual appearance
// Reset shadow
ctx.shadowBlur = 0;
// Restore context
ctx.restore();
}
/**
* Custom draw method for sign entity
* @param {CanvasRenderingContext2D} ctx - Canvas context
* @param {number} screenX - Screen X position
* @param {number} screenY - Screen Y position
* @param {number} width - Render width
* @param {number} height - Render height
* @param {number} zOffset - Z offset for rendering height
*/
draw(ctx, screenX, screenY, width, height, zOffset) {
debug(`SignEntity4: Drawing ceiling sign at (${this.x}, ${this.y}) -> screen (${screenX}, ${screenY})`);
try {
// Get sign image - either from our direct loading or asset loader as fallback
const signImage = this.signImage || assetLoader.getAsset(this.signKey);
if (signImage) {
debug(`SignEntity4: Image found, drawing actual ceiling sign`);
// Draw sign image
const signWidth = width * .9;
const signHeight = height * 1.6;
// Position sign higher for ceiling mounting
const signX = screenX - signWidth / 2;
const signY = screenY - signHeight - zOffset - this.zHeight;
// Draw the sign
ctx.drawImage(
signImage,
signX,
signY,
signWidth,
signHeight
);
// No mounting chain/rope visible for cleaner look
debug(`SignEntity4: Ceiling sign image drawn successfully`);
} else {
debug(`SignEntity4: No image available, drawing fallback`);
// If no image is loaded yet, try loading again if we haven't exceeded attempts
if (this.loadAttempts < this.maxLoadAttempts) {
this.directLoadSignImage();
}
// Draw fallback while loading or if loading failed
this.drawFallbackSign(ctx, screenX, screenY, width, height, zOffset);
}
} catch (err) {
console.error(`SignEntity4: Error drawing ceiling sign:`, err);
this.drawFallbackSign(ctx, screenX, screenY, width, height, zOffset);
}
}
}
export { SignEntity4 };