Skip to content

A powerful framework for building Terminal User Interface (TUI) games with physics, audio, particles, and more.

License

Notifications You must be signed in to change notification settings

arungeorgesaji/vivid-tui

Repository files navigation

Vivid TUI

A powerful framework for building Terminal User Interface (TUI) games with physics, audio, particles, and more.

Features

  • Physics Engine - Gravity, collisions, forces, and realistic movement
  • Audio System - Music and sound effects with WAV support
  • Particle Effects - Explosions, trails, and customizable visual effects
  • Camera System - Static and following camera modes with smooth tracking
  • Sprite Animations - Frame-based animations with customizable timing
  • Scene Management - Easy scene transitions and lifecycle management
  • Game State - Centralized state management for scores, lives, and progression

Installation

npm install vivid-tui

Quick Start

const { GameEngine } = require('vivid-tui');


const game = new GameEngine({ title: 'My Game' });


const player = game.createEntity(10, 10, 3, 3, {
   style: { fg: 'white', bg: 'blue' },
   content: 'P'

});


game.addGameObject(player);

game.start();

Core Concepts

Game Engine

Create a game instance with optional configuration:

const game = new GameEngine({ 
   title: 'My Game',
   audio: true,      // Enable audio system
   effects: true,    // Enable particle effects
   scenes: true      // Enable scene management

});

Entities

Create game objects with position, size, and styling:

const player = game.createEntity(x, y, width, height, {
   style: { fg: 'white', bg: 'blue' },
   content: 'P',
   hasGravity: true,    // Apply physics
   isStatic: true,      // Static objects don't move
   onCollision: function(other) {
     // Handle collisions
   }

});

Physics System

Gravity and Forces

// Create object with gravity

const ball = game.createEntity(10, 5, 3, 3, {
   hasGravity: true

});


// Apply forces

game.screen.key(['space'], () =>gt; {
   ball.applyForce({ x: 0, y: -8 });  // Jump

});


game.screen.key(['left'], () =>gt; {
   ball.applyForce({ x: -2, y: 0 });  // Move left

});

Collision Detection

const platform = game.createEntity(5, 13, 20, 2, {
   isStatic: true,
   onCollision: function(other) {
     console.log('Collision detected!');
     // Change appearance on collision
     this.element.style.bg = 'yellow';
   }

});

Camera System

Following Camera

// Set camera to follow an entity

game.setCameraTarget(player);


// Cycle through camera modes

game.screen.key(['c'], () =>gt; {
   const newMode = game.cycleCameraMode();
   console.log('Camera mode:', newMode);

});

Camera modes:

  • Static - Fixed camera position
  • Following - Smooth camera tracking

Particle System

Built-in Explosions

game.screen.key(['space'], () =>gt; {
   game.createExplosion(x, y);

});

Custom Particle Effects

// Emit custom particles

game.particles.emit(x, y, 20, {
   content: ['○', '●', '◎'],  // Particle characters
   style: { fg: 'cyan' },
   life: 2.0                   // Duration in seconds

});

game.particles.addToScreen(game.screen);

Particle Trails

let trailEnabled = false;


player.update = function(deltaTime) {
   // ... existing update code
  
    if (trailEnabled) {
     game.particles.emit(this.position.x, this.position.y, 2, {
       content: ['.', '·'],
       style: { fg: 'gray' },
       life: 0.5
     });
     game.particles.addToScreen(game.screen);
   }

};

Audio System

Loading Audio

const game = new GameEngine({ audio: true });


// Load music (looping background audio)

await game.loadMusic('background', './assets/music.wav', { 
   loop: true,
   volume: 0.7

});


// Load sound effects

await game.loadSound('explosion', './assets/explosion.wav');

await game.loadSound('beep', './assets/beep.wav');

Playing Audio

// Play music

game.screen.key(['1'], async () =>gt; {
   await game.playMusic('background');

});


// Stop music

game.screen.key(['2'], () =>gt; {
   game.stopMusic();

});


// Play sound effects

game.screen.key(['3'], () =>gt; {
   game.playSound('explosion');

});


// Toggle mute

game.screen.key(['m'], () =>gt; {
   const muted = game.audio.toggleMute();
   console.log(muted ? 'Muted' : 'Unmuted');

});

Sprite Animations

Creating Animated Sprites

const walker = game.createSprite(x, y, width, height, {
   frames: ['>O>'O>', '|O|', ', '|O|'],  // Animation frames
   frameDelay: 0.2,                        // Seconds per frame
   style: { fg: 'green', bg: 'black' }

});


// Add custom update logic

walker.onUpdate = function() {
   this.position.x = 5 + Math.sin(Date.now() / 1000) * 10;

};

Game State Management

Setting Up Game State

const { GameEngine, GameState } = require('vivid-tui');


const game = new GameEngine({ title: 'My Game' });

game.gameState = new GameState();


// Initialize state values

