User Tools

Site Tools


javascript_terminal

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
javascript_terminal [2023/11/20 11:57] appledogjavascript_terminal [2023/11/24 01:34] (current) appledog
Line 1: Line 1:
 = JavaScript Terminal = JavaScript Terminal
 +* Also see: [[JavaScript Terminal v2|Version 2]] which is a more advanced version of this codebase.
 +
 This section will outline the basic JavaScript terminal code. This code was not used much when I taught JavaScript to Roger and Neo, but it serves the same basic purpose as the [[PyGame Terminal]]. This section will outline the basic JavaScript terminal code. This code was not used much when I taught JavaScript to Roger and Neo, but it serves the same basic purpose as the [[PyGame Terminal]].
  
-The level of this code will be towards the end of JavaScript Season 1, or at the beginning of JavaScript Season 2. I thinkthat we will use console for Season 1, and start with this in Season 2 -- maybeIt's advanced because it has several classes and data structuresso it feels more like a Season itemAnyways,+The level of this code is the beginning of Season 2, for many reasons. If we took out the resize code, it might be late season materialbut with the resize code in I would say it is good for Season 2. Maybe a stripped down version could be produced later; but the idea here is that it will display on a cellphone or a tablet as well as on a desktop. 
 + 
 +You can view a technical demo of this program at: [[https://helloneo.ca/jnw/archive/jttd1/index.html|JavaScript Terminal Technical Demo 1]]. 
 + 
 +== The Font 
 +The font used in this technical demo is PxPlus_IBM_VGA_8x16.ttf which is available from the [[https://int10h.org/oldschool-pc-fonts/|The Ultimate Oldschool PC Font Pack]] at int10h.orgbless their kindness. We used version 2.2.
  
 == index.html == index.html
Line 8: Line 15:
  
 <Code:HTML> <Code:HTML>
-<!doctype html> 
 <html> <html>
 <head> <head>
-  <meta charset="utf-8"> +    <meta name="viewport" content="width=device-width, initial-scale=1"> 
-  <title>Basic Javascript Terminal</title>+    <title>Basic Javascript Terminal</title>
  
-  <style> +    <style> 
-      body, html { +        body, html { 
-          margin: 0; +            margin: 0; 
-          overflow: hidden; +            overflow: hidden; 
-      +        
-      canvas { + 
-          display: block; +        canvas { 
-      +            display: block; 
-       +            border: none; 
-  </style>+        
 + 
 +    </style>
 </head> </head>
-      +
 <body> <body>
-  <!-- Add your site or application content here --> +<canvas id="fsc"></canvas> 
-  <canvas style="border: none"></canvas> +<script src="js/Color.js"></script> 
-  <script src="js/Color.js"></script> +<script src="js/Character.js"></script> 
-  <script src="js/Character.js"></script> +<script src="js/Terminal.js"></script> 
-  <script src="js/Terminal.js"></script> +<script src="js/main.js"></script>
-  <script src="js/main.js"></script>+
 </body> </body>
  
Line 38: Line 45:
 </Code> </Code>
  
-There is not much to see here. In the original we used normalizer, modernizer and a few other things, but I have stripped those off to show the basic idea.+There is not much to see here. The most interesting line is probably the meta tag. We must set initial_scale to 1 or the text will look too small on higher resolution screens.
  
-There are four main parts: Color.js, which is a color map, Character.js which discusses what needs to be known to represent a character, Terminal, which holds the information about characters on the screen and how to draw them, and main.js which sets up everything and starts the game loop.+Otherwise our main goal is to load and run the JavaScript files. There are four main parts: Color.js, which is a color map, Character.js which discusses what needs to be known to represent a character, Terminal, which holds the information about characters on the screen and how to draw them, and main.js which sets up everything and starts the game loop.
  
 Actually, you could probably refactor some things in main into a class (such as a Game.js class) and then just instantiate and run the class, like we do in Python for PyGame. Perhaps this will be done in a part two sequel article to this one. For now, it's left as an exercise to the reader. Actually, you could probably refactor some things in main into a class (such as a Game.js class) and then just instantiate and run the class, like we do in Python for PyGame. Perhaps this will be done in a part two sequel article to this one. For now, it's left as an exercise to the reader.
  
 == Color.js == Color.js
-<code:JavaScript>+<Code:JavaScript>
 class Color { class Color {
     static black = '#000000';     static black = '#000000';
Line 63: Line 70:
     static yellow = '#FFFF55';     static yellow = '#FFFF55';
     static white = '#FFFFFF';     static white = '#FFFFFF';
-     + 
-    static colorMap = [ this.black, this.blue, this.green, this.cyan,+    static colorMap = [this.black, this.blue, this.green, this.cyan,
         this.red, this.magenta, this.brown, this.lightgray,         this.red, this.magenta, this.brown, this.lightgray,
         this.darkgray, this.lightblue, this.lightgreen, this.lightcyan,         this.darkgray, this.lightblue, this.lightgreen, this.lightcyan,
-        this.lightred, this.lightmagenta, this.yellow, this.white ]+        this.lightred, this.lightmagenta, this.yellow, this.white] 
  
     static getColor(index) {     static getColor(index) {
Line 108: Line 116:
 <Code:JavaScript> <Code:JavaScript>
 class Character { class Character {
-  constructor(ch = ' ', color = 'LightGray', background = 'black') { +    constructor(ch = ' ', color = 'LightGray', background = 'black') { 
-    this.ch = ch; +        this.ch = ch; 
-    this.color = color; +        this.color = color; 
-    this.background = background; +        this.background = background; 
-  }+    }
 } }
 +</Code>
  
 Simple! We will store the character (or it's ASCII code for printing), it's color, and it's background. This is all the data we need to represent a character on the screen. Simple! We will store the character (or it's ASCII code for printing), it's color, and it's background. This is all the data we need to represent a character on the screen.
Line 232: Line 241:
 <Code:JavaScript> <Code:JavaScript>
 // Set up Canvas // Set up Canvas
-// let canvas = document.getElementById('fsc');+let canvas = document.getElementById('fsc');
 let ctx = canvas.getContext('2d'); let ctx = canvas.getContext('2d');
  
Line 242: Line 251:
 // load font // load font
 const font = new FontFace('myvga', 'url(PxPlus_IBM_VGA_8x16.ttf)'); const font = new FontFace('myvga', 'url(PxPlus_IBM_VGA_8x16.ttf)');
-ctx.font = '32px myvga'; 
  
 font.load().then(() => { font.load().then(() => {
-  document.fonts.add(font); +    document.fonts.add(font); 
-    // Measure the width of a single character (assuming monospaced font+    ctx.font = '32px myvga';
-    const measureTextResult ctx.measureText('@'); +
- +
-    // Calculate the baseline offset +
-    font_baseline = 32 - measureTextResult.actualBoundingBoxAscent; +
-    terminal.font_baseline = font_baseline+
 }); });
  
Line 275: Line 278:
     terminal.copyContentTo(t);     terminal.copyContentTo(t);
     terminal = t;     terminal = t;
 +
 +    ctx.font = '32px myvga'; // This seems to be needed here.
 } }
  
 // Call the resizeCanvas function when the window is resized // Call the resizeCanvas function when the window is resized
-window.addEventListener('resize', resizeEvent);+window.addEventListener('resize', resizeCanvas);
  
-// Initial canvas setup +// Animation logic, timed events, etc. 
-resizeCanvas()+// I don't plan for this to be used much in a roguelike. 
- +// but it is useful for (ex.a static demo of the display engine. 
-function resizeEvent() { +function update() { 
-  resizeCanvas()+    n = getRandomInt(1, 100)
 +    if (n === 1) { 
 +        x = getRandomInt(0, terminal.cols - 1) 
 +        y = getRandomInt(0, terminal.rows - 1) 
 +        ch = getRandomLetter() 
 +        color = Color.getColor(getRandomInt(0, 15)) 
 +        background = Color.black 
 +        terminal.setch(x, y, ch, color, background) 
 +        //console.log("[" + ch + "], " + x + "," + y + " " + color); 
 +    }
 } }
  
Line 296: Line 310:
     // draw characters on terminal     // draw characters on terminal
     terminal.draw(ctx);     terminal.draw(ctx);
-} 
- 
-// Animation logic, timed events, etc. 
-// I don't plan for this to be used much in a roguelike. 
-// but it is useful for (ex.) a static demo of the display engine. 
-function update() { 
-    n = getRandomInt(1,100); 
-    if (n == 1) { 
-        x = getRandomInt(0,terminal.cols-1) 
-        y = getRandomInt(0,terminal.rows-1) 
-        ch = getRandomLetter() 
-        color = Color.getColor(getRandomInt(0,15)) 
-        background = Color.black 
-        terminal.setch(x, y, ch, color, background) 
-        //console.log("["+ch+"], " + x + "," + y + " " + color); 
-    } 
 } }
  
 function gameLoop() { function gameLoop() {
-  // Update game logic here +    // Update game logic here 
-  update()+    update()
  
-  // Render the game state +    // Render the game state 
-  render();+    render();
  
-  // Request the next frame +    // Request the next frame 
-  requestAnimationFrame(gameLoop);+    requestAnimationFrame(gameLoop);
 } }
  
 +// Initial canvas setup
 +resizeCanvas();
 +
 +// Quick test -- see update() for the rest of the 'demo' test code.
 terminal.setch(3, 3, '@', Color.lightgray); terminal.setch(3, 3, '@', Color.lightgray);
 terminal.setch(5, 3, 'a', Color.yellow); terminal.setch(5, 3, 'a', Color.yellow);
Line 330: Line 332:
 terminal.setch(7, 5, 'c', Color.red); terminal.setch(7, 5, 'c', Color.red);
 terminal.setch(8, 6, 'd', Color.magenta); terminal.setch(8, 6, 'd', Color.magenta);
- 
  
 // Start the game loop // Start the game loop
 gameLoop(); gameLoop();
- 
 </Code> </Code>
  
 == Analysis == Analysis
 Most of this should already be familiar since all of it would have been covered in JavaScript Season 1. Most of this should already be familiar since all of it would have been covered in JavaScript Season 1.
 +
 +However, one interesting quirk which arose is that the ctx.font has to be set upon terminal resize. I am not sure where the best place is to set it, but it seems to work great setting it on a resize. It would also work if you set it every time you drew a character, but if we assume that we are only using one font and are essentially the main application (a one-canvas app) then setting it on every character draw is probably unnecessary.
 +
 +== Also See
 +* Also see: [[JavaScript Terminal v2|Version 2]] which is a more advanced version of this codebase.
 +
 +
  
javascript_terminal.1700481443.txt.gz · Last modified: 2023/11/20 11:57 by appledog

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki