400 lines
14 KiB
JavaScript
400 lines
14 KiB
JavaScript
import { Application, Assets, Sprite, NineSliceSprite, Container, TilingSprite, Text, wordWrap } from 'pixi.js';
|
|
|
|
async function initGame() {
|
|
const app = new Application();
|
|
|
|
await app.init({
|
|
resizeTo: window,
|
|
backgroundAlpha: 0,
|
|
antialias: true,
|
|
resolution: window.devicePixelRatio || 1,
|
|
autoDensity: true,
|
|
});
|
|
|
|
document.getElementById('pixi-container').appendChild(app.canvas);
|
|
|
|
try {
|
|
const assetsToLoad = {
|
|
//background: 'src/raw-assets/backgrounds/SPR_SciFiMenus_Example_Image_SpookyComputer_01.png',
|
|
background: 'src/raw-assets/backgrounds/SPR_SciFiMenus_Example_Image_SpaceStation_01.png',
|
|
|
|
uiAtlas: 'src/assets/ui-atlas.json'
|
|
};
|
|
|
|
const backgroundTexture = await Assets.load(assetsToLoad.background);
|
|
const uiSpritesheet = await Assets.load(assetsToLoad.uiAtlas);
|
|
|
|
await document.fonts.load('16px "UI Font"');
|
|
await document.fonts.load('16px "Logo Font"');
|
|
|
|
buildScene(app, backgroundTexture, uiSpritesheet);
|
|
|
|
} catch (error) {
|
|
console.error("Fehler beim Laden der Assets:", error);
|
|
}
|
|
}
|
|
|
|
function buildScene(app, bgTexture, sheet) {
|
|
// --- Farb-Variablen (pixiJS) ---
|
|
const COLOR_PANEL_BG = 0x0b192c; // Dunkelblau für Panel & Inputs
|
|
const COLOR_PATTERN = 0x00f0ff; // Cyan für das Hexagon-Muster
|
|
const COLOR_TAB_ACTIVE = 0x00f0ff; // Cyan für aktiven Tab
|
|
const COLOR_TAB_INACTIVE = 0xaaaaaa; // Grau für inaktiven Tab
|
|
const COLOR_TAB_HOVER = 0xffffff; // Weiß beim Hovern der Tabs
|
|
const COLOR_BTN_DEFAULT = 0x00aa00; // Dunkelgrün für Registrieren Button
|
|
const COLOR_BTN_HOVER = 0x00ff00; // Hellgrün beim Hovern des Buttons
|
|
const COLOR_LOGO = 0x00f0ff; // Farbe des Logos
|
|
const COLOR_DISCORD_TEXT = 0xdaffde; // Hellgrün für Discord Text
|
|
const COLOR_DISCORD_TEXT_HOVER = 0xffffff; // Weiß beim Hovern des Discord Links
|
|
|
|
// --- Asset-Namen ---
|
|
const frameInput = 'SPR_SciFiMenus_Menu_Item_Selected_19'; // Rahmen für Eingabefelder
|
|
const frameBtn = 'SPR_SciFiMenus_Menu_Item_Selected_10'; // Rahmen für Tabs/Buttons
|
|
const menuBgName = 'SPR_SciFiMenus_Menu_Item_Background_07'; // Füll Asset für die Rahmen
|
|
const panelBgName = 'SPR_SciFiMenus_Frame_Box_Large_02_Background'; // Füll Asset für das große Panel
|
|
const patternBgName = 'SPR_SciFiMenus_Background_Hexagons_01'; // Kachelbares Pattern
|
|
const panelFmName = 'SPR_SciFiMenus_Frame_Box_Large_02'; // Rahmen für das große Panel
|
|
|
|
// --- Icons ---
|
|
const iconUserName = 'ICON_SciFiMenus_Menu_Solo_01_Clean';
|
|
const iconEmailName = 'ICON_SciFi_Map_Message';
|
|
const iconLockName = 'ICON_SciFiMenus_Menu_Lock_Closed_01_Clean';
|
|
|
|
// --- Logo Ring ---
|
|
const logoRingName = 'SPR_SciFiMenus_Ring_Medium_13';
|
|
|
|
// --- Discord Panel ---
|
|
const discordFrameName = 'SPR_SciFiMenus_Frame_Box_Large_12';
|
|
const discordBgName = 'SPR_SciFiMenus_Frame_Box_Large_12_Background';
|
|
const discordIconName = 'ICON_Social_Discord';
|
|
|
|
// --- Hintergrund ---
|
|
const background = new Sprite(bgTexture);
|
|
app.stage.addChild(background);
|
|
|
|
// --- Haupt-UI-Container ---
|
|
const uiContainer = new Container();
|
|
app.stage.addChild(uiContainer);
|
|
|
|
const panelBackground = new Sprite(sheet.textures[panelBgName]);
|
|
panelBackground.tint = COLOR_PANEL_BG;
|
|
panelBackground.width = 500;
|
|
panelBackground.height = 520;
|
|
panelBackground.position.set(0, -10);
|
|
uiContainer.addChild(panelBackground);
|
|
|
|
// --- Footer Hintergund in PixiJS kacheln
|
|
const footerBackgroundContainer = new Container();
|
|
|
|
const footerBackground = new TilingSprite({
|
|
texture: sheet.textures['SPR_SciFiMenus_Background_01'],
|
|
height: 40,
|
|
});
|
|
footerBackground.tileScale.set(1.0);
|
|
footerBackground.tint = 0x000000;
|
|
footerBackground.alpha = 1.0;
|
|
footerBackgroundContainer.addChild(footerBackground);
|
|
app.stage.addChild(footerBackgroundContainer);
|
|
|
|
const footerPattern = new TilingSprite({
|
|
texture: sheet.textures[patternBgName],
|
|
height: 40,
|
|
});
|
|
footerPattern.tileScale.set(0.3);
|
|
footerPattern.tint = COLOR_PATTERN;
|
|
footerPattern.alpha = 0.01;
|
|
footerBackgroundContainer.addChild(footerPattern);
|
|
app.stage.addChild(footerBackgroundContainer);
|
|
|
|
// --- Hexagon pattern
|
|
const pattern = new TilingSprite({
|
|
texture: sheet.textures[patternBgName],
|
|
width: 500,
|
|
height: 520,
|
|
});
|
|
pattern.tileScale.set(0.3);
|
|
pattern.position.set(0, -10);
|
|
pattern.alpha = 0.05;
|
|
pattern.tint = COLOR_PATTERN;
|
|
uiContainer.addChild(pattern);
|
|
|
|
// --- Main UI
|
|
const panelFrame = new NineSliceSprite({
|
|
texture: sheet.textures[panelFmName],
|
|
leftWidth: 510,
|
|
topHeight: 510,
|
|
rightWidth: 510,
|
|
bottomHeight: 510
|
|
});
|
|
panelFrame.width = 500;
|
|
panelFrame.height = 500;
|
|
uiContainer.addChild(panelFrame);
|
|
|
|
// --- Logo ---
|
|
const logoContainer = new Container();
|
|
logoContainer.position.set(250, -120);
|
|
|
|
const logoRing = new Sprite(sheet.textures[logoRingName]);
|
|
logoRing.anchor.set(0.5);
|
|
logoRing.tint = COLOR_LOGO;
|
|
logoRing.alpha = 1.0;
|
|
logoRing.scale.set(0.2);
|
|
logoContainer.addChild(logoRing);
|
|
|
|
const logoText = new Text({
|
|
text: 'Void-Genesis',
|
|
style: {
|
|
fontFamily: 'Logo Font',
|
|
fontSize: 50,
|
|
fill: COLOR_LOGO,
|
|
letterSpacing: 8,
|
|
}
|
|
});
|
|
logoText.anchor.set(0.5);
|
|
logoContainer.addChild(logoText);
|
|
|
|
uiContainer.addChild(logoContainer);
|
|
|
|
// --- UI Elemente ---
|
|
const tabLogin = createUIItem(65, 60, 180, 40, frameBtn, null, COLOR_TAB_INACTIVE, 0.6);
|
|
const tabRegister = createUIItem(255, 60, 180, 40, frameBtn, null, COLOR_TAB_ACTIVE, 0.4);
|
|
|
|
const inputUser = createUIItem(115, 135, 300, 50, frameInput, iconUserName, COLOR_PANEL_BG, 0.8);
|
|
const inputEmail = createUIItem(115, 200, 300, 50, frameInput, iconEmailName, COLOR_PANEL_BG, 0.8);
|
|
const inputLock = createUIItem(115, 265, 300, 50, frameInput, iconLockName, COLOR_PANEL_BG, 0.8);
|
|
|
|
const btnRegister = createUIItem(65, 370, 370, 55, frameBtn, null, COLOR_BTN_DEFAULT, 0.6);
|
|
|
|
// --- Discord Panel ---
|
|
const discordContainer = new Container();
|
|
discordContainer.position.set(640, 380);
|
|
|
|
const discordBackground = new NineSliceSprite({
|
|
texture: sheet.textures[discordBgName],
|
|
leftWidth: 0,
|
|
topHeight: 0,
|
|
rightWidth: 0,
|
|
bottomHeight: 0
|
|
});
|
|
discordBackground.tint = COLOR_PANEL_BG;
|
|
discordBackground.width = 255;
|
|
discordBackground.height = 75;
|
|
discordContainer.addChild(discordBackground);
|
|
|
|
const discordPattern = new TilingSprite({
|
|
texture: sheet.textures[patternBgName],
|
|
width: 255,
|
|
height: 75,
|
|
});
|
|
discordPattern.tileScale.set(0.3);
|
|
discordPattern.tint = COLOR_PATTERN;
|
|
discordPattern.alpha = 0.05;
|
|
discordContainer.addChild(discordPattern);
|
|
|
|
const discordFrame = new NineSliceSprite({
|
|
texture: sheet.textures[discordFrameName],
|
|
leftWidth: 0,
|
|
topHeight: 0,
|
|
rightWidth: 0,
|
|
bottomHeight: 0
|
|
});
|
|
discordFrame.width = 280;
|
|
discordFrame.height = 85;
|
|
discordFrame.position.set(-15, -10);
|
|
discordContainer.addChild(discordFrame);
|
|
|
|
const discordIcon = new Sprite(sheet.textures[discordIconName]);
|
|
discordIcon.position.set(10, 15);
|
|
discordIcon.scale.set(0.15);
|
|
discordIcon.tint = COLOR_TAB_INACTIVE;
|
|
discordContainer.addChild(discordIcon);
|
|
|
|
const discordText = new Text({
|
|
text: 'Offizieller Discord Server',
|
|
style: {
|
|
fontFamily: 'UI Font',
|
|
fontSize: 14,
|
|
fill: COLOR_TAB_INACTIVE,
|
|
wordWrap: false,
|
|
wordWrapWidth: 120
|
|
}
|
|
});
|
|
discordText.position.set(60, 25);
|
|
discordContainer.addChild(discordText);
|
|
|
|
uiContainer.addChild(discordContainer);
|
|
|
|
const htmlTabLogin = document.getElementById('tab-login');
|
|
const htmlTabRegistert = document.getElementById('tab-register');
|
|
const htmlButton = document.getElementById('btn-register');
|
|
let isLoginMode = false;
|
|
|
|
htmlTabLogin.addEventListener('mouseenter', () => {
|
|
if (!isLoginMode) {
|
|
tabLogin.fill.tint = COLOR_TAB_HOVER;
|
|
tabLogin.fill.alpha = 0.8;
|
|
}
|
|
});
|
|
|
|
htmlTabLogin.addEventListener('mouseleave', () => {
|
|
if (!isLoginMode) {
|
|
tabLogin.fill.tint = COLOR_TAB_INACTIVE;
|
|
tabLogin.fill.alpha = 0.4;
|
|
}
|
|
});
|
|
|
|
htmlTabRegistert.addEventListener('mouseenter', () => {
|
|
if (isLoginMode) {
|
|
tabRegister.fill.tint = COLOR_TAB_HOVER;
|
|
tabRegister.fill.alpha = 0.8;
|
|
}
|
|
});
|
|
|
|
htmlTabRegistert.addEventListener('mouseleave', () => {
|
|
if (isLoginMode) {
|
|
tabRegister.fill.tint = COLOR_TAB_INACTIVE;
|
|
tabRegister.fill.alpha = 0.4;
|
|
}
|
|
});
|
|
|
|
htmlButton.addEventListener('mouseenter', () => {
|
|
btnRegister.fill.tint = COLOR_BTN_HOVER;
|
|
btnRegister.fill.alpha = 1.0;
|
|
});
|
|
|
|
htmlButton.addEventListener('mouseleave', () => {
|
|
btnRegister.fill.tint = COLOR_BTN_DEFAULT;
|
|
btnRegister.fill.alpha = 0.6;
|
|
});
|
|
|
|
const htmlDiscord = document.getElementById('discord-link');
|
|
if (htmlDiscord) {
|
|
htmlDiscord.addEventListener('mouseenter', () => {
|
|
discordIcon.tint = COLOR_TAB_HOVER;
|
|
discordText.style.fill = COLOR_TAB_HOVER;
|
|
});
|
|
htmlDiscord.addEventListener('mouseleave', () => {
|
|
discordIcon.tint = COLOR_TAB_INACTIVE;
|
|
discordText.style.fill = COLOR_TAB_INACTIVE;
|
|
});
|
|
}
|
|
|
|
function setLoginMode() {
|
|
if (isLoginMode) return;
|
|
isLoginMode = true;
|
|
|
|
tabLogin.fill.tint = COLOR_TAB_ACTIVE;
|
|
tabLogin.fill.alpha = 0.6;
|
|
tabRegister.fill.tint = COLOR_TAB_INACTIVE;
|
|
tabRegister.fill.alpha = 0.4;
|
|
htmlTabLogin.classList.add('active');
|
|
htmlTabRegistert.classList.remove('active');
|
|
|
|
inputEmail.container.visible = false;
|
|
document.getElementById('group-email').style.display = 'none';
|
|
|
|
inputLock.container.y = 200;
|
|
document.getElementById('password').style.top = '200px';
|
|
|
|
document.getElementById('group-remember').style.display = 'flex';
|
|
|
|
htmlButton.textContent = 'LOGIN';
|
|
document.getElementById('username').placeholder = 'Username / E-Mail';
|
|
|
|
document.getElementById('msg-box').textContent = '';
|
|
}
|
|
|
|
function setRegisterMode() {
|
|
if (!isLoginMode) return;
|
|
isLoginMode = false;
|
|
|
|
tabRegister.fill.tint = COLOR_TAB_ACTIVE;
|
|
tabRegister.fill.alpha = 0.6;
|
|
tabLogin.fill.tint = COLOR_TAB_INACTIVE;
|
|
tabLogin.fill.alpha = 0.4;
|
|
htmlTabRegistert.classList.add('active');
|
|
htmlTabLogin.classList.remove('active');
|
|
|
|
inputEmail.container.visible = true;
|
|
document.getElementById('group-email').style.display = 'block';
|
|
|
|
inputLock.container.y = 265;
|
|
document.getElementById('password').style.top = '265px';
|
|
|
|
document.getElementById('group-remember').style.display = 'none';
|
|
|
|
htmlButton.textContent = 'REGISTRIEREN';
|
|
document.getElementById('username').placeholder = 'Enter Username';
|
|
|
|
document.getElementById('msg-box').textContent = '';
|
|
}
|
|
|
|
function createUIItem(x, y, width, height, frameTextureName, iconTextureName, fillTint, fillAlpha) {
|
|
const itemContainer = new Container();
|
|
itemContainer.position.set(x, y);
|
|
|
|
const fill = new NineSliceSprite({
|
|
texture: sheet.textures[menuBgName],
|
|
leftWidth: 120,
|
|
topHeight: 120,
|
|
rightWidth: 120,
|
|
bottomHeight: 120
|
|
});
|
|
|
|
fill.width = width;
|
|
fill.height = height;
|
|
fill.tint = fillTint;
|
|
fill.alpha = fillAlpha;
|
|
itemContainer.addChild(fill);
|
|
|
|
const frame = new NineSliceSprite({
|
|
texture: sheet.textures[frameTextureName],
|
|
leftWidth: 100,
|
|
topHeight: 120,
|
|
rightWidth: 140,
|
|
bottomHeight: 120
|
|
});
|
|
|
|
frame.width = width;
|
|
frame.height = height;
|
|
frame.alpha = 0.8;
|
|
itemContainer.addChild(frame);
|
|
|
|
if (iconTextureName) {
|
|
const icon = new Sprite(sheet.textures[iconTextureName]);
|
|
icon.position.set(-45, (height - (icon.height * 0.15)) / 2 - 5);
|
|
icon.scale.set(0.15);
|
|
itemContainer.addChild(icon);
|
|
}
|
|
|
|
uiContainer.addChild(itemContainer);
|
|
|
|
return { container: itemContainer, fill, frame };
|
|
}
|
|
|
|
function resize() {
|
|
const screenWidth = app.screen.width;
|
|
const screenHeight = app.screen.height;
|
|
|
|
const scaleX = screenWidth / background.texture.width;
|
|
const scaleY = screenHeight / background.texture.height;
|
|
const scale = Math.max(scaleX, scaleY);
|
|
background.scale.set(scale);
|
|
background.x = (screenWidth - background.width) / 2;
|
|
background.y = (screenHeight - background.height) / 2;
|
|
|
|
uiContainer.x = (screenWidth - panelFrame.width) / 2;
|
|
uiContainer.y = (screenHeight - panelFrame.height) / 2;
|
|
|
|
footerBackground.width = screenWidth;
|
|
footerPattern.width = screenWidth;
|
|
footerBackgroundContainer.y = screenHeight - 40;
|
|
}
|
|
|
|
htmlTabLogin.addEventListener('click', setLoginMode);
|
|
htmlTabRegistert.addEventListener('click', setRegisterMode);
|
|
app.renderer.on('resize', resize);
|
|
resize();
|
|
}
|
|
|
|
initGame(); |