Compare commits
96 Commits
Author | SHA1 | Date | |
---|---|---|---|
ab7aa00747 | |||
2bebb6056d | |||
22046c417c | |||
dc8afa6d45 | |||
22e2ab5ad9 | |||
f365726a8e | |||
e329b3bd2e | |||
d7b709e97b | |||
9714ec46e9 | |||
20ef54f565 | |||
554df0bce9 | |||
6c89dddef6 | |||
23f91895f7 | |||
3f83cda087 | |||
7e79635413 | |||
56e1cf91ac | |||
f9f96f33f0 | |||
0b33073be1 | |||
65594842fc | |||
c6ed665f84 | |||
79462deb24 | |||
5c05f3e241 | |||
4f7dd75fbe | |||
338e507b51 | |||
601231a5dc | |||
f0850336e5 | |||
a6b2187ec5 | |||
28ae4f4230 | |||
09933b6a8d | |||
45bb6e7cb3 | |||
33c234a87e | |||
e9aa343d67 | |||
d83039430c | |||
5b2e877aef | |||
c5b28f5b8e | |||
e765021bf9 | |||
dbcd9e535c | |||
cff88d67ad | |||
3f241e8bc9 | |||
69c3d2d249 | |||
bc04d30595 | |||
63a26835b1 | |||
79113115e0 | |||
573ed7f6f2 | |||
61da1032d6 | |||
36d455c693 | |||
42c766b6d7 | |||
6f00384891 | |||
8440f7c763 | |||
8a8e864f99 | |||
7a3402b782 | |||
5e9a5b29f4 | |||
aff9d1ee60 | |||
8add7e8efb | |||
e7dfd0531b | |||
d2b1f70ce2 | |||
fbf7513c44 | |||
e9bdc26d15 | |||
52fafe9359 | |||
971dca6c96 | |||
a761c27b19 | |||
a062a85c7f | |||
a9865a731a | |||
ba4095ac9c | |||
8606a00701 | |||
bf57ba2902 | |||
4cd61cd96a | |||
c4139a862f | |||
ca3cd1de22 | |||
d7f22bc8e6 | |||
28b28d0b52 | |||
0ee2b285c0 | |||
d5cb085264 | |||
c055a5d329 | |||
8fe8b78f4c | |||
f627f125c0 | |||
7d3254477a | |||
3149ed4c1d | |||
baeafcdebe | |||
12754acc54 | |||
329baaf9a4 | |||
47efcfb41f | |||
e2d1b8a55c | |||
579eb29ce3 | |||
ada9560642 | |||
7b352b3a58 | |||
a5d5836ea2 | |||
57dc26a127 | |||
3e37b03808 | |||
d035713786 | |||
6e4a71b2f4 | |||
0b4dd534ab | |||
ed07f0baad | |||
004d34b5df | |||
05098252ed | |||
1f32a4851e |
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,11 +1,15 @@
|
||||
node_modules
|
||||
yotta_modules
|
||||
yotta_targets
|
||||
pxt_modules
|
||||
built
|
||||
typings
|
||||
tmp
|
||||
temp
|
||||
projects/**
|
||||
clients/win10/app/AppPackages
|
||||
clients/win10/app/BundlePackages
|
||||
clients/win10/app/BundleArtifacts
|
||||
clients/win10/app/bin
|
||||
clients/win10/app/bld
|
||||
clients/win10/*.opendb
|
||||
@ -18,4 +22,4 @@ clients/**/obj/**
|
||||
*.tgz
|
||||
*.db
|
||||
*.suo
|
||||
*.log
|
||||
*.log
|
||||
|
@ -4,8 +4,12 @@ node_js:
|
||||
script:
|
||||
- "node node_modules/pxt-core/built/pxt.js travis"
|
||||
- "(cd libs/lang-test0; node ../../node_modules/pxt-core/built/pxt.js run)"
|
||||
- "(cd libs/lang-test1; node ../../node_modules/pxt-core/built/pxt.js run)"
|
||||
- "(cd libs/lang-test0; node ../../node_modules/pxt-core/built/pxt.js test)"
|
||||
- "(cd libs/lang-test1; node ../../node_modules/pxt-core/built/pxt.js test)"
|
||||
- "node node_modules/pxt-core/built/pxt.js testdir tests"
|
||||
- "node node_modules/pxt-core/built/pxt.js uploaddoc"
|
||||
- "(cd libs/hello; node ../../node_modules/pxt-core/built/pxt.js testconv ../../testconv.json)"
|
||||
- "(cd libs/hello; node ../../node_modules/pxt-core/built/pxt.js testconv https://az851932.vo.msecnd.net/files/td-converter-tests-v0.json)"
|
||||
sudo: false
|
||||
notifications:
|
||||
email:
|
||||
|
32
README.md
32
README.md
@ -9,12 +9,19 @@ PXT ([Microsoft Programming Experience Toolkit](https://github.com/Microsoft/pxt
|
||||
|
||||
## Local server
|
||||
|
||||
The local server allows to run the editor and the documentation from your computer.
|
||||
|
||||
### Setup
|
||||
|
||||
The following commands are a 1-time setup after synching the repo on your machine.
|
||||
|
||||
* clone this repo to your computer
|
||||
* install the PXT command line
|
||||
* if not yet installed, install [Node.js 4.4.5 or higher](https://nodejs.org/en/download/)
|
||||
* [clone this repo](https://help.github.com/articles/cloning-a-repository/) to your computer and go in the project folder
|
||||
```
|
||||
git clone https://github.com/microsoft/pxt-microbit
|
||||
cd pxt-microbit
|
||||
```
|
||||
* install the PXT command line (add ``sudo`` for Mac/Linux shells).
|
||||
```
|
||||
npm install -g pxt
|
||||
```
|
||||
@ -37,7 +44,9 @@ If you need modify the `.cpp` files, turn on yotta compilation with the ``-yt``
|
||||
pxt serve -yt
|
||||
```
|
||||
|
||||
To make sure you're running the latest tools, run (add ``sudo`` for Mac/Linux shells)
|
||||
## Updates
|
||||
|
||||
To update your PXT version and make sure you're running the latest tools, run (add ``sudo`` for Mac/Linux shells)
|
||||
```
|
||||
pxt update
|
||||
```
|
||||
@ -54,6 +63,23 @@ that wraps ``codethemicrobit.com`` and provides additional features.
|
||||
* Install Visual Studio 2015 Update 2 or higher. Make sure the Windows 10 templates are installed.
|
||||
* open the ``win10/app.sln`` solution and launch the ``codethemicrobit`` project.
|
||||
|
||||
## Testing
|
||||
|
||||
The build automatically runs the following:
|
||||
|
||||
* make sure the built-in packages compile
|
||||
* `pxt run` in `libs/lang-test*` - this will run the test in command line runner;
|
||||
there is a number of asserts in both of these
|
||||
* `pxt testdir` in `tests` - this makes sure all the files compile and generates .hex files
|
||||
* run the TD->TS converter on a number of test scripts from `microbit.co.uk` and make sure the results compile
|
||||
|
||||
To test something on the device:
|
||||
|
||||
* do a `pxt deploy` in `libs/lang-test*` - they should show `1` or `2` on the screen (and not unhappy face)
|
||||
* run `pxt testdir` in `tests` and deploy some of the hex files from `tests/built`
|
||||
|
||||
The `lang-test0` source comes from the `pxt-core` package. It's also tested with `pxt run` there.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
@ -20,22 +20,18 @@
|
||||
<ProjectConfiguration Include="Release|AnyCPU">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>AnyCPU</Platform>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x86">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
|
BIN
clients/win10/store/desktopblocks1366x768.png
Normal file
BIN
clients/win10/store/desktopblocks1366x768.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 172 KiB |
BIN
clients/win10/store/desktopjavascript1366x768.png
Normal file
BIN
clients/win10/store/desktopjavascript1366x768.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 121 KiB |
BIN
clients/win10/store/mobileblocks480x800.png
Normal file
BIN
clients/win10/store/mobileblocks480x800.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
@ -28,11 +28,12 @@ export function deployCoreAsync(res: ts.pxt.CompileResult) {
|
||||
|
||||
function getBitDrivesAsync(): Promise<string[]> {
|
||||
if (process.platform == "win32") {
|
||||
let rx = new RegExp("^([A-Z]:).* " + pxt.appTarget.compile.deployDrives)
|
||||
return execAsync("wmic PATH Win32_LogicalDisk get DeviceID, VolumeName, FileSystem")
|
||||
.then(buf => {
|
||||
let res: string[] = []
|
||||
buf.toString("utf8").split(/\n/).forEach(ln => {
|
||||
let m = /^([A-Z]:).* MICROBIT/.exec(ln)
|
||||
let m = rx.exec(ln)
|
||||
if (m) {
|
||||
res.push(m[1] + "/")
|
||||
}
|
||||
@ -41,8 +42,9 @@ function getBitDrivesAsync(): Promise<string[]> {
|
||||
})
|
||||
}
|
||||
else if (process.platform == "darwin") {
|
||||
let rx = new RegExp(pxt.appTarget.compile.deployDrives)
|
||||
return readDirAsync("/Volumes")
|
||||
.then(lst => lst.filter(s => /MICROBIT/.test(s)).map(s => "/Volumes/" + s + "/"))
|
||||
.then(lst => lst.filter(s => rx.test(s)).map(s => "/Volumes/" + s + "/"))
|
||||
} else {
|
||||
return Promise.resolve([])
|
||||
}
|
||||
|
@ -38,7 +38,9 @@ Learn about the [hardware components](/device) of the micro:bit to make the most
|
||||
You can program the micro:bit using [Blocks](/blocks) or [JavaScript](/javascript), via the [micro:bit APIs](/reference):
|
||||
|
||||
```blocks
|
||||
basic.showString("Hi!");
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
basic.showString("Hi!");
|
||||
})
|
||||
```
|
||||
|
||||
## Compile and Flash: Your Program!
|
||||
|
@ -86,7 +86,7 @@ if (led.point(1,1) && led.point(2,2)) {
|
||||
When you compare two Numbers, you get a Boolean value, such as the comparison `x < 5` in the code below:
|
||||
|
||||
```blocks
|
||||
let x = math.random(5)
|
||||
let x = Math.random(5)
|
||||
if(x < 5) {
|
||||
basic.showString("low");
|
||||
} else {
|
||||
|
@ -1,15 +1,36 @@
|
||||
# JavaScript
|
||||
# JavaScript and TypeScript
|
||||
|
||||
If you already know some JavaScript, you might be interested in [the JavaScript and TypeScript languages](/js/lang).
|
||||
Otherwise, visit the cards below to starting programming JavaScript with the micro:bit:
|
||||
Visit the cards below to starting programming JavaScript and TypeScript with the micro:bit:
|
||||
|
||||
```codecard
|
||||
[{
|
||||
"name": "Calling Functions",
|
||||
"url":"/js/call"
|
||||
"name": "Calling",
|
||||
"url": "/js/call"
|
||||
},{
|
||||
"name": "Sequencing Commands",
|
||||
"url":"/js/sequence"
|
||||
"name": "Sequencing",
|
||||
"url": "/js/sequence"
|
||||
},{
|
||||
"name": "Variables",
|
||||
"url": "/js/variables"
|
||||
},{
|
||||
"name": "Operators",
|
||||
"url": "/js/operators"
|
||||
},{
|
||||
"name": "Statements",
|
||||
"url": "/js/statements"
|
||||
},{
|
||||
"name": "Functions",
|
||||
"url": "/js/functions"
|
||||
},{
|
||||
"name": "Types",
|
||||
"url": "/js/types"
|
||||
},{
|
||||
"name": "Classes",
|
||||
"url": "/js/classes"
|
||||
},{
|
||||
"name": "FAQ",
|
||||
"url": "/js/faq"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
```
|
||||
|
@ -3,8 +3,8 @@
|
||||
The simplest way to get started in JavaScript with your micro:bit is to
|
||||
call one of the micro:bit's built-in JavaScript functions. Just like Blocks
|
||||
are organized into categories/drawers, the micro:bit functions are organized by
|
||||
namespaces, with names corresponding to the drawer names.
|
||||
The `basic` namespace contains a number of very helpful functions:
|
||||
namespaces, with names corresponding to the drawer names. The `basic` namespace
|
||||
contains a number of helpful functions, such as:
|
||||
|
||||
```typescript
|
||||
basic.showString("Hello!")
|
||||
|
268
docs/js/classes.md
Normal file
268
docs/js/classes.md
Normal file
@ -0,0 +1,268 @@
|
||||
# Classes
|
||||
|
||||
Traditional JavaScript focuses on functions and prototype-based inheritance as the basic means of building up reusable components,
|
||||
but this may feel a bit awkward to programmers more comfortable with an object-oriented approach, where classes inherit functionality
|
||||
and objects are built from these classes.
|
||||
|
||||
Starting with ECMAScript 2015, also known as ECMAScript 6, JavaScript programmers will be able to build their applications using
|
||||
this object-oriented class-based approach. TypeScript, allows you to use these techniques now, compiling them
|
||||
down to JavaScript that works across all major browsers and platforms, without having to wait for the next version of JavaScript.
|
||||
|
||||
Let's take a look at a simple class-based example:
|
||||
|
||||
```ts
|
||||
class Greeter {
|
||||
greeting: string;
|
||||
constructor(message: string) {
|
||||
this.greeting = message;
|
||||
}
|
||||
greet() {
|
||||
return "Hello, " + this.greeting;
|
||||
}
|
||||
}
|
||||
|
||||
let greeter = new Greeter("world");
|
||||
```
|
||||
|
||||
We declare a new class `Greeter`. This class has three members: a property called `greeting`, a constructor, and a method `greet`.
|
||||
|
||||
You'll notice that in the class when we refer to one of the members of the class we prepend `this.`.
|
||||
This denotes that it's a member access.
|
||||
|
||||
In the last line we construct an instance of the `Greeter` class using `new`.
|
||||
This calls into the constructor we defined earlier, creating a new object with the `Greeter` shape, and running the constructor to initialize it.
|
||||
|
||||
# Inheritance
|
||||
|
||||
### ~hint
|
||||
### Inheritance is not supported yet for the micro:bit. Coming soon...
|
||||
### ~
|
||||
|
||||
In TypeScript, we can use common object-oriented patterns.
|
||||
Of course, one of the most fundamental patterns in class-based programming is being able to extend existing classes to create new ones using inheritance.
|
||||
|
||||
Let's take a look at an example:
|
||||
|
||||
```ts
|
||||
class Animal {
|
||||
name: string;
|
||||
constructor(theName: string) { this.name = theName; }
|
||||
move(distanceInMeters: number = 0) {
|
||||
console.log(`${this.name} moved ${distanceInMeters}m.`);
|
||||
}
|
||||
}
|
||||
|
||||
class Snake extends Animal {
|
||||
constructor(name: string) { super(name); }
|
||||
move(distanceInMeters = 5) {
|
||||
console.log("Slithering...");
|
||||
super.move(distanceInMeters);
|
||||
}
|
||||
}
|
||||
|
||||
class Horse extends Animal {
|
||||
constructor(name: string) { super(name); }
|
||||
move(distanceInMeters = 45) {
|
||||
console.log("Galloping...");
|
||||
super.move(distanceInMeters);
|
||||
}
|
||||
}
|
||||
|
||||
let sam = new Snake("Sammy the Python");
|
||||
let tom: Animal = new Horse("Tommy the Palomino");
|
||||
|
||||
sam.move();
|
||||
tom.move(34);
|
||||
```
|
||||
|
||||
This example covers quite a few of the inheritance features in TypeScript that are common to other languages.
|
||||
Here we see the `extends` keywords used to create a subclass.
|
||||
You can see this where `Horse` and `Snake` subclass the base class `Animal` and gain access to its features.
|
||||
|
||||
Derived classes that contain constructor functions must call `super()` which will execute the constructor function on the base class.
|
||||
|
||||
The example also shows how to override methods in the base class with methods that are specialized for the subclass.
|
||||
Here both `Snake` and `Horse` create a `move` method that overrides the `move` from `Animal`, giving it functionality specific to each class.
|
||||
Note that even though `tom` is declared as an `Animal`, since its value is a `Horse`, when `tom.move(34)` calls the overriding method in `Horse`:
|
||||
|
||||
```Text
|
||||
Slithering...
|
||||
Sammy the Python moved 5m.
|
||||
Galloping...
|
||||
Tommy the Palomino moved 34m.
|
||||
```
|
||||
|
||||
# Public, private, and protected modifiers
|
||||
|
||||
## Public by default
|
||||
|
||||
In our examples, we've been able to freely access the members that we declared throughout our programs.
|
||||
If you're familiar with classes in other languages, you may have noticed in the above examples
|
||||
we haven't had to use the word `public` to accomplish this; for instance,
|
||||
C# requires that each member be explicitly labeled `public` to be visible.
|
||||
In TypeScript, each member is `public` by default.
|
||||
|
||||
You may still mark a member `public` explicitly.
|
||||
We could have written the `Animal` class from the previous section in the following way:
|
||||
|
||||
```ts
|
||||
class Animal {
|
||||
public name: string;
|
||||
public constructor(theName: string) { this.name = theName; }
|
||||
public move(distanceInMeters: number) {
|
||||
console.log(`${this.name} moved ${distanceInMeters}m.`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Understanding `private`
|
||||
|
||||
When a member is marked `private`, it cannot be accessed from outside of its containing class. For example:
|
||||
|
||||
```ts
|
||||
class Animal {
|
||||
private name: string;
|
||||
constructor(theName: string) { this.name = theName; }
|
||||
}
|
||||
|
||||
new Animal("Cat").name; // Error: 'name' is private;
|
||||
```
|
||||
|
||||
TypeScript is a structural type system.
|
||||
When we compare two different types, regardless of where they came from, if the types of all members are compatible, then we say the types themselves are compatible.
|
||||
|
||||
However, when comparing types that have `private` and `protected` members, we treat these types differently.
|
||||
For two types to be considered compatible, if one of them has a `private` member,
|
||||
then the other must have a `private` member that originated in the same declaration.
|
||||
The same applies to `protected` members.
|
||||
|
||||
Let's look at an example to better see how this plays out in practice:
|
||||
|
||||
```ts
|
||||
class Animal {
|
||||
private name: string;
|
||||
constructor(theName: string) { this.name = theName; }
|
||||
}
|
||||
|
||||
class Rhino extends Animal {
|
||||
constructor() { super("Rhino"); }
|
||||
}
|
||||
|
||||
class Employee {
|
||||
private name: string;
|
||||
constructor(theName: string) { this.name = theName; }
|
||||
}
|
||||
|
||||
let animal = new Animal("Goat");
|
||||
let rhino = new Rhino();
|
||||
let employee = new Employee("Bob");
|
||||
|
||||
animal = rhino;
|
||||
animal = employee; // Error: 'Animal' and 'Employee' are not compatible
|
||||
```
|
||||
|
||||
In this example, we have an `Animal` and a `Rhino`, with `Rhino` being a subclass of `Animal`.
|
||||
We also have a new class `Employee` that looks identical to `Animal` in terms of shape.
|
||||
We create some instances of these classes and then try to assign them to each other to see what will happen.
|
||||
Because `Animal` and `Rhino` share the `private` side of their shape from the same declaration of
|
||||
`private name: string` in `Animal`, they are compatible. However, this is not the case for `Employee`.
|
||||
When we try to assign from an `Employee` to `Animal` we get an error that these types are not compatible.
|
||||
Even though `Employee` also has a `private` member called `name`, it's not the one we declared in `Animal`.
|
||||
|
||||
## Understanding `protected`
|
||||
|
||||
The `protected` modifier acts much like the `private` modifier with the exception that members
|
||||
declared `protected` can also be accessed by instances of deriving classes. For example,
|
||||
|
||||
```ts
|
||||
class Person {
|
||||
protected name: string;
|
||||
constructor(name: string) { this.name = name; }
|
||||
}
|
||||
|
||||
class Employee extends Person {
|
||||
private department: string;
|
||||
|
||||
constructor(name: string, department: string) {
|
||||
super(name);
|
||||
this.department = department;
|
||||
}
|
||||
|
||||
public getElevatorPitch() {
|
||||
return `Hello, my name is ${this.name} and I work in ${this.department}.`;
|
||||
}
|
||||
}
|
||||
|
||||
let howard = new Employee("Howard", "Sales");
|
||||
console.log(howard.getElevatorPitch());
|
||||
console.log(howard.name); // error
|
||||
```
|
||||
|
||||
Notice that while we can't use `name` from outside of `Person`,
|
||||
we can still use it from within an instance method of `Employee` because `Employee` derives from `Person`.
|
||||
|
||||
A constructor may also be marked `protected`.
|
||||
This means that the class cannot be instantiated outside of its containing class, but can be extended. For example,
|
||||
|
||||
```ts
|
||||
class Person {
|
||||
protected name: string;
|
||||
protected constructor(theName: string) { this.name = theName; }
|
||||
}
|
||||
|
||||
// Employee can extend Person
|
||||
class Employee extends Person {
|
||||
private department: string;
|
||||
|
||||
constructor(name: string, department: string) {
|
||||
super(name);
|
||||
this.department = department;
|
||||
}
|
||||
|
||||
public getElevatorPitch() {
|
||||
return `Hello, my name is ${this.name} and I work in ${this.department}.`;
|
||||
}
|
||||
}
|
||||
|
||||
let howard = new Employee("Howard", "Sales");
|
||||
let john = new Person("John"); // Error: The 'Person' constructor is protected
|
||||
```
|
||||
|
||||
# Readonly modifier
|
||||
|
||||
You can make properties readonly by using the `readonly` keyword.
|
||||
Readonly properties must be initialized at their declaration or in the constructor.
|
||||
|
||||
```ts
|
||||
class Octopus {
|
||||
readonly name: string;
|
||||
readonly numberOfLegs: number = 8;
|
||||
constructor (theName: string) {
|
||||
this.name = theName;
|
||||
}
|
||||
}
|
||||
let dad = new Octopus("Man with the 8 strong legs");
|
||||
dad.name = "Man with the 3-piece suit"; // error! name is readonly.
|
||||
```
|
||||
|
||||
## Parameter properties
|
||||
|
||||
In our last example, we had to declare a readonly member `name` and a constructor parameter `theName` in the `Octopus` class, and we then immediately set `name` to `theName`.
|
||||
This turns out to be a very common practice.
|
||||
*Parameter properties* let you create and initialize a member in one place.
|
||||
Here's a further revision of the previous `Octopus` class using a parameter property:
|
||||
|
||||
```ts
|
||||
class Octopus {
|
||||
readonly numberOfLegs: number = 8;
|
||||
constructor(readonly name: string) {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Notice how we dropped `theName` altogether and just use the shortened `readonly name: string` parameter on the constructor to create and initialize the `name` member.
|
||||
We've consolidated the declarations and assignment into one location.
|
||||
|
||||
Parameter properties are declared by prefixing a constructor parameter with an accessibility modifier or `readonly`, or both.
|
||||
Using `private` for a parameter property declares and initializes a private member; likewise, the same is done for `public`, `protected`, and `readonly`.
|
||||
|
58
docs/js/faq.md
Normal file
58
docs/js/faq.md
Normal file
@ -0,0 +1,58 @@
|
||||
# Frequently asked questions
|
||||
|
||||
# What is the language supported for the micro:bit?
|
||||
|
||||
For the micro:bit, we support a "static" subset of TypeScript (itself a superset of JavaScript):
|
||||
|
||||
## Supported language features
|
||||
|
||||
* variables with `let`, `const`, and `var`
|
||||
* functions with lexical scoping and recursion
|
||||
* top-level code in the file; hello world really is `console.log("Hello world")`
|
||||
* `if ... else if ... else` statements
|
||||
* `while` and `do ... while` loops
|
||||
* `for(;;)` loops (see below about `for ... in/of`)
|
||||
* `break/continue`; also with labeled loops
|
||||
* `switch` statement (on numbers only)
|
||||
* `debugger` statement for breakpoints
|
||||
* conditional operator `? :`; lazy boolean operators
|
||||
* namespaces (a form of modules)
|
||||
* all arithmetic operators (including bitwise operators); note that in microcontroller targets
|
||||
all arithmetic is performed on integers, also when simulating in the browser
|
||||
* strings (with a few common methods)
|
||||
* [string templates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) (`` `x is ${x}` ``)
|
||||
* arrow functions `() => ...`
|
||||
* classes with fields, methods and constructors; `new` keyword
|
||||
* array literals `[1, 2, 3]`
|
||||
* enums
|
||||
|
||||
## Unsupported language features
|
||||
|
||||
We generally stay away from the more dynamic parts of JavaScript.
|
||||
Things you may miss and we may implement:
|
||||
|
||||
* exceptions (`throw`, `try ... catch`, `try ... finally`)
|
||||
* `for ... of` statements
|
||||
* object literals `{ foo: 1, bar: "two" }`
|
||||
* method-like properties (get/set accessors)
|
||||
* class inheritance
|
||||
|
||||
For JS-only targets we may implement the following:
|
||||
|
||||
* regular expressions
|
||||
* classes implementing interfaces
|
||||
|
||||
Things that we are not very likely to implement:
|
||||
|
||||
* file-based modules (`import * from ...`, `module.exports` etc); we do support namespaces
|
||||
* spread operator
|
||||
* `yield` expression and ``function*``
|
||||
* `await` expression and `async function`
|
||||
* `typeof` expression
|
||||
* tagged templates ``tag `text ${expression} more text` ``; regular templates are supported
|
||||
* binding with arrays or objects: `let [a, b] = ...; let { x, y } = ...`
|
||||
* `with` statement
|
||||
* `eval`
|
||||
* `delete` statement
|
||||
* `for ... in` statements
|
||||
* JSX (HTML as part of JavaScript)
|
161
docs/js/functions.md
Normal file
161
docs/js/functions.md
Normal file
@ -0,0 +1,161 @@
|
||||
# Functions
|
||||
|
||||
Functions are the fundamental building block of programs. Here is the simplest
|
||||
way to make a function that adds two numbers:
|
||||
|
||||
```ts
|
||||
// Named function
|
||||
function add(x : number, y : number) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
basic.showNumber(add(1, 2))
|
||||
```
|
||||
|
||||
### ~ hint
|
||||
For the micro:bit, you must specify a [type](/js/types) for each function parameter.
|
||||
### ~
|
||||
|
||||
Functions can refer to variables outside of the function body.
|
||||
When they do so, they're said to `capture` these variables.
|
||||
|
||||
```ts
|
||||
let z = 100;
|
||||
|
||||
function addToZ(x: number, y: number) {
|
||||
return x + y + z;
|
||||
}
|
||||
|
||||
basic.showNumber(addToZ(1, 2))
|
||||
```
|
||||
|
||||
## Typing the function
|
||||
|
||||
Let's add a return type to our add function:
|
||||
|
||||
```ts
|
||||
function add(x: number, y: number): number {
|
||||
return x + y;
|
||||
}
|
||||
```
|
||||
|
||||
TypeScript can figure the return type out by looking at the return statements, so you can optionally leave this off in many cases.
|
||||
|
||||
# Optional and Default Parameters
|
||||
|
||||
In TypeScript, the number of arguments given to a function has to match the number of parameters the function expects.
|
||||
|
||||
```ts
|
||||
function buildName(firstName: string, lastName: string) {
|
||||
return firstName + " " + lastName;
|
||||
}
|
||||
|
||||
let result1 = buildName("Bob"); // error, too few parameters
|
||||
let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
|
||||
let result3 = buildName("Bob", "Adams"); // ah, just right
|
||||
```
|
||||
|
||||
In JavaScript, every parameter is optional, and users may leave them off as they see fit.
|
||||
When they do, their value is `undefined`.
|
||||
We can get this functionality in TypeScript by adding a `?` to the end of parameters we want to be optional.
|
||||
For example, let's say we want the last name parameter from above to be optional:
|
||||
|
||||
```ts
|
||||
function buildName(firstName: string, lastName?: string) {
|
||||
if (lastName)
|
||||
return firstName + " " + lastName;
|
||||
else
|
||||
return firstName;
|
||||
}
|
||||
|
||||
let result1 = buildName("Bob"); // works correctly now
|
||||
let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
|
||||
let result3 = buildName("Bob", "Adams"); // ah, just right
|
||||
```
|
||||
|
||||
Any optional parameters must follow required parameters.
|
||||
Had we wanted to make the first name optional rather than the last name, we would need to change the order of parameters in the function, putting the first name last in the list.
|
||||
|
||||
In TypeScript, we can also set a value that a parameter will be assigned if the user does not provide one, or if the user passes `undefined` in its place.
|
||||
These are called default-initialized parameters.
|
||||
Let's take the previous example and default the last name to `"Smith"`.
|
||||
|
||||
```ts
|
||||
function buildName(firstName: string, lastName = "Smith") {
|
||||
return firstName + " " + lastName;
|
||||
}
|
||||
|
||||
let result1 = buildName("Bob"); // works correctly now, returns "Bob Smith"
|
||||
let result2 = buildName("Bob", undefined); // still works, also returns "Bob Smith"
|
||||
let result3 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
|
||||
let result4 = buildName("Bob", "Adams"); // ah, just right
|
||||
```
|
||||
|
||||
Default-initialized parameters that come after all required parameters are treated as optional, and just like optional parameters, can be omitted when calling their respective function.
|
||||
This means optional parameters and trailing default parameters will share commonality in their types, so both
|
||||
|
||||
```ts
|
||||
function buildName(firstName: string, lastName?: string) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
```ts
|
||||
function buildName(firstName: string, lastName = "Smith") {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
share the same type `(firstName: string, lastName?: string) => string`.
|
||||
The default value of `lastName` disappears in the type, only leaving behind the fact that the parameter is optional.
|
||||
|
||||
Unlike plain optional parameters, default-initialized parameters don't *need* to occur after required parameters.
|
||||
If a default-initialized parameter comes before a required parameter, users need to explicitly pass `undefined` to get the default initialized value.
|
||||
For example, we could write our last example with only a default initializer on `firstName`:
|
||||
|
||||
```ts
|
||||
function buildName(firstName = "Will", lastName: string) {
|
||||
return firstName + " " + lastName;
|
||||
}
|
||||
|
||||
let result1 = buildName("Bob"); // error, too few parameters
|
||||
let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
|
||||
let result3 = buildName("Bob", "Adams"); // okay and returns "Bob Adams"
|
||||
let result4 = buildName(undefined, "Adams"); // okay and returns "Will Adams"
|
||||
```
|
||||
|
||||
# Rest Parameters
|
||||
|
||||
Required, optional, and default parameters all have one thing in common: they talk about one parameter at a time.
|
||||
Sometimes, you want to work with multiple parameters as a group, or you may not know how many parameters a function will ultimately take.
|
||||
In JavaScript, you can work with the arguments directly using the `arguments` variable that is visible inside every function body.
|
||||
|
||||
In TypeScript, you can gather these arguments together into a variable:
|
||||
|
||||
```ts
|
||||
function buildName(firstName: string, ...restOfName: string[]) {
|
||||
return firstName + " " + restOfName.join(" ");
|
||||
}
|
||||
|
||||
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
|
||||
```
|
||||
|
||||
*Rest parameters* are treated as a boundless number of optional parameters.
|
||||
When passing arguments for a rest parameter, you can use as many as you want; you can even pass none.
|
||||
The compiler will build an array of the arguments passed in with the name given after the ellipsis (`...`), allowing you to use it in your function.
|
||||
|
||||
The ellipsis is also used in the type of the function with rest parameters:
|
||||
|
||||
```ts
|
||||
function buildName(firstName: string, ...restOfName: string[]) {
|
||||
return firstName + " " + restOfName.join(" ");
|
||||
}
|
||||
|
||||
let buildNameFun: (fname: string, ...rest: string[]) => string = buildName;
|
||||
```
|
||||
|
||||
### ~button /js/types
|
||||
NEXT: Types
|
||||
### ~
|
0
docs/js/inference.md
Normal file
0
docs/js/inference.md
Normal file
@ -1,75 +0,0 @@
|
||||
# JavaScript and TypeScript
|
||||
|
||||
You can write micro:bit programs in a subset of [TypeScript](https://www.typescriptlang.org), a superset of JavaScript.
|
||||
Many micro:bit programs, especially at the beginner's level, are just plain JavaScript. TypeScript introduces class-based
|
||||
object-oriented programming, such as:
|
||||
|
||||
```typescript
|
||||
class Greeter {
|
||||
greeting: string;
|
||||
constructor(message: string) {
|
||||
this.greeting = message;
|
||||
}
|
||||
greet() {
|
||||
return "Hello, " + this.greeting;
|
||||
}
|
||||
}
|
||||
|
||||
let greeter = new Greeter("world");
|
||||
basic.showString(greeter.greet())
|
||||
```
|
||||
|
||||
This site is meant for teaching programming first, and JavaScript second. For this
|
||||
reason, we have stayed away from concepts that are specific to JavaScript (for
|
||||
example, prototype inheritance), and instead focused on ones common to most
|
||||
modern programming languages (for example, loops, lexically scoped variables,
|
||||
functions, classes, lambdas).
|
||||
|
||||
We leverage TypeScript's [type inference](http://www.typescriptlang.org/docs/handbook/type-inference.html) so that
|
||||
students need not specify types when clear from context.
|
||||
|
||||
## Supported language features
|
||||
|
||||
* top-level code in the file: "Hello world!" really is just `basic.showString("Hello world!")`
|
||||
* [basic types](http://www.typescriptlang.org/docs/handbook/basic-types.html)
|
||||
* [variable declarations](http://www.typescriptlang.org/docs/handbook/variable-declarations.html): `let`, `const`, and `var`
|
||||
* [functions](http://www.typescriptlang.org/docs/handbook/functions.html) with lexical scoping and recursion
|
||||
|
||||
### User-defined types and modules
|
||||
|
||||
* [classes](http://www.typescriptlang.org/docs/handbook/classes.html) with fields, methods and constructors; `new` keyword
|
||||
* [enums](http://www.typescriptlang.org/docs/handbook/enums.html)
|
||||
* [namespaces](http://www.typescriptlang.org/docs/handbook/namespaces.html) (a form of modules)
|
||||
|
||||
### Control-flow constructs
|
||||
|
||||
* `if ... else if ... else` statements
|
||||
* `while` and `do ... while` loops
|
||||
* `for(;;)` loops (see below about `for ... in/of`)
|
||||
* `break/continue`; also with labeled loops
|
||||
* `switch` statement (on numbers only)
|
||||
* `debugger` statement for breakpoints
|
||||
|
||||
### Expressions
|
||||
|
||||
* conditional operator `? :`; lazy boolean operators
|
||||
* all arithmetic operators (including bitwise operators); note that in microcontroller targets
|
||||
all arithmetic is performed on integers, also when simulating in the browser
|
||||
* strings (with a few common methods)
|
||||
* [string templates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) (`` `x is ${x}` ``)
|
||||
* arrow functions `() => ...`
|
||||
* array literals `[1, 2, 3]`
|
||||
|
||||
|
||||
## Unsupported language features
|
||||
|
||||
We generally stay away from the more dynamic parts of JavaScript.
|
||||
Things you may miss and we may implement:
|
||||
|
||||
* exceptions (`throw`, `try ... catch`, `try ... finally`)
|
||||
* `for ... of` statements
|
||||
* object literals `{ foo: 1, bar: "two" }`
|
||||
* method-like properties (get/set accessors)
|
||||
* class inheritance
|
||||
|
||||
If there is something you'd like to see, please file an issue at [GitHub](http://github.com/microsoft/pxt/issues).
|
30
docs/js/operators.md
Normal file
30
docs/js/operators.md
Normal file
@ -0,0 +1,30 @@
|
||||
## Operators
|
||||
|
||||
The following JavaScript operators are supported for the micro:bit.
|
||||
|
||||
### ~hint
|
||||
Note that for the micro:bit all arithmetic is performed on integers, rather than floating point.
|
||||
This also is true when simulating in the browser.
|
||||
### ~
|
||||
|
||||
# Assignment, arithmetic and bitwise
|
||||
|
||||
* assignment operators - [read more](http://devdocs.io/javascript/operators/assignment_operators)
|
||||
* arithmetic operators - [read more](http://devdocs.io/javascript/operators/arithmetic_operators)
|
||||
* bitwise operators - [read more](http://devdocs.io/javascript/operators/bitwise_operators)
|
||||
|
||||
# Comparision and conditional
|
||||
|
||||
* comparison operators - [read more](http://devdocs.io/javascript/operators/comparison_operators)
|
||||
* conditional operator - [read more](http://devdocs.io/javascript/operators/conditional_operator)
|
||||
|
||||
## More
|
||||
|
||||
* lambda functions `() => { ... }`
|
||||
* array literals `[1, 2, 3]`
|
||||
* strings, with a few common methods
|
||||
* [string templates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) (`` `x is ${x}` ``)
|
||||
|
||||
### ~button /js/statements
|
||||
NEXT: Statements
|
||||
### ~
|
@ -1,6 +1,6 @@
|
||||
# Sequencing commands
|
||||
# Sequencing
|
||||
|
||||
By calling one function after another, you can create an animation:
|
||||
By calling one function after another, in sequence, you can create an animation:
|
||||
|
||||
```typescript
|
||||
basic.showLeds(`
|
||||
@ -9,17 +9,55 @@ basic.showLeds(`
|
||||
. . # . .
|
||||
# . . . #
|
||||
. # # # .
|
||||
`)
|
||||
`);
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
. . . . .
|
||||
. . . . .
|
||||
. # # # .
|
||||
# . . . #
|
||||
`)
|
||||
`);
|
||||
```
|
||||
|
||||
## The Semicolon
|
||||
### The semicolon
|
||||
|
||||
Coming soon...
|
||||
In JavaScript, the semicolon (;) is used to terminate (or end) a statement. However, in most
|
||||
cases, the semicolon is optional and can be omitted. So both code sequences below are
|
||||
legal:
|
||||
|
||||
```typescript
|
||||
basic.showNumber(1)
|
||||
basic.showNumber(2)
|
||||
```
|
||||
|
||||
```typescript
|
||||
basic.showNumber(1);
|
||||
basic.showNumber(2);
|
||||
```
|
||||
|
||||
### The empty statement
|
||||
|
||||
In JavaScript, there is the concept of an *empty statement*, which is whitespace followed by
|
||||
a semicolon in the context where a statement is expected.
|
||||
So, the following code is an infinite loop
|
||||
followed by a call to `showNumber` that will never execute:
|
||||
```typescript
|
||||
while(true) ;
|
||||
basic.showNumber(1);
|
||||
```
|
||||
|
||||
|
||||
### ~hint
|
||||
For the micro:bit, we don't allow a program to contain an empty statement, such as shown above.
|
||||
If you really want an empty statement, you need to use curly braces to delimit an empty statement block:
|
||||
```typescript
|
||||
while(true) { }
|
||||
basic.showNumber(1);
|
||||
```
|
||||
### ~
|
||||
|
||||
[Read more](http://inimino.org/~inimino/blog/javascript_semicolons) about semicolons in JavaScript.
|
||||
|
||||
### ~button /js/variables
|
||||
NEXT: Variable Declarations
|
||||
### ~
|
33
docs/js/statements.md
Normal file
33
docs/js/statements.md
Normal file
@ -0,0 +1,33 @@
|
||||
# Statements
|
||||
|
||||
The following JavaScript statements are supported for the micro:bit:
|
||||
|
||||
## Variable declarations
|
||||
* `const` statement - [read more](http://devdocs.io/javascript/statements/const)
|
||||
* `let` statement - [read more](http://devdocs.io/javascript/statements/let)
|
||||
* `var` statement - [read more](http://devdocs.io/javascript/statements/var)
|
||||
|
||||
## Block-structured statements
|
||||
|
||||
* `{ }` block statement - [read more](http://devdocs.io/javascript/statements/block)
|
||||
* `if-else` conditional statement - [read more](http://devdocs.io/javascript/statements/if...else)
|
||||
* `while` loop - [read more](http://devdocs.io/javascript/statements/do...while)
|
||||
* `do-while` loop - [read more](http://devdocs.io/javascript/statements/do...while)
|
||||
* `for(;;)` loop - [read more](http://devdocs.io/javascript/statements/for)
|
||||
* `switch` statement (on numbers only) - [read more](http://devdocs.io/javascript/statements/switch)
|
||||
|
||||
## Control-flow commands
|
||||
|
||||
* `break` statement - [read more](http://devdocs.io/javascript/statements/break)
|
||||
* `continue` statement - [read more](http://devdocs.io/javascript/statements/continue)
|
||||
* `return` statement - [read more](http://devdocs.io/javascript/statements/return)
|
||||
* `debugger` statement for breakpoints - [read more](http://devdocs.io/javascript/statements/debugger)
|
||||
|
||||
## Labelling statements
|
||||
|
||||
* labelled statement - [read more](http://devdocs.io/javascript/statements/label)
|
||||
* `default` statement - [read more](http://devdocs.io/javascript/statements/default)
|
||||
|
||||
### ~button /js/functions
|
||||
NEXT: Functions
|
||||
### ~
|
140
docs/js/types.md
Normal file
140
docs/js/types.md
Normal file
@ -0,0 +1,140 @@
|
||||
# Types
|
||||
|
||||
For programs to be useful, we need to be able to work with some of the simplest units of data:
|
||||
numbers, strings, structures, boolean values, and the like.
|
||||
|
||||
# Boolean
|
||||
|
||||
The most basic datatype is the simple true/false value, which is called a `boolean` value.
|
||||
|
||||
```ts
|
||||
let isDone: boolean = false;
|
||||
```
|
||||
|
||||
# Number
|
||||
|
||||
### ~ hint
|
||||
In JavaScript, `numbers` are floating point values.
|
||||
However, for the micro:bit, `numbers` are integer values.
|
||||
### ~
|
||||
|
||||
Integer values can be specified via decimal, hexadecimal and octal notation:
|
||||
|
||||
```ts
|
||||
let decimal: number = 42;
|
||||
let hex: number = 0xf00d;
|
||||
let binary: number = 0b1010;
|
||||
let octal: number = 0o744;
|
||||
```
|
||||
|
||||
# String
|
||||
|
||||
As in other languages, we use the type `string` to refer to textual data.
|
||||
Use double quotes (`"`) or single quotes (`'`) to surround string data.
|
||||
|
||||
```ts
|
||||
let color: string = "blue";
|
||||
color = 'red';
|
||||
```
|
||||
|
||||
You can also use *template strings*, which can span multiple lines and have embedded expressions.
|
||||
These strings are surrounded by the backtick/backquote (`` ` ``) character, and embedded expressions are of the form `${ expr }`.
|
||||
|
||||
```ts
|
||||
let fullName: string = `Bob Bobbington`;
|
||||
let age: number = 37;
|
||||
let sentence: string = `Hello, my name is ${ fullName }.
|
||||
|
||||
I'll be ${ age + 1 } years old next month.`
|
||||
```
|
||||
|
||||
This is equivalent to declaring `sentence` like so:
|
||||
|
||||
```ts
|
||||
let sentence: string = "Hello, my name is " + fullName + ".\n\n" +
|
||||
"I'll be " + (age + 1) + " years old next month."
|
||||
```
|
||||
|
||||
# Array
|
||||
|
||||
Arrays allow you to work with an expandable sequence of values, addressed by an integer-valued index.
|
||||
Array types can be written in one of two ways.
|
||||
In the first, you use the type of the elements followed by `[]` to denote an array of that element type:
|
||||
|
||||
```ts
|
||||
let list: number[] = [1, 2, 3];
|
||||
```
|
||||
|
||||
The second way uses a generic array type, `Array<elemType>`:
|
||||
|
||||
```ts
|
||||
let list: Array<number> = [1, 2, 3];
|
||||
```
|
||||
|
||||
### ~hint
|
||||
For the micro:bit, all elements of an array must have the same type.
|
||||
### ~
|
||||
|
||||
|
||||
# Enum
|
||||
|
||||
A helpful addition to the standard set of datatypes from JavaScript is the `enum`.
|
||||
As in languages like C#, an enum is a way of giving more friendly names to sets of numeric values.
|
||||
|
||||
```ts
|
||||
enum Color {Red, Green, Blue};
|
||||
let c: Color = Color.Green;
|
||||
```
|
||||
|
||||
By default, enums begin numbering their members starting at `0`.
|
||||
You can change this by manually setting the value of one of its members.
|
||||
For example, we can start the previous example at `1` instead of `0`:
|
||||
|
||||
```ts
|
||||
enum Color {Red = 1, Green, Blue};
|
||||
let c: Color = Color.Green;
|
||||
```
|
||||
|
||||
Or, even manually set all the values in the enum:
|
||||
|
||||
```ts
|
||||
enum Color {Red = 1, Green = 2, Blue = 4};
|
||||
let c: Color = Color.Green;
|
||||
```
|
||||
|
||||
# Any
|
||||
|
||||
The TypeScript type `any` is not supported in the micro:bit.
|
||||
|
||||
|
||||
# Void
|
||||
|
||||
`void` is the absence of having any type at all.
|
||||
You may commonly see this as the return type of functions that do not return a value:
|
||||
|
||||
```ts
|
||||
function warnUser(): void {
|
||||
basic.showString("This is my warning message");
|
||||
}
|
||||
```
|
||||
|
||||
Declaring variables of type `void` is not useful.
|
||||
|
||||
# Type Inference
|
||||
|
||||
In TypeScript, there are several places where type inference is used to provide type information when there is
|
||||
no explicit type annotation. For example, in this code
|
||||
|
||||
```ts
|
||||
let x = 3;
|
||||
let y = x + 3
|
||||
```
|
||||
|
||||
The type of the `x` variable is inferred to be `number`. Similarly, the type of `y` variable also is inferred to be `number`.
|
||||
This kind of inference takes place when initializing variables and members,
|
||||
setting parameter default values, and determining function return types.
|
||||
|
||||
|
||||
### ~button /js/classes
|
||||
NEXT: Classes
|
||||
### ~
|
121
docs/js/variables.md
Normal file
121
docs/js/variables.md
Normal file
@ -0,0 +1,121 @@
|
||||
# Variable Declarations
|
||||
|
||||
Declaring a variable in JavaScript has always traditionally been done with the `var` keyword.
|
||||
|
||||
```typescript
|
||||
var a = 10;
|
||||
```
|
||||
|
||||
The `var` construct has some [problems](http://www.typescriptlang.org/docs/handbook/variable-declarations.html),
|
||||
which is why `let` statements were introduced. Apart from the keyword used, `let` statements are written
|
||||
the same way `var` statements are.
|
||||
|
||||
```typescript
|
||||
let a = 10;
|
||||
```
|
||||
|
||||
The key difference is not in the syntax, but in the semantics, which we'll now dive into.
|
||||
|
||||
## Block-scoping
|
||||
|
||||
When a variable is declared using `let`, it uses what some call *lexical-scoping* or *block-scoping*.
|
||||
Unlike variables declared with `var` whose scopes leak out to their containing function,
|
||||
block-scoped variables are not visible outside of their nearest containing block or `for`-loop.
|
||||
|
||||
```typescript
|
||||
function f(input: boolean) {
|
||||
let a = 100;
|
||||
|
||||
if (input) {
|
||||
// Still okay to reference 'a'
|
||||
let b = a + 1;
|
||||
return b;
|
||||
}
|
||||
|
||||
// Error: 'b' doesn't exist here
|
||||
return b;
|
||||
}
|
||||
```
|
||||
|
||||
Here, we have two local variables `a` and `b`.
|
||||
`a`'s scope is limited to the body of `f` while `b`'s scope is limited to the containing `if` statement's block.
|
||||
|
||||
Another property of block-scoped variables is that they can't be read or written to before they're actually declared.
|
||||
While these variables are "present" throughout their scope, all points up until their declaration are part of their *temporal dead zone*.
|
||||
This is just a sophisticated way of saying you can't access them before the `let` statement, and luckily TypeScript will let you know that.
|
||||
|
||||
```typescript
|
||||
a++; // illegal to use 'a' before it's declared;
|
||||
let a;
|
||||
```
|
||||
|
||||
## Re-declarations
|
||||
|
||||
With `var` declarations, it doesn't matter how many times you declare your variables, you just get one:
|
||||
|
||||
```typescript
|
||||
var x = 10;
|
||||
var x = 20;
|
||||
```
|
||||
|
||||
In the above example, all declarations of `x` actually refer to the *same* `x`, and this is perfectly valid.
|
||||
This often ends up being a source of bugs. Thankfully, `let` declarations are not as forgiving.
|
||||
|
||||
```typescript
|
||||
let x = 10;
|
||||
let x = 20; // error: can't re-declare 'x' in the same scope
|
||||
```
|
||||
|
||||
## Shadowing
|
||||
|
||||
The act of introducing a new name in a more deeply nested scope is called *shadowing*.
|
||||
It is a bit of a double-edged sword in that it can introduce certain bugs on its own in the
|
||||
event of accidental shadowing, while also preventing certain bugs.
|
||||
For instance, imagine a `sumMatrix` function using `let` variables.
|
||||
|
||||
```typescript
|
||||
function sumMatrix(matrix: number[][]) {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < matrix.length; i++) {
|
||||
var currentRow = matrix[i];
|
||||
for (let i = 0; i < currentRow.length; i++) {
|
||||
sum += currentRow[i];
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
```
|
||||
|
||||
This version of the loop will actually perform the summation correctly because the inner loop's `i` shadows `i` from the outer loop.
|
||||
Shadowing should *usually* be avoided in the interest of write clearer code, such as
|
||||
|
||||
```typescript
|
||||
function sumMatrix(matrix: number[][]) {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < matrix.length; i++) {
|
||||
var currentRow = matrix[i];
|
||||
for (let j = 0; j < currentRow.length; j++) {
|
||||
sum += currentRow[j];
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
```
|
||||
While there are some scenarios where it may be fitting to take advantage of it, you should use your best judgement.
|
||||
|
||||
# `const` declarations
|
||||
|
||||
`const` declarations are another way of declaring variables.
|
||||
|
||||
```typescript
|
||||
const numLivesForCat = 9;
|
||||
```
|
||||
|
||||
They are like `let` declarations but, as their name implies, their value cannot be changed once they are bound.
|
||||
In other words, they have the same scoping rules as `let`, but you can't re-assign to them.
|
||||
|
||||
### ~button /js/operators
|
||||
NEXT: Operators
|
||||
### ~
|
@ -5,7 +5,7 @@
|
||||
Your beginning code should look like this:
|
||||
|
||||
```blocks
|
||||
let coll = (<string[]>[])
|
||||
let coll: string[] = []
|
||||
coll.push("puppy")
|
||||
coll.push("clock")
|
||||
coll.push("night")
|
||||
@ -27,7 +27,7 @@ game.startCountdown(30000)
|
||||
Let's add more words for the player to act out! But first, we need to increase the time in one round to give the player more time get through all the words. Let's change the `game->start countdown` statement.
|
||||
|
||||
```blocks
|
||||
let coll = (<string[]>[])
|
||||
let coll: string[] = []
|
||||
coll.push("puppy")
|
||||
coll.push("clock")
|
||||
coll.push("night")
|
||||
@ -52,7 +52,8 @@ game.startCountdown(60000)
|
||||
Now let's add 5 more words to our list of charade words. Right above the the line `word:=coll->at(index)` add 5 lines that say `coll->add("")`. In this example, we will add the words **bicycle, telephone, sun, car, and ant** but you can add whatever words you like.
|
||||
|
||||
```blocks
|
||||
let coll.push("puppy")
|
||||
let coll: string[] = []
|
||||
coll.push("puppy")
|
||||
coll.push("clock")
|
||||
coll.push("night")
|
||||
coll.push("cat")
|
||||
|
@ -19,7 +19,7 @@ A 'collection' is a group of variables of the same type stored together. A 'coll
|
||||
## 2. Consider the following lines of code.
|
||||
|
||||
```blocks
|
||||
let coll = (<string[]>[])
|
||||
let coll: string[] = []
|
||||
coll.push("puppy")
|
||||
coll.push("clock")
|
||||
```
|
||||
@ -35,7 +35,7 @@ basic.showString(coll[0], 150)
|
||||
## 3. Consider the following lines of code.
|
||||
|
||||
```blocks
|
||||
let coll = (<string[]>[])
|
||||
let coll: string[] = []
|
||||
coll.push("puppy")
|
||||
coll.push("clock")
|
||||
coll.push("cat")
|
||||
@ -52,7 +52,7 @@ basic.showString(coll[2], 150)
|
||||
## 4. Consider the following line of code.
|
||||
|
||||
```blocks
|
||||
let coll = (<string[]>[])
|
||||
let coll: string[] = []
|
||||
```
|
||||
|
||||
Write the five (5) lines of code that will add the following five words to `data->coll`: puppy, clock, night, cat, cow.
|
||||
@ -60,7 +60,8 @@ Write the five (5) lines of code that will add the following five words to `data
|
||||
<br/>
|
||||
|
||||
```blocks
|
||||
let coll.push("puppy")
|
||||
let coll: string[] = []
|
||||
coll.push("puppy")
|
||||
coll.push("clock")
|
||||
coll.push("night")
|
||||
coll.push("cat")
|
||||
|
@ -211,7 +211,7 @@ Let's setup the logic for the food and the ghost to be in different quadrants. F
|
||||
let hero = game.createSprite(2, 2);
|
||||
let food = game.createSprite(4, 4);
|
||||
let ghost = game.createSprite(0, 0);
|
||||
let ghost.change(LedSpriteProperty.Blink, 100);
|
||||
ghost.change(LedSpriteProperty.Blink, 100);
|
||||
food = led.brightness() == 8;
|
||||
while (true) {
|
||||
basic.pause(400);
|
||||
@ -265,7 +265,7 @@ while (true) {
|
||||
}
|
||||
|
||||
}
|
||||
0.set(LedSpriteProperty.X, 4);
|
||||
ghost.set(LedSpriteProperty.X, 4);
|
||||
|
||||
|
||||
```
|
||||
|
@ -14,7 +14,7 @@ Here are some cool projects that you can build with your micro:bit!
|
||||
"imageUrl": "/static/mb/projects/a2-buttons.png"
|
||||
},{
|
||||
"name": "Love Meter",
|
||||
"url":"/projects/lover-meter",
|
||||
"url":"/projects/love-meter",
|
||||
"imageUrl":"/static/mb/projects/a3-pins.png"
|
||||
},{
|
||||
"name": "Rock Paper Scissors",
|
||||
|
@ -148,12 +148,6 @@ Trim any leftover fabric, threads or tape.
|
||||
|
||||
Your watch is ready!
|
||||
|
||||
### ~avatar avatar
|
||||
|
||||
Excellent, you're ready to continue with the [challenges](/projects/rock-paper-scissors)!
|
||||
|
||||
### ~
|
||||
|
||||
### Acknowledgements
|
||||
|
||||
Artistic design by Melinda Hoeneisen.
|
||||
|
@ -22,14 +22,13 @@ control.inBackground(() => {
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
## Advanced
|
||||
|
||||
|
||||
```namespaces
|
||||
devices.tellCameraTo(MesCameraEvent.TakePhoto);
|
||||
bluetooth.onBluetoothConnected(() => {});
|
||||
```
|
||||
|
||||
|
||||
```package
|
||||
microbit-devices
|
||||
microbit-bluetooth
|
||||
|
@ -21,4 +21,4 @@ bluetooth.onBluetoothDisconnected(() => {
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
||||
```
|
||||
|
@ -1,148 +0,0 @@
|
||||
# Game Library
|
||||
|
||||
The game library supports simple single-player time-based games. The player has a **sprite**, number of **lives** and a **score**. The game has a sprite, number of **levels** and a **countdown clock**. The general goal of a game will be to move the sprite and achieve a top score before time runs out or the number of lives goes to zero.
|
||||
|
||||
The code below shows a simple game where the user gets to press the button ``A`` as much times as possible in 10 seconds.
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
game.addScore(1)
|
||||
})
|
||||
game.startCountdown(10000)
|
||||
```
|
||||
|
||||
### [Create sprite](/reference/game/create-sprite)
|
||||
|
||||
Create sprite with x, y coordinates and returns a LED Sprite. Create a new LED sprite.
|
||||
|
||||

|
||||
|
||||
```
|
||||
export function createSprite(x: number, y: number) : micro_bitSprites.LedSprite
|
||||
```
|
||||
|
||||
### [Move](/reference/game/move)
|
||||
|
||||
Sprite move by a certain number
|
||||
|
||||

|
||||
|
||||
```
|
||||
export function move(_this: micro_bitSprites.LedSprite, leds: number)
|
||||
```
|
||||
|
||||
### [Turn](/reference/game/turn)
|
||||
|
||||
Rotates a sprite to the right by a certain number of degrees
|
||||
|
||||

|
||||
|
||||
```
|
||||
export function turnRight(_this: micro_bitSprites.LedSprite, degrees: number)
|
||||
```
|
||||
|
||||
Rotates a sprite to the left by a certain number of degrees
|
||||
|
||||
```
|
||||
export function turnLeft(_this: micro_bitSprites.LedSprite, degrees: number)
|
||||
```
|
||||
|
||||
### [Change](/reference/game/change)
|
||||
|
||||
Sprite will change the x position by this number
|
||||
|
||||

|
||||
|
||||
```
|
||||
export function changeXBy(_this: micro_bitSprites.LedSprite, x: number)
|
||||
```
|
||||
|
||||
Sprite will change the y position by this number
|
||||
|
||||
```
|
||||
export function changeYBy(_this: micro_bitSprites.LedSprite, y: number)
|
||||
```
|
||||
|
||||
### [Set](/reference/game/set)
|
||||
|
||||
Sprite will change the x position by this number
|
||||
|
||||
```
|
||||
export function setX(_this: micro_bitSprites.LedSprite, x: number)
|
||||
```
|
||||
|
||||
Sprite will change the y position by this number
|
||||
|
||||

|
||||
|
||||
```
|
||||
export function changeYBy(_this: micro_bitSprites.LedSprite, y: number)
|
||||
```
|
||||
|
||||
### [If on edge, bounce](/reference/game/if-on-edge-bounce)
|
||||
|
||||
Sprite - If the sprite is on the edge, the sprite will bounce
|
||||
|
||||

|
||||
|
||||
```
|
||||
export function ifOnEdgeBounce(_this: micro_bitSprites.LedSprite)
|
||||
```
|
||||
|
||||
### [Change score by](/reference/game/change-score-by)
|
||||
|
||||
When a player achieves a goal, you can increase the game score
|
||||
|
||||
* add score points to the current score
|
||||
|
||||

|
||||
|
||||
```
|
||||
export function addScore(points: number)
|
||||
```
|
||||
|
||||
### [Score](/reference/game/score)
|
||||
|
||||
* set the current score to a particular value.
|
||||
|
||||
```
|
||||
export function setScore(value: number)
|
||||
```
|
||||
|
||||
* get the current score value
|
||||
|
||||

|
||||
|
||||
```
|
||||
export function score() : number
|
||||
```
|
||||
|
||||
### [Countdown](/reference/game/start-countdown)
|
||||
|
||||
If your game has a time limit, you can start a countdown in which case `game->current time` returns the remaining time.
|
||||
|
||||
* start a countdown with the maximum duration of the game in milliseconds.
|
||||
|
||||

|
||||
|
||||
```
|
||||
export function startCountdown(ms: number)
|
||||
```
|
||||
|
||||
### [Game over](/reference/game/game-over)
|
||||
|
||||
If the `life` reaches zero or the time expires (see countdown), the game enters the **game over** mode. When the game is over, `game->is running` returns false
|
||||
|
||||
* check if the game still running.
|
||||
|
||||
```
|
||||
let running = game.isRunning()
|
||||
```
|
||||
|
||||
You can also end the game by calling the `game -> game over` function:
|
||||
|
||||

|
||||
|
||||
```
|
||||
game.gameOver()
|
||||
```
|
@ -16,7 +16,7 @@ export function showFrame(img: micro_bit.Image, frame: number)
|
||||
|
||||
### Difference from `plot frame`
|
||||
|
||||
The `show frame` function is the same as [plot frame](/reference/image/plot-frame), but contains a built-in delay after the LED screen has been updated (whereas `plot frame` has no built-in delay)
|
||||
The `show frame` function is the same as [plot frame](/reference/images/plot-frame), but contains a built-in delay after the LED screen has been updated (whereas `plot frame` has no built-in delay)
|
||||
|
||||
### Example
|
||||
|
||||
|
@ -14,6 +14,7 @@ input.onPinPressed(TouchPin.P0, () => {
|
||||
});
|
||||
input.buttonIsPressed(Button.A);
|
||||
input.compassHeading();
|
||||
input.pinIsPressed(TouchPin.P0);
|
||||
input.temperature();
|
||||
input.acceleration(Dimension.X);
|
||||
input.lightLevel();
|
||||
@ -21,7 +22,6 @@ input.rotation(Rotation.Pitch);
|
||||
input.magneticForce(Dimension.X);
|
||||
input.runningTime();
|
||||
input.setAccelerometerRange(AcceleratorRange.OneG);
|
||||
input.pinIsPressed(TouchPin.P0);
|
||||
input.calibrate();
|
||||
input.onLogoDown(() => {
|
||||
|
||||
|
@ -3,11 +3,11 @@
|
||||
Display an [Image](/reference/images/image) on the BBC micro:bit's [LED screen](/device/screen). NOTE: `basic -> plot image` has been replaced by `basic -> show leds`.
|
||||
|
||||
```sig
|
||||
basic.plotLeds(`
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . # . .
|
||||
# ; . . #
|
||||
# . . . #
|
||||
. # # # .
|
||||
`)
|
||||
```
|
||||
@ -16,14 +16,14 @@ basic.plotLeds(`
|
||||
|
||||
* leds - a series of LED on/off states that form an image (see steps below)
|
||||
|
||||
### Example: simley
|
||||
### Example: smiley
|
||||
|
||||
```blocks
|
||||
basic.plotLeds(`
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . # . .
|
||||
# ; . . #
|
||||
# . . . #
|
||||
. # # # .
|
||||
`)
|
||||
```
|
||||
|
@ -9,14 +9,24 @@ led.stopAnimation()
|
||||
|
||||
### Example
|
||||
|
||||
This program...
|
||||
This program sets up the ``stop animation`` part of the program,
|
||||
and then shows a string that you can stop with button ``B``.
|
||||
|
||||
```blocks
|
||||
basic.showString("STOP ME! STOP ME! PLEASE, WON'T SOMEBODY STOP ME?");
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
led.stopAnimation();
|
||||
});
|
||||
'```
|
||||
basic.showString("STOP ME! STOP ME! PLEASE, WON'T SOMEBODY STOP ME?");
|
||||
```
|
||||
|
||||
### ~hint
|
||||
|
||||
It's important to set up ``stop animation`` before showing the
|
||||
animation, so the ``stop animation`` part of the program will be ready
|
||||
to go.
|
||||
|
||||
### ~
|
||||
|
||||
### See Also
|
||||
|
||||
|
||||
[show animation](/reference/basic/show-animation)
|
||||
|
@ -14,7 +14,7 @@ radio.receivedNumberAt(0);
|
||||
radio.receiveString();
|
||||
radio.receivedSignalStrength();
|
||||
radio.setGroup(0);
|
||||
radio.setTransmitPower(0);
|
||||
radio.setTransmitPower(7);
|
||||
radio.writeValueToSerial();
|
||||
radio.setTransmitSerialNumber(true);
|
||||
radio.setTransmitSerialNumber(false);
|
||||
```
|
||||
|
@ -1,18 +1,26 @@
|
||||
# Write Value To Serial
|
||||
|
||||
Writes the full data received data via ``radio`` to serial in JSON format.
|
||||
|
||||
**Note** - This method only works for [send number](/reference/radio/send-number) and [send value](/reference/radio/send-value). It does not work for [send string](/reference/radio/send-string) (although a string can be sent with [send value](/reference/radio/send-value)).
|
||||
Writes the data received by ``radio`` to serial in JSON format.
|
||||
|
||||
```sig
|
||||
radio.writeValueToSerial();
|
||||
```
|
||||
|
||||
## Data received format
|
||||
The format for received data printed to serial is as follows
|
||||
- [send number](/reference/radio/send-number) - ```{v:ValueSent,t:MicrobitTimeAlive,s:Unused}```
|
||||
- [send value](/reference/radio/send-number) - ```{v:Value,t:MicrobitTimeAlive,s:Unused,n:"Name"}```
|
||||
- [send string](/reference/radio/send-string) - ```{}``` (currently unavailable)
|
||||
### ~hint
|
||||
|
||||
This method only works for [send number](/reference/radio/send-number)
|
||||
and [send value](/reference/radio/send-value). It does not work for
|
||||
[send string](/reference/radio/send-string), although you can send a
|
||||
string as part of [send value](/reference/radio/send-value).
|
||||
|
||||
### ~
|
||||
|
||||
### Data received format
|
||||
|
||||
The format for received data printed to serial is as follows:
|
||||
|
||||
- [send number](/reference/radio/send-number): ```{v:ValueSent,t:MicrobitTimeAlive,s:Unused}```
|
||||
- [send value](/reference/radio/send-value): ```{v:ValueSent,t:MicrobitTimeAlive,s:Unused,n:"Name"}```
|
||||
|
||||
### Simulator
|
||||
|
||||
@ -20,7 +28,9 @@ This function only works on the micro:bit, not in browsers.
|
||||
|
||||
### Examples
|
||||
|
||||
When ```radio``` data is received (after pressing A button on 2nd micro:bit), output temperature data to serial.
|
||||
When ```radio``` data is received (after pressing the ``A`` button on
|
||||
the second micro:bit), this program sends temperature data to
|
||||
serial.
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
@ -30,9 +40,11 @@ radio.onDataReceived(() => {
|
||||
radio.writeValueToSerial();
|
||||
});
|
||||
```
|
||||
Example output to serial when A button pressed:
|
||||
Sample output to serial when ``A`` button pressed:
|
||||
```{v:27,t:323,s:0}```
|
||||
|
||||
### See also
|
||||
|
||||
[send number](/reference/radio/send-number), [send value](/reference/radio/send-number), [on data received](/reference/radio/on-data-received)
|
||||
[send number](/reference/radio/send-number),
|
||||
[send value](/reference/radio/send-value),
|
||||
[on data received](/reference/radio/on-data-received)
|
||||
|
@ -46,8 +46,6 @@ for
|
||||
|
||||
forever
|
||||
|
||||
game-library
|
||||
|
||||
game-over
|
||||
|
||||
if
|
||||
|
@ -61,7 +61,7 @@ The [math library](/blocks/math) includes math related functions.
|
||||
For example, the `absolute` function returns the returns the absolute value of input parameter `x`:
|
||||
|
||||
```blocks
|
||||
let abs = math.absolute(-42);
|
||||
let abs = Math.abs(-42);
|
||||
basic.showNumber(abs);
|
||||
```
|
||||
|
||||
|
3
docs/support.md
Normal file
3
docs/support.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Support
|
||||
|
||||
Please use the [GitHub issue tracker](https://github.com/microsoft/pxt-microbit) to report bugs.
|
@ -1,30 +0,0 @@
|
||||
# I2C FRAM driver
|
||||
|
||||
This library provides a driver for this FRAM part: https://www.adafruit.com/products/1895
|
||||
|
||||
The memory is accessed one byte at a time. The library provides a utility functions
|
||||
to write an entire buffer.
|
||||
|
||||
## Reading/writing byte
|
||||
|
||||
```
|
||||
let addr = 100
|
||||
i2c_fram.writeByte(addr, 42)
|
||||
let val = i2c_fram.readByte(addr)
|
||||
console.log(`${addr}: ${val}`)
|
||||
```
|
||||
|
||||
## Reading/writing a buffer
|
||||
|
||||
This code will log current time and acceleration in X axis every second.
|
||||
|
||||
```
|
||||
let bufSz = 8
|
||||
for (let addr = 0; addr < 0x8000; addr += bufSz) {
|
||||
let buf = pins.createBuffer(bufSz)
|
||||
buf.setNumber(NumberFormat.Int32LE, 0, input.runningTime())
|
||||
buf.setNumber(NumberFormat.Int32LE, 4, input.acceleration(Dimension.X))
|
||||
i2c_fram.writeBuffer(addr, buf)
|
||||
basic.pause(1000)
|
||||
}
|
||||
```
|
@ -1,55 +0,0 @@
|
||||
namespace i2c_fram {
|
||||
const devaddr = 0x50;
|
||||
const memend = 0x7fff;
|
||||
|
||||
//% shim=pxtrt::panic
|
||||
function panic(code: number) { }
|
||||
|
||||
function die() { panic(142) }
|
||||
|
||||
export function readByte(addr: number) {
|
||||
if (addr < 0 || addr > memend)
|
||||
die();
|
||||
|
||||
let buf = pins.createBuffer(2)
|
||||
buf[0] = (addr >> 8) & 0xff;
|
||||
buf[1] = addr & 0xff;
|
||||
|
||||
pins.i2cWriteBuffer(devaddr, buf);
|
||||
buf = pins.i2cReadBuffer(devaddr, 1);
|
||||
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
export function writeByte(addr: number, val: number) {
|
||||
if (addr < 0 || addr > memend)
|
||||
die();
|
||||
|
||||
if (val < 0 || val > 0xff)
|
||||
die();
|
||||
|
||||
let buf = pins.createBuffer(3)
|
||||
|
||||
buf[0] = (addr >> 8) & 0xff;
|
||||
buf[1] = addr & 0xff;
|
||||
buf[2] = val;
|
||||
|
||||
pins.i2cWriteBuffer(devaddr, buf)
|
||||
}
|
||||
|
||||
export function readBuffer(addr: number, length: number) {
|
||||
if (addr < 0 || length < 0 || (addr + length) > memend)
|
||||
die();
|
||||
let buf = pins.createBuffer(length)
|
||||
for (let i = 0; i < length; ++i)
|
||||
buf[i] = readByte(addr + i)
|
||||
return buf
|
||||
}
|
||||
|
||||
export function writeBuffer(addr: number, buf: Buffer) {
|
||||
if (addr < 0 || (addr + buf.length) > memend)
|
||||
die();
|
||||
for (let i = 0; i < buf.length; ++i)
|
||||
writeByte(addr + i, buf[i])
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
i2c_fram.writeByte(100, 42)
|
||||
i2c_fram.writeByte(101, 108)
|
||||
|
||||
function toBuf(arr: number[]) {
|
||||
let buf = pins.createBuffer(arr.length)
|
||||
for (let i = 0; i < arr.length; ++i)
|
||||
buf[i] = arr[i]
|
||||
return buf
|
||||
}
|
||||
|
||||
i2c_fram.writeBuffer(98, toBuf([1, 2, 3, 4, 5, 6, 7]))
|
||||
|
||||
console.log("100:" + i2c_fram.readByte(100))
|
||||
console.log("101:" + i2c_fram.readByte(101))
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
{
|
||||
"name": "i2c-fram",
|
||||
"description": "AdaFruit I2C FRAM driver for micro:bit",
|
||||
"files": [
|
||||
"README.md",
|
||||
"fram.ts"
|
||||
],
|
||||
"testFiles": [
|
||||
"ftest.ts"
|
||||
],
|
||||
"public": true,
|
||||
"dependencies": {
|
||||
"microbit": "file:../microbit"
|
||||
},
|
||||
"installedVersion": "hhneqa"
|
||||
}
|
@ -1,774 +0,0 @@
|
||||
//
|
||||
// Note that this is supposed to run from command line.
|
||||
// Do not use anything besides basic.pause, control.inBackground, console.log
|
||||
//
|
||||
|
||||
//% shim=pxtrt::panic
|
||||
function panic(code2: number): void { }
|
||||
|
||||
function msg(s: string): void {
|
||||
//console.log(s)
|
||||
//basic.pause(50);
|
||||
}
|
||||
|
||||
function assert(cond: boolean, msg_: string) {
|
||||
if (!cond) {
|
||||
console.log("ASSERT: " + msg_);
|
||||
panic(45);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// start tests
|
||||
//
|
||||
|
||||
var glb1: number;
|
||||
var s2: string;
|
||||
var x: number;
|
||||
var action: Action;
|
||||
var tot: string;
|
||||
var lazyAcc: number;
|
||||
var sum: number;
|
||||
|
||||
var xyz = 12;
|
||||
|
||||
console.log("Starting...")
|
||||
|
||||
//lib.print_17(3);
|
||||
basic.showNumber(0);
|
||||
//assert(lib3.getX() == 17 * 3, "");
|
||||
|
||||
testNums();
|
||||
testStrings();
|
||||
testNumCollection();
|
||||
testStringCollection();
|
||||
testStringOps();
|
||||
testReccoll();
|
||||
inBg();
|
||||
testAction(1);
|
||||
testAction(7);
|
||||
testIter();
|
||||
testActionSave();
|
||||
testLazyOps();
|
||||
testRefLocals();
|
||||
testByRefParams();
|
||||
testFunDecl();
|
||||
testDefaultArgs();
|
||||
testMemoryFree();
|
||||
testMemoryFreeHOF();
|
||||
postPreFix()
|
||||
eqOp()
|
||||
testEnums()
|
||||
testBuffer()
|
||||
|
||||
// test some top-level code
|
||||
let xsum = 0;
|
||||
for (let i = 0; i < 11; ++i) {
|
||||
xsum = xsum + i;
|
||||
}
|
||||
assert(xsum == 55, "mainfor")
|
||||
|
||||
control.inBackground(() => {
|
||||
xsum = xsum + 10;
|
||||
})
|
||||
|
||||
basic.pause(20)
|
||||
assert(xsum == 65, "mainforBg")
|
||||
|
||||
assert(xyz == 12, "init")
|
||||
|
||||
function incrXyz() {
|
||||
xyz++;
|
||||
return 0;
|
||||
}
|
||||
var unusedInit = incrXyz();
|
||||
|
||||
assert(xyz == 13, "init2")
|
||||
|
||||
|
||||
testClass()
|
||||
|
||||
basic.showNumber(1)
|
||||
|
||||
|
||||
console.log("ALL TESTS OK")
|
||||
|
||||
|
||||
function defaultArgs(x: number, y = 3, z = 7) {
|
||||
return x + y + z;
|
||||
}
|
||||
|
||||
function testDefaultArgs() {
|
||||
msg("testDefaultArgs");
|
||||
assert(defaultArgs(1) == 11, "defl0")
|
||||
assert(defaultArgs(1, 4) == 12, "defl1")
|
||||
assert(defaultArgs(1, 4, 8) == 13, "defl2")
|
||||
|
||||
assert(optargs(1) == 1, "opt0");
|
||||
assert(optargs(1, 2) == 3, "opt1");
|
||||
assert(optargs(1, 2, 3) == 3, "opt2");
|
||||
|
||||
assert(optstring(3) == 6, "os0")
|
||||
assert(optstring(3, "7") == 10, "os1")
|
||||
assert(optstring2(3) == 6, "os0")
|
||||
assert(optstring2(3, "7") == 10, "os1")
|
||||
}
|
||||
|
||||
function optargs(x: number, y ?: number, z ?: number) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
function optstring(x: number, s ?: string) {
|
||||
if (s != null) {
|
||||
return parseInt(s) + x;
|
||||
}
|
||||
return x * 2;
|
||||
}
|
||||
|
||||
function optstring2(x: number, s: string = null) {
|
||||
if (s != null) {
|
||||
return parseInt(s) + x;
|
||||
}
|
||||
return x * 2;
|
||||
}
|
||||
|
||||
function testNums(): void {
|
||||
let x = 40 + 2;
|
||||
assert(x == 42, "add");
|
||||
x = 40 / 2;
|
||||
assert(x == 20, "div");
|
||||
let r = fib(15);
|
||||
msg("FIB" + r);
|
||||
assert(r == 987, "fib");
|
||||
let x3 = doStuff(x, 2);
|
||||
assert(x3 == 10, "call order");
|
||||
glb1 = 5;
|
||||
incrBy_2();
|
||||
assert(glb1 == 7, "glb1");
|
||||
incrBy_2();
|
||||
assert(glb1 == 9, "glb2");
|
||||
assert(Math.abs(-42) == 42, "abs");
|
||||
assert(Math.abs(42) == 42, "abs");
|
||||
assert(Math.sign(42) == 1, "abs");
|
||||
testIf();
|
||||
|
||||
assert((3 & 6) == 2, "&")
|
||||
assert((3 | 6) == 7, "|")
|
||||
assert((3 ^ 6) == 5, "^")
|
||||
assert((-10 >> 2) == -3, ">>")
|
||||
assert((-10 >>> 20) == 4095, ">>>")
|
||||
assert((-10 << 2) == -40, "<<")
|
||||
assert((10 << 2) == 40, "<<+")
|
||||
assert((10 >> 2) == 2, ">>+")
|
||||
assert((10 >>> 2) == 2, ">>>+")
|
||||
assert(1000000 * 1000000 == -727379968, "*")
|
||||
assert(100000001 * 100000001 == 2074919425, "*2")
|
||||
|
||||
assert(105 % 100 == 5, "perc")
|
||||
}
|
||||
|
||||
|
||||
|
||||
function fib(p: number): number {
|
||||
if (p <= 2) {
|
||||
return p;
|
||||
}
|
||||
let p2 = p - 1;
|
||||
return fib(p2) + fib(p - 2);
|
||||
}
|
||||
|
||||
function doStuff(x: number, x2: number): number {
|
||||
let x3 = x / x2;
|
||||
return x3;
|
||||
}
|
||||
|
||||
|
||||
function testIf(): void {
|
||||
let b = false;
|
||||
if (!b) {
|
||||
glb1 = 7;
|
||||
} else {
|
||||
assert(false, "b0");
|
||||
}
|
||||
assert(glb1 == 7, "glb3");
|
||||
if (b) {
|
||||
assert(false, "b1");
|
||||
} else {
|
||||
glb1 = 8;
|
||||
}
|
||||
assert(glb1 == 8, "glb3");
|
||||
}
|
||||
|
||||
|
||||
function incrBy_2(): void {
|
||||
glb1 = glb1 + 2;
|
||||
}
|
||||
|
||||
function testStrings(): void {
|
||||
assert((42).toString() == "42", "42");
|
||||
|
||||
let s = "live";
|
||||
assert(s == "live", "hello eq");
|
||||
s = s + "4OK";
|
||||
s2 = s;
|
||||
assert(s.charCodeAt(4) == 52, "hello eq2");
|
||||
assert(s.charAt(4) == "4", "hello eq2X");
|
||||
assert(s[4] == "4", "hello eq2X");
|
||||
assert(s.length == 7, "len7");
|
||||
s = "";
|
||||
for (let i = 0; i < 10; i++) {
|
||||
s = s + i;
|
||||
}
|
||||
assert(s == "0123456789", "for");
|
||||
let x = 10;
|
||||
s = "";
|
||||
while (x >= 0) {
|
||||
s = s + x;
|
||||
x = x - 1;
|
||||
}
|
||||
assert(s == "109876543210", "while");
|
||||
msg(s);
|
||||
msg(s2);
|
||||
|
||||
s2 = "";
|
||||
// don't leak ref
|
||||
|
||||
x = 21
|
||||
s = "foo"
|
||||
s = `a${ x * 2 }X${ s }X${ s }Z`
|
||||
assert(s == "a42XfooXfoo" + "Z", "`")
|
||||
|
||||
assert("X" + true == "Xt" + "rue", "boolStr")
|
||||
}
|
||||
|
||||
|
||||
function testNumCollection(): void {
|
||||
let collXYZ: number[] =[];
|
||||
assert(collXYZ.length == 0, "");
|
||||
collXYZ.push(42);
|
||||
assert(collXYZ.length == 1, "");
|
||||
collXYZ.push(22);
|
||||
assert(collXYZ[1] == 22, "");
|
||||
collXYZ.splice(0, 1);
|
||||
assert(collXYZ[0] == 22, "");
|
||||
collXYZ.removeElement(22);
|
||||
assert(collXYZ.length == 0, "");
|
||||
for (let i = 0; i < 100; i++) {
|
||||
collXYZ.push(i);
|
||||
}
|
||||
assert(collXYZ.length == 100, "");
|
||||
|
||||
collXYZ =[1, 2, 3];
|
||||
assert(collXYZ.length == 3, "cons");
|
||||
assert(collXYZ[0] == 1, "cons0");
|
||||
assert(collXYZ[1] == 2, "cons1");
|
||||
assert(collXYZ[2] == 3, "cons2");
|
||||
}
|
||||
|
||||
function testStringCollection(): void {
|
||||
let coll = (< string[] >[]);
|
||||
coll.push("foobar");
|
||||
coll.push((12).toString());
|
||||
coll.push(coll[0] + "xx");
|
||||
assert(coll.indexOf("12") == 1, "idx");
|
||||
coll =[
|
||||
"a" + "b",
|
||||
coll[2],
|
||||
]
|
||||
assert(coll[0] == "ab", "")
|
||||
assert(coll[1] == "foob" + "arxx", "")
|
||||
assert(coll.length == 2, "")
|
||||
}
|
||||
|
||||
function testStringOps(): void {
|
||||
assert("foo".concat("bar") == "foobar", "concat");
|
||||
assert("xAb".charCodeAt(1) == 65, "code at");
|
||||
assert("B".charCodeAt(0) == 66, "tcc");
|
||||
assert(parseInt("-123") == -123, "tonum");
|
||||
assert("fo"[1] == "o", "at");
|
||||
assert("fo".length == 2, "count");
|
||||
assert("fo".charCodeAt(17) == 0, "ct oor");
|
||||
}
|
||||
|
||||
class Testrec {
|
||||
str: string;
|
||||
num: number;
|
||||
bool: boolean;
|
||||
str2: string;
|
||||
}
|
||||
|
||||
function recordId(x: Testrec) {
|
||||
lazyAcc++
|
||||
return x
|
||||
}
|
||||
|
||||
function postPreFix() {
|
||||
msg("postPref")
|
||||
let x = new Testrec()
|
||||
lazyAcc = 0
|
||||
recordId(x).num = 12
|
||||
assert(x.num == 12 && lazyAcc == 1, "X0")
|
||||
let y = recordId(x).num++
|
||||
assert(x.num == 13 && lazyAcc == 2, "X1")
|
||||
assert(y == 12, "X2")
|
||||
y = ++recordId(x).num
|
||||
assert(y == 14 && x.num == 14 && lazyAcc == 3, "X2")
|
||||
|
||||
recordId(x).num >>= 1
|
||||
assert(x.num == 7, "X3")
|
||||
assert(lazyAcc == 4, "X4")
|
||||
}
|
||||
|
||||
function eqOp() {
|
||||
msg("eqOp")
|
||||
let x = 12
|
||||
assert((x += 10) == 22, "Y0")
|
||||
assert(x == 22, "Y1")
|
||||
x /= 2
|
||||
assert(x == 11, "Y2")
|
||||
|
||||
let s = ("fo" + 1)
|
||||
let t = ("ba" + 2)
|
||||
s += t
|
||||
assert(s == "fo1b" + "a2", "fb")
|
||||
}
|
||||
|
||||
function testRec0(): Testrec {
|
||||
let testrec = new Testrec();
|
||||
testrec.str2 = "Hello" + " world";
|
||||
testrec.str = testrec.str2;
|
||||
testrec.num = 42;
|
||||
assert(testrec.str == "Hello world", "recstr");
|
||||
assert(testrec.num == 42, "recnum");
|
||||
msg(testrec.str2);
|
||||
let testrec2 = < Testrec > null;
|
||||
assert(testrec2 == null, "isinv");
|
||||
assert(testrec == testrec, "eq");
|
||||
assert(testrec != null, "non inv");
|
||||
return testrec;
|
||||
}
|
||||
|
||||
function testReccoll(): void {
|
||||
let coll: Testrec[] =[];
|
||||
let item = testRec0();
|
||||
msg("in reccoll");
|
||||
coll.push(item);
|
||||
}
|
||||
|
||||
function inBg() {
|
||||
let k = 7
|
||||
let q = 14
|
||||
let rec = new Testrec();
|
||||
glb1 = 0
|
||||
control.inBackground(() => {
|
||||
glb1 = glb1 + 10 + (q - k)
|
||||
rec.str = "foo"
|
||||
})
|
||||
control.inBackground(() => {
|
||||
glb1 = glb1 + 1
|
||||
})
|
||||
basic.pause(50)
|
||||
assert(glb1 == 18, "inbg0")
|
||||
assert(rec.str == "foo", "inbg1")
|
||||
}
|
||||
|
||||
function runTwice(fn: Action): void {
|
||||
msg("r2 start");
|
||||
fn();
|
||||
fn();
|
||||
msg("r2 stop");
|
||||
}
|
||||
|
||||
function iter(max: number, fn: (v: number) => void) {
|
||||
for (var i = 0; i < max; ++i) {
|
||||
fn(i);
|
||||
}
|
||||
}
|
||||
|
||||
function testIter() {
|
||||
x = 0
|
||||
iter(10, v => {
|
||||
x = x + (v + 1)
|
||||
})
|
||||
assert(x == 55, "55")
|
||||
}
|
||||
|
||||
function testAction(p: number): void {
|
||||
let s = "hello" + "1";
|
||||
let coll =[] as number[];
|
||||
let p2 = p * 2;
|
||||
x = 42;
|
||||
runTwice(() => {
|
||||
x = x + p + p2;
|
||||
coll.push(x);
|
||||
msg(s + x);
|
||||
});
|
||||
assert(x == 42 + p * 6, "run2");
|
||||
assert(coll.length == 2, "run2");
|
||||
}
|
||||
|
||||
function add7() {
|
||||
sum = sum + 7;
|
||||
}
|
||||
|
||||
function testFunDecl() {
|
||||
msg("testFunDecl");
|
||||
let x = 12;
|
||||
sum = 0;
|
||||
function addX() {
|
||||
sum = sum + x;
|
||||
}
|
||||
function add10() {
|
||||
sum = sum + 10;
|
||||
}
|
||||
runTwice(addX)
|
||||
assert(sum == 24, "cap")
|
||||
msg("testAdd10");
|
||||
runTwice(add10);
|
||||
msg("end-testAdd10");
|
||||
assert(sum == 44, "nocap");
|
||||
runTwice(add7);
|
||||
assert(sum == 44 + 14, "glb")
|
||||
addX();
|
||||
add10();
|
||||
assert(sum == 44 + 14 + x + 10, "direct");
|
||||
}
|
||||
|
||||
function saveAction(fn: Action): void {
|
||||
action = fn;
|
||||
}
|
||||
|
||||
function saveGlobalAction(): void {
|
||||
let s = "foo" + "42";
|
||||
tot = "";
|
||||
saveAction(() => {
|
||||
tot = tot + s;
|
||||
});
|
||||
}
|
||||
|
||||
function testActionSave(): void {
|
||||
saveGlobalAction();
|
||||
runTwice(action);
|
||||
msg(tot);
|
||||
assert(tot == "foo42foo42", "");
|
||||
tot = "";
|
||||
action = null;
|
||||
}
|
||||
|
||||
function testLazyOps(): void {
|
||||
lazyAcc = 0;
|
||||
if (incrLazyAcc(10, false) && incrLazyAcc(1, true)) {
|
||||
assert(false, "");
|
||||
} else {
|
||||
assert(lazyAcc == 10, "lazy1");
|
||||
}
|
||||
assert(lazyAcc == 10, "lazy2");
|
||||
if (incrLazyAcc(100, true) && incrLazyAcc(1, false)) {
|
||||
assert(false, "");
|
||||
} else {
|
||||
assert(lazyAcc == 111, "lazy4");
|
||||
}
|
||||
lazyAcc = 0;
|
||||
if (incrLazyAcc(100, true) && incrLazyAcc(8, true)) {
|
||||
assert(lazyAcc == 108, "lazy5");
|
||||
} else {
|
||||
assert(false, "");
|
||||
}
|
||||
lazyAcc = 0;
|
||||
if (incrLazyAcc(10, true) || incrLazyAcc(1, true)) {
|
||||
assert(lazyAcc == 10, "lazy1b");
|
||||
} else {
|
||||
assert(false, "");
|
||||
}
|
||||
assert(lazyAcc == 10, "lazy2xx");
|
||||
if (incrLazyAcc(100, false) || incrLazyAcc(1, false)) {
|
||||
assert(false, "");
|
||||
} else {
|
||||
assert(lazyAcc == 111, "lazy4x");
|
||||
}
|
||||
lazyAcc = 0;
|
||||
if (incrLazyAcc(100, false) || incrLazyAcc(8, true)) {
|
||||
assert(lazyAcc == 108, "lazy5");
|
||||
} else {
|
||||
assert(false, "");
|
||||
}
|
||||
lazyAcc = 0;
|
||||
if (incrLazyAcc(10, true) && incrLazyAcc(1, true) && incrLazyAcc(100, false)) {
|
||||
assert(false, "");
|
||||
} else {
|
||||
assert(lazyAcc == 111, "lazy10");
|
||||
}
|
||||
lazyAcc = 0;
|
||||
if (incrLazyAcc(10, true) && incrLazyAcc(1, true) || incrLazyAcc(100, false)) {
|
||||
assert(lazyAcc == 11, "lazy101");
|
||||
} else {
|
||||
assert(false, "");
|
||||
}
|
||||
|
||||
lazyAcc = 0;
|
||||
assert((true ? incrLazyNum(1, 42): incrLazyNum(10, 36)) == 42, "?:")
|
||||
assert(lazyAcc == 1, "?:0");
|
||||
assert((false ? incrLazyNum(1, 42): incrLazyNum(10, 36)) == 36, "?:1")
|
||||
assert(lazyAcc == 11, "?:2");
|
||||
}
|
||||
|
||||
function incrLazyAcc(delta: number, res: boolean): boolean {
|
||||
lazyAcc = lazyAcc + delta;
|
||||
return res;
|
||||
}
|
||||
|
||||
function incrLazyNum(delta: number, res: number) {
|
||||
lazyAcc = lazyAcc + delta;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
function testRefLocals(): void {
|
||||
msg("start test ref locals");
|
||||
let s = "";
|
||||
// For 4 or more it runs out of memory
|
||||
for (let i = 0; i < 3; i++) {
|
||||
msg(i + "");
|
||||
let copy = i;
|
||||
control.inBackground(() => {
|
||||
basic.pause(10 * i);
|
||||
copy = copy + 10;
|
||||
});
|
||||
control.inBackground(() => {
|
||||
basic.pause(20 * i);
|
||||
s = s + copy;
|
||||
});
|
||||
}
|
||||
basic.pause(200);
|
||||
assert(s == "101112", "reflocals");
|
||||
}
|
||||
|
||||
function byRefParam_0(p: number): void {
|
||||
control.inBackground(() => {
|
||||
basic.pause(1);
|
||||
sum = sum + p;
|
||||
});
|
||||
p = p + 1;
|
||||
}
|
||||
|
||||
function byRefParam_2(pxx: number): void {
|
||||
pxx = pxx + 1;
|
||||
control.inBackground(() => {
|
||||
basic.pause(1);
|
||||
sum = sum + pxx;
|
||||
});
|
||||
}
|
||||
|
||||
function testByRefParams(): void {
|
||||
msg("testByRefParams");
|
||||
refparamWrite("a" + "b");
|
||||
refparamWrite2(new Testrec());
|
||||
refparamWrite3(new Testrec());
|
||||
sum = 0;
|
||||
let x = 1;
|
||||
control.inBackground(() => {
|
||||
basic.pause(1);
|
||||
sum = sum + x;
|
||||
});
|
||||
x = 2;
|
||||
byRefParam_0(4);
|
||||
byRefParam_2(10);
|
||||
basic.pause(30);
|
||||
assert(sum == 18, "by ref");
|
||||
}
|
||||
|
||||
function refparamWrite(s: string): void {
|
||||
s = s + "c";
|
||||
assert(s == "abc", "abc");
|
||||
}
|
||||
|
||||
function refparamWrite2(testrec: Testrec): void {
|
||||
testrec = new Testrec();
|
||||
assert(testrec.bool == false, "");
|
||||
}
|
||||
|
||||
function refparamWrite3(testrecX: Testrec): void {
|
||||
control.inBackground(() => {
|
||||
basic.pause(1);
|
||||
assert(testrecX.str == "foo", "ff");
|
||||
testrecX.str = testrecX.str + "x";
|
||||
});
|
||||
testrecX = new Testrec();
|
||||
testrecX.str = "foo";
|
||||
basic.pause(30);
|
||||
assert(testrecX.str == "foox", "ff2");
|
||||
}
|
||||
|
||||
function testMemoryFree(): void {
|
||||
msg("testMemoryFree");
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
allocImage();
|
||||
}
|
||||
}
|
||||
|
||||
function runOnce(fn: Action): void {
|
||||
fn();
|
||||
}
|
||||
|
||||
function createObj() {
|
||||
return new Testrec();
|
||||
}
|
||||
|
||||
function testMemoryFreeHOF(): void {
|
||||
msg("testMemoryFreeHOF");
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
runOnce(() => {
|
||||
let tmp = createObj();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function allocImage(): void {
|
||||
let tmp = createObj();
|
||||
}
|
||||
|
||||
class Foo {
|
||||
pin: number;
|
||||
buf: number[];
|
||||
|
||||
constructor(k: number, l: number) {
|
||||
this.pin = k - l
|
||||
}
|
||||
|
||||
setPin(p: number) {
|
||||
this.pin = p
|
||||
}
|
||||
|
||||
getPin() {
|
||||
return this.pin
|
||||
}
|
||||
|
||||
init() {
|
||||
this.buf =[1, 2]
|
||||
}
|
||||
}
|
||||
|
||||
function testClass() {
|
||||
let f = new Foo(272, 100);
|
||||
assert(f.getPin() == 172, "ctor")
|
||||
f.setPin(42)
|
||||
assert(f.getPin() == 42, "getpin")
|
||||
}
|
||||
|
||||
enum En {
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D = 4200,
|
||||
E,
|
||||
}
|
||||
|
||||
enum En2 {
|
||||
D0 = En.D,
|
||||
D1,
|
||||
D2 = 1,
|
||||
}
|
||||
|
||||
|
||||
function testEnums() {
|
||||
msg("enums")
|
||||
|
||||
let k = En.C as number
|
||||
assert(k == 2, "e0")
|
||||
k = En.D as number
|
||||
assert(k == 4200, "e1")
|
||||
k = En.E as number
|
||||
assert(k == 4201, "e43")
|
||||
|
||||
k = En2.D0 as number
|
||||
assert(k == 4200, "eX0")
|
||||
k = En2.D1 as number
|
||||
assert(k == 4201, "eX1")
|
||||
|
||||
msg("enums0")
|
||||
assert(switchA(En.A) == 7, "s1")
|
||||
assert(switchA(En.B) == 7, "s2")
|
||||
assert(switchA(En.C) == 12, "s3")
|
||||
assert(switchA(En.D) == 13, "s4")
|
||||
assert(switchA(En.E) == 12, "s5")
|
||||
assert(switchA(-3 as En) == 12, "s6")
|
||||
|
||||
msg("enums1")
|
||||
assert(switchB(En.A) == 7, "x1")
|
||||
assert(switchB(En.B) == 7, "x2")
|
||||
assert(switchB(En.C) == 17, "x3")
|
||||
assert(switchB(En.D) == 13, "x4")
|
||||
assert(switchB(En.E) == 14, "x5")
|
||||
}
|
||||
|
||||
|
||||
function switchA(e: En) {
|
||||
let r = 12;
|
||||
switch (e) {
|
||||
case En.A:
|
||||
case En.B: return 7;
|
||||
case En.D: r = 13; break;
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
function switchB(e: En) {
|
||||
let r = 33;
|
||||
switch (e) {
|
||||
case En.A:
|
||||
case En.B: return 7;
|
||||
case En.D: r = 13; break;
|
||||
case En.E: r = 14; break;
|
||||
default: return 17;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
function bufferIs(b: Buffer, a: number[]) {
|
||||
assert(b.length == a.length, "bis-len")
|
||||
for (let i = 0; i < a.length; ++i) {
|
||||
if (a[i] != b[i]) {
|
||||
assert(false, `bufferIs: buf[${ i }]:${ b[i] } != ${ a[i] }`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testBuffer() {
|
||||
let b = pins.createBuffer(3);
|
||||
assert(b[0] == 0, "buf0");
|
||||
assert(b[1] == 0, "buf0");
|
||||
assert(b[2] == 0, "buf0");
|
||||
assert(b[-100000] == 0, "bufM");
|
||||
assert(b[100000] == 0, "bufM");
|
||||
|
||||
b[0] = 42;
|
||||
bufferIs(b,[42, 0, 0]);
|
||||
b[2] = 41;
|
||||
bufferIs(b,[42, 0, 41]);
|
||||
|
||||
b.rotate(1)
|
||||
bufferIs(b,[0, 41, 42]);
|
||||
b.rotate(-2)
|
||||
bufferIs(b,[41, 42, 0]);
|
||||
b.shift(1)
|
||||
bufferIs(b,[42, 0, 0]);
|
||||
b.rotate(9)
|
||||
bufferIs(b,[42, 0, 0]);
|
||||
b.rotate(-9)
|
||||
bufferIs(b,[42, 0, 0]);
|
||||
|
||||
b.fill(4);
|
||||
bufferIs(b,[4, 4, 4]);
|
||||
|
||||
b.fill(12, 1, 1);
|
||||
bufferIs(b,[4, 12, 4]);
|
||||
|
||||
b.fill(13, 1, -1);
|
||||
bufferIs(b,[4, 13, 13]);
|
||||
|
||||
b.fill(100, -1, -1);
|
||||
bufferIs(b,[4, 13, 13]);
|
||||
|
||||
b.shift(-1)
|
||||
bufferIs(b,[0, 4, 13]);
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
"lang-test0.ts"
|
||||
],
|
||||
"public": true,
|
||||
"additionalFilePath": "../../node_modules/pxt-core/libs/lang-test0",
|
||||
"dependencies": {
|
||||
"microbit": "file:../microbit"
|
||||
}
|
||||
|
77
libs/lang-test1/lang-test1.ts
Normal file
77
libs/lang-test1/lang-test1.ts
Normal file
@ -0,0 +1,77 @@
|
||||
//
|
||||
// Note that this is supposed to run from command line.
|
||||
// Do not use anything besides basic.pause, control.inBackground, console.log
|
||||
//
|
||||
|
||||
//% shim=pxtrt::panic
|
||||
function panic(code2: number): void { }
|
||||
|
||||
function msg(s: string): void {
|
||||
//console.log(s)
|
||||
//basic.pause(50);
|
||||
}
|
||||
|
||||
function assert(cond: boolean, msg_: string) {
|
||||
if (!cond) {
|
||||
console.log("ASSERT: " + msg_);
|
||||
panic(45);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Starting...")
|
||||
basic.showNumber(0);
|
||||
|
||||
testBuffer()
|
||||
|
||||
basic.showNumber(2);
|
||||
console.log("ALL TESTS OK")
|
||||
|
||||
|
||||
function bufferIs(b: Buffer, a: number[]) {
|
||||
assert(b.length == a.length, "bis-len")
|
||||
for (let i = 0; i < a.length; ++i) {
|
||||
if (a[i] != b[i]) {
|
||||
assert(false, `bufferIs: buf[${i}]:${b[i]} != ${a[i]}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testBuffer() {
|
||||
let b = pins.createBuffer(3);
|
||||
assert(b[0] == 0, "buf0");
|
||||
assert(b[1] == 0, "buf0");
|
||||
assert(b[2] == 0, "buf0");
|
||||
assert(b[-100000] == 0, "bufM");
|
||||
assert(b[100000] == 0, "bufM");
|
||||
|
||||
b[0] = 42;
|
||||
bufferIs(b, [42, 0, 0]);
|
||||
b[2] = 41;
|
||||
bufferIs(b, [42, 0, 41]);
|
||||
|
||||
b.rotate(1)
|
||||
bufferIs(b, [0, 41, 42]);
|
||||
b.rotate(-2)
|
||||
bufferIs(b, [41, 42, 0]);
|
||||
b.shift(1)
|
||||
bufferIs(b, [42, 0, 0]);
|
||||
b.rotate(9)
|
||||
bufferIs(b, [42, 0, 0]);
|
||||
b.rotate(-9)
|
||||
bufferIs(b, [42, 0, 0]);
|
||||
|
||||
b.fill(4);
|
||||
bufferIs(b, [4, 4, 4]);
|
||||
|
||||
b.fill(12, 1, 1);
|
||||
bufferIs(b, [4, 12, 4]);
|
||||
|
||||
b.fill(13, 1, -1);
|
||||
bufferIs(b, [4, 13, 13]);
|
||||
|
||||
b.fill(100, -1, -1);
|
||||
bufferIs(b, [4, 13, 13]);
|
||||
|
||||
b.shift(-1)
|
||||
bufferIs(b, [0, 4, 13]);
|
||||
}
|
12
libs/lang-test1/pxt.json
Normal file
12
libs/lang-test1/pxt.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "lang-test1",
|
||||
"description": "Test for the TypeScript -> HEX compiler; microbit specific parts",
|
||||
"installedVersion": "file:.",
|
||||
"files": [
|
||||
"lang-test1.ts"
|
||||
],
|
||||
"public": true,
|
||||
"dependencies": {
|
||||
"microbit": "file:../microbit"
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"bluetooth": "Support for additional Bluetooth services.",
|
||||
"bluetooth.onBluetoothConnected": "Register code to run when the micro:bit is connected to over Bluetooth",
|
||||
"bluetooth.onBluetoothConnected|block": "on bluetooth connected",
|
||||
"bluetooth.onBluetoothConnected|param|body": "Code to run when a Bluetooth connection is established",
|
||||
"bluetooth.onBluetoothDisconnected": "Register code to run when a bluetooth connection to the micro:bit is lost",
|
||||
"bluetooth.onBluetoothDisconnected|block": "on bluetooth disconnected",
|
||||
"bluetooth.onBluetoothDisconnected|param|body": "Code to run when a Bluetooth connection is lost",
|
||||
"bluetooth.startAccelerometerService": "Starts the Bluetooth accelerometer service",
|
||||
"bluetooth.startAccelerometerService|block": "bluetooth accelerometer service",
|
||||
"bluetooth.startButtonService": "Starts the Bluetooth button service",
|
||||
"bluetooth.startButtonService|block": "bluetooth button service",
|
||||
"bluetooth.startIOPinService": "Starts the Bluetooth IO pin service.",
|
||||
"bluetooth.startIOPinService|block": "bluetooth io pin service",
|
||||
"bluetooth.startLEDService": "Starts the Bluetooth LED service",
|
||||
"bluetooth.startLEDService|block": "bluetooth led service",
|
||||
"bluetooth.startMagnetometerService": "Starts the Bluetooth magnetometer service",
|
||||
"bluetooth.startMagnetometerService|block": "bluetooth magnetometer service",
|
||||
"bluetooth.startTemperatureService": "Starts the Bluetooth temperature service",
|
||||
"bluetooth.startTemperatureService|block": "bluetooth temperature service",
|
||||
"bluetooth.uartRead": "Reads from the Bluetooth UART service buffer, returning its contents when the specified delimiter character is encountered.",
|
||||
"bluetooth.uartRead|block": "bluetooth uart read %del=bluetooth_uart_delimiter_conv",
|
||||
"bluetooth.uartWrite": "Writes to the Bluetooth UART service buffer. From there the data is transmitted over Bluetooth to a connected device.",
|
||||
"bluetooth.uartWrite|block": "bluetooth uart write %data",
|
||||
"bluetooth|block": "bluetooth"
|
||||
}
|
26
libs/microbit-devices/_locales/microbit-devices-strings.json
Normal file
26
libs/microbit-devices/_locales/microbit-devices-strings.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"devices": "Control a phone with the BBC micro:bit via Bluetooth.",
|
||||
"devices.onGamepadButton": "Register code to run when the micro:bit receives a command from the paired gamepad.",
|
||||
"devices.onGamepadButton|block": "on gamepad button|%NAME",
|
||||
"devices.onGamepadButton|param|body": "code to run when button is pressed",
|
||||
"devices.onGamepadButton|param|name": "button name",
|
||||
"devices.onNotified": "Registers code to run when the device notifies about a particular event.",
|
||||
"devices.onNotified|block": "on notified|%event",
|
||||
"devices.onNotified|param|body": "code handler when event is triggered",
|
||||
"devices.onNotified|param|event": "event description",
|
||||
"devices.onSignalStrengthChanged": "Registers code to run when the device notifies about a change of signal strength.",
|
||||
"devices.onSignalStrengthChanged|block": "on signal strength changed",
|
||||
"devices.onSignalStrengthChanged|param|body": "Code run when the signal strength changes.",
|
||||
"devices.raiseAlertTo": "Sends an ``alert`` command to the parent device.",
|
||||
"devices.raiseAlertTo|block": "raise alert to|%property",
|
||||
"devices.raiseAlertTo|param|event": "event description",
|
||||
"devices.signalStrength": "Returns the last signal strength reported by the paired device.",
|
||||
"devices.signalStrength|block": "signal strength",
|
||||
"devices.tellCameraTo": "Sends a ``camera`` command to the parent device.",
|
||||
"devices.tellCameraTo|block": "tell camera to|%property",
|
||||
"devices.tellCameraTo|param|event": "event description",
|
||||
"devices.tellRemoteControlTo": "Sends a ``remote control`` command to the parent device.",
|
||||
"devices.tellRemoteControlTo|block": "tell remote control to|%property",
|
||||
"devices.tellRemoteControlTo|param|event": "event description",
|
||||
"devices|block": "devices"
|
||||
}
|
@ -1,101 +1,32 @@
|
||||
{
|
||||
"basic": "Provides access to basic micro:bit functionality.",
|
||||
"basic.clearScreen": "Turn off all LEDs",
|
||||
"basic.forever": "Repeats the code forever in the background. On each iteration, allows other codes to run.",
|
||||
"basic.pause": "Pause for the specified time in milliseconds",
|
||||
"basic.plotLeds": "Draws an image on the LED screen.",
|
||||
"basic.showAnimation": "Shows a sequence of LED screens as an animation.",
|
||||
"basic.showLeds": "Draws an image on the LED screen.",
|
||||
"basic.showNumber": "Scroll a number on the screen. If the number fits on the screen (i.e. is a single digit), do not scroll.",
|
||||
"basic.showString": "Display text on the display, one character at a time. If the string fits on the screen (i.e. is one letter), does not scroll.",
|
||||
"control": "Runtime and event utilities.",
|
||||
"control.inBackground": "Schedules code that run in the background.",
|
||||
"control.reset": "Resets the BBC micro:bit.",
|
||||
"game": "A single-LED sprite game engine",
|
||||
"game.addScore": "Adds points to the current score",
|
||||
"game.gameOver": "Displays a game over animation.",
|
||||
"game.score": "Gets the current score",
|
||||
"game.setScore": "Sets the current score value",
|
||||
"game.startCountdown": "Starts a game countdown timer",
|
||||
"images": "Creation, manipulation and display of LED images.",
|
||||
"images.createBigImage": "Creates an image with 2 frames.",
|
||||
"images.createImage": "Creates an image that fits on the LED screen.",
|
||||
"input": "Events and data from sensors",
|
||||
"input.acceleration": "Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up, x=0, y=0 and z=-1024)",
|
||||
"input.buttonIsPressed": "Get the button state (pressed or not) for ``A`` and ``B``.",
|
||||
"input.calibrate": "Obsolete, compass calibration is automatic.",
|
||||
"input.compassHeading": "Get the current compass compass heading in degrees.",
|
||||
"input.lightLevel": "Reads the light level applied to the LED screen in a range from ``0`` (dark) to ``255`` bright.",
|
||||
"input.magneticForce": "Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the simulator.",
|
||||
"input.onButtonPressed": "Do something when a button (``A``, ``B`` or both ``A+B``) is pressed",
|
||||
"input.onGesture": "Attaches code to run when the screen is facing up.",
|
||||
"input.onLogoDown": "Attaches code to run when the logo is oriented downwards and the board is vertical.",
|
||||
"input.onLogoUp": "Attaches code to run when the logo is oriented upwards and the board is vertical.",
|
||||
"input.onPinPressed": "Do something when a pin(``P0``, ``P1`` or both ``P2``) is pressed.",
|
||||
"input.onScreenDown": "Attaches code to run when the screen is facing down.",
|
||||
"input.onScreenUp": "Attaches code to run when the screen is facing up.",
|
||||
"input.onShake": "Attaches code to run when the device is shaken.",
|
||||
"input.pinIsPressed": "Get the pin state (pressed or not). Requires to hold the ground to close the circuit.",
|
||||
"input.rotation": "The pitch of the device, rotation along the ``x-axis``, in degrees.",
|
||||
"input.runningTime": "Gets the number of milliseconds elapsed since power on.",
|
||||
"input.setAccelerometerRange": "Sets the accelerometer sample range in gravities.",
|
||||
"input.temperature": "Gets the temperature in Celsius degrees (°C).",
|
||||
"led": "Control of the LED screen.",
|
||||
"led.brightness": "Get the screen brightness from 0 (off) to 255 (full bright).",
|
||||
"led.fadeIn": "Fades in the screen display.",
|
||||
"led.fadeOut": "Fades out the screen brightness.",
|
||||
"led.plot": "Turn on the specified LED using x, y coordinates (x is horizontal, y is vertical). (0,0) is upper left.",
|
||||
"led.plotAll": "Turns all LEDS on",
|
||||
"led.plotBarGraph": "Displays a vertical bar graph based on the `value` and `high` value.\nIf `high` is 0, the chart gets adjusted automatically.",
|
||||
"led.point": "Get the on/off state of the specified LED using x, y coordinates. (0,0) is upper left.",
|
||||
"led.screenshot": "Takes a screenshot of the LED screen and returns an image.",
|
||||
"led.setBrightness": "Set the screen brightness from 0 (off) to 255 (full bright).",
|
||||
"led.setDisplayMode": "Sets the display mode between black and white and greyscale for rendering LEDs.",
|
||||
"led.stopAnimation": "Cancels the current animation and clears other pending animations.",
|
||||
"led.toggle": "Toggles a particular pixel",
|
||||
"led.toggleAll": "Inverts the current LED display",
|
||||
"led.unplot": "Turn off the specified LED using x, y coordinates (x is horizontal, y is vertical). (0,0) is upper left.",
|
||||
"music": "Generation of music tones through pin ``P0``.",
|
||||
"music.beat": "Returns the duration of a beat in milli-seconds",
|
||||
"music.changeTempoBy": "Change the tempo by the specified amount",
|
||||
"music.noteFrequency": "Gets the frequency of a note.",
|
||||
"music.playTone": "Plays a tone through pin ``P0`` for the given duration.",
|
||||
"music.rest": "Rests (plays nothing) for a specified time through pin ``P0``.",
|
||||
"music.ringTone": "Plays a tone through pin ``P0``.",
|
||||
"music.setTempo": "Sets the tempo to the specified amount",
|
||||
"music.tempo": "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.",
|
||||
"pins": "Control currents in Pins for analog/digital signals, servos, i2c, ...",
|
||||
"pins.analogPitch": "Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin.",
|
||||
"pins.analogReadPin": "Read the connector value as analog, that is, as a value comprised between 0 and 1023.",
|
||||
"pins.analogSetPeriod": "Configures the Pulse-width modulation (PWM) of the analog output to the given value in **microseconds** or `1/1000` milliseconds.\nIf this pin is not configured as an analog output (using `analog write pin`), the operation has no effect.",
|
||||
"pins.analogSetPitchPin": "Sets the pin used when using `pins->analog pitch`.",
|
||||
"pins.analogWritePin": "Set the connector value as analog. Value must be comprised between 0 and 1023.",
|
||||
"pins.digitalReadPin": "Read the specified pin or connector as either 0 or 1",
|
||||
"pins.digitalWritePin": "Set a pin or connector value to either 0 or 1.",
|
||||
"pins.i2cReadNumber": "Read one number from 7-bit I2C address.",
|
||||
"pins.i2cWriteNumber": "Write one number to a 7-bit I2C address.",
|
||||
"pins.map": "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.",
|
||||
"pins.onPulsed": "Configures this pin to a digital input, and generates events where the timestamp is the duration that this pin was either ``high`` or ``low``.",
|
||||
"pins.pulseDuration": "Gets the duration of the last pulse in micro-seconds. This function should be called from a ``onPulse`` handler.",
|
||||
"pins.servoSetPulse": "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.",
|
||||
"pins.servoWritePin": "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).",
|
||||
"radio": "Communicate data using radio packets",
|
||||
"radio.onDataReceived": "Registers code to run when a packet is received over radio.",
|
||||
"radio.onDataReceived|block": "on data received",
|
||||
"radio.receiveNumber": "Reads the next packet as a number from the radio queue.",
|
||||
"radio.receiveNumber|block": "receive number",
|
||||
"radio.receiveString": "Reads the next packet as a string and returns it.",
|
||||
"radio.receiveString|block": "receive string",
|
||||
"radio.receivedNumberAt": "Reads a number at a given index, between ``0`` and ``3``, from the packet received by ``receive number``. Not supported in simulator.",
|
||||
"radio.receivedNumberAt|block": "receive number|at %VALUE",
|
||||
"radio.receivedNumberAt|param|index": "index of the number to read from 0 to 3. 1 eg",
|
||||
"radio.receivedSignalStrength": "Gets the received signal strength indicator (RSSI) from the packet received by ``receive number``. Not supported in simulator.\nnamespace=radio",
|
||||
"radio.receivedSignalStrength|block": "received signal strength",
|
||||
"radio.sendNumber": "Broadcasts a number over radio to any connected micro:bit in the group.",
|
||||
"radio.sendNumber|block": "send number %value",
|
||||
"radio.sendString": "Broadcasts a number over radio to any connected micro:bit in the group.",
|
||||
"radio.sendString|block": "send string %msg",
|
||||
"radio.sendValue": "Broadcasts a name / value pair along with the device serial number\nand running time to any connected BBC micro:bit in the group.",
|
||||
"radio.sendValue|block": "send|value %name|= %value",
|
||||
"radio.sendValue|param|name": "the field name (max 12 characters), eg: \"data\"",
|
||||
"radio.sendValue|param|value": "the numberic value",
|
||||
"radio.setGroup": "Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time.\n@ param id the group id between ``0`` and ``255``, 1 eg",
|
||||
"radio.setGroup|block": "set group %ID",
|
||||
"radio.setTransmitPower": "Change the output power level of the transmitter to the given value.",
|
||||
"radio.setTransmitPower|block": "set transmit power %power",
|
||||
"radio.setTransmitPower|param|power": "a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7",
|
||||
"radio.setTransmitSerialNumber": "Set the radio to transmit the serial number in each message.",
|
||||
"radio.setTransmitSerialNumber|block": "set tranmist serial number %transmit",
|
||||
"radio.writeValueToSerial": "Reads a value sent with `stream value` and writes it\nto the serial stream as JSON",
|
||||
"serial": "Reading and writing data over a serial connection.",
|
||||
"serial.readLine": "Reads a line of text from the serial port.",
|
||||
"serial.writeLine": "Prints a line of text to the serial",
|
||||
"serial.writeNumber": "Prints a numeric value to the serial",
|
||||
"serial.writeString": "Sends a piece of text through Serial connection.",
|
||||
"serial.writeValue": "Writes a ``name: value`` pair line to the serial."
|
||||
"radio.writeValueToSerial|block": "write value to serial",
|
||||
"radio|block": "radio"
|
||||
}
|
@ -43,7 +43,7 @@ namespace radio {
|
||||
*/
|
||||
//% help=radio/send-number
|
||||
//% weight=60
|
||||
//% blockId=radio_datagram_send block="send number %value" blockGap=8
|
||||
//% blockId=radio_datagram_send block="radio send number %value" blockGap=8
|
||||
void sendNumber(int value) {
|
||||
if (radioEnable() != MICROBIT_OK) return;
|
||||
uint32_t t = system_timer_current_time();
|
||||
@ -54,13 +54,13 @@ namespace radio {
|
||||
|
||||
/**
|
||||
* Broadcasts a name / value pair along with the device serial number
|
||||
* and running time to any connected BBC micro:bit in the group.
|
||||
* and running time to any connected micro:bit in the group.
|
||||
* @param name the field name (max 12 characters), eg: "data"
|
||||
* @param value the numberic value
|
||||
*/
|
||||
//% help=radio/send-value
|
||||
//% weight=59
|
||||
//% blockId=radio_datagram_send_value block="send|value %name|= %value" blockGap=8
|
||||
//% blockId=radio_datagram_send_value block="radio send|value %name|= %value" blockGap=8
|
||||
void sendValue(StringData* name, int value) {
|
||||
if (radioEnable() != MICROBIT_OK) return;
|
||||
|
||||
@ -86,7 +86,7 @@ namespace radio {
|
||||
*/
|
||||
//% help=radio/send-string
|
||||
//% weight=58
|
||||
//% blockId=radio_datagram_send_string block="send string %msg"
|
||||
//% blockId=radio_datagram_send_string block="radio send string %msg"
|
||||
void sendString(StringData* msg) {
|
||||
if (radioEnable() != MICROBIT_OK) return;
|
||||
|
||||
@ -103,7 +103,7 @@ namespace radio {
|
||||
*/
|
||||
//% help=radio/write-value-to-serial
|
||||
//% weight=3
|
||||
//% blockId=radio_write_value_serial block="write value to serial"
|
||||
//% blockId=radio_write_value_serial block="radio write value to serial"
|
||||
void writeValueToSerial() {
|
||||
if (radioEnable() != MICROBIT_OK) return;
|
||||
PacketBuffer p = uBit.radio.datagram.recv();
|
||||
@ -139,7 +139,7 @@ namespace radio {
|
||||
*/
|
||||
//% help=radio/on-data-received
|
||||
//% weight=50
|
||||
//% blockId=radio_datagram_received_event block="on data received" blockGap=8
|
||||
//% blockId=radio_datagram_received_event block="radio on data received" blockGap=8
|
||||
void onDataReceived(Action body) {
|
||||
if (radioEnable() != MICROBIT_OK) return;
|
||||
registerWithDal(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, body);
|
||||
@ -151,7 +151,7 @@ namespace radio {
|
||||
*/
|
||||
//% help=radio/received-number-at
|
||||
//% weight=45 debug=true
|
||||
//% blockId=radio_datagram_received_number_at block="receive number|at %VALUE" blockGap=8
|
||||
//% blockId=radio_datagram_received_number_at block="radio receive number|at %VALUE" blockGap=8
|
||||
int receivedNumberAt(int index) {
|
||||
if (radioEnable() != MICROBIT_OK) return 0;
|
||||
if (0 <= index && index < packet.length() / 4) {
|
||||
@ -168,7 +168,7 @@ namespace radio {
|
||||
*/
|
||||
//% help=radio/receive-number
|
||||
//% weight=46
|
||||
//% blockId=radio_datagram_receive block="receive number" blockGap=8
|
||||
//% blockId=radio_datagram_receive block="radio receive number" blockGap=8
|
||||
int receiveNumber()
|
||||
{
|
||||
if (radioEnable() != MICROBIT_OK) return 0;
|
||||
@ -179,7 +179,7 @@ namespace radio {
|
||||
/**
|
||||
* Reads the next packet as a string and returns it.
|
||||
*/
|
||||
//% blockId=radio_datagram_receive_string block="receive string" blockGap=8
|
||||
//% blockId=radio_datagram_receive_string block="radio receive string" blockGap=8
|
||||
//% weight=44
|
||||
//% help=radio/receive-string
|
||||
StringData* receiveString() {
|
||||
@ -194,7 +194,7 @@ namespace radio {
|
||||
*/
|
||||
//% help=radio/received-signal-strength
|
||||
//% weight=40
|
||||
//% blockId=radio_datagram_rssi block="received signal strength"
|
||||
//% blockId=radio_datagram_rssi block="radio received signal strength"
|
||||
int receivedSignalStrength() {
|
||||
if (radioEnable() != MICROBIT_OK) return 0;
|
||||
return packet.getRSSI();
|
||||
@ -205,8 +205,8 @@ namespace radio {
|
||||
* @ param id the group id between ``0`` and ``255``, 1 eg
|
||||
*/
|
||||
//% help=radio/set-group
|
||||
//% weight=10
|
||||
//% blockId=radio_set_group block="set group %ID"
|
||||
//% weight=10 blockGap=8
|
||||
//% blockId=radio_set_group block="radio set group %ID"
|
||||
void setGroup(int id) {
|
||||
if (radioEnable() != MICROBIT_OK) return;
|
||||
uBit.radio.setGroup(id);
|
||||
@ -217,8 +217,8 @@ namespace radio {
|
||||
* @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7
|
||||
*/
|
||||
//% help=radio/set-transmit-power
|
||||
//% weight=9
|
||||
//% blockId=radio_set_transmit_power block="set transmit power %power"
|
||||
//% weight=9 blockGap=8
|
||||
//% blockId=radio_set_transmit_power block="radio set transmit power %power"
|
||||
void setTransmitPower(int power) {
|
||||
if (radioEnable() != MICROBIT_OK) return;
|
||||
uBit.radio.setTransmitPower(power);
|
||||
@ -228,8 +228,8 @@ namespace radio {
|
||||
* Set the radio to transmit the serial number in each message.
|
||||
*/
|
||||
//% help=radio/set-transmit-serial-number
|
||||
//% weight=8
|
||||
//% block=radio_set_transmit_serial_number block="set tranmist serial number %transmit"
|
||||
//% weight=8 blockGap=8
|
||||
//% blockId=radio_set_transmit_serial_number block="radio set transmit serial number %transmit"
|
||||
void setTransmitSerialNumber(bool transmit) {
|
||||
transmitSerialNumber = transmit;
|
||||
}
|
||||
|
32
libs/microbit-radio/shims.d.ts
vendored
32
libs/microbit-radio/shims.d.ts
vendored
@ -10,18 +10,18 @@ declare namespace radio {
|
||||
*/
|
||||
//% help=radio/send-number
|
||||
//% weight=60
|
||||
//% blockId=radio_datagram_send block="send number %value" blockGap=8 shim=radio::sendNumber
|
||||
//% blockId=radio_datagram_send block="radio send number %value" blockGap=8 shim=radio::sendNumber
|
||||
function sendNumber(value: number): void;
|
||||
|
||||
/**
|
||||
* Broadcasts a name / value pair along with the device serial number
|
||||
* and running time to any connected BBC micro:bit in the group.
|
||||
* and running time to any connected micro:bit in the group.
|
||||
* @param name the field name (max 12 characters), eg: "data"
|
||||
* @param value the numberic value
|
||||
*/
|
||||
//% help=radio/send-value
|
||||
//% weight=59
|
||||
//% blockId=radio_datagram_send_value block="send|value %name|= %value" blockGap=8 shim=radio::sendValue
|
||||
//% blockId=radio_datagram_send_value block="radio send|value %name|= %value" blockGap=8 shim=radio::sendValue
|
||||
function sendValue(name: string, value: number): void;
|
||||
|
||||
/**
|
||||
@ -29,7 +29,7 @@ declare namespace radio {
|
||||
*/
|
||||
//% help=radio/send-string
|
||||
//% weight=58
|
||||
//% blockId=radio_datagram_send_string block="send string %msg" shim=radio::sendString
|
||||
//% blockId=radio_datagram_send_string block="radio send string %msg" shim=radio::sendString
|
||||
function sendString(msg: string): void;
|
||||
|
||||
/**
|
||||
@ -38,7 +38,7 @@ declare namespace radio {
|
||||
*/
|
||||
//% help=radio/write-value-to-serial
|
||||
//% weight=3
|
||||
//% blockId=radio_write_value_serial block="write value to serial" shim=radio::writeValueToSerial
|
||||
//% blockId=radio_write_value_serial block="radio write value to serial" shim=radio::writeValueToSerial
|
||||
function writeValueToSerial(): void;
|
||||
|
||||
/**
|
||||
@ -46,7 +46,7 @@ declare namespace radio {
|
||||
*/
|
||||
//% help=radio/on-data-received
|
||||
//% weight=50
|
||||
//% blockId=radio_datagram_received_event block="on data received" blockGap=8 shim=radio::onDataReceived
|
||||
//% blockId=radio_datagram_received_event block="radio on data received" blockGap=8 shim=radio::onDataReceived
|
||||
function onDataReceived(body: () => void): void;
|
||||
|
||||
/**
|
||||
@ -55,7 +55,7 @@ declare namespace radio {
|
||||
*/
|
||||
//% help=radio/received-number-at
|
||||
//% weight=45 debug=true
|
||||
//% blockId=radio_datagram_received_number_at block="receive number|at %VALUE" blockGap=8 shim=radio::receivedNumberAt
|
||||
//% blockId=radio_datagram_received_number_at block="radio receive number|at %VALUE" blockGap=8 shim=radio::receivedNumberAt
|
||||
function receivedNumberAt(index: number): number;
|
||||
|
||||
/**
|
||||
@ -63,13 +63,13 @@ declare namespace radio {
|
||||
*/
|
||||
//% help=radio/receive-number
|
||||
//% weight=46
|
||||
//% blockId=radio_datagram_receive block="receive number" blockGap=8 shim=radio::receiveNumber
|
||||
//% blockId=radio_datagram_receive block="radio receive number" blockGap=8 shim=radio::receiveNumber
|
||||
function receiveNumber(): number;
|
||||
|
||||
/**
|
||||
* Reads the next packet as a string and returns it.
|
||||
*/
|
||||
//% blockId=radio_datagram_receive_string block="receive string" blockGap=8
|
||||
//% blockId=radio_datagram_receive_string block="radio receive string" blockGap=8
|
||||
//% weight=44
|
||||
//% help=radio/receive-string shim=radio::receiveString
|
||||
function receiveString(): string;
|
||||
@ -80,7 +80,7 @@ declare namespace radio {
|
||||
*/
|
||||
//% help=radio/received-signal-strength
|
||||
//% weight=40
|
||||
//% blockId=radio_datagram_rssi block="received signal strength" shim=radio::receivedSignalStrength
|
||||
//% blockId=radio_datagram_rssi block="radio received signal strength" shim=radio::receivedSignalStrength
|
||||
function receivedSignalStrength(): number;
|
||||
|
||||
/**
|
||||
@ -88,8 +88,8 @@ declare namespace radio {
|
||||
* @ param id the group id between ``0`` and ``255``, 1 eg
|
||||
*/
|
||||
//% help=radio/set-group
|
||||
//% weight=10
|
||||
//% blockId=radio_set_group block="set group %ID" shim=radio::setGroup
|
||||
//% weight=10 blockGap=8
|
||||
//% blockId=radio_set_group block="radio set group %ID" shim=radio::setGroup
|
||||
function setGroup(id: number): void;
|
||||
|
||||
/**
|
||||
@ -97,16 +97,16 @@ declare namespace radio {
|
||||
* @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7
|
||||
*/
|
||||
//% help=radio/set-transmit-power
|
||||
//% weight=9
|
||||
//% blockId=radio_set_transmit_power block="set transmit power %power" shim=radio::setTransmitPower
|
||||
//% weight=9 blockGap=8
|
||||
//% blockId=radio_set_transmit_power block="radio set transmit power %power" shim=radio::setTransmitPower
|
||||
function setTransmitPower(power: number): void;
|
||||
|
||||
/**
|
||||
* Set the radio to transmit the serial number in each message.
|
||||
*/
|
||||
//% help=radio/set-transmit-serial-number
|
||||
//% weight=8
|
||||
//% block=radio_set_transmit_serial_number block="set tranmist serial number %transmit" shim=radio::setTransmitSerialNumber
|
||||
//% weight=8 blockGap=8
|
||||
//% blockId=radio_set_transmit_serial_number block="radio set transmit serial number %transmit" shim=radio::setTransmitSerialNumber
|
||||
function setTransmitSerialNumber(transmit: boolean): void;
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@
|
||||
"input.onShake": "Attaches code to run when the device is shaken.",
|
||||
"input.onShake|param|body": "TODO",
|
||||
"input.pinIsPressed": "Get the pin state (pressed or not). Requires to hold the ground to close the circuit.",
|
||||
"input.pinIsPressed|block": "pin|%NAME|is pressed",
|
||||
"input.pinIsPressed|block": "pin %NAME|is pressed",
|
||||
"input.pinIsPressed|param|name": "pin used to detect the touch",
|
||||
"input.rotation": "The pitch of the device, rotation along the ``x-axis``, in degrees.",
|
||||
"input.rotation|block": "rotation (°)|%NAME",
|
||||
|
@ -23,7 +23,7 @@ namespace basic {
|
||||
if (value < 0 || value >= 10) {
|
||||
uBit.display.scroll(t, interval);
|
||||
} else {
|
||||
uBit.display.print(t.charAt(0), interval * 5);
|
||||
uBit.display.printChar(t.charAt(0), interval * 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,6 +167,17 @@ namespace input {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pin state (pressed or not). Requires to hold the ground to close the circuit.
|
||||
* @param name pin used to detect the touch
|
||||
*/
|
||||
//% help=input/pin-is-pressed weight=56
|
||||
//% blockId="device_pin_is_pressed" block="pin %NAME|is pressed" icon="\uf094"
|
||||
//% blockGap=8
|
||||
bool pinIsPressed(TouchPin name) {
|
||||
auto pin = getPin((int)name);
|
||||
return pin && pin->isTouched();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current compass compass heading in degrees.
|
||||
@ -270,16 +281,6 @@ namespace input {
|
||||
//% help=input/calibrate weight=0
|
||||
void calibrate() { }
|
||||
|
||||
/**
|
||||
* Get the pin state (pressed or not). Requires to hold the ground to close the circuit.
|
||||
* @param name pin used to detect the touch
|
||||
*/
|
||||
//% help=input/pin-is-pressed weight=58 block="pin|%NAME|is pressed" icon="\uf094"
|
||||
bool pinIsPressed(TouchPin name) {
|
||||
auto pin = getPin((int)name);
|
||||
return pin && pin->isTouched();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the accelerometer sample range in gravities.
|
||||
* @param range a value describe the maximum strengh of acceleration measured
|
||||
|
16
libs/microbit/shims.d.ts
vendored
16
libs/microbit/shims.d.ts
vendored
@ -230,6 +230,15 @@ declare namespace input {
|
||||
//% icon="\uf192" blockGap=8 shim=input::buttonIsPressed
|
||||
function buttonIsPressed(button: Button): boolean;
|
||||
|
||||
/**
|
||||
* Get the pin state (pressed or not). Requires to hold the ground to close the circuit.
|
||||
* @param name pin used to detect the touch
|
||||
*/
|
||||
//% help=input/pin-is-pressed weight=56
|
||||
//% blockId="device_pin_is_pressed" block="pin %NAME|is pressed" icon="\uf094"
|
||||
//% blockGap=8 shim=input::pinIsPressed
|
||||
function pinIsPressed(name: TouchPin): boolean;
|
||||
|
||||
/**
|
||||
* Get the current compass compass heading in degrees.
|
||||
*/
|
||||
@ -290,13 +299,6 @@ declare namespace input {
|
||||
//% help=input/calibrate weight=0 shim=input::calibrate
|
||||
function calibrate(): void;
|
||||
|
||||
/**
|
||||
* Get the pin state (pressed or not). Requires to hold the ground to close the circuit.
|
||||
* @param name pin used to detect the touch
|
||||
*/
|
||||
//% help=input/pin-is-pressed weight=58 block="pin|%NAME|is pressed" icon="\uf094" shim=input::pinIsPressed
|
||||
function pinIsPressed(name: TouchPin): boolean;
|
||||
|
||||
/**
|
||||
* Sets the accelerometer sample range in gravities.
|
||||
* @param range a value describe the maximum strengh of acceleration measured
|
||||
|
@ -1,45 +0,0 @@
|
||||
# NeoPixel driver
|
||||
|
||||
This library provides a driver for various Neo Pixel LED strips,
|
||||
see https://www.adafruit.com/category/168
|
||||
|
||||
NeoPixels consist of a number of RGB LEDs, every one of them controlled
|
||||
separately.
|
||||
|
||||
## Basic usage
|
||||
|
||||
```blocks
|
||||
// Create a NeoPixel driver - specify the number of LEDs:
|
||||
let strip = neopixel.create(DigitalPin.P0, 24)
|
||||
|
||||
// set pixel colors
|
||||
strip.setPixelColor(0, 255, 255, 255) // white
|
||||
strip.setPixelColor(1, 255, 0, 0) // red
|
||||
strip.setPixelColor(2, 0, 255, 0) // green
|
||||
strip.setPixelColor(3, 0, 0, 255) // blue
|
||||
|
||||
// send the data to the strip
|
||||
strip.show()
|
||||
```
|
||||
|
||||
Use `strip.setBrigthness()` to lower the brightness (it's maxed out by default).
|
||||
|
||||
Use `strip.shift()` or `strip.rotate()` to shift the lights around.
|
||||
|
||||
## Example: Using accelerometer to control colors
|
||||
|
||||
This little program will let the position of the microbit control the color of the first LED.
|
||||
This first LED will then get shifted further away every 100ms.
|
||||
|
||||
```blocks
|
||||
let strip = neopixel.create(DigitalPin.P0, 24)
|
||||
while (true) {
|
||||
let x = input.acceleration(Dimension.X) / 2
|
||||
let y = input.acceleration(Dimension.Y) / 2
|
||||
let z = input.acceleration(Dimension.Z) / 2
|
||||
strip.setPixelColor(0, x, y, -z);
|
||||
strip.shift(1);
|
||||
strip.show();
|
||||
basic.pause(100);
|
||||
}
|
||||
```
|
@ -1,119 +0,0 @@
|
||||
/**
|
||||
* Functions to operate NeoPixel strips.
|
||||
*/
|
||||
//% weight=5 color=#2699BF
|
||||
namespace neopixel {
|
||||
|
||||
//% shim=sendBufferAsm
|
||||
function sendBuffer(buf: Buffer, pin: DigitalPin) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A NeoPixel strip
|
||||
*/
|
||||
export class Strip {
|
||||
buf: Buffer;
|
||||
pin: DigitalPin;
|
||||
brightness: number;
|
||||
|
||||
/**
|
||||
* Set give LED to a given color (range 0-255 for r, g, b)
|
||||
*/
|
||||
//% blockId="neopixel_set_pixel_color" block="%strip|set pixel color at %ledoff|red: %red|green: %green|blue: %blue" blockGap=8
|
||||
//% weight=80
|
||||
setPixelColor(ledoff: number, red: number, green: number, blue: number): void {
|
||||
ledoff = ledoff * 3;
|
||||
let br = this.brightness;
|
||||
if (br < 255) {
|
||||
red = (Math.clamp(0, 255, red) * br) >> 8;
|
||||
green = (Math.clamp(0, 255, blue) * br) >> 8;
|
||||
blue = (Math.clamp(0, 255, blue) * br) >> 8;
|
||||
}
|
||||
let buf = this.buf;
|
||||
buf[ledoff + 0] = Math.clamp(0, 255, green);
|
||||
buf[ledoff + 1] = Math.clamp(0, 255, red);
|
||||
buf[ledoff + 2] = Math.clamp(0, 255, blue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send all the changes to the strip.
|
||||
*/
|
||||
//% blockId="neopixel_show" block="%strip|show" blockGap=8
|
||||
//% weight=79
|
||||
show() {
|
||||
basic.pause(1)
|
||||
sendBuffer(this.buf, this.pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn off all LEDs.
|
||||
*/
|
||||
//% blockId="neopixel_clear" block="%strip|clear"
|
||||
//% weight=76
|
||||
clear(): void {
|
||||
this.buf.fill(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of pixels declared on the strip
|
||||
*/
|
||||
//% blockId="neopixel_length" block="%strip|length" blockGap=8
|
||||
//% weight=60
|
||||
length() {
|
||||
return this.buf.length / 3
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the brightness of the strip, 0-255. eg: 255
|
||||
*/
|
||||
//% blockId="neopixel_set_brightness" block="%strip|set brightness %brightness" blockGap=8
|
||||
//% weight=59
|
||||
setBrigthness(brightness: number): void {
|
||||
this.brightness = brightness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift LEDs forward and clear with zeros.
|
||||
* @param off number of pixels to shift forward, eg: 1
|
||||
*/
|
||||
//% blockId="neopixel_shift" block="%strip|shift pixels forward by %off" blockGap=8
|
||||
//% weight=40
|
||||
shift(off: number = 1): void {
|
||||
this.buf.shift(-off * 3)
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate LEDs forward.
|
||||
* @param off number of pixels to rotate forward, eg: 1
|
||||
*/
|
||||
//% blockId="neopixel_rotate" block="%strip|rotate pixels forward by %off" blockGap=8
|
||||
//% weight=39
|
||||
rotate(off:number = 1): void {
|
||||
this.buf.rotate(-off * 3)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the pin where the neopixel is connected, defaults to P0.
|
||||
*/
|
||||
setPin(pin: DigitalPin): void {
|
||||
this.pin = pin;
|
||||
pins.digitalWritePin(this.pin, 0)
|
||||
basic.pause(50)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new NeoPixel driver for `numleds` LEDs.
|
||||
* @param pin the pin where the neopixel is connected.
|
||||
* @param numleds number of leds in the strip, eg: 24,30,60,64
|
||||
*/
|
||||
//% blockId="neopixel_create" block="neopixel create|at pin %pin|with %numleds leds"
|
||||
//% weight=90
|
||||
export function create(pin: DigitalPin, numleds: number): Strip {
|
||||
let strip = new Strip();
|
||||
strip.buf = pins.createBuffer(numleds * 3);
|
||||
strip.setBrigthness(255)
|
||||
strip.setPin(pin)
|
||||
return strip;
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
let strip = neopixel.create(DigitalPin.P0, 24);
|
||||
let br = 100;
|
||||
strip.setBrigthness(100);
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
br = br + 20;
|
||||
if (br > 255) {
|
||||
br = 5;
|
||||
}
|
||||
strip.setBrigthness(br);
|
||||
});
|
||||
|
||||
let rotationMode = false;
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
rotationMode = !rotationMode;
|
||||
if (rotationMode) {
|
||||
basic.showLeds(`
|
||||
. # # # .
|
||||
# . . . #
|
||||
# . . . #
|
||||
# . . . #
|
||||
. # # # .
|
||||
`);
|
||||
} else {
|
||||
basic.showLeds(`
|
||||
. . # . .
|
||||
. . . # .
|
||||
# # # # #
|
||||
. . . # .
|
||||
. . # . .
|
||||
`);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
while (true) {
|
||||
let x = input.acceleration(Dimension.X) / 2
|
||||
let y = input.acceleration(Dimension.Y) / 2
|
||||
let z = input.acceleration(Dimension.Z) / 2
|
||||
if (rotationMode) {
|
||||
strip.rotate();
|
||||
} else {
|
||||
strip.setPixelColor(0, x, y, -z);
|
||||
strip.shift(1);
|
||||
}
|
||||
strip.show();
|
||||
basic.pause(100);
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
{
|
||||
"name": "neopixel",
|
||||
"description": "AdaFruit NeoPixel driver for micro:bit",
|
||||
"files": [
|
||||
"README.md",
|
||||
"neopixel.ts",
|
||||
"sendbuffer.asm"
|
||||
],
|
||||
"testFiles": [
|
||||
"neotest.ts"
|
||||
],
|
||||
"yotta": {
|
||||
"config": {
|
||||
"microbit-dal": {
|
||||
"bluetooth": {
|
||||
"enabled": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"public": true,
|
||||
"dependencies": {
|
||||
"microbit": "file:../microbit"
|
||||
},
|
||||
"installedVersion": "fgluxh"
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
sendBufferAsm:
|
||||
|
||||
push {r4,r5,r6,r7,lr}
|
||||
|
||||
mov r4, r0 ; save buff
|
||||
mov r6, r1 ; save pin
|
||||
|
||||
mov r0, r4
|
||||
bl BufferMethods::length
|
||||
mov r5, r0
|
||||
|
||||
mov r0, r4
|
||||
bl BufferMethods::getBytes
|
||||
mov r4, r0
|
||||
|
||||
; setup pin as digital
|
||||
mov r0, r6
|
||||
movs r1, #0
|
||||
bl pins::digitalWritePin
|
||||
|
||||
; load pin address
|
||||
mov r0, r6
|
||||
bl pins::getPinAddress
|
||||
|
||||
ldr r0, [r0, #8] ; get mbed DigitalOut from MicroBitPin
|
||||
ldr r1, [r0, #4] ; r1-mask for this pin
|
||||
ldr r2, [r0, #16] ; r2-clraddr
|
||||
ldr r3, [r0, #12] ; r3-setaddr
|
||||
|
||||
cpsid i ; disable irq
|
||||
|
||||
b .start
|
||||
|
||||
.nextbit: ; C0
|
||||
str r1, [r3, #0] ; pin := hi C2
|
||||
tst r6, r0 ; C3
|
||||
bne .islate ; C4
|
||||
str r1, [r2, #0] ; pin := lo C6
|
||||
.islate:
|
||||
lsrs r6, r6, #1 ; r6 >>= 1 C7
|
||||
bne .justbit ; C8
|
||||
|
||||
; not just a bit - need new byte
|
||||
adds r4, #1 ; r4++ C9
|
||||
subs r5, #1 ; r5-- C10
|
||||
bcc .stop ; if (r5<0) goto .stop C11
|
||||
.start:
|
||||
movs r6, #0x80 ; reset mask C12
|
||||
nop ; C13
|
||||
|
||||
.common: ; C13
|
||||
str r1, [r2, #0] ; pin := lo C15
|
||||
; always re-load byte - it just fits with the cycles better this way
|
||||
ldrb r0, [r4, #0] ; r0 := *r4 C17
|
||||
b .nextbit ; C20
|
||||
|
||||
.justbit: ; C10
|
||||
; no nops, branch taken is already 3 cycles
|
||||
b .common ; C13
|
||||
|
||||
.stop:
|
||||
str r1, [r2, #0] ; pin := lo
|
||||
cpsie i ; enable irq
|
||||
|
||||
pop {r4,r5,r6,r7,pc}
|
||||
|
||||
|
@ -185,7 +185,6 @@ Functions in this category require to be connected to a remote device.
|
||||
|
||||
### Libraries
|
||||
|
||||
* [game library](/js/game-library)
|
||||
* [serial library](/js/serial-library)
|
||||
|
||||
### ~
|
||||
|
@ -47,7 +47,6 @@ Learn how to create a guessing game with **global variables** `var str: "this is
|
||||
* **on screen down** [read more...](/functions/on-screen-down)
|
||||
* **on screen up** [read more...](/functions/on-screen-up)
|
||||
* **math random** : [read more...](/js/math)
|
||||
* **game library** [read more...](/js/game-library)
|
||||
|
||||
## Resources
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "pxt-microbit",
|
||||
"version": "0.2.187",
|
||||
"version": "0.3.11",
|
||||
"description": "BBC micro:bit target for PXT",
|
||||
"keywords": [
|
||||
"JavaScript",
|
||||
@ -29,6 +29,6 @@
|
||||
"typescript": "^1.8.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"pxt-core": "0.2.196"
|
||||
"pxt-core": "0.3.14"
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,7 @@
|
||||
"libs/microbit",
|
||||
"libs/microbit-radio",
|
||||
"libs/microbit-devices",
|
||||
"libs/microbit-bluetooth",
|
||||
"libs/neopixel"
|
||||
"libs/microbit-bluetooth"
|
||||
],
|
||||
"cloud": {
|
||||
"workspace": false,
|
||||
@ -53,7 +52,7 @@
|
||||
"compile": {
|
||||
"isNative": false,
|
||||
"hasHex": true,
|
||||
"deployDrives": "^MICROBIT",
|
||||
"deployDrives": "(MICROBIT|MBED)",
|
||||
"driveName": "MICROBIT",
|
||||
"hexMimeType": "application/x-microbit-hex"
|
||||
},
|
||||
@ -125,5 +124,9 @@
|
||||
}
|
||||
],
|
||||
"sideDoc": "getting-started"
|
||||
},
|
||||
"analytics": {
|
||||
"userVoiceApiKey": "WEkkIGaj1WtJnSUF59iwaA",
|
||||
"userVoiceForumId": 402381
|
||||
}
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ namespace pxsim.basic {
|
||||
clearScreen();
|
||||
pause(interval * 5);
|
||||
} else {
|
||||
if (s.length == 1) showLeds(createImageFromString(s), interval * 5)
|
||||
if (s.length == 1) showLeds(createImageFromString(s + " "), interval * 5)
|
||||
else ImageMethods.scrollImage(createImageFromString(s + " "), 1, interval);
|
||||
}
|
||||
}
|
||||
@ -725,6 +725,7 @@ namespace pxsim.ImageMethods {
|
||||
board().animationQ.enqueue({
|
||||
interval: interval,
|
||||
frame: () => {
|
||||
//TODO: support right to left.
|
||||
if (off >= leds.width || off < 0) return false;
|
||||
stride > 0 ? display.shiftLeft(stride) : display.shiftRight(-stride);
|
||||
let c = Math.min(stride, leds.width - off);
|
||||
|
@ -612,9 +612,9 @@ svg.sim.grayscale {
|
||||
|
||||
private attachEvents() {
|
||||
Runtime.messagePosted = (msg) => {
|
||||
switch (msg.type || '') {
|
||||
case 'serial': this.flashSystemLed(); break;
|
||||
case 'radiopacket': this.flashAntenna(); break;
|
||||
switch (msg.type || "") {
|
||||
case "serial": this.flashSystemLed(); break;
|
||||
case "radiopacket": this.flashAntenna(); break;
|
||||
}
|
||||
}
|
||||
let tiltDecayer = 0;
|
||||
|
@ -600,7 +600,8 @@ namespace pxsim {
|
||||
Runtime.postMessage(<SimulatorSerialMessage>{
|
||||
type: "serial",
|
||||
data: this.serialOutBuffer,
|
||||
id: runtime.id
|
||||
id: runtime.id,
|
||||
sim: true
|
||||
})
|
||||
this.serialOutBuffer = ""
|
||||
break;
|
||||
|
670
testconv.json
670
testconv.json
@ -1,670 +0,0 @@
|
||||
{
|
||||
"apiUrl": "https://www.microbit.co.uk/api/",
|
||||
"fakeids": [
|
||||
"zzltaj",
|
||||
"zzpgxf",
|
||||
"rhisri",
|
||||
"zztzyk"
|
||||
],
|
||||
"ids": [
|
||||
"balcxr",
|
||||
"bambkh",
|
||||
"bbfxnw",
|
||||
"bbtlly",
|
||||
"bbvscl",
|
||||
"bbxapr",
|
||||
"bcbxtu",
|
||||
"bchtnm",
|
||||
"bcpnpx",
|
||||
"bcredt",
|
||||
"bdbwuy",
|
||||
"bdddfl",
|
||||
"bedihg",
|
||||
"behvrp",
|
||||
"bevhll",
|
||||
"bezbat",
|
||||
"bfrafy",
|
||||
"bfvuez",
|
||||
"bgqdmi",
|
||||
"bguxyx",
|
||||
"bhbzvc",
|
||||
"bhhzvr",
|
||||
"bhollk",
|
||||
"biczhe",
|
||||
"bieoqj",
|
||||
"biwfto",
|
||||
"bjayrk",
|
||||
"bjcbpf",
|
||||
"bjcdte",
|
||||
"bjomis",
|
||||
"bjqlzz",
|
||||
"bkaofs",
|
||||
"bkbsfh",
|
||||
"bkxbji",
|
||||
"blbhmr",
|
||||
"blkuau",
|
||||
"bllhdc",
|
||||
"blougi",
|
||||
"blpvxv",
|
||||
"bmevma",
|
||||
"bmlwtk",
|
||||
"bmmayl",
|
||||
"bncsjd",
|
||||
"bnlfif",
|
||||
"bnsfch",
|
||||
"bnucdu",
|
||||
"bolvvm",
|
||||
"bouhxx",
|
||||
"bpbvyx",
|
||||
"bpmeio",
|
||||
"bpqvtv",
|
||||
"bptlwr",
|
||||
"bqceny",
|
||||
"bqgsnm",
|
||||
"bqkwia",
|
||||
"bqvoqy",
|
||||
"bqyoyn",
|
||||
"brlcdr",
|
||||
"bsmmsp",
|
||||
"bsncre",
|
||||
"bstaqt",
|
||||
"butypx",
|
||||
"buuzga",
|
||||
"bvnciu",
|
||||
"bwbuga",
|
||||
"bwhttb",
|
||||
"bwkezu",
|
||||
"bxswvm",
|
||||
"bynkeb",
|
||||
"bypanj",
|
||||
"bywqzx",
|
||||
"byzegt",
|
||||
"bzaaya",
|
||||
"bzrusu",
|
||||
"bzwbps",
|
||||
"dalzjm",
|
||||
"damymx",
|
||||
"dbdpxx",
|
||||
"dcapfd",
|
||||
"dceikq",
|
||||
"ddikkz",
|
||||
"ddjpss",
|
||||
"ddtadz",
|
||||
"ddxbjj",
|
||||
"dfkuyn",
|
||||
"dfmpxf",
|
||||
"dfypdn",
|
||||
"dhabye",
|
||||
"dhbioa",
|
||||
"dieoiu",
|
||||
"diuhli",
|
||||
"djchkz",
|
||||
"djohvc",
|
||||
"djztxc",
|
||||
"dkqbyq",
|
||||
"dkvxwr",
|
||||
"dmbcwi",
|
||||
"dmekmj",
|
||||
"dmghho",
|
||||
"dnmrlu",
|
||||
"dnnzgd",
|
||||
"dooboj",
|
||||
"dosuna",
|
||||
"dqgnhz",
|
||||
"dqqfgv",
|
||||
"dqwrsw",
|
||||
"drmbxg",
|
||||
"drrrty",
|
||||
"dscjnc",
|
||||
"dsvguv",
|
||||
"dtemsf",
|
||||
"dtmmmc",
|
||||
"dundpx",
|
||||
"dushve",
|
||||
"duupgd",
|
||||
"dvgzyq",
|
||||
"dvnoer",
|
||||
"dwcxtn",
|
||||
"dwtoyp",
|
||||
"dxdfbw",
|
||||
"dxqdqw",
|
||||
"dxroxs",
|
||||
"dxvgvs",
|
||||
"dycuzj",
|
||||
"dyhnkt",
|
||||
"dyxejk",
|
||||
"dzlocb",
|
||||
"dzlogl",
|
||||
"fadekj",
|
||||
"faffgr",
|
||||
"fapznm",
|
||||
"fbgdog",
|
||||
"fbpnng",
|
||||
"fbyrog",
|
||||
"fcfoox",
|
||||
"fcicvk",
|
||||
"fcjlto",
|
||||
"fcvwvj",
|
||||
"fdjhpo",
|
||||
"fdtayy",
|
||||
"fdyxvx",
|
||||
"fegzbd",
|
||||
"felusd",
|
||||
"fethzd",
|
||||
"ffcqby",
|
||||
"ffjeei",
|
||||
"ffjuuz",
|
||||
"fflxnx",
|
||||
"ffpyfa",
|
||||
"fhcyyx",
|
||||
"fhoonu",
|
||||
"fitucj",
|
||||
"fitvxu",
|
||||
"fjdnmb",
|
||||
"fjhnpw",
|
||||
"fjlzrt",
|
||||
"fjwknw",
|
||||
"fkgprd",
|
||||
"fklpld",
|
||||
"fllghh",
|
||||
"flqpgb",
|
||||
"fmdsdi",
|
||||
"fmdzgg",
|
||||
"fnimjx",
|
||||
"fnjmfx",
|
||||
"fnscgh",
|
||||
"fomwmz",
|
||||
"fpelnl",
|
||||
"fpngwv",
|
||||
"fpqusd",
|
||||
"fpuclv",
|
||||
"fpvrwv",
|
||||
"fqmgsu",
|
||||
"fqsbhp",
|
||||
"fqsrdu",
|
||||
"frlxvd",
|
||||
"froxsb",
|
||||
"frqqnm",
|
||||
"ftcrip",
|
||||
"ftrzta",
|
||||
"fubsaf",
|
||||
"fvgogo",
|
||||
"fvgxfz",
|
||||
"fvkluo",
|
||||
"fvsfrv",
|
||||
"fwkjkj",
|
||||
"fxxsgy",
|
||||
"fyazlp",
|
||||
"fypaix",
|
||||
"fzcoly",
|
||||
"fzidej",
|
||||
"hatpaz",
|
||||
"haxiza",
|
||||
"hbfvlb",
|
||||
"hbklfv",
|
||||
"hbwlkf",
|
||||
"hcmpdm",
|
||||
"hdnlmx",
|
||||
"hetmho",
|
||||
"hfklxz",
|
||||
"hfkvpg",
|
||||
"hfmkbt",
|
||||
"hftxjx",
|
||||
"hfunev",
|
||||
"hgepqq",
|
||||
"hivbxk",
|
||||
"hjesfm",
|
||||
"hklazc",
|
||||
"hkncxl",
|
||||
"hkrfni",
|
||||
"hlenxc",
|
||||
"hlhipg",
|
||||
"hlhvoe",
|
||||
"hlwdwo",
|
||||
"hnljdp",
|
||||
"howggk",
|
||||
"hpjppy",
|
||||
"hptebp",
|
||||
"hpupwc",
|
||||
"hqdpet",
|
||||
"hqhclr",
|
||||
"hqheal",
|
||||
"hqoqjh",
|
||||
"hqpuxt",
|
||||
"hrnitd",
|
||||
"hrooif",
|
||||
"hsuiag",
|
||||
"hsxmox",
|
||||
"humerf",
|
||||
"huqcpc",
|
||||
"huydje",
|
||||
"hwetsq",
|
||||
"hxuwlt",
|
||||
"hzcxdp",
|
||||
"hzpfge",
|
||||
"hzpkma",
|
||||
"jaeeve",
|
||||
"jcmkmq",
|
||||
"jcojot",
|
||||
"jcvdvp",
|
||||
"jdcils",
|
||||
"jddumo",
|
||||
"jdsqxr",
|
||||
"jerwei",
|
||||
"jfwcov",
|
||||
"jgdknu",
|
||||
"jgjijp",
|
||||
"jgofmw",
|
||||
"jhjauh",
|
||||
"jhrjvj",
|
||||
"jhseak",
|
||||
"jiyhsk",
|
||||
"jiyoeq",
|
||||
"jjumac",
|
||||
"jkppnc",
|
||||
"jkxyeh",
|
||||
"jkymhg",
|
||||
"jlatje",
|
||||
"jlbxjm",
|
||||
"jlmzps",
|
||||
"jmmgyn",
|
||||
"jmshop",
|
||||
"jnengo",
|
||||
"jnhcat",
|
||||
"jnvrkr",
|
||||
"jnxdok",
|
||||
"jociyw",
|
||||
"joryiq",
|
||||
"jpbfze",
|
||||
"jpcrcj",
|
||||
"jrfuqz",
|
||||
"jrfwyh",
|
||||
"jrpbtk",
|
||||
"jrwkyz",
|
||||
"jrxhxe",
|
||||
"jsxvju",
|
||||
"jszrpp",
|
||||
"jtbdng",
|
||||
"jtglrx",
|
||||
"jtodxy",
|
||||
"julzbh",
|
||||
"juqrkb",
|
||||
"jvstzh",
|
||||
"jwckaz",
|
||||
"jwplaw",
|
||||
"jwskcb",
|
||||
"jxgcel",
|
||||
"jxjryw",
|
||||
"jxmrht",
|
||||
"jxqobc",
|
||||
"jzenhj",
|
||||
"jzwxbr",
|
||||
"jzzbqg",
|
||||
"laanun",
|
||||
"lagxjo",
|
||||
"lamnpb",
|
||||
"lapexp",
|
||||
"lazmuu",
|
||||
"lbeyfh",
|
||||
"lbhuwc",
|
||||
"lcdeuk",
|
||||
"lchqfb",
|
||||
"lcpmnp",
|
||||
"ldgoae",
|
||||
"lecrpo",
|
||||
"lfpidi",
|
||||
"lfrpst",
|
||||
"lgsrwm",
|
||||
"lhjcvy",
|
||||
"licgsp",
|
||||
"likrcp",
|
||||
"ljauxo",
|
||||
"ljkskx",
|
||||
"llsepx",
|
||||
"llxcdk",
|
||||
"lmvoxp",
|
||||
"lniybn",
|
||||
"loafab",
|
||||
"loehfe",
|
||||
"lpnzct",
|
||||
"lqwdio",
|
||||
"lqxnnj",
|
||||
"lracic",
|
||||
"lrwotp",
|
||||
"lryglt",
|
||||
"lsikdy",
|
||||
"ltchng",
|
||||
"ltsbpa",
|
||||
"lucaof",
|
||||
"lvahkk",
|
||||
"lvvdne",
|
||||
"lwtsxc",
|
||||
"lxleej",
|
||||
"lxwstg",
|
||||
"lxwwtd",
|
||||
"lzndlk",
|
||||
"lzosmg",
|
||||
"lzsseg",
|
||||
"naevvc",
|
||||
"nawmtp",
|
||||
"nbomql",
|
||||
"nbuuii",
|
||||
"nbwine",
|
||||
"ndayhb",
|
||||
"ndikwg",
|
||||
"ndlikc",
|
||||
"ndljim",
|
||||
"ndooqj",
|
||||
"ndqgow",
|
||||
"nfjrxg",
|
||||
"nfmunh",
|
||||
"nghraa",
|
||||
"nhpyof",
|
||||
"nhtyzy",
|
||||
"nikzhg",
|
||||
"nitcfc",
|
||||
"njfeff",
|
||||
"njvcbs",
|
||||
"njynsd",
|
||||
"nkdbmy",
|
||||
"nlyuwy",
|
||||
"nmbxkh",
|
||||
"nmdfik",
|
||||
"nmuhlk",
|
||||
"noftar",
|
||||
"noikvz",
|
||||
"novevx",
|
||||
"noxyjg",
|
||||
"noyovd",
|
||||
"npkjbk",
|
||||
"nqdtvd",
|
||||
"nqgyno",
|
||||
"nqxloa",
|
||||
"nrjdzu",
|
||||
"nsaumh",
|
||||
"nsegbi",
|
||||
"ntfmsx",
|
||||
"ntsvek",
|
||||
"nujrlc",
|
||||
"nvogiv",
|
||||
"nvrqzl",
|
||||
"nvtfbc",
|
||||
"nvymrn",
|
||||
"nwowql",
|
||||
"nwxlij",
|
||||
"nxhnvy",
|
||||
"nxpwae",
|
||||
"nynwto",
|
||||
"nytwlb",
|
||||
"nyuakq",
|
||||
"nzrgyf",
|
||||
"nzrwza",
|
||||
"nzzcea",
|
||||
"pbsolq",
|
||||
"pbtnpf",
|
||||
"pcdvqu",
|
||||
"pchzqo",
|
||||
"pdmxpl",
|
||||
"pdnntw",
|
||||
"pdsghq",
|
||||
"pewcsa",
|
||||
"pflxxj",
|
||||
"pfutwa",
|
||||
"pgvoic",
|
||||
"phehbm",
|
||||
"phgmqm",
|
||||
"phhkfi",
|
||||
"phjonu",
|
||||
"phvurr",
|
||||
"piaksu",
|
||||
"pijsrg",
|
||||
"piubiw",
|
||||
"pjsmac",
|
||||
"pjxdoj",
|
||||
"pjzfgn",
|
||||
"pkmwkn",
|
||||
"pkntkb",
|
||||
"pkquey",
|
||||
"pmxlhz",
|
||||
"pnvgvr",
|
||||
"pooqwk",
|
||||
"ppslyh",
|
||||
"ppxsux",
|
||||
"prglvf",
|
||||
"probjd",
|
||||
"psmgrz",
|
||||
"psptyd",
|
||||
"psqjon",
|
||||
"pughxs",
|
||||
"puhetz",
|
||||
"pujfoc",
|
||||
"purkko",
|
||||
"puthiz",
|
||||
"pvjilh",
|
||||
"pvqrgm",
|
||||
"pvzmhz",
|
||||
"pxebwk",
|
||||
"pxizap",
|
||||
"pxyovu",
|
||||
"pymfqh",
|
||||
"pzmjbx",
|
||||
"pzucty",
|
||||
"rannhh",
|
||||
"rbnvdq",
|
||||
"rccfvy",
|
||||
"rceosh",
|
||||
"rcobok",
|
||||
"rdamey",
|
||||
"rdhndz",
|
||||
"rdpdll",
|
||||
"rdzfjv",
|
||||
"redkby",
|
||||
"reqjzm",
|
||||
"revjgd",
|
||||
"rfihyn",
|
||||
"rfzukz",
|
||||
"rgtmoz",
|
||||
"rheeoa",
|
||||
"rheyiw",
|
||||
"rilbti",
|
||||
"rilexn",
|
||||
"riotng",
|
||||
"riqiss",
|
||||
"riupfo",
|
||||
"rjglqu",
|
||||
"rjthvx",
|
||||
"rjvjwq",
|
||||
"rlporb",
|
||||
"rmazpa",
|
||||
"rmyvbb",
|
||||
"rnkxav",
|
||||
"rnvzdo",
|
||||
"ropkaf",
|
||||
"rozudg",
|
||||
"rrvdls",
|
||||
"rsdjun",
|
||||
"rudelg",
|
||||
"rugwft",
|
||||
"rupbjr",
|
||||
"rvjwiu",
|
||||
"rvqkwq",
|
||||
"rwdqcz",
|
||||
"rwjnfq",
|
||||
"rxdqqf",
|
||||
"rxnztr",
|
||||
"rxugmm",
|
||||
"rydpvf",
|
||||
"ryftuq",
|
||||
"rygikf",
|
||||
"ryvkkx",
|
||||
"rzmnrf",
|
||||
"tbehov",
|
||||
"tcaulx",
|
||||
"tcrfuz",
|
||||
"tcvaou",
|
||||
"tdfxfg",
|
||||
"tdkwue",
|
||||
"tfrbqz",
|
||||
"tgbxuq",
|
||||
"tglsyl",
|
||||
"tgorrv",
|
||||
"theruf",
|
||||
"thhvzq",
|
||||
"thncnj",
|
||||
"tiircu",
|
||||
"tjdpzj",
|
||||
"tjliry",
|
||||
"tjpwmu",
|
||||
"tjqgba",
|
||||
"tkhgfo",
|
||||
"tkxbfr",
|
||||
"tmkbao",
|
||||
"tmnhhx",
|
||||
"tnripk",
|
||||
"tnudiw",
|
||||
"tnuuwe",
|
||||
"tnvnko",
|
||||
"toqcgf",
|
||||
"tpdiyw",
|
||||
"tqeddl",
|
||||
"tqhpqp",
|
||||
"tqwach",
|
||||
"trkitt",
|
||||
"trkrrh",
|
||||
"tsdmft",
|
||||
"ttvzqd",
|
||||
"ttxeud",
|
||||
"tujsjf",
|
||||
"tvbjyi",
|
||||
"tvkqoe",
|
||||
"twrsnj",
|
||||
"txkmpg",
|
||||
"txouzs",
|
||||
"txszvu",
|
||||
"txwbbf",
|
||||
"tzqydt",
|
||||
"vaszak",
|
||||
"vaymbt",
|
||||
"vbcdot",
|
||||
"vbtmwf",
|
||||
"vcijrw",
|
||||
"vcoevo",
|
||||
"vcrvjm",
|
||||
"vcudrv",
|
||||
"vczceh",
|
||||
"vfcwwr",
|
||||
"vftxlg",
|
||||
"vfusfw",
|
||||
"vgovse",
|
||||
"vgvkok",
|
||||
"vgxdxq",
|
||||
"vhhygu",
|
||||
"vioniz",
|
||||
"vipnog",
|
||||
"vjkwgj",
|
||||
"vjmnkh",
|
||||
"vkhabg",
|
||||
"vkhiga",
|
||||
"vkybzm",
|
||||
"vlrsar",
|
||||
"vmhvfa",
|
||||
"vndxor",
|
||||
"vodekh",
|
||||
"vopucc",
|
||||
"vovivd",
|
||||
"vpnspf",
|
||||
"vpslsg",
|
||||
"vreifv",
|
||||
"vrikcc",
|
||||
"vrxpod",
|
||||
"vsbzms",
|
||||
"vslnue",
|
||||
"vsrguv",
|
||||
"vsyfym",
|
||||
"vtfund",
|
||||
"vtviqj",
|
||||
"vtzfzy",
|
||||
"vuwzmu",
|
||||
"vwkpiw",
|
||||
"vwlohb",
|
||||
"vwnjqy",
|
||||
"vwtwos",
|
||||
"vxjfnm",
|
||||
"vyewot",
|
||||
"vyhvrg",
|
||||
"vzmvvw",
|
||||
"vzniie",
|
||||
"vzrycv",
|
||||
"vztdyx",
|
||||
"xascqb",
|
||||
"xaurjv",
|
||||
"xcenyy",
|
||||
"xczuut",
|
||||
"xdvawd",
|
||||
"xdwebc",
|
||||
"xdxlsd",
|
||||
"xfdrwr",
|
||||
"xfrysj",
|
||||
"xfytns",
|
||||
"xhgnmw",
|
||||
"xhjkvj",
|
||||
"xjngae",
|
||||
"xjuzjz",
|
||||
"xkrsfl",
|
||||
"xlfmnd",
|
||||
"xltsru",
|
||||
"xmcivt",
|
||||
"xmlisq",
|
||||
"xmzztb",
|
||||
"xndixq",
|
||||
"xnhxka",
|
||||
"xnurqq",
|
||||
"xolqgf",
|
||||
"xoojpa",
|
||||
"xoulbi",
|
||||
"xoygfg",
|
||||
"xpekdp",
|
||||
"xpiqbj",
|
||||
"xrqriw",
|
||||
"xrsohj",
|
||||
"xrvzyi",
|
||||
"xsvwgh",
|
||||
"xtrrnu",
|
||||
"xtsmne",
|
||||
"xuxlra",
|
||||
"xvjcdf",
|
||||
"xvmxti",
|
||||
"xvpkiq",
|
||||
"xxuosa",
|
||||
"xymixn",
|
||||
"xzcsqr",
|
||||
"xzlzgl",
|
||||
"zaidka",
|
||||
"zbiznd",
|
||||
"zbqfmt",
|
||||
"zdfkcr",
|
||||
"zdntvf",
|
||||
"zdwmwu",
|
||||
"zehjio",
|
||||
"zelzkd",
|
||||
"zewaak",
|
||||
"zgozuh",
|
||||
"zifrtl",
|
||||
"ziqeez",
|
||||
"zldufm",
|
||||
"zlfusn",
|
||||
"zmrcwu",
|
||||
"zoyilz",
|
||||
"zqlcxg",
|
||||
"zqotda",
|
||||
"zswztj",
|
||||
"zszuqa",
|
||||
"zwkhxx",
|
||||
"zwpewj",
|
||||
"zytfqg",
|
||||
"zywows",
|
||||
"zzltaj",
|
||||
"zzpgxf",
|
||||
"zztzyk"
|
||||
]
|
||||
}
|
232
tests/hat-game.ts
Normal file
232
tests/hat-game.ts
Normal file
@ -0,0 +1,232 @@
|
||||
let correctBall: number
|
||||
let ballRevealing: boolean
|
||||
let cupSelect: string
|
||||
let index: number
|
||||
let score: number
|
||||
let level: number
|
||||
let swapSpeed: number
|
||||
|
||||
initializeGame()
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
if (ballRevealing) {
|
||||
index = index + 1
|
||||
if (index > 2) {
|
||||
index = 0
|
||||
}
|
||||
basic.showString(cupSelect[index], 150)
|
||||
}
|
||||
})
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
if (ballRevealing) {
|
||||
ballRevealing = false
|
||||
if (correctBall == index) {
|
||||
score = score + level
|
||||
images.createImage(`
|
||||
. . . . .
|
||||
. . . . #
|
||||
. . . # .
|
||||
# . # . .
|
||||
. # . . .
|
||||
`).showImage(0)
|
||||
basic.pause(1000)
|
||||
basic.showString("+".concat(level.toString()), 150)
|
||||
basic.pause(1000)
|
||||
} else {
|
||||
images.createImage(`
|
||||
# . . . #
|
||||
. # . # .
|
||||
. . # . .
|
||||
. # . # .
|
||||
# . . . #
|
||||
`).showImage(0)
|
||||
basic.pause(1000)
|
||||
basic.clearScreen()
|
||||
revealBall(correctBall)
|
||||
basic.pause(1000)
|
||||
}
|
||||
}
|
||||
level = level + 1
|
||||
if (level == 4) {
|
||||
basic.showString("FINAL SCORE:", 75)
|
||||
basic.showNumber(score, 150)
|
||||
} else {
|
||||
playLevel(level)
|
||||
}
|
||||
})
|
||||
playLevel(1)
|
||||
|
||||
function revealBall(p: number) {
|
||||
let xCoordinate = 2 * p
|
||||
for (let j = 0; j < 3; j++) {
|
||||
led.plot(j * 2, 2)
|
||||
}
|
||||
for (let i = 0; i < 3; i++) {
|
||||
led.unplot(xCoordinate, 2)
|
||||
led.plot(xCoordinate, 1)
|
||||
basic.pause(100)
|
||||
led.unplot(xCoordinate, 1)
|
||||
led.plot(xCoordinate, 0)
|
||||
basic.pause(200)
|
||||
led.unplot(xCoordinate, 0)
|
||||
led.plot(xCoordinate, 1)
|
||||
basic.pause(100)
|
||||
led.unplot(xCoordinate, 1)
|
||||
led.plot(xCoordinate, 2)
|
||||
basic.pause(75)
|
||||
}
|
||||
basic.pause(1000)
|
||||
}
|
||||
|
||||
function initializeGame() {
|
||||
ballRevealing = false
|
||||
level = 1
|
||||
score = 0
|
||||
cupSelect = "LMR"
|
||||
}
|
||||
|
||||
function swapCups(cup_1: number, cup_2: number, pauseDifficulty: number) {
|
||||
let cup_1X = 2 * cup_1
|
||||
let cup_2X = 2 * cup_2
|
||||
let cupXAverage = (cup_1X + cup_2X) / 2
|
||||
led.unplot(cup_1X, 2)
|
||||
led.unplot(cup_2X, 2)
|
||||
led.plot(cup_1X, 3)
|
||||
led.plot(cup_2X, 1)
|
||||
basic.pause(pauseDifficulty)
|
||||
led.unplot(cup_1X, 3)
|
||||
led.unplot(cup_2X, 1)
|
||||
led.plot(cup_1X, 4)
|
||||
led.plot(cup_2X, 0)
|
||||
basic.pause(pauseDifficulty)
|
||||
led.unplot(cup_1X, 4)
|
||||
led.unplot(cup_2X, 0)
|
||||
if (cupXAverage == 2) {
|
||||
led.plot((cupXAverage + cup_1X) / 2, 4)
|
||||
led.plot((cupXAverage + cup_2X) / 2, 0)
|
||||
basic.pause(pauseDifficulty)
|
||||
led.unplot((cupXAverage + cup_1X) / 2, 4)
|
||||
led.unplot((cupXAverage + cup_2X) / 2, 0)
|
||||
}
|
||||
led.plot(cupXAverage, 4)
|
||||
led.plot(cupXAverage, 0)
|
||||
basic.pause(pauseDifficulty)
|
||||
led.unplot(cupXAverage, 4)
|
||||
led.unplot(cupXAverage, 0)
|
||||
if (cupXAverage == 2) {
|
||||
led.plot((cupXAverage + cup_2X) / 2, 4)
|
||||
led.plot((cupXAverage + cup_1X) / 2, 0)
|
||||
basic.pause(pauseDifficulty)
|
||||
led.unplot((cupXAverage + cup_2X) / 2, 4)
|
||||
led.unplot((cupXAverage + cup_1X) / 2, 0)
|
||||
}
|
||||
led.plot(cup_2X, 4)
|
||||
led.plot(cup_1X, 0)
|
||||
basic.pause(pauseDifficulty)
|
||||
led.unplot(cup_2X, 4)
|
||||
led.unplot(cup_1X, 0)
|
||||
led.plot(cup_2X, 3)
|
||||
led.plot(cup_1X, 1)
|
||||
basic.pause(pauseDifficulty)
|
||||
led.unplot(cup_2X, 3)
|
||||
led.unplot(cup_1X, 1)
|
||||
led.plot(cup_2X, 2)
|
||||
led.plot(cup_1X, 2)
|
||||
basic.pause(pauseDifficulty)
|
||||
if (correctBall == cup_1) {
|
||||
correctBall = cup_2
|
||||
} else if (correctBall == cup_2) {
|
||||
correctBall = cup_1
|
||||
}
|
||||
}
|
||||
|
||||
function swapFake(cup_1: number, cup_2: number, pauseDifficulty: number) {
|
||||
let cup_1X = 2 * cup_1
|
||||
let cup_2X = 2 * cup_2
|
||||
let cupXAverage = (cup_1X + cup_2X) / 2
|
||||
led.unplot(cup_1X, 2)
|
||||
led.unplot(cup_2X, 2)
|
||||
led.plot(cup_1X, 3)
|
||||
led.plot(cup_2X, 1)
|
||||
basic.pause(pauseDifficulty)
|
||||
led.unplot(cup_1X, 3)
|
||||
led.unplot(cup_2X, 1)
|
||||
led.plot(cup_1X, 4)
|
||||
led.plot(cup_2X, 0)
|
||||
basic.pause(pauseDifficulty)
|
||||
led.unplot(cup_1X, 4)
|
||||
led.unplot(cup_2X, 0)
|
||||
if (cupXAverage == 2) {
|
||||
led.plot((cupXAverage + cup_1X) / 2, 4)
|
||||
led.plot((cupXAverage + cup_2X) / 2, 0)
|
||||
basic.pause(pauseDifficulty)
|
||||
led.unplot((cupXAverage + cup_1X) / 2, 4)
|
||||
led.unplot((cupXAverage + cup_2X) / 2, 0)
|
||||
}
|
||||
led.plot(cupXAverage, 4)
|
||||
led.plot(cupXAverage, 0)
|
||||
basic.pause(pauseDifficulty)
|
||||
led.unplot(cupXAverage, 4)
|
||||
led.unplot(cupXAverage, 0)
|
||||
if (cupXAverage == 2) {
|
||||
led.plot((cupXAverage + cup_1X) / 2, 4)
|
||||
led.plot((cupXAverage + cup_2X) / 2, 0)
|
||||
basic.pause(pauseDifficulty)
|
||||
led.unplot((cupXAverage + cup_1X) / 2, 4)
|
||||
led.unplot((cupXAverage + cup_2X) / 2, 0)
|
||||
}
|
||||
led.plot(cup_1X, 4)
|
||||
led.plot(cup_2X, 0)
|
||||
basic.pause(pauseDifficulty)
|
||||
led.unplot(cup_1X, 4)
|
||||
led.unplot(cup_2X, 0)
|
||||
led.plot(cup_1X, 3)
|
||||
led.plot(cup_2X, 1)
|
||||
basic.pause(pauseDifficulty)
|
||||
led.unplot(cup_1X, 3)
|
||||
led.unplot(cup_2X, 1)
|
||||
led.plot(cup_1X, 2)
|
||||
led.plot(cup_2X, 2)
|
||||
basic.pause(pauseDifficulty)
|
||||
}
|
||||
|
||||
function playLevel(level1: number) {
|
||||
basic.showNumber(level, 150)
|
||||
basic.pause(3000)
|
||||
basic.clearScreen()
|
||||
for (let i = 0; i < 3; i++) {
|
||||
led.plot(2 * i, 2)
|
||||
}
|
||||
basic.pause(1000)
|
||||
correctBall = Math.random(3)
|
||||
revealBall(correctBall)
|
||||
basic.pause(1000)
|
||||
let swaps = 5 + 10 * level1
|
||||
if (level1 == 1) {
|
||||
swapSpeed = 80
|
||||
} else if (level1 == 2) {
|
||||
swapSpeed = 40
|
||||
} else {
|
||||
swapSpeed = 20
|
||||
}
|
||||
for (let i1 = 0; i1 < swaps; i1++) {
|
||||
let swapType = Math.random(3)
|
||||
let not = Math.random(3)
|
||||
if (swapType < 2) {
|
||||
let swapOrientation = Math.random(2)
|
||||
if (swapOrientation == 0) {
|
||||
swapCups((not + 1) % 3, (not + 2) % 3, swapSpeed)
|
||||
} else {
|
||||
swapCups((not + 2) % 3, (not + 1) % 3, swapSpeed)
|
||||
}
|
||||
} else {
|
||||
let swapOrientation1 = Math.random(2)
|
||||
if (swapOrientation1 == 0) {
|
||||
swapFake((not + 1) % 3, (not + 2) % 3, swapSpeed)
|
||||
} else {
|
||||
swapFake((not + 2) % 3, (not + 1) % 3, swapSpeed)
|
||||
}
|
||||
}
|
||||
}
|
||||
index = -1
|
||||
ballRevealing = true
|
||||
}
|
155
tests/meteorite.ts
Normal file
155
tests/meteorite.ts
Normal file
@ -0,0 +1,155 @@
|
||||
let oneX: number
|
||||
let oneY: number
|
||||
let twoX: number
|
||||
let twoY: number
|
||||
let pause: number
|
||||
let meteoriteOneX: number
|
||||
let meteoriteOneY: number
|
||||
let meteoriteTwoX: number
|
||||
let meteoriteTwoY: number
|
||||
let counter: number
|
||||
|
||||
basic.pause(2000)
|
||||
oneX = 0
|
||||
oneY = 4
|
||||
twoX = 1
|
||||
twoY = 4
|
||||
counter = 0
|
||||
pause = 700
|
||||
led.plot(oneX, oneY)
|
||||
led.plot(twoX, twoY)
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
if (oneX > 0) {
|
||||
led.unplot(oneX, oneY)
|
||||
led.unplot(twoX, twoY)
|
||||
oneX = oneX - 1
|
||||
twoX = twoX - 1
|
||||
led.plot(oneX, oneY)
|
||||
led.plot(twoX, twoY)
|
||||
}
|
||||
})
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
if (twoX < 4) {
|
||||
led.unplot(oneX, oneY)
|
||||
led.unplot(twoX, twoY)
|
||||
oneX = oneX + 1
|
||||
twoX = twoX + 1
|
||||
led.plot(oneX, oneY)
|
||||
led.plot(twoX, twoY)
|
||||
}
|
||||
})
|
||||
meteoriteOneX = Math.random(5)
|
||||
meteoriteOneY = 0
|
||||
meteoriteTwoX = Math.random(5)
|
||||
meteoriteTwoY = -3
|
||||
basic.pause(1000)
|
||||
for (let i = 0; i < 3; i++) {
|
||||
led.plot(meteoriteTwoX, meteoriteTwoY)
|
||||
led.plot(meteoriteOneX, meteoriteOneY)
|
||||
basic.pause(pause)
|
||||
led.unplot(meteoriteTwoX, meteoriteTwoY)
|
||||
led.unplot(meteoriteOneX, meteoriteOneY)
|
||||
meteoriteOneY = meteoriteOneY + 1
|
||||
meteoriteTwoY = meteoriteTwoY + 1
|
||||
}
|
||||
basic.forever(() => {
|
||||
for (let i1 = 0; i1 < 3; i1++) {
|
||||
led.plot(meteoriteTwoX, meteoriteTwoY)
|
||||
led.plot(meteoriteOneX, meteoriteOneY)
|
||||
basic.pause(pause)
|
||||
led.unplot(meteoriteOneX, meteoriteOneY)
|
||||
led.unplot(meteoriteTwoX, meteoriteTwoY)
|
||||
meteoriteOneY = meteoriteOneY + 1
|
||||
meteoriteTwoY = meteoriteTwoY + 1
|
||||
if (meteoriteOneY == 4) {
|
||||
if (meteoriteOneX == oneX) {
|
||||
for (let j = 0; j < 10; j++) {
|
||||
led.plotAll()
|
||||
basic.pause(200)
|
||||
basic.clearScreen()
|
||||
basic.pause(200)
|
||||
}
|
||||
basic.showNumber(counter, 150)
|
||||
basic.pause(10000)
|
||||
} else if (meteoriteOneX == twoX) {
|
||||
for (let j1 = 0; j1 < 10; j1++) {
|
||||
led.plotAll()
|
||||
basic.pause(200)
|
||||
basic.clearScreen()
|
||||
basic.pause(200)
|
||||
}
|
||||
basic.showNumber(counter, 150)
|
||||
basic.pause(10000)
|
||||
}
|
||||
}
|
||||
}
|
||||
while (Math.abs(meteoriteTwoX - meteoriteOneX) < 1) {
|
||||
meteoriteOneX = Math.random(5)
|
||||
}
|
||||
meteoriteOneY = 0
|
||||
counter = counter + 1
|
||||
if (counter == 3) {
|
||||
pause = pause - 250
|
||||
} else if (counter == 8) {
|
||||
pause = pause - 100
|
||||
} else if (counter == 12) {
|
||||
pause = pause - 100
|
||||
} else if (counter == 20) {
|
||||
pause = pause - 100
|
||||
} else if (counter == 30) {
|
||||
pause = pause - 70
|
||||
}
|
||||
if (counter == 40) {
|
||||
pause = pause - 70
|
||||
}
|
||||
for (let i2 = 0; i2 < 3; i2++) {
|
||||
led.plot(meteoriteOneX, meteoriteOneY)
|
||||
led.plot(meteoriteTwoX, meteoriteTwoY)
|
||||
basic.pause(pause)
|
||||
led.unplot(meteoriteOneX, meteoriteOneY)
|
||||
led.unplot(meteoriteTwoX, meteoriteTwoY)
|
||||
meteoriteOneY = meteoriteOneY + 1
|
||||
meteoriteTwoY = meteoriteTwoY + 1
|
||||
if (meteoriteTwoY == 4) {
|
||||
if (meteoriteTwoX == oneX) {
|
||||
for (let j2 = 0; j2 < 10; j2++) {
|
||||
led.plotAll()
|
||||
basic.pause(200)
|
||||
basic.clearScreen()
|
||||
basic.pause(200)
|
||||
}
|
||||
basic.showNumber(counter, 150)
|
||||
basic.pause(10000)
|
||||
} else if (meteoriteTwoX == twoX) {
|
||||
for (let j3 = 0; j3 < 10; j3++) {
|
||||
led.plotAll()
|
||||
basic.pause(200)
|
||||
basic.clearScreen()
|
||||
basic.pause(200)
|
||||
}
|
||||
basic.showNumber(counter, 150)
|
||||
basic.pause(10000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
meteoriteTwoX = Math.random(5)
|
||||
while (Math.abs(meteoriteTwoX - meteoriteOneX) < 1) {
|
||||
meteoriteTwoX = Math.random(5)
|
||||
}
|
||||
meteoriteTwoY = 0
|
||||
counter = counter + 1
|
||||
if (counter == 3) {
|
||||
pause = pause - 250
|
||||
} else if (counter == 8) {
|
||||
pause = pause - 100
|
||||
} else if (counter == 12) {
|
||||
pause = pause - 100
|
||||
} else if (counter == 20) {
|
||||
pause = pause - 100
|
||||
} else if (counter == 30) {
|
||||
pause = pause - 70
|
||||
} else if (counter == 40) {
|
||||
pause = pause - 70
|
||||
}
|
||||
})
|
230
tests/pac-man-runaway.ts
Normal file
230
tests/pac-man-runaway.ts
Normal file
@ -0,0 +1,230 @@
|
||||
let levelTime: number
|
||||
let person: Entity
|
||||
let monsters: Entity[]
|
||||
let totalMonsters: number
|
||||
let playing: boolean
|
||||
let gameSuspended: boolean
|
||||
let busyPos: Point[]
|
||||
|
||||
class Entity {
|
||||
public x: number
|
||||
public y: number
|
||||
public dirX: number
|
||||
public dirY: number
|
||||
public hitHorizontalWall(): boolean {
|
||||
return this.y == 0 && this.dirY == -1 || this.y == 4 && this.dirY == 1
|
||||
}
|
||||
|
||||
public hitVerticalWall(): boolean {
|
||||
return this.x == 0 && this.dirX == -1 || this.x == 4 && this.dirX == 1
|
||||
}
|
||||
|
||||
public possHorizontalDir(): number {
|
||||
if (this.x == 0) {
|
||||
return 1
|
||||
} else if (this.x == 4) {
|
||||
return - 1
|
||||
} else {
|
||||
return Math.random(2) * 2 - 1
|
||||
}
|
||||
}
|
||||
|
||||
public possVerticalDir(): number {
|
||||
if (this.y == 0) {
|
||||
return 1
|
||||
} else if (this.y == 4) {
|
||||
return - 1
|
||||
} else {
|
||||
return Math.random(2) * 2 - 1
|
||||
}
|
||||
}
|
||||
|
||||
public collidesX(p2: Entity): boolean {
|
||||
return this.y == p2.y && this.y + this.dirY == p2.y + p2.dirY && (this.x + this.dirX == p2.x || this.x + this.dirX == p2.x + p2.dirX || p2.x + p2.dirX == this.x)
|
||||
}
|
||||
|
||||
public collidesY(p2: Entity): boolean {
|
||||
return this.x == p2.x && this.x + this.dirX == p2.x + p2.dirX && (this.y + this.dirY == p2.y || this.y + this.dirY == p2.y + p2.dirY || p2.y + p2.dirY == this.y)
|
||||
}
|
||||
|
||||
public move1() {
|
||||
this.x = this.x + this.dirX
|
||||
this.y = this.y + this.dirY
|
||||
}
|
||||
|
||||
public towardsX(p2: Entity): number {
|
||||
return Math.sign(p2.x - this.x)
|
||||
}
|
||||
|
||||
public towardsY(p2: Entity): number {
|
||||
return Math.sign(p2.y - this.y)
|
||||
}
|
||||
|
||||
public plot() {
|
||||
led.plot(this.x, this.y)
|
||||
}
|
||||
|
||||
public blink() {
|
||||
led.plot(this.x, this.y)
|
||||
basic.pause(125)
|
||||
led.unplot(this.x, this.y)
|
||||
basic.pause(125)
|
||||
led.plot(this.x, this.y)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Point {
|
||||
public x: number
|
||||
public y: number
|
||||
}
|
||||
|
||||
initializeState()
|
||||
redraw()
|
||||
basic.pause(1000)
|
||||
basic.forever(() => {
|
||||
levelTime = levelTime + 12
|
||||
basic.pause(12)
|
||||
if (!playing) {
|
||||
levelTime = 0
|
||||
playing = true
|
||||
}
|
||||
if (levelTime >= 5000) {
|
||||
gameSuspended = true
|
||||
game.levelUp()
|
||||
levelUp()
|
||||
levelTime = 0
|
||||
resetState()
|
||||
redraw()
|
||||
basic.pause(1000)
|
||||
gameSuspended = false
|
||||
}
|
||||
})
|
||||
basic.forever(() => {
|
||||
if (!gameSuspended) {
|
||||
logic()
|
||||
redraw()
|
||||
basic.pause(500)
|
||||
}
|
||||
})
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
let temp = Math.abs(person.dirX) * (-1)
|
||||
person.dirX = Math.abs(person.dirY) * (-1)
|
||||
person.dirY = temp
|
||||
})
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
let temp1 = Math.abs(person.dirX)
|
||||
person.dirX = Math.abs(person.dirY)
|
||||
person.dirY = temp1
|
||||
})
|
||||
|
||||
function redraw() {
|
||||
basic.clearScreen()
|
||||
person.plot()
|
||||
for (let i = 0; i < totalMonsters; i++) {
|
||||
monsters[i].blink()
|
||||
}
|
||||
}
|
||||
|
||||
function initializeState() {
|
||||
person = new Entity()
|
||||
playing = false
|
||||
busyPos = ([] as Point[])
|
||||
let busyPos1 = new Point()
|
||||
busyPos1.x = 1
|
||||
busyPos1.y = 1
|
||||
let busyPos2 = new Point()
|
||||
busyPos2.x = 1
|
||||
busyPos2.y = 3
|
||||
let busyPos3 = new Point()
|
||||
busyPos3.x = 3
|
||||
busyPos3.y = 1
|
||||
busyPos.push(busyPos1)
|
||||
busyPos.push(busyPos2)
|
||||
busyPos.push(busyPos3)
|
||||
monsters = ([] as Entity[])
|
||||
addMonster()
|
||||
resetState()
|
||||
}
|
||||
|
||||
function logic() {
|
||||
if (person.hitHorizontalWall()) {
|
||||
person.dirY = 0
|
||||
person.dirX = person.possHorizontalDir()
|
||||
}
|
||||
if (person.hitVerticalWall()) {
|
||||
person.dirX = 0
|
||||
person.dirY = person.possVerticalDir()
|
||||
}
|
||||
let lost = false
|
||||
for (let i = 0; i < totalMonsters; i++) {
|
||||
let m = monsters[i]
|
||||
m.dirX = m.towardsX(person)
|
||||
m.dirY = m.towardsY(person)
|
||||
if (m.dirX != 0 && m.dirY != 0) {
|
||||
let x = Math.random(2)
|
||||
if (x == 1) {
|
||||
m.dirX = 0
|
||||
} else {
|
||||
m.dirY = 0
|
||||
}
|
||||
}
|
||||
if (person.collidesX(m) || person.collidesY(m)) {
|
||||
lost = true
|
||||
}
|
||||
}
|
||||
if (!lost) {
|
||||
moveAll()
|
||||
} else {
|
||||
loseLife()
|
||||
}
|
||||
}
|
||||
|
||||
function loseLife() {
|
||||
moveAll()
|
||||
basic.pause(500)
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
. . # . .
|
||||
. . . . .
|
||||
. # # # .
|
||||
# . . . #
|
||||
`, 400)
|
||||
basic.pause(1000)
|
||||
basic.clearScreen()
|
||||
game.removeLife(1)
|
||||
playing = false
|
||||
resetState()
|
||||
}
|
||||
|
||||
function moveAll() {
|
||||
person.move1()
|
||||
for (let i = 0; i < totalMonsters; i++) {
|
||||
monsters[i].move1()
|
||||
}
|
||||
}
|
||||
|
||||
function addMonster() {
|
||||
let m = new Entity()
|
||||
monsters.push(m)
|
||||
totalMonsters = totalMonsters + 1
|
||||
}
|
||||
|
||||
function levelUp() {
|
||||
addMonster()
|
||||
}
|
||||
|
||||
function resetState() {
|
||||
levelTime = 0
|
||||
game.setLife(5)
|
||||
person.x = 4
|
||||
person.y = 4
|
||||
person.dirX = -1
|
||||
person.dirY = 0
|
||||
for (let i = 0; i < totalMonsters; i++) {
|
||||
let busy = busyPos[i]
|
||||
let m = monsters[i]
|
||||
m.x = (busy.x + Math.random(3)) - 1
|
||||
m.y = (busy.y + Math.random(3)) - 1
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user