아케이드 티딩 가이드 목록으로
🚀 직접 따라해보기

클로버 모으기

💡 참고: 이 가이드는 메이크코드 아케이드 튜토리얼 Collect the Clovers를 바탕으로 제작되었습니다.

🎯 학습 목표:

  • 게임 루프(Update Interval)를 사용하여 주기적으로 이벤트를 발생시킵니다.
  • 발사체(Projectile)를 생성하고 랜덤(Random) 속도를 적용합니다.
  • 스프라이트의 종류(Kind)를 변경하여 아군(아이템)과 적을 구분합니다.
  • 충돌 이벤트(Overlap)를 통해 점수 획득과 게임 오버 규칙을 만듭니다.
1

배경 설정 및 영웅 만들기

게임을 시작하기 위해 아름다운 정원 배경과 주인공(토끼)을 만들어 봅시다.

  1. ||scene:장면|| 카테고리에서 ||scene:배경 이미지 설정|| 블록을 가져와 배경을 그립니다.
  2. ||sprites:스프라이트|| 카테고리에서 ||variables(sprites):[hero]를 스프라이트 설정...|| 블록을 가져옵니다.
  3. ||controller:컨트롤러||||controller:[hero]를 버튼으로 이동|| 블록을 연결하여 캐릭터를 움직이게 합니다.
  4. 캐릭터가 화면 밖으로 나가지 않도록 ||sprites:[hero]를 화면에 머무르기||<켬>으로 설정하세요.
Game Intro
scene.setBackgroundImage(sprites.background.forest2)
// @highlight
let hero = sprites.create(img`
    1 1 . . . . . . . . . . . . . .
    1 1 1 . . . . . . . . . 1 1 . .
    1 1 3 1 . . . . . . . 1 1 1 1 .
    . 1 3 3 1 . . . . . 1 3 1 1 1 .
    . 1 1 3 3 . . . . 1 3 3 1 1 1 .
    . . 1 1 3 1 . . . 3 3 1 d . . .
    . . . 1 1 1 1 1 1 1 1 d . . . .
    . . . 1 1 d d 1 d d 1 . . . . .
    . . . . 1 d f 1 f d 1 . . . . .
    . . . 1 1 1 1 3 1 1 1 1 . . . .
    . . . 1 1 1 b 1 b 1 1 1 . . . .
    . . . . 1 1 1 1 1 1 1 . . . . .
    . . . . b d d d d d b . . . . .
    . . 1 d 7 f f 7 7 f f f 7 1 . .
    . . 1 7 7 c 7 7 7 f c 7 7 1 . .
    . 1 d e e e e e e e e e e d 1 .
    . 1 1 1 e e e e e e e e 1 1 1 .
    . 1 1 b e e e e e e e e b 1 1 .
    1 1 1 b d d d d d d d d b 1 1 1
`, SpriteKind.Player)
controller.moveSprite(hero)
hero.setStayInScreen(true)
2

행운의 클로버 생성하기

일정한 시간마다 화면에 클로버가 나타나도록 만들어 봅시다.


||game:게임|| 카테고리에서 ||game:게임 업데이트시 [500] ms 마다|| 블록을 가져와 시간을 5000ms(5초)로 변경합니다.

► 그 안에 ||sprites:[clover]를 발사체로 설정...|| 블록을 넣습니다. (변수 이름을 clover로 바꿔주세요!)

► 클로버가 매번 다른 방향으로 날아가도록, vxvy 값에 ||math:계산|| 카테고리의 ||math:[0]부터 [10]까지의 정수 랜덤값|| 블록을 넣습니다.

💡 팁: 랜덤값 범위를 -50 에서 50 정도로 설정하면 다양한 방향으로 움직입니다.
game.onUpdateInterval(5000, function () {
    // @highlight
    let clover = sprites.createProjectileFromSide(img`
        . . . b b b . . . b b . . . . .
        . . b 5 7 b . . b 5 b b . . . .
        . b b 7 7 b . . b 7 7 b b . . .
        b b 7 7 7 b b b b 7 7 7 7 b . .
        b 7 6 6 7 7 b b 7 7 6 6 7 b . .
        . b b b 6 7 7 7 7 6 b b b . . .
        . . . . b b 7 7 b b . . . . . .
        b b b b 7 7 7 7 7 7 b b b b . .
        b 5 7 7 7 6 b b 6 7 7 7 5 b . .
        b 7 7 7 6 b b 6 b 6 7 7 7 b . .
        b b 7 7 b . b 6 b b 6 7 b b . .
        . b b 6 b . b 6 . b b 6 b . . .
        . . b b . . b b 6 . b b . . . .
        . . . . . . . b 7 6 . . . . . .
        . . . . . . . b b b . . . . . .
        . . . . . . . . . . . . . . . .
    `, randint(-50, 50), randint(-50, 50))
})
3

