Files
void-genesis/dev/lobby-frontend/src/main.js
T
2026-05-26 20:18:12 +02:00

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();