DEV Community

Sebastian Nozzi
Sebastian Nozzi

Posted on

Movement-events on Mini Micro (part 1)

In this post I want to share with you different ways to check for (sprite) "movement" events in Mini Micro.

This is partly inspired by Joe's comment at my "Coin Collector" tutorial. He suggested to use the key.axis function instead of checking for concrete key-codes (like for the arrow keys).

First, I want to categorize the firing of "movement events" into two main types:

  1. Continuous firing
  2. Discrete firing

(I came up with these names, apologies if there are more known or accepted names out there).

"Discrete firing" is when only one movement event is fired when the user presses an arrow key. This will be discussed in a future post. For this post, let's focus on "continuous firing" ...

Continuous firing

In "continuous firing" the player's object keeps moving in one direction as long as the corresponding arrow-key (or joystick axis) is being pushed.

The movement only stops when the key is released (or the joystick returns to neutral position).

An example of one of my projects that I could bring up is the spaceship from my "Letter Shooter" game. It moves with the arrow keys, and keeps moving when a key is being held down.

A reduced / simplified form would look like this:

Spaceship moving

So, does one code continuous-firing of movement events in Mini Micro?

Arrow-keys

A first version, checking for arrow keys, could look like this:

clear

while true
    if key.pressed("up") then print "^", ""
    if key.pressed("down") then print "V", ""
    if key.pressed("left") then print "<", ""
    if key.pressed("right") then print ">", ""
    wait 0.01
end while
Enter fullscreen mode Exit fullscreen mode

(By the way, if you ever need to know the "names" of the keys available for the key.pressed function, try pprint key.keyNames on the console).

Try it! When run, the code will print the corresponding "direction" characters as long as an arrow-key is pressed.

Characters showing arrow-key-presses

A short delay was introduced so that the screen is not filled-up too quickly with characters, making it difficult to see what's going on. Experiment with different values, replacing it with yield or removing it entirely.

Enter the Spaceship

Let's make the above example more interesting by actually adding the "spaceship" and moving it on the screen:

clear

// Display 4 is our default sprite-display
sprDisp = display(4)

s = new Sprite
s.image = file.loadImage("/sys/pics/Fighter.png")
// Place on the center of the screen
s.x = 960 / 2
s.y = 640 / 2
// Make it face up, and smaller
s.rotation = 90
s.scale = 0.5

sprDisp.sprites.push s

// Velocity. Spaceship will move this amount of pixels
// for each "key-down" event.
v = 5

while true
    if key.pressed("up") then s.y += v
    if key.pressed("down") then s.y -= v
    if key.pressed("left") then s.x -= v
    if key.pressed("right") then s.x += v
    wait 0.01
end while
Enter fullscreen mode Exit fullscreen mode

Now this works, but "only" supports arrow-keys. Personally, this is what I do in most of my projects. But one could generalize this by using the key.axis function (thanks Joe Strout for pointing this out). This would support both arrow-keys and gamepads / joysticks with one codebase.

Using key.axis

The key.axis function returns values between -1 and 1 (and typically 0) depending on the state of one of its "axis" (which can be "Horizontal" or "Vertical"). As mentioned, it reacts both to arrow keys and gamepads / joysticks.

A re-worked while-loop with key.axis would look like this:

while true
    if key.axis("Vertical") > 0 then s.y += v
    if key.axis("Vertical") < 0 then s.y -= v
    if key.axis("Horizontal") < 0 then s.x -= v
    if key.axis("Horizontal") > 0 then s.x += v
    wait 0.01
end while
Enter fullscreen mode Exit fullscreen mode

Factor to velocity

While trying things out for this post there is something I noticed. When exploring the returned values of key.axis, it does not just return -1 or 1. Even when using arrow keys. It also returns values in-between when the firing is "starting" to take place. As if "warming up". This nicely simulates a gamepad / joystick slowing leaving the neutral position while reaching one of the extremes of a direction (going all the way "left" or "up").

This code snippet showcases this fact:

clear

while true
    vAxis = key.axis("Vertical")
    hAxis = key.axis("Horizontal")
        // Only print if any of the values is not 0
    if vAxis or hAxis then 
        print "V:" + vAxis + " - H:" + hAxis
    end if
    wait 0.02
end while
Enter fullscreen mode Exit fullscreen mode

Armed with this information, one could further adapt the spaceship-movement example to use the axis-values as "factors" (in a multiplication) to the velocity. And while we are at it, let's replace our wait with a yield.

Our while-loop would look like this:

while true
    vAxis = key.axis("Vertical")
    hAxis = key.axis("Horizontal")
    s.x += hAxis * v
    s.y += vAxis * v
    yield
end while
Enter fullscreen mode Exit fullscreen mode

Notice how we don't need "ifs" anymore. Just take the current values, multiply and add to the current position (of course multiplying by 0 results in 0, and adding 0 to current coordinates does nothing).

Spaceship moving

The change in movement is subtle. You should notice the space-ship slowly starting to move in one direction and the acquiring constant speed. Nice.

Conclusion

This post showed how to detect movement-firing events "continuously" and also how to apply that information to moving a sprite.

In a further post we will talk about "discrete" movement-events and see some applications.

Have fun with Mini Micro!

Top comments (0)