folding sub-libs into single lib

This commit is contained in:
Peli de Halleux
2016-03-10 22:17:32 -08:00
parent 6c045640d2
commit 78aee5fdd4
17 changed files with 9 additions and 103 deletions

723
libs/microbit/game.ts Normal file
View File

@ -0,0 +1,723 @@
enum Direction {
//% blockId=right
Right,
//% blockId=left
Left
}
enum LedSpriteProperty {
//% blockId=x
X,
//% blockId=y
Y,
//% blockId=direction
Direction,
//% blockId=brightness
Brightness,
//% blockId=blink
Blink
}
//% color=176 weight=32
namespace game {
var _score: number = 0;
var _life: number = 3;
var _startTime: number = 0;
var _endTime: number = 0;
var _isGameOver: boolean = false;
var _countdownPause: number = 0;
var _level: number = 1;
var _gameId: number = 0;
var img: images.Image;
var sprites: LedSprite[];
/**
* Creates a new LED sprite pointing to the right.
* @param x sprite horizontal coordinate, eg: 2
* @param y sprite vertical coordinate, eg: 2
*/
//% weight=60
//% blockId=game_create_sprite block="create sprite at|x: %x|y: %y"
export function createSprite(x: number, y: number): LedSprite {
init();
let p = new LedSprite(x, y);
sprites.push(p);
plot();
return p;
}
/**
* Gets the current score
*/
//% weight=9 help=td/game-library
//% blockId=game_score block="score" blockGap=8
export function score(): number {
return _score;
}
/**
* Adds points to the current score
* @param points amount of points to change, eg: 1
*/
//% weight=10 help=td/game-library
//% blockId=game_add_score block="change score by|%points" blockGap=8
export function addScore(points: number): void {
setScore(_score + points);
control.inBackground(() => {
led.stopAnimation();
basic.showAnimation(`0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0`, 20);
});
}
/**
* Starts a game countdown timer
* @param ms countdown duration in milliseconds, eg: 10000
*/
//% weight=9 help=td/game-library
//% blockId=game_start_countdown block="start countdown|(ms) %duration" blockGap=8
export function startCountdown(ms: number): void {
if (checkStart()) {
basic.showAnimation(`1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0`, 400);
_countdownPause = Math.max(500, ms);
_startTime = -1;
_endTime = input.runningTime() + _countdownPause;
control.inBackground(() => {
basic.pause(_countdownPause);
gameOver();
});
}
}
/**
* Displays a game over animation.
*/
//% weight=8 help=td/game-library
//% blockId=game_game_over block="game over"
export function gameOver(): void {
if (!_isGameOver) {
_isGameOver = true;
unplugEvents();
led.stopAnimation();
led.setBrightness(255);
led.setDisplayMode(DisplayMode.BackAndWhite);
while (true) {
for (let i = 0; i < 8; i++) {
basic.clearScreen();
basic.pause(100);
basic.showLeds(`1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1`, 300);
}
basic.showAnimation(`1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 0 1 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0`, 100);
for (let j = 0; j < 3; j++) {
basic.showString(" GAMEOVER ", 100);
showScore();
}
}
} else {
// already in game over mode in another fiber
while (true) {
basic.pause(10000);
}
}
}
/**
* Sets the current score value
* @param value TODO
*/
//% weight=10 help=td/game-library
export function setScore(value: number): void {
_score = Math.max(0, value);
}
/**
* Gets the current life
*/
//% weight=10 help=td/game-library
export function life(): number {
return _life;
}
/**
* Sets the current life value
* @param value TODO
*/
//% weight=10 help=td/game-library
export function setLife(value: number): void {
_life = Math.max(0, value);
if (_life <= 0) {
gameOver();
}
}
/**
* Adds life points to the current life
* @param lives TODO
*/
//% weight=10 help=td/game-library
export function addLife(lives: number): void {
setLife(_life + lives);
}
/**
* Gets the remaining time (since `start countdown`) or current time (since the device started or `start stopwatch`) in milliseconds.
*/
//% weight=10 help=td/game-library
export function currentTime(): number {
if (_endTime > 0) {
return Math.max(0, _endTime - input.runningTime());
} else {
return input.runningTime() - _startTime;
}
}
/**
* Removes some life
* @param life TODO
*/
//% weight=10 help=td/game-library
export function removeLife(life: number): void {
setLife(_life - life);
control.inBackground(() => {
led.stopAnimation();
basic.showAnimation(`1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0
0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0
1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0`, 40);
});
}
/**
* Increments the level and display a message.
*/
//% weight=10 help=td/game-library
export function levelUp(): void {
_level = _level + 1;
basic.showString("LEVEL:", 150);
basic.showNumber(_level, 150);
}
/**
* Gets the current level
*/
//% weight=10 help=td/game-library
export function level(): number {
return _level;
}
/**
* Starts a stopwatch timer. `current time` will return the elapsed time.
*/
//% weight=10 help=td/game-library
export function startStopwatch(): void {
_startTime = input.runningTime();
_endTime = -1;
}
/**
* Gets a value indicating if the game is still running. Returns `false` if game over.
*/
//% weight=10 help=td/game-library
export function isRunning(): boolean {
let running: boolean;
return !_isGameOver;
}
/**
* Displays the score on the screen.
*/
//% help=td/game-library weight=60
export function showScore(): void {
basic.showString(" SCORE ", 100);
basic.showNumber(_score, 150);
basic.showString(" ", 150);
}
/**
* Indicates if the game is display the game over sequence.
*/
//% help=/functions/game-library
export function isGameOver(): boolean {
let over: boolean;
return _isGameOver;
}
/**
* returns false if game can't start
*/
function checkStart(): boolean {
if (_countdownPause > 0 || _startTime > 0) {
return false;
} else {
return true;
}
}
function unplugEvents(): void {
input.onButtonPressed(Button.A, () => { });
input.onButtonPressed(Button.B, () => { });
input.onButtonPressed(Button.AB, () => {
control.reset();
});
}
export class LedSprite {
private _x: number;
private _y: number;
private _dir: number;
private _brightness: number;
private _blink: number;
constructor(x: number, y: number) {
this._x = math.clamp(0, 4, x);
this._y = math.clamp(0, 4, y);
this._dir = 90;
this._brightness = 255;
init();
sprites.push(this);
plot();
}
/**
* Move a certain number of LEDs
* @param this the sprite to move
* @param leds number of leds to move, eg: 1, -1
*/
//% weight=50
//% blockId=game_move_sprite block="%sprite|move by %leds" blockGap=8
public move(leds: number): void {
if (this._dir == 0) {
this._y = this._y - leds;
} else if (this._dir == 45) {
this._x = this._x + leds;
this._y = this._y - leds;
} else if (this._dir == 90) {
this._x = this._x + leds;
} else if (this._dir == 135) {
this._x = this._x + leds;
this._y = this._y + leds;
} else if (this._dir == 180) {
this._y = this._y + leds;
} else if (this._dir == -45) {
this._x = this._x - leds;
this._y = this._y - leds;
} else if (this._dir == -90) {
this._x = this._x - leds;
} else {
this._x = this._x - leds;
this._y = this._y + leds;
}
this._x = math.clamp(0, 4, this._x);
this._y = math.clamp(0, 4, this._y);
plot();
}
/**
* Go to this position on the screen
* @param this TODO
* @param x TODO
* @param y TODO
*/
public goTo(x: number, y: number): void {
this._x = x;
this._y = y;
this._x = math.clamp(0, 4, this._x);
this._y = math.clamp(0, 4, this._y);
plot();
}
/**
* If touching the edge of the stage, then bounce away.
* @param this TODO
*/
//% weight=18
//% blockId=game_sprite_bounce block="%sprite|if on edge, bounce"
public ifOnEdgeBounce(): void {
if (this._dir == 0 && this._y == 0) {
this._dir = 180;
} else if (this._dir == 45 && (this._x == 4 || this._y == 0)) {
if (this._x == 0 && this._y == 0) {
this._dir = -135;
} else if (this._y == 0) {
this._dir = 135;
} else {
this._dir = -45;
}
} else if (this._dir == 90 && this._x == 4) {
this._dir = -90;
} else if (this._dir == 135 && (this._x == 4 || this._y == 4)) {
if (this.x() == 4 && this.y() == 4) {
this._dir = -45;
} else if (this._y == 4) {
this._dir = 45;
} else {
this._dir = -135;
}
} else if (this._dir == 180 && this._y == 4) {
this._dir = 0;
} else if (this._dir == -45 && (this._x == 0 || this._y == 0)) {
if (this.x() == 0 && this.y() == 0) {
this._dir = 135;
} else if (this._y == 0) {
this._dir = -135;
} else {
this._dir = 45;
}
} else if (this._dir == -90 && this._x == 0) {
this._dir = 90;
} else if (this._dir == -135 && (this._x == 0 || this._y == 4)) {
if (this._x == 0 && this._y == 4) {
this._dir = 45;
} else if (this._y == 4) {
this._dir = -45;
} else {
this._dir = 135;
}
}
plot();
}
/**
* Turn the sprite
* @param this TODO
* @param direction left or right
* @param degrees angle in degrees to turn, eg: 45, 90, 180, 135
*/
//% weight=49
//% blockId=game_turn_sprite block="%sprite|turn %direction|by (°) %degrees"
public turn(direction : Direction, degrees: number) {
if (direction == Direction.Right)
this.setDirection(this._dir + degrees);
else
this.setDirection(this._dir - degrees);
}
/**
* Turn to the right (clockwise)
* @param this TODO
* @param degrees TODO
*/
public turnRight(degrees: number): void {
this.turn(Direction.Right, degrees);
}
/**
* Turn to the left (counter-clockwise)
* @param this TODO
* @param degrees TODO
*/
public turnLeft(degrees: number): void {
this.turn(Direction.Left, degrees);
}
/**
* Sets a property of the sprite
* @param property the name of the property to change
* @param the updated value
*/
//% weight=29
//% blockId=game_sprite_set_property block="%sprite|set %property|to %value" blockGap=8
public set(property : LedSpriteProperty, value:number) {
switch(property) {
case LedSpriteProperty.X: this.setX(value); break;
case LedSpriteProperty.Y: this.setY(value); break;
case LedSpriteProperty.Direction: this.setDirection(value); break;
case LedSpriteProperty.Brightness: this.setBrightness(value); break;
case LedSpriteProperty.Blink: this.setBlink(value); break;
}
}
/**
* Changes a property of the sprite
* @param property the name of the property to change
* @param value amount of change, eg: 1
*/
//% weight=30
//% blockId=game_sprite_change_xy block="%sprite|change %property|by %value" blockGap=8
public change(property : LedSpriteProperty, value:number) {
switch(property) {
case LedSpriteProperty.X: this.changeXBy(value); break;
case LedSpriteProperty.Y: this.changeYBy(value); break;
case LedSpriteProperty.Direction: this.changeDirectionBy(value); break;
case LedSpriteProperty.Brightness: this.changeBrightnessBy(value); break;
case LedSpriteProperty.Blink: this.changeBlinkBy(value); break;
}
}
/**
* Gets a property of the sprite
* @param property the name of the property to change
*/
//% weight=28
//% blockId=game_sprite_property block="%sprite|%property"
public get(property : LedSpriteProperty) {
switch(property) {
case LedSpriteProperty.X: return this.x();
case LedSpriteProperty.Y: return this.y();
case LedSpriteProperty.Direction: return this.direction()
case LedSpriteProperty.Brightness: return this.brightness();
case LedSpriteProperty.Blink: return this.blink();
default: return 0;
}
}
/**
* Set the direction of the current sprite, rounded to the nearest multiple of 45
* @param this TODO
* @param degrees TODO
*/
public setDirection(degrees: number): void {
this._dir = ((degrees / 45) % 8) * 45;
if (this._dir <= -180) {
this._dir = this._dir + 360;
} else if (this._dir > 180) {
this._dir = this._dir - 360;
}
plot();
}
/**
* Reports the ``x`` position of a sprite on the LED screen
* @param this TODO
*/
public x(): number {
return this._x;
}
/**
* Reports the ``y`` position of a sprite on the LED screen
* @param this TODO
*/
public y(): number {
return this._y;
}
/**
* Reports the current direction of a sprite
* @param this TODO
*/
public direction(): number {
return this._dir;
}
/**
* Set the ``x`` position of a sprite
* @param this TODO
* @param x TODO
*/
public setX(x: number): void {
this.goTo(x, this._y);
}
/**
* Set the ``y`` position of a sprite
* @param this TODO
* @param y TODO
*/
public setY(y: number): void {
this.goTo(this._x, y);
}
/**
* Changes the ``y`` position by the given amount
* @param this TODO
* @param y TODO
*/
public changeYBy(y: number): void {
this.goTo(this._x, this._y + y);
}
/**
* Changes the ``x`` position by the given amount
* @param this TODO
* @param x TODO
*/
public changeXBy(x: number): void {
this.goTo(this._x + x, this._y);
}
/**
* Reports true if sprite is touching specified sprite
* @param this TODO
* @param other TODO
*/
//% weight=20
//% blockId=game_sprite_touching_sprite block="%sprite|touching %other|?" blockGap=8
public isTouching(other: LedSprite): boolean {
return this._x == other._x && this._y == other._y;
}
/**
* Reports true if sprite is touching an edge
* @param this TODO
*/
//% weight=19
//% blockId=game_sprite_touching_edge block="%sprite|touching edge?" blockGap=8
public isTouchingEdge(): boolean {
return this._x == 0 || this._x == 4 || this._y == 0 || this._y == 4;
}
/**
* Turns on the sprite (on by default)
* @param this TODO
*/
public on(): void {
this.setBrightness(255);
}
/**
* Turns off the sprite (on by default)
* @param this TODO
*/
public off(): void {
this.setBrightness(0);
}
/**
* Set the ``brightness`` of a sprite
* @param this TODO
* @param brightness TODO
*/
public setBrightness(brightness: number): void {
this._brightness = math.clamp(0, 255, brightness);
plot();
}
/**
* Reports the ``brightness` of a sprite on the LED screen
* @param this TODO
*/
public brightness(): number {
let r: number;
return this._brightness;
}
/**
* Changes the ``y`` position by the given amount
* @param this TODO
* @param value TODO
*/
public changeBrightnessBy(value: number): void {
this.setBrightness(this._brightness + value);
}
/**
* Changes the ``direction`` position by the given amount by turning right
* @param this TODO
* @param angle TODO
*/
public changeDirectionBy(angle: number): void {
this.turnRight(angle);
}
/**
* Deletes the sprite from the game engine. All further operation of the sprite will not have any effect.
* @param sprite TODO
*/
public delete(sprite: LedSprite): void {
sprites.removeElement(sprite);
}
/**
* Sets the blink duration interval in millisecond.
* @param sprite TODO
* @param ms TODO
*/
public setBlink(ms: number): void {
this._blink = math.clamp(0, 10000, ms);
}
/**
* Changes the ``blink`` duration by the given amount of millisecons
* @param this TODO
* @param ms TODO
*/
public changeBlinkBy(ms: number): void {
this.setBlink(this._blink + ms);
}
/**
* Reports the ``blink`` duration of a sprite
* @param this TODO
*/
public blink(): number {
let r: number;
return this._blink;
}
//% weight=-1
public _plot(now: number) {
let ps = this
if (ps._brightness > 0) {
let r = 0;
if (ps._blink > 0) {
r = (now / ps._blink) % 2;
}
if (r == 0) {
img.setPixelBrightness(ps._x, ps._y, img.pixelBrightness(ps._x, ps._y) + ps._brightness);
}
}
}
}
function init(): void {
if (img == null) {
img = images.createImage(
`0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0`);
sprites = (<LedSprite[]>[]);
led.setDisplayMode(DisplayMode.Greyscale);
basic.forever(() => {
basic.pause(30);
plot();
if (game.isGameOver()) {
basic.pause(600);
}
});
}
}
/**
* Plots the current sprites on the screen
*/
function plot(): void {
if (game.isGameOver()) {
return;
}
let now = input.runningTime();
img.clear();
for (let i = 0; i < sprites.length; i++) {
sprites[i]._plot(now);
}
img.plotImage(0);
}
/**
* Gets an invalid sprite; used to initialize locals.
*/
//% weight=0
export function invalidSprite(): LedSprite {
return null;
}
}

