Today you will write a game where the player must eat all the food which appears, while avoiding an enemy that bounces around the screen!
In this lab, you will learn to:
- Detect collisions between different sprites.
- Make sprites appear in random locations.
- Adjust the score and player lives.
You will first learn how to make sprites appear regularly at random
locations using the ||game:on game update every "x" ms||
and
||math:pick random||
.
Step 1: From the ||game:Game||
drawer, add an
||game:on game update every "500" ms||
to your project.
Step 2: Change time from 500
ms to 3000
ms in the ||game:on game update||
block.
Step 3: From the ||sprites:Sprite||
drawer, add a ||sprites:sprite of kind "Food"||
to the ||game:on game update every "3000" ms"||
block.
Step 4: Name this ||variables(sprites):sprite||
whatever you want and
select any image from the gallery you would like.
let foodSprite: Sprite = null
game.onUpdateInterval(3000, function () {
foodSprite = sprites.create(img`
. . . . . . b b b b . . . . . .
. . . . . . b 4 4 4 b . . . . .
. . . . . . b b 4 4 4 b . . . .
. . . . . b 4 b b b 4 4 b . . .
. . . . b d 5 5 5 4 b 4 4 b . .
. . . . b 3 2 3 5 5 4 e 4 4 b .
. . . b d 2 2 2 5 7 5 4 e 4 4 e
. . . b 5 3 2 3 5 5 5 5 e e e e
. . b d 7 5 5 5 3 2 3 5 5 e e e
. . b 5 5 5 5 5 2 2 2 5 5 d e e
. b 3 2 3 5 7 5 3 2 3 5 d d e 4
. b 2 2 2 5 5 5 5 5 5 d d e 4 .
b d 3 2 d 5 5 5 d d d 4 4 . . .
b 5 5 5 5 d d 4 4 4 4 . . . . .
4 d d d 4 4 4 . . . . . . . . .
4 4 4 4 . . . . . . . . . . . .
`, SpriteKind.Food)
})
Now, let's give the ||variables(sprites):foodSprite||
a random position
on the screen.
Step 1: From the ||sprites:Sprites||
drawer, add a ||sprites:set position||
block to ||game:on game update||
.
Step 2: From the ||math:Math||
drawer, add a ||math:pick random "0" to "10"||
to your project.
Step 3: Connect it to the "X" entry in your ||sprites:set position||
block.
Set the numbers to 8
and 152
.
Step 4: Add a second ||math:pick random||
block to the "Y" entry in your
||sprites:set position||
block. Set the numbers to 8
and 112
.
let foodSprite: Sprite = null
game.onUpdateInterval(3000, function () {
foodSprite = sprites.create(img`
. . . . . . b b b b . . . . . .
. . . . . . b 4 4 4 b . . . . .
. . . . . . b b 4 4 4 b . . . .
. . . . . b 4 b b b 4 4 b . . .
. . . . b d 5 5 5 4 b 4 4 b . .
. . . . b 3 2 3 5 5 4 e 4 4 b .
. . . b d 2 2 2 5 7 5 4 e 4 4 e
. . . b 5 3 2 3 5 5 5 5 e e e e
. . b d 7 5 5 5 3 2 3 5 5 e e e
. . b 5 5 5 5 5 2 2 2 5 5 d e e
. b 3 2 3 5 7 5 3 2 3 5 d d e 4
. b 2 2 2 5 5 5 5 5 5 d d e 4 .
b d 3 2 d 5 5 5 d d d 4 4 . . .
b 5 5 5 5 d d 4 4 4 4 . . . . .
4 d d d 4 4 4 . . . . . . . . .
4 4 4 4 . . . . . . . . . . . .
`, SpriteKind.Food)
// @highlight
foodSprite.setPosition(randint(8, 152), randint(8, 112))
})
From the ||sprites:Sprites||
drawer, add a ||sprites:sprite of kind "Player"||
to your ||loops:on start||
block.
Name it whatever you want and select whatever image you want. Then add blocks so the Player:
- Starts in the middle of the screen.
- Stays on the screen.
- Moves with the buttons.
let heroSprite = sprites.create(img`
. . . . . . f f f f . . . . . .
. . . . f f f 2 2 f f f . . . .
. . . f f f 2 2 2 2 f f f . . .
. . f f f e e e e e e f f f . .
. . f f e 2 2 2 2 2 2 e e f . .
. . f e 2 f f f f f f 2 e f . .
. . f f f f e e e e f f f f . .
. f f e f b f 4 4 f b f e f f .
. f e e 4 1 f d d f 1 4 e e f .
. . f e e d d d d d d e e f . .
. . . f e e 4 4 4 4 e e f . . .
. . e 4 f 2 2 2 2 2 2 f 4 e . .
. . 4 d f 2 2 2 2 2 2 f d 4 . .
. . 4 4 f 4 4 5 5 4 4 f 4 4 . .
. . . . . f f f f f f . . . . .
. . . . . f f . . f f . . . . .
`, SpriteKind.Player)
controller.moveSprite(heroSprite)
heroSprite.setStayInScreen(true)
From the ||sprites:Sprites||
drawer, add a ||sprites:sprite of kind "Enemy"||
to your ||loops:on start||
block.
Name it whatever you want and select whatever image you want. Then add blocks so the Enemy:
- Starts in a random location.
- Moves with a random velocity.
- Bounces off the edges of the screen.
let heroSprite = sprites.create(img`
. . . . . . f f f f . . . . . .
. . . . f f f 2 2 f f f . . . .
. . . f f f 2 2 2 2 f f f . . .
. . f f f e e e e e e f f f . .
. . f f e 2 2 2 2 2 2 e e f . .
. . f e 2 f f f f f f 2 e f . .
. . f f f f e e e e f f f f . .
. f f e f b f 4 4 f b f e f f .
. f e e 4 1 f d d f 1 4 e e f .
. . f e e d d d d d d e e f . .
. . . f e e 4 4 4 4 e e f . . .
. . e 4 f 2 2 2 2 2 2 f 4 e . .
. . 4 d f 2 2 2 2 2 2 f d 4 . .
. . 4 4 f 4 4 5 5 4 4 f 4 4 . .
. . . . . f f f f f f . . . . .
. . . . . f f . . f f . . . . .
`, SpriteKind.Player)
controller.moveSprite(heroSprite)
heroSprite.setStayInScreen(true)
// @highlight
let enemySprite = sprites.create(img`
........................
........................
........................
........................
..........ffff..........
........ff1111ff........
.......fb111111bf.......
.......f11111111f.......
......fd11111111df......
......fd11111111df......
......fddd1111dddf......
......fbdbfddfbdbf......
......fcdcf11fcdcf......
.......fb111111bf.......
......fffcdb1bdffff.....
....fc111cbfbfc111cf....
....f1b1b1ffff1b1b1f....
....fbfbffffffbfbfbf....
.........ffffff.........
...........fff..........
........................
........................
........................
........................
`, SpriteKind.Enemy)
// @highlight
enemySprite.setPosition(randint(8, 152), randint(8, 112))
// @highlight
enemySprite.setVelocity(randint(-100, 100), randint(-100, 100))
// @highlight
enemySprite.setBounceOnWall(true)
When two sprites are drawn so that one overlaps the other, it is called a sprites collision.
Sprites collisions are an important part of all games. Without them, nothing happens in a game.
Add an ||sprites:on sprite overlaps||
block to your game.
Step 1: Set it so it will run when a ||variables:sprite||
||sprites: of kind "Player"||
overlaps with an ||variables:otherSprite||
||sprites: of kind "Enemy"||
.
Step 2: Drag the red ||variables:otherSprite||
block from the top of the
||sprites:overlaps||
block and connect it to ||variables:mySprite||
space in the ||sprites:set position||
& ||sprites:set velocity||
block.
Step 3: The ||variables:otherSprite||
(which is the ||variables:enemySprite||
)
moves to a new ||math:random||
position with a new ||math:random||
velocity.
Add another ||sprites:on sprite overlaps||
block to your game.
Step 1: Set it so it will run when a ||variables:sprite||
||sprites:of kind "Player"||
overlaps with an ||variables:otherSprite||
||sprites:of kind "Food"||
.
Step 2: Drag the red ||variables:otherSprite||
block from the top of the
||sprites:overlaps||
block and connect it to ||variables:mySprite||
space in the ||sprites:destroy||
block.
The ||variables:otherSprite||
(which is the ||variables:foodSprite||
)
will be destroyed when the Player collides with it.
So far, your game has a player, an enemy, and some food to eat.
Now let's add some scoring and lives.
Let's make the player lose a life when they collide with the enemy.
From the ||info:Info||
drawer, find the ||info:change life by "-1"||
block and add it to the appropriate ||sprites:on overlaps||
block.
sprites.onOverlap(SpriteKind.Player, SpriteKind.Enemy, function (sprite, otherSprite) {
otherSprite.setPosition(randint(8, 152), randint(8, 112))
otherSprite.setVelocity(randint(-100, 100), randint(-100, 100))
// @highlight
info.changeLifeBy(-1)
})
Now, let's increase the score when the player collides with some food.
From the ||info:Info||
drawer, find the ||info:change score by "1"||
block and add it to the appropriate ||sprites:on overlaps||
block.
sprites.onOverlap(SpriteKind.Player, SpriteKind.Food, function (sprite, otherSprite) {
sprites.destroy(otherSprite)
// @highlight
info.changeScoreBy(1)
Here are some things you can add to your game which can make it more interesting and personal.
- Make both the Player and Enemy relocate when they collide.
- Have the Player lose points if the Enemy collides with Food.
- Play a sound when the Enemy and Player collide, and when the Player and Food collide.
- Design your own sprites.
- Add a background
What else can you think of?
music.play(music.stringPlayable("- - - - - - - - ", 120), music.PlaybackMode.UntilDone)
music.play(music.createSong(hex`00780004080200`), music.PlaybackMode.UntilDone)
music.play(music.melodyPlayable(music.baDing), music.PlaybackMode.UntilDone)
music.play(music.createSoundEffect(WaveShape.Sine, 5000, 0, 255, 0, 500, SoundExpressionEffect.None, InterpolationCurve.Linear), music.PlaybackMode.UntilDone)
music.stopAllSounds()