[EXTENSION] arcade-sprite-basics

It’s been a while since I’ve last posted but I’m back now with a new extension.

I’ve made this extension to help handle things like movement, handling whether the sprite is or isn’t allowed to move, determining whether it can or can’t go through walls, and determining proximity between sprites in a vertical, horizontal, or circular range.

3 Likes

Most of everything else can be done with the base blocks

But this?

This is cool

3 Likes

I have to admit that everything in this extension is entirely possible with base blocks.
this extension is meant for new makecode users or people like me who are too lazy to write out all the code for these functions.

1 Like

I’m making a new block to show the proximity boundary around a sprite, but I’m not sure how to draw the circle or beam around the sprite. I basically want something like this:
if you have a horizontal line of sight:


If circular line of sight:

1 Like

@EugeneRedwing8 you’ll want to create a renderable so you can draw the screen, then use the fillRect or fillCircle functions to draw the actual ui.

for example:

function showLineOfSight(sprite: Sprite, isCircle: boolean, radius: number, color: number) {
    // scene.createRenderable() creates a fake "sprite" that takes a function
    // which lets you draw whatever you want to the screen. the first argument
    // is the z index of the sprite; we're going to pass in a value that is 
    // slightly lower than the sprite's z so that this UI always draws below
    // the actual sprite
    let renderable = scene.createRenderable(sprite.z - 0.01, (target, camera) => {
        // first check to see if the sprite was destroyed
        if (sprite.flags & sprites.Flag.Destroyed) {
            renderable.destroy();
            return;
        }

        // check if this sprite is invisible
        if (sprite.flags & SpriteFlag.Invisible) {
            return;
        }

        // then make sure that we update the z if the sprite changed its z value.
        // ideally this should be updated inside of an onGameUpdate or something
        // because doing it inside of this function will cause the renderable to
        // be drawn in the wrong z for one frame whenever the sprite's z changes
        renderable.z = sprite.z - 0.01;
        
        let offsetX = 0;
        let offsetY = 0;

        // if this sprite isn't a RelativeToCamera sprite, then we need to take
        // the camera position into account when drawing. these numbers need to
        // be subtracted from the x/y values when drawing
        if (!(sprite.flags & SpriteFlag.RelativeToCamera)) {
            offsetX = camera.drawOffsetX;
            offsetY = camera.drawOffsetY;
        }

        // finally, draw the actual ui
        if (isCircle) {
            target.fillCircle(
                sprite.x - offsetX,
                sprite.y - offsetY,
                radius,
                color
            );
        }
        else {
            target.fillRect(
                sprite.x - offsetX,
                sprite.y - offsetY,
                radius,
                1,
                color
            );
        }
    })
}

2 Likes

Umm… I’m not sure I did this correctly. As soon as I put in the code to create a sight rectangle the sprite disappears.

Here is the code for my block, did I do something wrong here?
//% group=“proximity”
//% block=“show area of sight from $sprite=variables_get(mysprite) is circular $isCircle radius $radius color $color”
//% pixels.defl=60
//% color.shadow=colorindexpicker

function show_sight(sprite: Sprite, isCircle: Boolean, radius: number, color: number){
    let renderable = scene.createRenderable(sprite.z - 0.01, (target, camera) => {
            if(sprite.flags & sprites.Flag.Destroyed) {
                renderable.destroy();
                return;
            }
            
            if(sprite.flags & SpriteFlag.Invisible) {
                return;
            }

            game.onUpdate(function(){
                renderable.z = sprite.z - 0.01

                let offsetX = 0;
                let offsetY = 0;

                if(!(sprite.flags & SpriteFlag.RelativeToCamera)) {
                    offsetX = camera.drawOffsetX;
                    offsetY = camera.drawOffsetY;
                }

                if(isCircle) {
                    target.fillCircle(
                        sprite.x - offsetX,
                        sprite.y - offsetY,
                        radius,
                        color
                    );
                }
                else {
                    target.fillRect(
                        sprite.x - offsetX,
                        sprite.y - offsetY,
                        radius,
                        1,
                        color
                    );
                }
            })
        })      
    }
1 Like

ah, don’t use the onGameUpdate inside the createRenderable like that.

the function passed in to createRenderable is called every frame, so this is going to register another onGameUpdate every frame. what you’re seeing is the game freezing because of how many of those are being registered in a short time!

you can ignore my comment about the onGameUpdate; it’s just a change to take care of a potential bug. it only matters if the sprite is changing its z-index value.

one change you might have to make to my code, however, is to change this:

let renderable = scene.createRenderable(...

to this:

let renderable: scene.Renderable;
renderable = scene.createRenderable(...

this is to work around a bug in our compiler. sorry, i didn’t actually try to run the sample code before sending it to you the first time

2 Likes

Thank you, this completely fixed the problem!
I do have one more question though, the boolean true/false block isn’t showing up in the main block. Is there a way to fix this?

1 Like

@EugeneRedwing8 yup, just change Boolean to boolean in your function definition.

for historic reasons, JavaScript has capitalized versions of all the primitive types (e.g. Number, String, Boolean), but you should never use them! always use the lowercase version

1 Like

@richard All this has been really helpful! thanks for your help!

1 Like

The new line of sight block is now finished!
it creates either a circular or rectangular “line of sight” from a specific sprite in a certain direction (up, down, left, right).