game.gameState.set('score', 0);

game.gameState.set('lives', 3);

game.gameState.set('level', 1);

Using Game State

// Get values

const score = game.gameState.get('score');


// Update values

game.gameState.set('score', score + 10);


// Game over state

game.gameState.setGameOver(true);

if (game.gameState.isGameOver) {
   console.log('Game Over!');

}


// Reset state

game.gameState.reset();

HUD Display

const hud = game.createEntity(2, 18, 50, 1, {
   style: { fg: 'white', bg: 'black' },
   content: 'Score: 0 | Lives: 3 | Level: 1',
   isStatic: true

});


function updateHUD() {
   const score = game.gameState.get('score') || 0;
   const lives = game.gameState.get('lives') || 0;
   const level = game.gameState.get('level') || 1;
  
    hud.element.setContent(`Score: ${score} | Lives: ${lives} | Level: ${level}`);

}

Scene Management

Creating Scenes

const game = new GameEngine({ scenes: true });


const menuScene = {
   name: 'menu',
   onEnter: function() {
     console.log('Menu loaded');
     // Create menu objects
     const title = game.createEntity(10, 5, 20, 5, {
       style: { fg: 'white', bg: 'red' },
       content: 'MAIN MENU',
       isStatic: true
     });
     game.addGameObject(title);
     this.title = title;
   },
   onExit: function() {
     // Clean up scene objects
     if (this.title &∓& this.title.element) {
       this.title.element.detach();
     }
   }

};

Managing Scenes

// Add scenes

game.scenes.addScene('menu', menuScene);

game.scenes.addScene('gameplay', gameplayScene);

game.scenes.addScene('gameover', gameoverScene);


// Switch scenes

game.scenes.switchTo('menu');


// Switch with keyboard

game.screen.key(['1'], () =>gt; game.scenes.switchTo('menu'));

game.screen.key(['2'], () =>gt; game.scenes.switchTo('gameplay'));

Input Handling

// Keyboard input

game.screen.key(['up', 'w'], () =>gt; {
   player.applyForce({ x: 0, y: -5 });

});


game.screen.key(['space'], () =>gt; {
   // Jump or shoot

});


// Multiple key options

game.screen.key(['left', 'a'], () =>gt; {
   player.applyForce({ x: -2, y: 0 });

});

Game Loop

The engine handles the game loop automatically. You can hook into updates:

// Custom update logic

const originalUpdate = game.update.bind(game);

game.update = function(deltaTime) {
   originalUpdate(deltaTime);
  
    // Your custom update code
   if (timer >gt; 3.0) {
     // Do something every 3 seconds
     timer = 0;
   }

};

Complete Example

const { GameEngine, GameState } = require('vivid-tui');


const game = new GameEngine({ 
   title: 'Platform Game',
   audio: true,
   effects: true

});


game.gameState = new GameState();

game.gameState.set('score', 0);


// Player

const player = game.createEntity(10, 10, 3, 3, {
   style: { fg: 'white', bg: 'blue' },
   content: 'P',
   hasGravity: true

});


// Platform

const platform = game.createEntity(0, 15, 80, 2, {
   style: { fg: 'white', bg: 'gray' },
   isStatic: true

});


// Camera follows player

game.setCameraTarget(player);


// Controls

game.screen.key(['space'], () =>gt; {
   player.applyForce({ x: 0, y: -8 });
   game.createExplosion(player.position.x, player.position.y);

});


game.screen.key(['left'], () =>gt; {
   player.applyForce({ x: -2, y: 0 });

});


game.screen.key(['right'], () =>gt; {
   player.applyForce({ x: 2, y: 0 });

});


// Start game

game.addGameObject(player);

game.addGameObject(platform);

game.start();

API Reference

GameEngine

Constructor Options:

  • title - Window title
  • audio - Enable audio system
  • effects - Enable particle effects
  • scenes - Enable scene management

Methods:

  • createEntity(x, y, width, height, options) - Create game object
  • createSprite(x, y, width, height, options) - Create animated sprite
  • addGameObject(entity) - Add entity to game
  • start() - Start game loop
  • setCameraTarget(entity) - Set camera follow target
  • cycleCameraMode() - Switch camera modes
  • createExplosion(x, y) - Create explosion effect
  • loadMusic(name, path, options) - Load music file
  • loadSound(name, path) - Load sound effect
  • playMusic(name) - Play loaded music
  • stopMusic() - Stop music
  • playSound(name) - Play sound effect

GameState

Methods:

  • set(key, value) - Set state value
  • get(key) - Get state value
  • setGameOver(boolean) - Set game over state
  • reset() - Reset all state

Particle System

Methods:

  • particles.emit(x, y, count, options) - Emit particles
  • particles.addToScreen(screen) - Add particles to screen

About

A powerful framework for building Terminal User Interface (TUI) games with physics, audio, particles, and more.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published