This commit is contained in:
tcsenpai 2025-04-01 11:45:41 +02:00
parent 2e155588a2
commit 05bad8b6cf
2 changed files with 91 additions and 3 deletions

View File

@ -9,6 +9,7 @@ import {
loadingAnimation
} from './visualEffects';
import { playSound } from './soundEffects';
import { levelUI } from './levelRenderer';
export async function renderGameUI(): Promise<void> {
const gameState = getCurrentGameState();
@ -39,15 +40,18 @@ export async function renderGameUI(): Promise<void> {
));
console.log('');
// Render current level
await currentLevel.render();
// Render current level in a box
await levelUI.levelContent(currentLevel.name, async () => {
await currentLevel.render();
});
console.log('');
console.log(theme.secondary('Available commands:'));
console.log(`${theme.accent('/help')} - Show help, ${theme.accent('/save')} - Save game, ${theme.accent('/menu')} - Main menu, ${theme.accent('/hint')} - Get a hint`);
console.log('');
// Get player input
// Display input box and get player input
levelUI.inputBox();
const input = await promptInput('');
// Handle special commands

View File

@ -1,6 +1,31 @@
import { styles, drawBox, drawTable } from './uiHelpers';
import { getTheme } from './visualEffects';
// Helper function to wrap text to fit within a width
function wrapText(text: string, maxWidth: number): string[] {
const words = text.split(' ');
const lines: string[] = [];
let currentLine = '';
words.forEach(word => {
// If adding this word would exceed the max width
if ((currentLine + ' ' + word).length > maxWidth && currentLine.length > 0) {
lines.push(currentLine);
currentLine = word;
} else {
// Add word to current line (with a space if not the first word)
currentLine = currentLine.length === 0 ? word : currentLine + ' ' + word;
}
});
// Add the last line
if (currentLine.length > 0) {
lines.push(currentLine);
}
return lines;
}
export const levelUI = {
title: (text: string) => {
const theme = getTheme();
@ -21,6 +46,65 @@ export const levelUI = {
console.log(drawBox(theme.accent(title), content));
},
// Improved level content box
levelContent: (title: string, content: () => Promise<void>) => {
const theme = getTheme();
const boxWidth = 76;
// Start capturing console output
const originalLog = console.log;
let capturedOutput: string[] = [];
console.log = (...args) => {
capturedOutput.push(args.join(' '));
};
// Execute the content function and then process the output
return content().then(() => {
// Restore console.log
console.log = originalLog;
// Process and format the captured output
let formattedLines: string[] = [];
capturedOutput.forEach(line => {
// Skip empty lines at the beginning
if (formattedLines.length === 0 && line.trim() === '') {
return;
}
// Handle long lines by wrapping them
if (line.length > boxWidth - 4) {
const wrappedLines = wrapText(line, boxWidth - 4);
formattedLines.push(...wrappedLines);
} else {
formattedLines.push(line);
}
});
// Draw the box with the formatted content
console.log('┌' + '─'.repeat(boxWidth - 2) + '┐');
// Title bar
console.log('│ ' + theme.accent(title.padEnd(boxWidth - 4)) + ' │');
console.log('├' + '─'.repeat(boxWidth - 2) + '┤');
// Content
formattedLines.forEach(line => {
console.log('│ ' + line.padEnd(boxWidth - 4) + ' │');
});
// Bottom of box
console.log('└' + '─'.repeat(boxWidth - 2) + '┘');
});
},
// Revert to the simpler input box
inputBox: () => {
const theme = getTheme();
console.log('Enter your command below:');
},
terminal: (content: string) => {
const theme = getTheme();
console.log(' ' + theme.secondary('┌─ Terminal ───────────────────────┐'));