View File

@ -9,7 +9,12 @@
"images.ts",
"basic.ts",
"input.ts",
"control.ts"
"control.ts",
"game.ts",
"led.ts",
"music.ts",
"pins.ts",
"serial.ts"
],
"public": true,
"dependencies": {},
@ -23,12 +28,7 @@
"name": "{0} block",
"dependencies": {
"microbit": "*",
"microbit-led": "*",
"microbit-music": "*",
"microbit-radio": "*",
"microbit-game": "*",
"microbit-pins": "*",
"microbit-serial": "*"
"microbit-radio": "*"
},
"description": "",
"files": [
@ -49,12 +49,7 @@
"name": "{0} bit",
"dependencies": {
"microbit": "*",
"microbit-led": "*",
"microbit-music": "*",
"microbit-radio": "*",
"microbit-game": "*",
"microbit-pins": "*",
"microbit-serial": "*"
"microbit-radio": "*"
},
"description": "",
"files": [

208
libs/microbit/led.ts Normal file
View File

@ -0,0 +1,208 @@
enum DisplayMode {
//% enumval=0 blockId="black and white"
BackAndWhite,
//% enumval=1 blockId="greyscale"
Greyscale,
}
//% color=3 weight=35
namespace led {
/**
* Turn on the specified LED using x, y coordinates (x is horizontal, y is vertical). (0,0) is upper left.
* @param x TODO
* @param y TODO
*/
//% help=functions/plot weight=78 shim=micro_bit::plot
//% blockId=device_plot block="plot|x %x|y %y" icon="\uf205" blockGap=8
export function plot(x: number, y: number): void { }
/**
* Turn off the specified LED using x, y coordinates (x is horizontal, y is vertical). (0,0) is upper left.
* @param x TODO
* @param y TODO
*/
//% help=functions/unplot weight=77 shim=micro_bit::unPlot
//% blockId=device_unplot block="unplot|x %x|y %y" icon="\uf204" blockGap=8
export function unplot(x: number, y: number): void { }
/**
* Get the on/off state of the specified LED using x, y coordinates. (0,0) is upper left.
* @param x TODO
* @param y TODO
*/
//% help=functions/point weight=76 shim=micro_bit::point
//% blockId=device_point block="point|x %x|y %y" icon="\uf10c"
export function point(x: number, y: number): boolean {
return false;
}
/**
* Get the screen brightness from 0 (off) to 255 (full bright).
*/
//% help=functions/brightness weight=60 shim=micro_bit::getBrightness
//% blockId=device_get_brightness block="brightness" icon="\uf042" blockGap=8
export function brightness(): number {
return 0;
}
/**
* Set the screen brightness from 0 (off) to 255 (full bright).
* @param value the brightness value, eg:255, 127, 0
*/
//% help=functions/set-brightness weight=59 shim=micro_bit::setBrightness
//% blockId=device_set_brightness block="set brightness %value" icon="\uf042"
export function setBrightness(value: number): void { }
/**
* Cancels the current animation and clears other pending animations.
*/
//% weight=50 shim=uBit.display.stopAnimation help=functions/stop-animation
//% blockId=device_stop_animation block="stop animation" icon="\uf04d"
export function stopAnimation(): void { }
/**
* Displays a vertical bar graph based on the ``value`` and ``high`` value.
* @param value current value to plot
* @param high maximum value, eg: 1023, 255
*/
//% help=/functions/plot-bar-graph weight=20
//% blockId=device_plot_bar_graph block="plot bar graph of %value |up to %high" icon="\uf080" blockExternalInputs=true
export function plotBarGraph(value: number, high: number = 1023): void {
writeString("v: ");
writeString(value.toString());
writeString("\n");
let v = Math.abs((value * 15) / high);
let k = 0;
for(let y = 4; y >= 0; --y) {
for (let x = 0; x < 3; ++x) {
if (k > v) {
unplot(2-x,y);
unplot(2+x,y);
} else {
plot(2-x, y);
plot(2+x, y);
}
++k;
}
}
}
/**
* Writes a string to serial
*/
//% shim=micro_bit::serialSendString
function writeString(text: string): void { }
/**
* Sets the display mode between black and white and greyscale for rendering LEDs.
* @param mode TODO
*/
//% shim=micro_bit::setDisplayMode weight=1 help=/functions/set-display-mode
export function setDisplayMode(mode: DisplayMode): void { }
/**
* Toggles a particular pixel
* @param x TODO
* @param y TODO
*/
//% help=functions/toggle
export function toggle(x: number, y: number): void {
if (led.point(x, y)) {
led.unplot(x, y);
} else {
led.plot(x, y);
}
}
/**
* Turns all LEDS on
*/
//% help=functions/plot-all
export function plotAll(): void {
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 5; j++) {
led.plot(i, j);
}
}
}
/**
* Inverts the current LED display
*/
//% help=functions/toggle-all
export function toggleAll(): void {
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 5; j++) {
led.toggle(i, j);
}
}
}
/**
* Fades in the screen display.
* @param ms TODO
*/
//% help=functions/fade-in
export function fadeIn(ms: number = 700): void {
if (ms < 20) {
led.setBrightness(255);
return;
}
let dt = 50;
let brightness = led.brightness();
let start = input.runningTime();
let elapsed = 0;
while (elapsed < ms) {
led.setBrightness(brightness + ((255 - brightness) * elapsed) / ms);
basic.pause(dt);
elapsed = input.runningTime() - start;
}
led.setBrightness(255);
}
/**
* Fades out the screen brightness.
* @param ms TODO
*/
//% help=functions/fade-out
export function fadeOut(ms: number = 700): void {
if (ms < 20) {
led.setBrightness(0);
return;
}
let brightness = led.brightness();
let dt = 50;
let start = input.runningTime();
let elapsed = 0;
while (elapsed < ms) {
led.setBrightness(brightness - (brightness * elapsed) / ms);
basic.pause(dt);
elapsed = input.runningTime() - start;
}
led.setBrightness(0);
}
/**
* Takes a screenshot of the LED screen and returns an image.
*/
//% shim=uBit.display.screenShot help=functions/screenshot
export function screenshot(): images.Image {
/*
let img: Image;
img = image.createImage("");
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 5; j++) {
if (led.point(i, j)) {
img.setPixel(i, j, true);
}
}
}
return img;
*/
return null;
}
}

