malison 0.10.1+1

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 76

Malison is a small Dart library for drawing old school ASCII terminals in the browser. I harvested it from my roguelike game, Hauberk and it's aimed primarily at web games ASCII graphics. Think of it like curses for the web.

Using it

Add it to your package's pubspec:

dependencies:
  malison: any

Then use the library:

import 'dart:html';

import 'package:malison/malison.dart';

void main() {
  // Create or query a <canvas> element to bind it to.
  var canvas = new CanvasElement();
  document.body.children.add(canvas);

  // Create a new terminal. CanvasTerminal uses your browser's fonts.
  // RetroTerminal uses a built in DOS-style Code Page 437 font.
  var terminal = new RetroTerminal.dos(80, 40, canvas);

  // You can draw strings at given positions.
  terminal.writeAt(0, 0, "This is a terminal!");

  // You can control the foreground and background color.
  terminal.writeAt(0, 1, "This is blue on green", Color.blue, Color.green);

  // You can also draw individual glyphs -- character+color units.
  terminal.drawGlyph(3, 4, new Glyph.fromCharCode(CharCode.blackHeartSuit,
      Color.red, Color.white));

  // When you're done drawing, tell it to render all of the changes. It renders
  // in batches for performance.
  terminal.render();
}

0.10.0

  • Update to Dart 2. Remove new and const keywords.

0.9.0

  • keyUp() events.

0.8.0

  • Change Color.blend() to take a value from (0, 1.0) instead of a percent.
  • Add Color.add().

0.7.0

  • Fill in the rest of the character codes to CharCode.
  • Add Color.blend() and store colors as RGB.
  • Add foreColor, backColor, and fill() to Terminal.

0.6.0

  • Split into two libraries. The core malison library does not import "dart:html" and can be used in command-line applications. It's not useful outside of the web, but it lets you test code in a "headless" fashion that uses malison on the standalone VM.

0.5.1

  • Get rid of implicit casts and dynamic.

0.5.0

  • Add type parameters to UserInterface, KeyBindings, and Screen so that the bound objects can be precisely typed.

0.4.3

  • Make strong mode clean.

0.4.2

  • Widen constraint on piecemeal.

0.4.1

  • Fix semicolon handling on Firefox.

0.4.0

  • Add constants to CharCode for every character in code page 437.
  • Make constants lowerCamelCase.

0.3.0

  • Automatically create a canvas if not given one.
  • Allow creating a UserInterface without an initial terminal.
  • Add an example app.

0.2.1

  • Fix bad assert in Screen._bind().

0.2.0

  • Redo key input handling. Instead of a (mostly broken) Keyboard class, it exposes raw key down events as they happen and also allows user-defined key bindings.

  • Refactor UserInterface and clean up how opaque/transparent screens are handled.

  • Remove (useless) write() method.

  • Handle semicolon keyCode difference between Firefox (59) and Chrome (186).

example/main.dart

import 'dart:html' as html;
import 'dart:math' as math;

import 'package:malison/malison.dart';
import 'package:malison/malison_web.dart';

const width = 80;
const height = 30;

final ui = UserInterface<String>();

/// A few different terminals to choose from.
final terminals = <RenderableTerminal Function()>[
  () => RetroTerminal.dos(width, height),
  () => RetroTerminal.shortDos(width, height),
  () => CanvasTerminal(width, height,
      Font('Menlo, Consolas', size: 12, w: 8, h: 14, x: 1, y: 11)),
  () => CanvasTerminal(
      width, height, Font('Courier', size: 13, w: 10, h: 15, x: 1, y: 11)),
  () => CanvasTerminal(
      width, height, Font('Courier', size: 12, w: 8, h: 14, x: 1, y: 10))
];

/// Index of the current terminal in [terminals].
int terminalIndex = 0;

void main() {
  // Set up the keybindings.
  ui.keyPress.bind("next terminal", KeyCode.tab);
  ui.keyPress.bind("prev terminal", KeyCode.tab, shift: true);
  ui.keyPress.bind("animate", KeyCode.space);

  updateTerminal();

  ui.push(MainScreen());

  ui.handlingInput = true;
  ui.running = true;
}

void updateTerminal() {
  html.document.body.children.clear();
  ui.setTerminal(terminals[terminalIndex]());
}

class MainScreen extends Screen<String> {
  final List<Ball> balls = [];

  MainScreen() {
    var colors = [
      Color.red,
      Color.orange,
      Color.gold,
      Color.yellow,
      Color.green,
      Color.aqua,
      Color.blue,
      Color.purple
    ];

    var random = math.Random();

    for (var char in [CharCode.bullet, CharCode.asterisk, "O".codeUnitAt(0)]) {
      for (var color in colors) {
        balls.add(Ball(
            color,
            char,
            random.nextDouble() * Ball.pitWidth,
            random.nextDouble() * (Ball.pitHeight / 2.0),
            random.nextDouble() + 0.2,
            0.0));
      }
    }
  }

  bool handleInput(String input) {
    switch (input) {
      case "next terminal":
        terminalIndex = (terminalIndex + 1) % terminals.length;
        updateTerminal();
        ui.refresh();
        break;

      case "prev terminal":
        terminalIndex = (terminalIndex - 1) % terminals.length;
        updateTerminal();
        ui.refresh();
        break;

      case "animate":
        ui.running = !ui.running;
        break;

      default:
        return false;
    }

    return true;
  }

  void update() {
    for (var ball in balls) {
      ball.update();
    }

    dirty();
  }

