143 lines
4.4 KiB
JavaScript
143 lines
4.4 KiB
JavaScript
/**
|
|
* Galaxy Strike Online - Texture Manager
|
|
* Handles texture loading and missing texture fallbacks
|
|
*/
|
|
|
|
class TextureManager {
|
|
constructor(gameEngine) {
|
|
this.game = gameEngine;
|
|
this.textures = new Map();
|
|
this.missingTextureUrl = 'assets/textures/missing-texture.png';
|
|
|
|
// Initialize missing texture
|
|
this.loadMissingTexture();
|
|
}
|
|
|
|
async loadMissingTexture() {
|
|
try {
|
|
const img = new Image();
|
|
img.src = this.missingTextureUrl;
|
|
await img.decode();
|
|
this.textures.set('missing', img);
|
|
} catch (error) {
|
|
console.warn('Could not load missing texture, creating fallback');
|
|
this.createFallbackTexture();
|
|
}
|
|
}
|
|
|
|
createFallbackTexture() {
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = 64;
|
|
canvas.height = 64;
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
// Create a pink and black checkerboard pattern
|
|
const squareSize = 8;
|
|
for (let y = 0; y < 8; y++) {
|
|
for (let x = 0; x < 8; x++) {
|
|
ctx.fillStyle = (x + y) % 2 === 0 ? '#FF00FF' : '#000000';
|
|
ctx.fillRect(x * squareSize, y * squareSize, squareSize, squareSize);
|
|
}
|
|
}
|
|
|
|
// Add "GSO Missing" text
|
|
ctx.fillStyle = '#FFFFFF';
|
|
ctx.font = 'bold 12px Arial';
|
|
ctx.textAlign = 'center';
|
|
ctx.textBaseline = 'middle';
|
|
ctx.fillText('GSO', 32, 28);
|
|
ctx.fillText('Missing', 32, 36);
|
|
|
|
const img = new Image();
|
|
img.src = canvas.toDataURL();
|
|
this.textures.set('missing', img);
|
|
}
|
|
|
|
async loadTexture(textureId, textureUrl) {
|
|
// Check if already loaded
|
|
if (this.textures.has(textureId)) {
|
|
return this.textures.get(textureId);
|
|
}
|
|
|
|
try {
|
|
const img = new Image();
|
|
img.src = textureUrl;
|
|
await img.decode();
|
|
this.textures.set(textureId, img);
|
|
return img;
|
|
} catch (error) {
|
|
console.warn(`Failed to load texture ${textureId} from ${textureUrl}, using missing texture`);
|
|
return this.getMissingTexture();
|
|
}
|
|
}
|
|
|
|
getTexture(textureId) {
|
|
return this.textures.get(textureId) || this.getMissingTexture();
|
|
}
|
|
|
|
getMissingTexture() {
|
|
return this.textures.get('missing') || this.createFallbackTexture();
|
|
}
|
|
|
|
// Icon fallback for FontAwesome icons
|
|
getIcon(iconClass) {
|
|
// Check if this is a valid FontAwesome icon
|
|
const validIconPrefixes = ['fas', 'far', 'fab', 'fal'];
|
|
const iconParts = iconClass.split(' ');
|
|
const hasValidPrefix = iconParts.some(part => validIconPrefixes.includes(part));
|
|
|
|
if (hasValidPrefix) {
|
|
return iconClass;
|
|
}
|
|
|
|
// Return missing icon fallback - use missing texture
|
|
return 'missing-texture';
|
|
}
|
|
|
|
// Get item icon as HTML element
|
|
getItemIconElement(iconClass, size = '32px') {
|
|
const icon = this.getIcon(iconClass);
|
|
|
|
if (icon === 'missing-texture') {
|
|
return `<img src="assets/textures/missing-texture.png" style="width: ${size}; height: ${size}; object-fit: contain;" alt="Missing texture">`;
|
|
}
|
|
|
|
return `<i class="fas ${icon}" style="font-size: ${size};"></i>`;
|
|
}
|
|
|
|
// Preload common textures
|
|
async preloadTextures() {
|
|
const commonTextures = [
|
|
'ship_fighter',
|
|
'ship_cruiser',
|
|
'room_command_center',
|
|
'room_power_core',
|
|
'item_weapon',
|
|
'item_shield'
|
|
];
|
|
|
|
const loadPromises = commonTextures.map(textureId => {
|
|
const url = `assets/textures/${textureId}.png`;
|
|
return this.loadTexture(textureId, url);
|
|
});
|
|
|
|
try {
|
|
await Promise.all(loadPromises);
|
|
console.log('Common textures preloaded');
|
|
} catch (error) {
|
|
console.warn('Some textures failed to preload:', error);
|
|
}
|
|
}
|
|
|
|
// Clean up unused textures
|
|
cleanup() {
|
|
// Keep only essential textures in memory
|
|
const essentialTextures = ['missing'];
|
|
for (const [textureId, texture] of this.textures) {
|
|
if (!essentialTextures.includes(textureId)) {
|
|
this.textures.delete(textureId);
|
|
}
|
|
}
|
|
}
|
|
}
|