201
libs/microbit/music.ts Normal file
View File

@ -0,0 +1,201 @@
enum Notes {
//% enumval=262
C,
//% enumval=277 blockId=C#
CSharp,
//% enumval=294
D,
//% enumval=311
Eb,
//% enumval=330
E,
//% enumval=349
F,
//% enumval=370 blockId=F#
FSharp,
//% enumval=392
G,
//% enumval=415 blockId=G#
GSharp,
//% enumval=440
A,
//% enumval=466
Bb,
//% enumval=494
B,
//% enumval=131
C3,
//% enumval=139 blockId=C#3
CSharp3,
//% enumval=147
D3,
//% enumval=156
Eb3,
//% enumval=165
E3,
//% enumval=175
F3,
//% enumval=185 blockId=F#3
FSharp3,
//% enumval=196
G3,
//% enumval=208 blockId=G#3
GSharp3,
//% enumval=220
A3,
//% enumval=233
Bb3,
//% enumval=247
B3,
//% enumval=262
C4,
//% enumval=277 blockId=C#4
CSharp4,
//% enumval=294
D4,
//% enumval=311
Eb4,
//% enumval=330
E4,
//% enumval=349
F4,
//% enumval=370 blockId=F#3
FSharp4,
//% enumval=392
G4,
//% enumval=415 blockId=G#3
GSharp4,
//% enumval=440
A4,
//% enumval=466
Bb4,
//% enumval=494
B4,
//% enumval=523
C5,
//% enumval=555 blockId=C#5
CSharp5,
//% enumval=587
D5,
//% enumval=622
Eb5,
//% enumval=659
E5,
//% enumval=698
F5,
//% enumval=740 blockId=F#5
FSharp5,
//% enumval=784
G5,
//% enumval=831 blockId=G#5
GSharp5,
//% enumval=880
A5,
//% enumval=932
Bb5,
//% enumval=989
B5,
}
enum BeatFraction {
//% enumVal=1 blockId=1
Whole = 1,
//% enumVal=2 blockId="1/2"
Half = 2,
//% enumVal=4 blockId="1/4"
Quater = 4,
//% enumVal=8 blockId="1/8"
Heighth = 8,
//% enumVal=16 blockId="1/16"
Sixteenth = 16
}
//% color=52 weight=33
namespace music {
var beatsPerMinute: number = 120;
/**
* Plays a tone through pin ``P0`` for the given duration.
* @param frequency TODO
* @param ms TODO
*/
//% help=functions/play-tone weight=90
//% blockId=device_play_note block="play|tone (Hz) %note=device_note|for (ms) %duration=device_beat" icon="\uf025" blockGap=8
export function playTone(frequency: number, ms: number): void {
pins.analogSetPitchPin(AnalogPins.P0);
pins.analogPitch(frequency, ms);
}
/**
* Plays a tone through pin ``P0``.
* @param frequency TODO
*/
//% help=functions/ring-tone weight=80
//% blockId=device_ring block="ring tone (Hz)|%note=device_note" icon="\uf025" blockGap=8
export function ringTone(frequency: number): void {
pins.analogSetPitchPin(AnalogPins.P0);
pins.analogPitch(frequency, 0);
}
/**
* Rests (plays nothing) for a specified time through pin ``P0``.
* @param ms TODO
*/
//% help=functions/rest weight=79
//% blockId=device_rest block="rest(ms)|%duration=device_beat"
export function rest(ms: number): void {
playTone(0, ms);
}
/**
* Gets the frequency of a note.
* @param name TODO
*/
//% shim=TD_ID weight=50 help=functions/note-frequency
//% blockId=device_note block="%note"
export function noteFrequency(name: Notes): number {
return name;
}
/**
* Returns the duration of a beat in milli-seconds
*/
//% help=/functions/beat weight=49
//% blockId=device_beat block="%fraction|beat"
export function beat(fraction : BeatFraction = BeatFraction.Whole): number {
let ms: number;
return 60000 / fraction / beatsPerMinute;
}
/**
* Returns the tempo in beats per minute. Tempo is the speed (bpm = beats per minute) at which notes play. The larger the tempo value, the faster the notes will play.
*/
//% help=/functions/tempo weight=40
//% blockId=device_tempo block="tempo (bpm)" blockGap=8
export function tempo(): number {
return beatsPerMinute;
}
/**
* Change the tempo by the specified amount
* @param bpm The change in beats per minute to the tempo, eg: 20
*/
//% help=/functions/tempo weight=39
//% blockId=device_change_tempo block="change tempo by (bpm)|%value" blockGap=8
export function changeTempoBy(bpm: number): void {
setTempo(beatsPerMinute + bpm);
}
/**
* Sets the tempo to the specified amount
* @param bpm The new tempo in beats per minute, eg: 120
*/
//% help=/functions/tempo weight=38
//% blockId=device_set_tempo block="set tempo to (bpm)|%value"
export function setTempo(bpm: number): void {
if (bpm > 0) {
beatsPerMinute = Math.max(1, bpm);
}
}
}