  void render(Terminal terminal) {
    terminal.clear();

    void colorBar(int y, String name, Color light, Color medium, Color dark) {
      terminal.writeAt(2, y, name, Color.gray);
      terminal.writeAt(10, y, "light", light);
      terminal.writeAt(16, y, "medium", medium);
      terminal.writeAt(23, y, "dark", dark);

      terminal.writeAt(28, y, " light ", Color.black, light);
      terminal.writeAt(35, y, " medium ", Color.black, medium);
      terminal.writeAt(43, y, " dark ", Color.black, dark);
    }

    terminal.writeAt(0, 0, "Predefined colors:");
    terminal.writeAt(59, 0, "switch terminal [tab]", Color.darkGray);
    terminal.writeAt(75, 0, "[tab]", Color.lightGray);
    colorBar(1, "gray", Color.lightGray, Color.gray, Color.darkGray);
    colorBar(2, "red", Color.lightRed, Color.red, Color.darkRed);
    colorBar(3, "orange", Color.lightOrange, Color.orange, Color.darkOrange);
    colorBar(4, "gold", Color.lightGold, Color.gold, Color.darkGold);
    colorBar(5, "yellow", Color.lightYellow, Color.yellow, Color.darkYellow);
    colorBar(6, "green", Color.lightGreen, Color.green, Color.darkGreen);
    colorBar(7, "aqua", Color.lightAqua, Color.aqua, Color.darkAqua);
    colorBar(8, "blue", Color.lightBlue, Color.blue, Color.darkBlue);
    colorBar(9, "purple", Color.lightPurple, Color.purple, Color.darkPurple);
    colorBar(10, "brown", Color.lightBrown, Color.brown, Color.darkBrown);

    terminal.writeAt(0, 12, "Code page 437:");
    var lines = [
      " ☺☻♥♦♣♠•◘○◙♂♀♪♫☼",
      "►◄↕‼¶§▬↨↑↓→←∟↔▲▼",
      " !\"#\$%&'()*+,-./",
      "0123456789:;<=>?",
      "@ABCDEFGHIJKLMNO",
      "PQRSTUVWXYZ[\\]^_",
      "`abcdefghijklmno",
      "pqrstuvwxyz{|}~⌂",
      "ÇüéâäàåçêëèïîìÄÅ",
      "ÉæÆôöòûùÿÖÜ¢£¥₧ƒ",
      "áíóúñѪº¿⌐¬½¼¡«»",
      "░▒▓│┤╡╢╖╕╣║╗╝╜╛┐",
      "└┴┬├─┼╞╟╚╔╩╦╠═╬╧",
      "╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀",
      "αßΓπΣσµτΦΘΩδ∞φε∩",
      "≡±≥≤⌠⌡÷≈°∙·√ⁿ²■"
    ];

    var y = 13;
    for (var line in lines) {
      terminal.writeAt(3, y++, line, Color.lightGray);
    }

    terminal.writeAt(22, 12, "Simple game loop:");
    terminal.writeAt(66, 12, "toggle [space]", Color.darkGray);
    terminal.writeAt(73, 12, "[space]", Color.lightGray);

    for (var ball in balls) {
      ball.render(terminal);
    }
  }
}

class Ball {
  static const pitWidth = 56.0;
  static const pitHeight = 17.0;

  final Color color;
  final int charCode;

  double x, y, h, v;

  Ball(this.color, this.charCode, this.x, this.y, this.h, this.v);

  void update() {
    x += h;
    if (x < 0.0) {
      x = -x;
      h = -h;
    } else if (x > pitWidth) {
      x = pitWidth - x + pitWidth;
      h = -h;
    }

    v += 0.03;
    y += v;
    if (y > pitHeight) {
      y = pitHeight - y + pitHeight;
      v = -v;
    }
  }

  void render(Terminal terminal) {
    terminal.drawChar(24 + x.toInt(), 13 + y.toInt(), charCode, color);
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  malison: ^0.10.1+1

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter packages get

Alternatively, your editor might support pub get or flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:malison/malison.dart';
  
Version Uploaded Documentation Archive
0.10.1+1 Oct 22, 2018 Go to the documentation of malison 0.10.1+1 Download malison 0.10.1+1 archive
0.10.1 Aug 5, 2018 Go to the documentation of malison 0.10.1 Download malison 0.10.1 archive
0.10.0 Jun 13, 2018 Go to the documentation of malison 0.10.0 Download malison 0.10.0 archive
0.9.0 Jun 4, 2018 Go to the documentation of malison 0.9.0 Download malison 0.9.0 archive
0.8.0 Dec 16, 2017 Go to the documentation of malison 0.8.0 Download malison 0.8.0 archive
0.7.0 Sep 16, 2017 Go to the documentation of malison 0.7.0 Download malison 0.7.0 archive
0.6.0 Jan 8, 2017 Go to the documentation of malison 0.6.0 Download malison 0.6.0 archive
0.5.1+1 Jan 4, 2017 Go to the documentation of malison 0.5.1+1 Download malison 0.5.1+1 archive
0.5.1 Jan 4, 2017 Go to the documentation of malison 0.5.1 Download malison 0.5.1 archive
0.5.0 Apr 15, 2016 Go to the documentation of malison 0.5.0 Download malison 0.5.0 archive

All 19 versions...

Popularity:
Describes how popular the package is relative to other packages. [more]
60
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
80
Overall:
Weighted score of the above. [more]
76
Learn more about scoring.

We analyzed this package on Nov 14, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0
  • pana: 0.12.6

Platforms

Detected platforms: Flutter, web, other

No platform restriction found in primary library package:malison/malison.dart.

Maintenance suggestions

The description is too short. (-20 points)

Add more detail about the package, what it does and what is its target use case. Try to write at least 60 characters.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.62.0 <3.0.0
piecemeal >=0.3.7 <0.5.0 0.4.1
Dev dependencies
browser any
build_runner any
build_web_compilers any