import * as PIXI from "pixi.js"; import { global, player } from "./globals.ts"; import { part_texture_url, planet_texture_url, indicator_texture_url, } from "./textures.ts"; import tex_starfield from "./assets/starfield_dim.svg"; import tex_starfield_transp from "./assets/starfield_transp.svg"; const PART_WIDTH = 50; const PART_HEIGHT = 50; export function startRender() { let app = new PIXI.Application({ width: window.innerWidth, height: window.innerHeight, resizeTo: window, hello: true, antialias: true, }); (globalThis as any).__PIXI_APP__ = app; // eslint-disable-line document .getElementById("gamewindow")! .appendChild(app.view); (app.view).classList.add("game"); (app.view).addEventListener("click", () => { (app.view).focus(); }); global.rendering = { app: app, player_text_map: new Map(), planet_sprite_map: new Map(), part_sprite_map: new Map(), indicator_sprite_map: new Map(), starfield: { sprite: new PIXI.TilingSprite( PIXI.Texture.from(tex_starfield), //1024, //1024, ), off_x: 0, off_y: 0, }, starfield_near: { sprite: new PIXI.TilingSprite( PIXI.Texture.from(tex_starfield_transp), //1024, //1024, ), off_x: 0, off_y: 0, }, part_sprites_need_texture_change: [], }; // Main starfield global.rendering!.app.stage.addChild(global.rendering!.starfield.sprite); // Near starfield global.rendering!.app.stage.addChild(global.rendering!.starfield_near.sprite); app.ticker.add(() => { if (player() === undefined) { return; } let width = window.innerWidth; let height = window.innerHeight; global.rendering!.app.stage.x = -player()?.transform.x! * global.scale + width / 2; global.rendering!.app.stage.y = -player()?.transform.y! * global.scale + height / 2; /*global.rendering!.app.stage.x = -player()?.transform.x! + width / 2; global.rendering!.app.stage.y = -player()?.transform.y! + height / 2;*/ global.rendering!.app.stage.scale.x = global.scale; global.rendering!.app.stage.scale.y = global.scale; // TODO: refactor, make parallax configurable // Main starfield const sprite_size_scale_basis = 3 / 4; const sprite_size_px_basis = 512; // size of single tile const sprite_size = (sprite_size_px_basis * sprite_size_scale_basis) / global.scale; global.rendering!.starfield.sprite.height = window.innerHeight / global.scale + sprite_size; global.rendering!.starfield.sprite.width = window.innerWidth / global.scale + sprite_size; global.rendering!.starfield.off_x = (player()?.transform.x! * sprite_size_scale_basis) % global.scale; global.rendering!.starfield.off_y = (player()?.transform.y! * sprite_size_scale_basis) % global.scale; global.rendering!.starfield.sprite.x = Math.floor(player()?.transform.x! / sprite_size) * sprite_size - global.rendering!.starfield.sprite.width / 2 + sprite_size / 2; global.rendering!.starfield.sprite.y = Math.floor(player()?.transform.y! / sprite_size) * sprite_size - global.rendering!.starfield.sprite.height / 2 + sprite_size / 2; global.rendering!.starfield.sprite.tilePosition.x = global.rendering!.starfield.off_x; global.rendering!.starfield.sprite.tilePosition.y = global.rendering!.starfield.off_y; // Near starfield //const sprite_size_near = // sprite_size_px_basis * (sprite_size_scale_basis * 2); global.rendering!.starfield_near.sprite.height = window.innerHeight / global.scale + 2 * sprite_size; global.rendering!.starfield_near.sprite.width = window.innerWidth / global.scale + 2 * sprite_size; global.rendering!.starfield_near.off_x = //(player()?.transform.x!/2) % (sprite_size*2*global.scale); (player()?.transform.x! / 2) % (sprite_size_px_basis * (sprite_size_scale_basis * 2)); global.rendering!.starfield_near.off_y = //(player()?.transform.y!/2) % (sprite_size*2*global.scale); (player()?.transform.y! / 2) % (sprite_size_px_basis * (sprite_size_scale_basis * 2)); global.rendering!.starfield_near.sprite.x = Math.floor(player()?.transform.x! / 2 / sprite_size) * 2 * sprite_size - global.rendering!.starfield_near.sprite.width / 2 + sprite_size; global.rendering!.starfield_near.sprite.y = Math.floor(player()?.transform.y! / 2 / sprite_size) * 2 * sprite_size - global.rendering!.starfield_near.sprite.height / 2 + sprite_size; global.rendering!.starfield_near.sprite.tilePosition.x = global.rendering!.starfield_near.off_x; global.rendering!.starfield_near.sprite.tilePosition.y = global.rendering!.starfield_near.off_y; for (let [id, part] of global.parts_map) { let part_sprite; if (global.rendering!.part_sprite_map.has(id)) { part_sprite = global.rendering!.part_sprite_map.get(id)!; if (global.rendering!.part_sprites_need_texture_change.includes(id)) { // slow :( part_sprite.texture = PIXI.Texture.from( part_texture_url(part.part_type, part.flags.attached), ); } } else { part_sprite = PIXI.Sprite.from( part_texture_url(part.part_type, part.flags.attached), ); global.rendering!.part_sprite_map.set(id, part_sprite); global.rendering!.app.stage.addChild(part_sprite); } part_sprite.anchor.set(0.5); part_sprite.height = PART_HEIGHT; part_sprite.width = PART_WIDTH; part_sprite.x = part.transform.x; part_sprite.y = part.transform.y; part_sprite.rotation = part.transform.rot; } for (let [id, planet] of global.planets_map) { let planet_sprite; if (global.rendering!.planet_sprite_map.has(id)) { planet_sprite = global.rendering!.planet_sprite_map.get(id)!; } else { planet_sprite = PIXI.Sprite.from( planet_texture_url(planet.planet_type), ); global.rendering!.planet_sprite_map.set(id, planet_sprite); global.rendering!.app.stage.addChild(planet_sprite); } planet_sprite.anchor.set(0.5); planet_sprite.height = planet.radius * 2; planet_sprite.width = planet.radius * 2; planet_sprite.x = planet.transform.x; planet_sprite.y = planet.transform.y; planet_sprite.rotation = planet.transform.rot; } for (let [id, username] of global.players_map) { let username_text; if (global.rendering!.player_text_map.has(id)) { username_text = global.rendering!.player_text_map.get(id)!; } else { username_text = new PIXI.Text(username); username_text.alpha = 0.6; username_text.style = new PIXI.TextStyle({ fontFamily: "sans-serif", fontSize: 27, fill: "#ffffff", }); global.rendering!.player_text_map.set(id, username_text); global.rendering!.app.stage.addChild(username_text); } let player_transform = global.parts_map.get(id)!.transform; username_text.anchor.set(0.5); username_text.x = player_transform.x; username_text.y = player_transform.y - 50; } let username_text; if (global.rendering!.player_text_map.has(global.me!.part_id)) { username_text = global.rendering!.player_text_map.get( global.me!.part_id, )!; // don't really know where else to put this for (let [id, planet] of global.planets_map) { let indicator_sprite; if (global.rendering!.indicator_sprite_map.has(id)) { indicator_sprite = global.rendering!.indicator_sprite_map.get(id)!; } else { indicator_sprite = PIXI.Sprite.from( indicator_texture_url(planet.planet_type), ); global.rendering!.indicator_sprite_map.set(id, indicator_sprite); global.rendering!.app.stage.addChild(indicator_sprite); } indicator_sprite.anchor.set(0.5); indicator_sprite.height = 32 / global.scale; // undo zoom scale effect indicator_sprite.width = 32 / global.scale; let player_transform = global.parts_map.get( global.me!.part_id, )!.transform; let angle_to_planet = Math.atan2( planet.transform.y - player_transform.y, planet.transform.x - player_transform.x, ); let indicator_distance = height / 4 / global.scale; indicator_sprite.x = player_transform.x + Math.cos(angle_to_planet) * indicator_distance; indicator_sprite.y = player_transform.y + Math.sin(angle_to_planet) * indicator_distance; indicator_sprite.rotation = angle_to_planet; indicator_sprite.alpha = 0.5; } } else { username_text = new PIXI.Text(global.me!.username); username_text.alpha = 0.6; username_text.style = new PIXI.TextStyle({ fontFamily: "sans-serif", fontSize: 27, fill: "#ffffff", stroke: "#000000", strokeThickness: 2, }); global.rendering!.player_text_map.set(global.me!.part_id, username_text); global.rendering!.app.stage.addChild(username_text); } let player_transform = global.parts_map.get(global.me!.part_id)!.transform; username_text.anchor.set(0.5); username_text.x = player_transform.x; username_text.y = player_transform.y - 50; }); }