방해꾼 '벌' 등장시키기

클로버와 함께 피해야 할 '벌'도 나타나게 해볼까요?


► 방금 만든 게임 업데이트 블록 안에 또 다른 발사체 생성 블록을 추가합니다.

► 변수 이름을 ||variables(noclick):[bee]||로 설정하고 벌을 그립니다. 속도는 마찬가지로 랜덤하게 설정하세요.

가장 중요한 단계입니다! 벌은 우리를 공격해야 하므로, ||sprites:[bee]의 종류를 [Player]로 설정|| 블록을 추가하고 종류를 Enemy(적)로 변경합니다.

game.onUpdateInterval(5000, function () {
    let clover = sprites.createProjectileFromSide(img`
        . . . b b b . . . b b . . . . .
        . . b 5 7 b . . b 5 b b . . . .
        . b b 7 7 b . . b 7 7 b b . . .
        b b 7 7 7 b b b b 7 7 7 7 b . .
        b 7 6 6 7 7 b b 7 7 6 6 7 b . .
        . b b b 6 7 7 7 7 6 b b b . . .
        . . . . b b 7 7 b b . . . . . .
        b b b b 7 7 7 7 7 7 b b b b . .
        b 5 7 7 7 6 b b 6 7 7 7 5 b . .
        b 7 7 7 6 b b 6 b 6 7 7 7 b . .
        b b 7 7 b . b 6 b b 6 7 b b . .
        . b b 6 b . b 6 . b b 6 b . . .
        . . b b . . b b 6 . b b . . . .
        . . . . . . . b 7 6 . . . . . .
        . . . . . . . b b b . . . . . .
        . . . . . . . . . . . . . . . .
    `, randint(-50, 50), randint(-50, 50))
    // @highlight
    let bee = sprites.createProjectileFromSide(img`
        . . . . 1 9 1 9 1 1 9 1 9 . . .
        . . . . 1 . 9 . 9 . 9 . 9 . . .
        . . . . . 9 . 1 . 9 . 1 9 . . .
        . . . . . . 9 9 9 9 9 9 . . . .
        . . f f . . 5 5 f 5 4 f . . . .
        . f f f f 4 5 f 5 5 f 5 4 . . .
        f d f f f 5 5 f 5 5 f 5 5 f . .
        f f f f f 5 5 f 5 5 f 5 5 f f f
        f d f f f 5 5 f 5 5 f 5 5 f . .
        . f f f f 4 5 f 5 5 f 5 4 . . .
        . . f f . . 5 5 f 5 4 f . . . .
        . . . . . . 9 9 9 9 9 9 . . . .
        . . . . . 9 . 1 . 9 . 1 9 . . .
        . . . . 1 . 9 . 9 . 9 . 9 . . .
        . . . . 1 9 1 9 1 1 9 1 9 . . .
        . . . . . . . . . . . . . . . .
    `, randint(-50, 50), randint(-50, 50))
    // @highlight
    bee.setKind(SpriteKind.Enemy)
})
4

클로버 수집하기 (점수 획득)

이제 플레이어가 클로버에 닿았을 때 점수를 얻도록 해봅시다.

  1. ||sprites:스프라이트||에서 ||sprites:... [sprite]가 ... [otherSprite]와 닿았을 때|| 블록을 가져옵니다.
  2. 종류를 PlayerProjectile(클로버)로 설정합니다.
  3. 닿은 클로버(otherSprite)를 파괴(destroy)하고 점수를 1점 올립니다.
  4. 효과(Effect)와 소리(Sound)를 추가하면 더 재미있겠죠?
⚠️ 주의: 반드시 헤더에 있는 ||variables(noclick):otherSprite|| 블록을 드래그해서 파괴 블록에 넣어야 닿은 그 클로버가 사라집니다.
sprites.onOverlap(SpriteKind.Player, SpriteKind.Projectile, function (sprite, otherSprite) {
    // @highlight
    otherSprite.destroy(effects.confetti, 100)
    // @highlight
    music.baDing.play()
    // @highlight
    info.changeScoreBy(1)
})
5

벌에 쏘이다! (게임 오버 규칙)

마지막으로 벌에 닿았을 때의 규칙을 만듭니다.


닿았을 때 블록을 하나 더 추가하거나 복사합니다.

► 이번에는 두 번째 종류를 Enemy(벌)로 설정해야 합니다.

► 벌에 닿으면 ||info:생명(Life)||-1만큼 변경하여 생명을 깎습니다.

► 벌이 사라지는 효과와 소리도 클로버와 다르게(예: disintegrate, pewPew) 설정해 보세요.

