mirror of
https://github.com/Xevion/Pac-Man.git
synced 2025-12-07 22:07:47 -06:00
fix: proper font loading, cross platform assets, better platform independent trait implementation, conditional modules
This commit is contained in:
@@ -11,7 +11,8 @@ pub enum Asset {
|
|||||||
Wav2,
|
Wav2,
|
||||||
Wav3,
|
Wav3,
|
||||||
Wav4,
|
Wav4,
|
||||||
Atlas,
|
AtlasImage,
|
||||||
|
Font,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Asset {
|
impl Asset {
|
||||||
@@ -23,7 +24,8 @@ impl Asset {
|
|||||||
Wav2 => "sound/waka/2.ogg",
|
Wav2 => "sound/waka/2.ogg",
|
||||||
Wav3 => "sound/waka/3.ogg",
|
Wav3 => "sound/waka/3.ogg",
|
||||||
Wav4 => "sound/waka/4.ogg",
|
Wav4 => "sound/waka/4.ogg",
|
||||||
Atlas => "atlas.png",
|
AtlasImage => "atlas.png",
|
||||||
|
Font => "TerminalVector.ttf",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use crate::systems::{
|
|||||||
AudioState, Collider, DeltaTime, DirectionalAnimated, EntityType, Ghost, GhostBundle, GhostCollider, GlobalState,
|
AudioState, Collider, DeltaTime, DirectionalAnimated, EntityType, Ghost, GhostBundle, GhostCollider, GlobalState,
|
||||||
ItemBundle, ItemCollider, PacmanCollider, PlayerBundle, PlayerControlled, RenderDirty, Renderable, ScoreResource,
|
ItemBundle, ItemCollider, PacmanCollider, PlayerBundle, PlayerControlled, RenderDirty, Renderable, ScoreResource,
|
||||||
},
|
},
|
||||||
debug::{debug_render_system, DebugState, DebugTextureResource},
|
debug::{debug_render_system, DebugFontResource, DebugState, DebugTextureResource},
|
||||||
ghost::ghost_movement_system,
|
ghost::ghost_movement_system,
|
||||||
input::input_system,
|
input::input_system,
|
||||||
item::item_system,
|
item::item_system,
|
||||||
@@ -28,17 +28,14 @@ use crate::systems::{
|
|||||||
render::{directional_render_system, dirty_render_system, render_system, BackbufferResource, MapTextureResource},
|
render::{directional_render_system, dirty_render_system, render_system, BackbufferResource, MapTextureResource},
|
||||||
};
|
};
|
||||||
use crate::texture::animated::AnimatedTexture;
|
use crate::texture::animated::AnimatedTexture;
|
||||||
use bevy_ecs::schedule::IntoScheduleConfigs;
|
use bevy_ecs::event::EventRegistry;
|
||||||
use bevy_ecs::system::NonSendMut;
|
use bevy_ecs::observer::Trigger;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::schedule::Schedule;
|
||||||
event::EventRegistry,
|
use bevy_ecs::system::{NonSendMut, Res, ResMut};
|
||||||
observer::Trigger,
|
use bevy_ecs::world::World;
|
||||||
schedule::Schedule,
|
|
||||||
system::{Res, ResMut},
|
|
||||||
world::World,
|
|
||||||
};
|
|
||||||
use sdl2::image::LoadTexture;
|
use sdl2::image::LoadTexture;
|
||||||
use sdl2::render::{Canvas, ScaleMode, TextureCreator};
|
use sdl2::render::{Canvas, ScaleMode, TextureCreator};
|
||||||
|
use sdl2::rwops::RWops;
|
||||||
use sdl2::video::{Window, WindowContext};
|
use sdl2::video::{Window, WindowContext};
|
||||||
use sdl2::EventPump;
|
use sdl2::EventPump;
|
||||||
|
|
||||||
@@ -70,6 +67,7 @@ impl Game {
|
|||||||
) -> GameResult<Game> {
|
) -> GameResult<Game> {
|
||||||
let mut world = World::default();
|
let mut world = World::default();
|
||||||
let mut schedule = Schedule::default();
|
let mut schedule = Schedule::default();
|
||||||
|
let ttf_context = Box::leak(Box::new(sdl2::ttf::init().map_err(|e| GameError::Sdl(e.to_string()))?));
|
||||||
|
|
||||||
EventRegistry::register_event::<GameError>(&mut world);
|
EventRegistry::register_event::<GameError>(&mut world);
|
||||||
EventRegistry::register_event::<GameEvent>(&mut world);
|
EventRegistry::register_event::<GameEvent>(&mut world);
|
||||||
@@ -92,11 +90,18 @@ impl Game {
|
|||||||
.map_err(|e| GameError::Sdl(e.to_string()))?;
|
.map_err(|e| GameError::Sdl(e.to_string()))?;
|
||||||
debug_texture.set_scale_mode(ScaleMode::Nearest);
|
debug_texture.set_scale_mode(ScaleMode::Nearest);
|
||||||
|
|
||||||
|
let font_data = get_asset_bytes(Asset::Font)?;
|
||||||
|
let static_font_data: &'static [u8] = Box::leak(font_data.to_vec().into_boxed_slice());
|
||||||
|
let font_asset = RWops::from_bytes(static_font_data).map_err(|_| GameError::Sdl("Failed to load font".to_string()))?;
|
||||||
|
let debug_font = ttf_context
|
||||||
|
.load_font_from_rwops(font_asset, 12)
|
||||||
|
.map_err(|e| GameError::Sdl(e.to_string()))?;
|
||||||
|
|
||||||
// Initialize audio system
|
// Initialize audio system
|
||||||
let audio = crate::audio::Audio::new();
|
let audio = crate::audio::Audio::new();
|
||||||
|
|
||||||
// Load atlas and create map texture
|
// Load atlas and create map texture
|
||||||
let atlas_bytes = get_asset_bytes(Asset::Atlas)?;
|
let atlas_bytes = get_asset_bytes(Asset::AtlasImage)?;
|
||||||
let atlas_texture = texture_creator.load_texture_bytes(&atlas_bytes).map_err(|e| {
|
let atlas_texture = texture_creator.load_texture_bytes(&atlas_bytes).map_err(|e| {
|
||||||
if e.to_string().contains("format") || e.to_string().contains("unsupported") {
|
if e.to_string().contains("format") || e.to_string().contains("unsupported") {
|
||||||
GameError::Texture(crate::error::TextureError::InvalidFormat(format!(
|
GameError::Texture(crate::error::TextureError::InvalidFormat(format!(
|
||||||
@@ -187,6 +192,7 @@ impl Game {
|
|||||||
world.insert_non_send_resource(BackbufferResource(backbuffer));
|
world.insert_non_send_resource(BackbufferResource(backbuffer));
|
||||||
world.insert_non_send_resource(MapTextureResource(map_texture));
|
world.insert_non_send_resource(MapTextureResource(map_texture));
|
||||||
world.insert_non_send_resource(DebugTextureResource(debug_texture));
|
world.insert_non_send_resource(DebugTextureResource(debug_texture));
|
||||||
|
world.insert_non_send_resource(DebugFontResource(debug_font));
|
||||||
world.insert_non_send_resource(AudioResource(audio));
|
world.insert_non_send_resource(AudioResource(audio));
|
||||||
|
|
||||||
world.insert_resource(map);
|
world.insert_resource(map);
|
||||||
@@ -207,40 +213,37 @@ impl Game {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
schedule.add_systems(
|
schedule.add_systems((
|
||||||
(
|
profile(SystemId::Input, input_system),
|
||||||
profile(SystemId::Input, input_system),
|
profile(SystemId::PlayerControls, player_control_system),
|
||||||
profile(SystemId::PlayerControls, player_control_system),
|
profile(SystemId::PlayerMovement, player_movement_system),
|
||||||
profile(SystemId::PlayerMovement, player_movement_system),
|
profile(SystemId::Ghost, ghost_movement_system),
|
||||||
profile(SystemId::Ghost, ghost_movement_system),
|
profile(SystemId::Collision, collision_system),
|
||||||
profile(SystemId::Collision, collision_system),
|
profile(SystemId::Item, item_system),
|
||||||
profile(SystemId::Item, item_system),
|
profile(SystemId::Audio, audio_system),
|
||||||
profile(SystemId::Audio, audio_system),
|
profile(SystemId::Blinking, blinking_system),
|
||||||
profile(SystemId::Blinking, blinking_system),
|
profile(SystemId::DirectionalRender, directional_render_system),
|
||||||
profile(SystemId::DirectionalRender, directional_render_system),
|
profile(SystemId::DirtyRender, dirty_render_system),
|
||||||
profile(SystemId::DirtyRender, dirty_render_system),
|
profile(SystemId::Render, render_system),
|
||||||
profile(SystemId::Render, render_system),
|
profile(SystemId::DebugRender, debug_render_system),
|
||||||
profile(SystemId::DebugRender, debug_render_system),
|
profile(
|
||||||
profile(
|
SystemId::Present,
|
||||||
SystemId::Present,
|
|mut canvas: NonSendMut<&mut Canvas<Window>>,
|
||||||
|mut canvas: NonSendMut<&mut Canvas<Window>>,
|
backbuffer: NonSendMut<BackbufferResource>,
|
||||||
backbuffer: NonSendMut<BackbufferResource>,
|
debug_state: Res<DebugState>,
|
||||||
debug_state: Res<DebugState>,
|
mut dirty: ResMut<RenderDirty>| {
|
||||||
mut dirty: ResMut<RenderDirty>| {
|
if dirty.0 || *debug_state != DebugState::Off {
|
||||||
if dirty.0 || *debug_state != DebugState::Off {
|
// Only copy backbuffer to main canvas if debug rendering is off
|
||||||
// Only copy backbuffer to main canvas if debug rendering is off
|
// (debug rendering draws directly to main canvas)
|
||||||
// (debug rendering draws directly to main canvas)
|
if *debug_state == DebugState::Off {
|
||||||
if *debug_state == DebugState::Off {
|
canvas.copy(&backbuffer.0, None, None).unwrap();
|
||||||
canvas.copy(&backbuffer.0, None, None).unwrap();
|
|
||||||
}
|
|
||||||
dirty.0 = false;
|
|
||||||
canvas.present();
|
|
||||||
}
|
}
|
||||||
},
|
dirty.0 = false;
|
||||||
),
|
canvas.present();
|
||||||
)
|
}
|
||||||
.chain(),
|
},
|
||||||
);
|
),
|
||||||
|
));
|
||||||
|
|
||||||
// Spawn player
|
// Spawn player
|
||||||
world.spawn(player);
|
world.spawn(player);
|
||||||
@@ -288,7 +291,7 @@ impl Game {
|
|||||||
Ok(Game { world, schedule })
|
Ok(Game { world, schedule })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawns all four ghosts at their starting positions with appropriate textures.
|
/// Spowns all four ghosts at their starting positions with appropriate textures.
|
||||||
fn spawn_ghosts(world: &mut World) -> GameResult<()> {
|
fn spawn_ghosts(world: &mut World) -> GameResult<()> {
|
||||||
// Extract the data we need first to avoid borrow conflicts
|
// Extract the data we need first to avoid borrow conflicts
|
||||||
let ghost_start_positions = {
|
let ghost_start_positions = {
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use crate::asset::Asset;
|
use crate::asset::Asset;
|
||||||
use crate::error::{AssetError, PlatformError};
|
use crate::error::{AssetError, PlatformError};
|
||||||
use crate::platform::Platform;
|
use crate::platform::CommonPlatform;
|
||||||
|
|
||||||
/// Desktop platform implementation.
|
/// Desktop platform implementation.
|
||||||
pub struct DesktopPlatform;
|
pub struct Platform;
|
||||||
|
|
||||||
impl Platform for DesktopPlatform {
|
impl CommonPlatform for Platform {
|
||||||
fn sleep(&self, duration: Duration, focused: bool) {
|
fn sleep(&self, duration: Duration, focused: bool) {
|
||||||
if focused {
|
if focused {
|
||||||
spin_sleep::sleep(duration);
|
spin_sleep::sleep(duration);
|
||||||
@@ -75,7 +75,8 @@ impl Platform for DesktopPlatform {
|
|||||||
Asset::Wav2 => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/waka/2.ogg"))),
|
Asset::Wav2 => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/waka/2.ogg"))),
|
||||||
Asset::Wav3 => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/waka/3.ogg"))),
|
Asset::Wav3 => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/waka/3.ogg"))),
|
||||||
Asset::Wav4 => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/waka/4.ogg"))),
|
Asset::Wav4 => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/waka/4.ogg"))),
|
||||||
Asset::Atlas => Ok(Cow::Borrowed(include_bytes!("../../assets/game/atlas.png"))),
|
Asset::AtlasImage => Ok(Cow::Borrowed(include_bytes!("../../assets/game/atlas.png"))),
|
||||||
|
Asset::Font => Ok(Cow::Borrowed(include_bytes!("../../assets/game/TerminalVector.ttf"))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use crate::asset::Asset;
|
use crate::asset::Asset;
|
||||||
use crate::error::{AssetError, PlatformError};
|
use crate::error::{AssetError, PlatformError};
|
||||||
use crate::platform::Platform;
|
use crate::platform::CommonPlatform;
|
||||||
|
|
||||||
/// Emscripten platform implementation.
|
/// Emscripten platform implementation.
|
||||||
pub struct EmscriptenPlatform;
|
pub struct Platform;
|
||||||
|
|
||||||
impl Platform for EmscriptenPlatform {
|
impl CommonPlatform for Platform {
|
||||||
fn sleep(&self, duration: Duration, _focused: bool) {
|
fn sleep(&self, duration: Duration, _focused: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
emscripten_sleep(duration.as_millis() as u32);
|
emscripten_sleep(duration.as_millis() as u32);
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ use crate::error::{AssetError, PlatformError};
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
pub mod desktop;
|
#[cfg(not(target_os = "emscripten"))]
|
||||||
pub mod emscripten;
|
mod desktop;
|
||||||
|
#[cfg(target_os = "emscripten")]
|
||||||
|
mod emscripten;
|
||||||
|
|
||||||
/// Platform abstraction trait that defines cross-platform functionality.
|
/// Platform abstraction trait that defines cross-platform functionality.
|
||||||
pub trait Platform {
|
pub trait CommonPlatform {
|
||||||
/// Sleep for the specified duration using platform-appropriate method.
|
/// Sleep for the specified duration using platform-appropriate method.
|
||||||
fn sleep(&self, duration: Duration, focused: bool);
|
fn sleep(&self, duration: Duration, focused: bool);
|
||||||
|
|
||||||
@@ -32,17 +34,14 @@ pub trait Platform {
|
|||||||
|
|
||||||
/// Get the current platform implementation.
|
/// Get the current platform implementation.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn get_platform() -> &'static dyn Platform {
|
pub fn get_platform() -> &'static dyn CommonPlatform {
|
||||||
static DESKTOP: desktop::DesktopPlatform = desktop::DesktopPlatform;
|
|
||||||
static EMSCRIPTEN: emscripten::EmscriptenPlatform = emscripten::EmscriptenPlatform;
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "emscripten"))]
|
#[cfg(not(target_os = "emscripten"))]
|
||||||
{
|
{
|
||||||
&DESKTOP
|
&desktop::Platform
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "emscripten")]
|
#[cfg(target_os = "emscripten")]
|
||||||
{
|
{
|
||||||
&EMSCRIPTEN
|
&emscripten::Platform
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use glam::{IVec2, UVec2, Vec2};
|
|||||||
use sdl2::pixels::Color;
|
use sdl2::pixels::Color;
|
||||||
use sdl2::rect::{Point, Rect};
|
use sdl2::rect::{Point, Rect};
|
||||||
use sdl2::render::{Canvas, Texture, TextureCreator};
|
use sdl2::render::{Canvas, Texture, TextureCreator};
|
||||||
|
use sdl2::ttf::Font;
|
||||||
use sdl2::video::{Window, WindowContext};
|
use sdl2::video::{Window, WindowContext};
|
||||||
|
|
||||||
#[derive(Resource, Default, Debug, Copy, Clone, PartialEq)]
|
#[derive(Resource, Default, Debug, Copy, Clone, PartialEq)]
|
||||||
@@ -36,6 +37,9 @@ impl DebugState {
|
|||||||
/// Resource to hold the debug texture for persistent rendering
|
/// Resource to hold the debug texture for persistent rendering
|
||||||
pub struct DebugTextureResource(pub Texture<'static>);
|
pub struct DebugTextureResource(pub Texture<'static>);
|
||||||
|
|
||||||
|
/// Resource to hold the debug font
|
||||||
|
pub struct DebugFontResource(pub Font<'static, 'static>);
|
||||||
|
|
||||||
/// Transforms a position from logical canvas coordinates to output canvas coordinates (with board offset)
|
/// Transforms a position from logical canvas coordinates to output canvas coordinates (with board offset)
|
||||||
fn transform_position_with_offset(pos: Vec2, scale: f32) -> IVec2 {
|
fn transform_position_with_offset(pos: Vec2, scale: f32) -> IVec2 {
|
||||||
((pos + BOARD_PIXEL_OFFSET.as_vec2()) * scale).as_ivec2()
|
((pos + BOARD_PIXEL_OFFSET.as_vec2()) * scale).as_ivec2()
|
||||||
@@ -46,13 +50,8 @@ fn render_timing_display(
|
|||||||
canvas: &mut Canvas<Window>,
|
canvas: &mut Canvas<Window>,
|
||||||
texture_creator: &mut TextureCreator<WindowContext>,
|
texture_creator: &mut TextureCreator<WindowContext>,
|
||||||
timings: &SystemTimings,
|
timings: &SystemTimings,
|
||||||
|
font: &Font,
|
||||||
) {
|
) {
|
||||||
// Get TTF context
|
|
||||||
let ttf_context = sdl2::ttf::init().unwrap();
|
|
||||||
|
|
||||||
// Load font
|
|
||||||
let font = ttf_context.load_font("assets/site/TerminalVector.ttf", 12).unwrap();
|
|
||||||
|
|
||||||
// Format timing information using the formatting module
|
// Format timing information using the formatting module
|
||||||
let lines = timings.format_timing_display();
|
let lines = timings.format_timing_display();
|
||||||
let line_height = 14; // Approximate line height for 12pt font
|
let line_height = 14; // Approximate line height for 12pt font
|
||||||
@@ -104,6 +103,7 @@ pub fn debug_render_system(
|
|||||||
mut canvas: NonSendMut<&mut Canvas<Window>>,
|
mut canvas: NonSendMut<&mut Canvas<Window>>,
|
||||||
backbuffer: NonSendMut<BackbufferResource>,
|
backbuffer: NonSendMut<BackbufferResource>,
|
||||||
mut debug_texture: NonSendMut<DebugTextureResource>,
|
mut debug_texture: NonSendMut<DebugTextureResource>,
|
||||||
|
debug_font: NonSendMut<DebugFontResource>,
|
||||||
debug_state: Res<DebugState>,
|
debug_state: Res<DebugState>,
|
||||||
timings: Res<SystemTimings>,
|
timings: Res<SystemTimings>,
|
||||||
map: Res<Map>,
|
map: Res<Map>,
|
||||||
@@ -130,6 +130,7 @@ pub fn debug_render_system(
|
|||||||
|
|
||||||
// Get texture creator before entering the closure to avoid borrowing conflicts
|
// Get texture creator before entering the closure to avoid borrowing conflicts
|
||||||
let mut texture_creator = canvas.texture_creator();
|
let mut texture_creator = canvas.texture_creator();
|
||||||
|
let font = &debug_font.0;
|
||||||
|
|
||||||
let cursor_world_pos = match *cursor {
|
let cursor_world_pos = match *cursor {
|
||||||
CursorPosition::None => None,
|
CursorPosition::None => None,
|
||||||
@@ -192,8 +193,6 @@ pub fn debug_render_system(
|
|||||||
let node = map.graph.get_node(closest_node_id).unwrap();
|
let node = map.graph.get_node(closest_node_id).unwrap();
|
||||||
let pos = transform_position_with_offset(node.position, scale);
|
let pos = transform_position_with_offset(node.position, scale);
|
||||||
|
|
||||||
let ttf_context = sdl2::ttf::init().unwrap();
|
|
||||||
let font = ttf_context.load_font("assets/site/TerminalVector.ttf", 12).unwrap();
|
|
||||||
let surface = font.render(&closest_node_id.to_string()).blended(Color::WHITE).unwrap();
|
let surface = font.render(&closest_node_id.to_string()).blended(Color::WHITE).unwrap();
|
||||||
let texture = texture_creator.create_texture_from_surface(&surface).unwrap();
|
let texture = texture_creator.create_texture_from_surface(&surface).unwrap();
|
||||||
let dest = Rect::new(pos.x + 10, pos.y - 5, texture.query().width, texture.query().height);
|
let dest = Rect::new(pos.x + 10, pos.y - 5, texture.query().width, texture.query().height);
|
||||||
@@ -217,7 +216,7 @@ pub fn debug_render_system(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render timing information in the top-left corner
|
// Render timing information in the top-left corner
|
||||||
render_timing_display(debug_canvas, &mut texture_creator, &timings);
|
render_timing_display(debug_canvas, &mut texture_creator, &timings, font);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ pub fn setup_sdl() -> Result<(Canvas<Window>, TextureCreator<WindowContext>, Sdl
|
|||||||
|
|
||||||
pub fn create_atlas(canvas: &mut sdl2::render::Canvas<sdl2::video::Window>) -> SpriteAtlas {
|
pub fn create_atlas(canvas: &mut sdl2::render::Canvas<sdl2::video::Window>) -> SpriteAtlas {
|
||||||
let texture_creator = canvas.texture_creator();
|
let texture_creator = canvas.texture_creator();
|
||||||
let atlas_bytes = get_asset_bytes(Asset::Atlas).unwrap();
|
let atlas_bytes = get_asset_bytes(Asset::AtlasImage).unwrap();
|
||||||
|
|
||||||
let texture = texture_creator.load_texture_bytes(&atlas_bytes).unwrap();
|
let texture = texture_creator.load_texture_bytes(&atlas_bytes).unwrap();
|
||||||
let texture: Texture<'static> = unsafe { std::mem::transmute(texture) };
|
let texture: Texture<'static> = unsafe { std::mem::transmute(texture) };
|
||||||
|
|||||||
21
web.build.ts
21
web.build.ts
@@ -1,7 +1,7 @@
|
|||||||
import { $ } from "bun";
|
import { $ } from "bun";
|
||||||
import { existsSync, promises as fs } from "fs";
|
import { existsSync, promises as fs } from "fs";
|
||||||
import { platform } from "os";
|
import { platform } from "os";
|
||||||
import { dirname, join, relative, resolve } from "path";
|
import { basename, dirname, join, relative, resolve } from "path";
|
||||||
import { match, P } from "ts-pattern";
|
import { match, P } from "ts-pattern";
|
||||||
import { configure, getConsoleSink, getLogger } from "@logtape/logtape";
|
import { configure, getConsoleSink, getLogger } from "@logtape/logtape";
|
||||||
|
|
||||||
@@ -79,16 +79,19 @@ async function build(release: boolean, env: Record<string, string> | null) {
|
|||||||
|
|
||||||
// The files to copy into 'dist'
|
// The files to copy into 'dist'
|
||||||
const files = [
|
const files = [
|
||||||
...["index.html", "favicon.ico", "build.css", "TerminalVector.ttf"].map(
|
...[
|
||||||
(file) => ({
|
"index.html",
|
||||||
src: join(siteFolder, file),
|
"favicon.ico",
|
||||||
dest: join(dist, file),
|
"build.css",
|
||||||
optional: false,
|
"../game/TerminalVector.ttf",
|
||||||
})
|
].map((file) => ({
|
||||||
),
|
src: resolve(join(siteFolder, file)),
|
||||||
|
dest: join(dist, basename(file)),
|
||||||
|
optional: false,
|
||||||
|
})),
|
||||||
...["pacman.wasm", "pacman.js", "deps/pacman.data"].map((file) => ({
|
...["pacman.wasm", "pacman.js", "deps/pacman.data"].map((file) => ({
|
||||||
src: join(outputFolder, file),
|
src: join(outputFolder, file),
|
||||||
dest: join(dist, file.split("/").pop() || file),
|
dest: join(dist, basename(file)),
|
||||||
optional: false,
|
optional: false,
|
||||||
})),
|
})),
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user