155
libs/microbit/pins.ts Normal file
View File

@ -0,0 +1,155 @@
enum DigitalPins {
//% enumval=uBit.io.P0
P0,
//% enumval=uBit.io.P1
P1,
//% enumval=uBit.io.P2
P2,
//% enumval=uBit.io.P3
P3,
//% enumval=uBit.io.P4
P4,
//% enumval=uBit.io.P5
P5,
//% enumval=uBit.io.P6
P6,
//% enumval=uBit.io.P7
P7,
//% enumval=uBit.io.P8
P8,
//% enumval=uBit.io.P9
P9,
//% enumval=uBit.io.P10
P10,
//% enumval=uBit.io.P11
P11,
//% enumval=uBit.io.P12
P12,
//% enumval=uBit.io.P13
P13,
//% enumval=uBit.io.P14
P14,
//% enumval=uBit.io.P15
P15,
//% enumval=uBit.io.P16
P16,
//% enumval=uBit.io.P19
P19,
//% enumval=uBit.io.P20
P20,
}
enum AnalogPins {
//% enumval=uBit.io.P0
P0,
//% enumval=uBit.io.P1
P1,
//% enumval=uBit.io.P2
P2,
//% enumval=uBit.io.P3
P3,
//% enumval=uBit.io.P4
P4,
//% enumval=uBit.io.P10
P10,
}
//% color=351 weight=30
namespace pins {
/**
* Read the specified pin or connector as either 0 or 1
* @param name pin to read from
*/
//% help=functions/digital-read-pin weight=30 shim=micro_bit::digitalReadPin
//% blockId=device_get_digital_pin block="digital read|pin %name" blockGap=8
export function digitalReadPin(name: DigitalPins): number {
return 0;
}
/**
* Set a pin or connector value to either 0 or 1.
* @param name pin to write to
* @param value value to set on the pin, eg: 1,0
*/
//% help=functions/digital-write-pin weight=29 shim=micro_bit::digitalWritePin
//% blockId=device_set_digital_pin block="digital write|pin %name|to %value"
export function digitalWritePin(name: DigitalPins, value: number): void { }
/**
* Read the connector value as analog, that is, as a value comprised between 0 and 1023.
* @param name pin to write to
*/
//% help=functions/analog-read-pin weight=25 shim=micro_bit::analogReadPin
//% blockId=device_get_analog_pin block="analog read|pin %name" blockGap="8"
export function analogReadPin(name: AnalogPins): number {
return 0;
}
/**
* Set the connector value as analog. Value must be comprised between 0 and 1023.
* @param name pin name to write to
* @param value value to write to the pin between ``0`` and ``1023``. eg:1023,0
*/
//% help=functions/analog-write-pin weight=24 shim=micro_bit::analogWritePin
//% blockId=device_set_analog_pin block="analog write|pin %name|to %value" blockGap=8
export function analogWritePin(name: AnalogPins, value: number): void { }
/**
* Configures the Pulse-width modulation (PWM) of the analog output to the given value in **microseconds** or `1/1000` milliseconds.
* If this pin is not configured as an analog output (using `analog write pin`), the operation has no effect.
* @param pin analog pin to set period to
* @param micros period in micro seconds. eg:20000
*/
//% shim=micro_bit::setAnalogPeriodUs help=functions/analog-set-period weight=23
//% blockId=device_set_analog_period block="analog set period|pin %pin|to (µs)%micros"
export function analogSetPeriod(pin: AnalogPins, micros: number): void { }
/**
* Writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one direction, ``180`` being full speed in the other, and a value near ``90`` being no movement).
* @param name pin to write to
* @param value angle or rotation speed, eg:180,90,0
*/
//% help=functions/servo-write-pin weight=20 shim=micro_bit::servoWritePin
//% blockId=device_set_servo_pin block="servo write|pin %name|to %value" blockGap=8
export function servoWritePin(name: AnalogPins, value: number): void { }
/**
* Configures this IO pin as an analog/pwm output, configures the period to be 20 ms, and sets the pulse width, based on the value it is given **microseconds** or `1/1000` milliseconds.
* @param pin pin name
* @param micros pulse duration in micro seconds, eg:1500
*/
//% shim=micro_bit::setServoPulseUs help=functions/serial-set-pulse weight=19
//% blockId=device_set_servo_pulse block="servo set pulse|pin %value|to (µs) %micros"
export function servoSetPulse(pin: AnalogPins, micros: number): void { }
/**
* Re-maps a number from one range to another. That is, a value of ``from low`` would get mapped to ``to low``, a value of ``from high`` to ``to high``, values in-between to values in-between, etc.
* @param value value to map in ranges
* @param fromLow the lower bound of the value's current range
* @param fromHigh the upper bound of the value's current range, eg: 1023
* @param toLow the lower bound of the value's target range
* @param toHigh the upper bound of the value's target range, eg: 4
*/
//% help=functions/map weight=15
//% blockId=math_map block="map %value|from low %fromLow|from high %fromHigh|to low %toLow|to high %toHigh"
export function map(value: number, fromLow: number, fromHigh: number, toLow: number, toHigh: number): number {
return ((value - fromLow) * (toHigh - toLow)) / (fromHigh - fromLow) + toLow;
}
/**
* Sets the pin used when using `pins->analog pitch`.
* @param name TODO
*/
//% shim=micro_bit::enablePitch help=functions/analog-set-pitch weight=12
export function analogSetPitchPin(name: AnalogPins): void { }
/**
* Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin.
* @param frequency TODO
* @param ms TODO
*/
//% shim=micro_bit::pitch help=functions/analog-pitch weight=14 async
export function analogPitch(frequency: number, ms: number): void { }
}