Overlap Enemy
sprites.onOverlap(SpriteKind.Player, SpriteKind.Enemy, function (sprite, otherSprite) {
    // @highlight
    otherSprite.destroy(effects.disintegrate, 100)
    // @highlight
    music.pewPew.play()
    // @highlight
    info.changeLifeBy(-1)
})
🎉

완성!

축하합니다! 나만의 클로버 모으기 게임이 완성되었습니다.

전체 화면으로 플레이하며 점수를 얼마나 낼 수 있는지 확인해 보세요.

아래는 완성된 전체 블록 코드입니다.

Final Game
sprites.onOverlap(SpriteKind.Player, SpriteKind.Projectile, function (sprite, otherSprite) {
    otherSprite.destroy(effects.confetti, 100)
    music.baDing.play()
    info.changeScoreBy(1)
})
sprites.onOverlap(SpriteKind.Player, SpriteKind.Enemy, function (sprite, otherSprite) {
    otherSprite.destroy(effects.disintegrate, 100)
    music.pewPew.play()
    info.changeLifeBy(-1)
})
scene.setBackgroundImage(sprites.background.forest2)
let hero = sprites.create(img`
    1 1 . . . . . . . . . . . . . .
    1 1 1 . . . . . . . . . 1 1 . .
    1 1 3 1 . . . . . . . 1 1 1 1 .
    . 1 3 3 1 . . . . . 1 3 1 1 1 .
    . 1 1 3 3 . . . . 1 3 3 1 1 1 .
    . . 1 1 3 1 . . . 3 3 1 d . . .
    . . . 1 1 1 1 1 1 1 1 d . . . .
    . . . 1 1 d d 1 d d 1 . . . . .
    . . . . 1 d f 1 f d 1 . . . . .
    . . . 1 1 1 1 3 1 1 1 1 . . . .
    . . . 1 1 1 b 1 b 1 1 1 . . . .
    . . . . 1 1 1 1 1 1 1 . . . . .
    . . . . b d d d d d b . . . . .
    . . 1 d 7 f f 7 7 f f f 7 1 . .
    . . 1 7 7 c 7 7 7 f c 7 7 1 . .
    . 1 d e e e e e e e e e e d 1 .
    . 1 1 1 e e e e e e e e 1 1 1 .
    . 1 1 b e e e e e e e e b 1 1 .
    1 1 1 b d d d d d d d d b 1 1 1
`, SpriteKind.Player)
controller.moveSprite(hero)
hero.setStayInScreen(true)
game.onUpdateInterval(5000, function () {
    let clover = sprites.createProjectileFromSide(img`
        . . . b b b . . . b b . . . . .
        . . b 5 7 b . . b 5 b b . . . .
        . b b 7 7 b . . b 7 7 b b . . .
        b b 7 7 7 b b b b 7 7 7 7 b . .
        b 7 6 6 7 7 b b 7 7 6 6 7 b . .
        . b b b 6 7 7 7 7 6 b b b . . .
        . . . . b b 7 7 b b . . . . . .
        b b b b 7 7 7 7 7 7 b b b b . .
        b 5 7 7 7 6 b b 6 7 7 7 5 b . .
        b 7 7 7 6 b b 6 b 6 7 7 7 b . .
        b b 7 7 b . b 6 b b 6 7 b b . .
        . b b 6 b . b 6 . b b 6 b . . .
        . . b b . . b b 6 . b b . . . .
        . . . . . . . b 7 6 . . . . . .
        . . . . . . . b b b . . . . . .
        . . . . . . . . . . . . . . . .
    `, randint(-50, 50), randint(-50, 50))
    let bee = sprites.createProjectileFromSide(img`
        . . . . 1 9 1 9 1 1 9 1 9 . . .
        . . . . 1 . 9 . 9 . 9 . 9 . . .
        . . . . . 9 . 1 . 9 . 1 9 . . .
        . . . . . . 9 9 9 9 9 9 . . . .
        . . f f . . 5 5 f 5 4 f . . . .
        . f f f f 4 5 f 5 5 f 5 4 . . .
        f d f f f 5 5 f 5 5 f 5 5 f . .
        f f f f f 5 5 f 5 5 f 5 5 f f f
        f d f f f 5 5 f 5 5 f 5 5 f . .
        . f f f f 4 5 f 5 5 f 5 4 . . .
        . . f f . . 5 5 f 5 4 f . . . .
        . . . . . . 9 9 9 9 9 9 . . . .
        . . . . . 9 . 1 . 9 . 1 9 . . .
        . . . . 1 . 9 . 9 . 9 . 9 . . .
        . . . . 1 9 1 9 1 1 9 1 9 . . .
        . . . . . . . . . . . . . . . .
    `, randint(-50, 50), randint(-50, 50))
    bee.setKind(SpriteKind.Enemy)
})