• Stars
    star
    138
  • Rank 264,508 (Top 6 %)
  • Language
    JavaScript
  • License
    BSD 3-Clause "New...
  • Created about 10 years ago
  • Updated about 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An embeddable Tetris clone without dependencies in 4 kB of JavaScript

Tis

Play Tis here, with the source code in the background.

Tis is a self-contained Tetrisยฎ clone in 4 kB of pure JavaScript (ECMAScript 5). This includes code to generate the necessary HTML markup and inline CSS.

Tis can be embedded into any web page by simply adding a <script> tag. It can then be invoked as an easter egg using the Konami code.

Features

Tis has nearly all of the features you might expect from a modern Tetris:

  • All seven tetromino shapes.
  • Block movement and rotation.
  • Key repeats.
  • Soft and hard drop.
  • Ghost piece.
  • Lock delay.
  • Bag-of-seven random generator.
  • Animated line clearing.
  • Look-ahead to the upcoming block.
  • Wall kicks.
  • Infinite levels, with corresponding speed increase.
  • Score, depending on level and number of lines cleared at once.
  • Animated game-over screen.
  • Sound effects.
  • Music with two treble voices and a bass voice.

Missing features

  • Points for T-spins and split line clears.
  • A hold area.
  • Multiple look-ahead.

Deploying

Simply grab tis.min.js from this repository, put it on your webserver somewhere, and put the following just before the </body> tag in your HTML:

<script src="/path/to/tis.min.js"></script>

Visitors of your web page will now get a nice surprise when they type the Konami code.

Implementation notes

To keep the code at least somewhat sane, it relies on UglifyJS for variable renaming, brace removal and more such niceties. However, there was still plenty to be done by hand. This section describes some of the tricks used.

HTML/CSS

  • Extracting common parts of HTML and CSS into strings, for example the string '<div style="margin:'.
  • Using pc instead of px in the CSS; one pica is 16 pixels.

Game data

  • The music is encoded as a string of characters, where each character represents both the pitch and the duration of a single note.
  • The tetromino shapes in their respective orientations are encoded as bitmasks, but because we can't efficiently encode bytes above 127 in UTF-8, they are encoded in base-64 instead.
  • Wall kick tables are encoded as a string, where each character encodes a single x and y offset.
  • Tetromino colours are encoded in a single string of #fff-style hex values (without the # of course), separated by the character 9. We use a digit because it doesn't require quotes when passing to Array.split().
  • Sound effects are encoded as a single number, packing a few bits for decay speed, a few for initial frequency, and a few more for another frequency that kicks in after 1000 (1e3) samples.

JavaScript

  • Names of global objects (window, document) and of frequently used fields/methods are stored in variables to make access shorter.
  • Instead of document.getElementById(...), use the fact that element IDs are also registered on the window object: window[...].
  • Because var declarations are costly, do them only once at the top-level scope, and reuse variables as much as possible. This does make it difficult to safely invoke functions.
  • Inline as many functions as possible, because function is an awfully long word that cannot be shortened.
  • Let undefined be the desired initial value of variables as much as possible, so we don't need to initialize them.
  • Be aware of the for(i in a) syntax as an alternative to for(i=0;i<n;i++). However, this isn't always shorter, because the traditional for loop lets you put more stuff inside the initialization, condition and increment part.
  • Put assignments inside expressions where possible: instead of x++;y=2*x write y=2*x++.
  • Instead of x>=0&&x<4, write !(x&~3). This works even if x is negative.
  • Use ~~(a+b) instead of Math.floor(a+b) to cast to integer. 0|(a+b) also works.
  • For somewhat arbitrary constants, 9 is better than 10, 99 better than 100.
  • switch/case is extremely verbose, especially if you need break (i.e. almost always). Just use if/else if instead.
  • There is even one goto-like label, to break out of two for loops at the same time. This is the only thing labels in JavaScript can be used for.

More Repositories

1

jfxr

A browser-based tool to create sound effects for games.
JavaScript
400
star
2

taekwindow

Taekwindow is a simple, lightweight and free Windows program that allows you to move and resize windows by dragging them with the Alt key, similar to many X11 window managers.
C++
59
star
3

sf2github

A Python script to migrate projects from SourceForge to GitHub; currently very immature and incomplete.
Python
39
star
4

aoc2017

My solutions for Advent of Code 2017, each in a different language.
Eiffel
30
star
5

aoc2016

My solutions for Advent of Code 2016, each in a different language
C
17
star
6

commonmark

A CommonMark parser and HTML generator for Go
Go
16
star
7

harmonograph

A harmonograph simulator in JavaScript
JavaScript
13
star
8

gladder

Gladder is a WebGL wrapper library written in CoffeeScript, compiling down to pure JavaScript.
JavaScript
12
star
9

ebisu_dart

Ebisu intelligent quiz scheduling algorithm based on Bayesian statistics and an exponential forgetting curve (Dart implementation)
Dart
11
star
10

leonardo

An entry for the Ludum Dare 36 compo: http://leonardo.frozenfractal.com
Haxe
8
star
11

rugscriptie

LaTeX package to format the title of a thesis in the style of the University of Groningen
TeX
7
star
12

pickomino

An experimental AI for the dice game Pickomino
C++
7
star
13

papageno

A mobile app that helps you learn to recognize bird sounds by ear
Dart
4
star
14

rustyknife

An implementation of the Inform Z-Machine in Rust
Rust
4
star
15

whistler

A webapp for recording whistling via your microphone and turning it into a MIDI file
JavaScript
3
star
16

toytown

Ludum Dare 31 entry, a city builder game
TypeScript
3
star
17

aoc2018

Advent of Code 2018 in Rust
Rust
3
star
18

titlepic

A LaTeX package to put a picture on the title page of a document
TeX
3
star
19

blimp

A flexible content management system based on Git and Redis
Ruby
2
star
20

beebqr

An experimental program for the BBC Microcomputer to transfer data via QR codes
Java
2
star
21

prikmeter

ESP8266 (Arduino Core) code to read data from a Dutch smart meter (DSMR) and a Node.js server to receive and process it
C++
2
star
22

mistyisles

My entry for the 2nd Alakajam! game jam, Solo league
GDScript
1
star
23

aoc2021

My solutions for Advent of Code 2021
Python
1
star
24

aoc2020

My solutions for Advent of Code 2020
Rust
1
star
25

obersprengmeister

A game made in 48 hours for the 4th Alakajam! game jam โ€“ Play at https://obersprengmeister.frozenfractal.com
GDScript
1
star
26

discharge

A 3D browser game where you avoid the lightning by planting trees
JavaScript
1
star
27

godot_stretch_demo

Short demonstration of different viewport stretch settings in Godot Engine
GDScript
1
star
28

crosswordfinder

Crossword Finder is a web application to search for words fitting a partially filled crossword puzzle.
Ruby
1
star
29

journaldriver

journald -> Stackdriver Logging
Rust
1
star
30

parkitect-legoland

Legoland Billund reconstruction in the game Parkitect
1
star
31

apodwp

Python script that fetches and resizes the Astronomy Picture of the Day for use as a wallpaper
Python
1
star
32

kiffany

An experimental voxel engine, reminiscent of a certain mining game.
C++
1
star