59
libs/microbit/serial.ts Normal file
View File

@ -0,0 +1,59 @@
//% weight=1
namespace serial {
/**
* Prints a line of text to the serial
* @param value to send over serial
*/
//% blockId=serial_writeline block="serial|write %text"
export function writeLine(text: string): void {
writeString(text);
writeString("\r\n");
}
/**
* Prints a numeric value to the serial
*/
export function writeNumber(value: number): void {
writeString(value.toString());
}
/**
* Reads a line of text from the serial port.
*/
//% shim=micro_bit::serialReadString
export function readString(): string {
return ""
}
/**
* Sends a piece of text through Serial connection.
*/
//% shim=micro_bit::serialSendString
export function writeString(text: string): void { }
/**
* Sends the current pixel values, byte-per-pixel, over serial.
*/
//% shim=micro_bit::serialSendDisplayState
export function writeScreen(): void { }
/**
* Reads the screen from serial.
*/
//% shim=micro_bit::serialReadDisplayState
export function readScreen(): void { }
/**
* Writes a ``name: value`` pair line to the serial.
* @param name name of the value stream, eg: x
* @param value to write
*/
//% weight=80
//% blockId=serial_writevalue block="serial|write %name|= %value"
export function writeValue(name: string, value: number): void {
writeString(name);
writeString(": ");
writeNumber(value);
writeLine("");
}
}