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:
- Continuous firing
- 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:
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
(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.
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
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
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
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
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).
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)