Microsoft MakeCode

Arrays of classes and seemingly redundant stuff?

Whilst getting to grips with Makecode, Typescript etc over the last few weeks, I pored over a lot of things. One thing that puzzles me is the way in which the “games.ts” Game extension to Microbit Makecode is written. The relevant code is summarised below, and my query about it follows:

namespace game {
    let _sprites: LedSprite[];
    ....blah blah...
    export function createSprite(x: number, y: number): LedSprite {
        init();
        let p = new LedSprite(x, y);
        return p;
    }
    export class LedSprite {
       constructor(x: number, y: number) {
            ...blah blah....
            init();
            _sprites.push(this);
            plot();
        }
        various class methods etc....
    }  // end class definition
    function init(): void {
        ...blah blah...
        _sprites = (<LedSprite[]>[]);
    }
}

The _sprites variable, an array of sprite objects, is defined within the namespace. The LedSprite is a class and its constructor calls init() which contains the line _sprites = (<LedSprite[]>[]) which puzzles me to start with. More to the point, though, I don’t understand why the sprites need to be pushed to the internal array _sprites at all.

I’ve written a game from scratch with a class within a namespace, a worm a certain number of pixels long which runs around my 17x7 LED display. In my game code I create the worm objects in the same way objects are created using the LedSprite objects from the game extension, thus:

let MyWorms: worms.Worm[] = []
MyWorms[0] = worms.createWorm(4, 0, 4, 0)
MyWorms[1] = worms.createWorm(6, 6, 4, 2)
// I suppose I should use push for the sake of tidiness, but the above works

But I do not push them to an array equivalent to the _sprites within the worms namespace. And it works fine without that. So why is the done in the Game extension? What is its benefit and purpose of the _sprites array?

It’s worth noting this library is VERY old; if you look at git blame you’ll see almost all of it was written 3 or 4 years ago besides a few bug fixes, which is around when makecode was first getting started (way before I started working on it :slight_smile: ). A lot of the code might be kludgy to work around features that didn’t exist yet / bugs that were blocking things.

the line you mentioned in init is definitely a bit overwritten; it’s just casting the array as the type of array it’s defined to be. This may have been to avoid a bug at the time (?), or maybe was just from a bit of a mish mash as everyone started working together / potentially learning typescript from other languages / etc. Anyways, yes, the proper way to write that now would just be _sprites = [].

If you could share a link to your game it would be helpful to compare and contrast, but I’d say it’s worth noting that you’re keeping an array of your worms too; the reason behind that is likely because you want to be able to do things with multiple times. the _sprites array is only used (for something beyond keeping itself up to date) when updating the screen; if you look in the plot function at the bottom of the file, you’ll see that each time plot is called, it resets the screen, and then tells each sprite to ‘plot itself’ using that array.

If it didn’t keep track of the sprites internally, you would have to update the state based off of the sprite movements, which could lead to invalid views; if you have two sprites on top of eachother, and one of them moves, the only info you’d have would be that you’re moving one sprite from one position to another; you would turn off the led at the origin and turn it on at the new position, and now everything’s broken because the other sprite you had is invisible. I would also suspect that the game lib was written with some sort of extensibility in mind; if you ever wanted to add velocities to sprites, it’s much simpler to manage when you already keep track of them.

Thank you very much. For some reason I thought I had searched games.ts and not seen any further reference to _sprites but I can see it’s necessary for the plot() function.

At some point I’ll upload the worms game to Github - useful for anyone using a Pimoroni 17x7 scrollbit LED matrix with Microbit.

The typescript code was originally machine translated from the TouchDevelop code; the translator introduced spurious parenthesis.

1 Like