프리 드로우
🎯 학습 목표:
- 배경(Background)을 설정하여 농구 코트를 만듭니다.
- 스프라이트(Sprite)를 생성하고 속도와 위치를 설정합니다.
- 발사체(Projectile)를 이용하여 공을 던지는 기능을 구현합니다.
- 겹침(Overlap) 이벤트를 통해 골인 여부를 판단하고 점수를 얻습니다.
농구 코트 준비하기
게임을 시작하기 위해 농구 코트 배경을 깔아봅시다.
||scene:장면||카테고리에서||scene:배경 이미지 설정||블록을 가져와||loops:시작하면||안에 넣습니다.- 회색 상자를 클릭하여 농구 코트를 그리거나 갤러리에서 선택하세요.
// @highlight
scene.setBackgroundImage(img`.`)
선수 입장 (Athlete)
공을 던질 선수를 만들어 위치를 잡아줍니다.
► ||sprites:스프라이트||에서 ||variables(sprites):[athlete]를 스프라이트 설정|| 블록을 가져옵니다. (변수 이름을 athlete로 바꿔주세요)
► 선수가 코트 위를 움직이도록 ||sprites:[athlete] 위치 설정|| (x: 80, y: 90)과 ||sprites:[athlete] 속도 설정|| (vx: 50, vy: 0)을 추가합니다.
► ||sprites:[athlete] 벽에 닿으면 튕기기||를 <켬>으로 설정하여 화면 밖으로 나가지 않게 하세요.
scene.setBackgroundImage(img`.`)
// @highlight
let athlete = sprites.create(img`
. . f f . . . . . . . .
. f f f f . . . . . . .
. f f f f f f . . . . .
. f 6 6 6 6 6 6 . . . .
. . f f a a a a . . . .
. . f f a f a f . . . .
. . f a a a a a . . . .
. . . a a a a a . . . .
. . . . a a a . . . . .
. a a 1 a a 1 a 4 4 4 a
. a a 1 6 6 1 4 f 4 f 4
. a a a 6 6 6 a a f 4 4
. a a a 6 6 a a a 4 f 4
. . a a a a a 6 4 4 4 .
. . 6 a a a 6 6 . . . .
. . 1 1 1 1 1 1 . . . .
. . 6 6 6 8 6 6 . . . .
. . 6 6 6 8 6 6 . . . .
. . 6 6 6 8 6 6 . . . .
. . a a . . a a . . . .
. . a a . . a a . . . .
. . 6 1 . . 6 1 . . . .
. . 1 1 1 . 1 1 1 . . .
. . . . . . . . . . . .
`, SpriteKind.Player)
// @highlight
athlete.setPosition(80, 90)
// @highlight
athlete.setVelocity(50, 0)
// @highlight
athlete.setBounceOnWall(true)
골대 설치 (Hoop)
공을 넣을 골대를 만들어 봅시다.
► ||sprites:스프라이트|| 생성 블록을 하나 더 추가하고 변수 이름을 hoop으로 변경합니다.
► 중요: 종류(Kind)를 Enemy로 설정해야 합니다. (Goal과 같은 새로운 종류를 만들어도 됩니다.
► 골대의 위치를 x: 80, y: 35로 설정하여 화면 상단에 배치합니다.
let athlete = sprites.create(img`
. . f f . . . . . . . .
. f f f f . . . . . . .
. f f f f f f . . . . .
. f 6 6 6 6 6 6 . . . .
. . f f a a a a . . . .
. . f f a f a f . . . .
. . f a a a a a . . . .
. . . a a a a a . . . .
. . . . a a a . . . . .
. a a 1 a a 1 a 4 4 4 a
. a a 1 6 6 1 4 f 4 f 4
. a a a 6 6 6 a a f 4 4
. a a a 6 6 a a a 4 f 4
. . a a a a a 6 4 4 4 .
. . 6 a a a 6 6 . . . .
. . 1 1 1 1 1 1 . . . .
. . 6 6 6 8 6 6 . . . .
. . 6 6 6 8 6 6 . . . .
. . 6 6 6 8 6 6 . . . .
. . a a . . a a . . . .
. . a a . . a a . . . .
. . 6 1 . . 6 1 . . . .
. . 1 1 1 . 1 1 1 . . .
. . . . . . . . . . . .
`, SpriteKind.Player)
athlete.setPosition(80, 90)
athlete.setVelocity(50, 0)
athlete.setBounceOnWall(true)
// @highlight
let hoop = sprites.create(img`
. . 3 3 4 4 4 4 4 4 4 3 3 . . .
. 3 4 4 1 1 . . . 1 1 4 4 3 . .
3 4 4 . 1 . 1 . 1 . 1 . 4 4 3 .
3 4 1 . 1 . . 1 . . 1 . 1 4 3 .
4 3 4 1 1 . 1 . 1 . 1 1 4 3 4 .
1 4 3 3 1 1 . . . 1 1 3 3 4 1 .
1 1 4 4 3 3 3 3 3 3 3 4 4 1 1 .
1 . 1 . 4 4 4 4 4 4 4 . 1 . 1 .
1 . . 1 1 . 1 . 1 . 1 1 . . 1 .
1 . 1 . 1 1 . . . 1 1 . 1 . 1 .
1 1 . . 1 . 1 . 1 . 1 . . 1 1 .
1 . 1 . 1 . . 1 . . 1 . 1 . 1 .
1 . . 1 1 . 1 . 1 . 1 1 . . 1 .
. . . . 1 1 . . . 1 1 . . . . .
. . . . 1 . 1 . 1 . 1 . . . . .
. . . . 1 . . 1 . . 1 . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
`, SpriteKind.Enemy)
// @highlight
hoop.setPosition(80, 35)
제한 시간 설정
긴장감을 더하기 위해 제한 시간을 둡니다.
► ||info:정보|| 카테고리의 ||info:카운트다운 시작 [10] (s)|| 블록을 시작하면 블록의 맨 마지막에 넣고, 시간을 30초로 변경합니다.
// (이전 코드 생략 없이 전체 포함)
scene.setBackgroundImage(img`.`)
let athlete = sprites.create(img`
. . f f . . . . . . . .
. f f f f . . . . . . .
. f f f f f f . . . . .
. f 6 6 6 6 6 6 . . . .
. . f f a a a a . . . .
. . f f a f a f . . . .
. . f a a a a a . . . .
. . . a a a a a . . . .
. . . . a a a . . . . .
. a a 1 a a 1 a 4 4 4 a
. a a 1 6 6 1 4 f 4 f 4
. a a a 6 6 6 a a f 4 4
. a a a 6 6 a a a 4 f 4
. . a a a a a 6 4 4 4 .
. . 6 a a a 6 6 . . . .
. . 1 1 1 1 1 1 . . . .
. . 6 6 6 8 6 6 . . . .
. . 6 6 6 8 6 6 . . . .
. . 6 6 6 8 6 6 . . . .
. . a a . . a a . . . .
. . a a . . a a . . . .
. . 6 1 . . 6 1 . . . .
. . 1 1 1 . 1 1 1 . . .
. . . . . . . . . . . .
`, SpriteKind.Player)
athlete.setPosition(80, 90)
athlete.setVelocity(50, 0)
athlete.setBounceOnWall(true)
let hoop = sprites.create(img`
. . 3 3 4 4 4 4 4 4 4 3 3 . . .
. 3 4 4 1 1 . . . 1 1 4 4 3 . .
3 4 4 . 1 . 1 . 1 . 1 . 4 4 3 .
3 4 1 . 1 . . 1 . . 1 . 1 4 3 .
4 3 4 1 1 . 1 . 1 . 1 1 4 3 4 .
1 4 3 3 1 1 . . . 1 1 3 3 4 1 .
1 1 4 4 3 3 3 3 3 3 3 4 4 1 1 .
1 . 1 . 4 4 4 4 4 4 4 . 1 . 1 .
1 . . 1 1 . 1 . 1 . 1 1 . . 1 .
1 . 1 . 1 1 . . . 1 1 . 1 . 1 .
1 1 . . 1 . 1 . 1 . 1 . . 1 1 .
1 . 1 . 1 . . 1 . . 1 . 1 . 1 .
1 . . 1 1 . 1 . 1 . 1 1 . . 1 .
. . . . 1 1 . . . 1 1 . . . . .
. . . . 1 . 1 . 1 . 1 . . . . .
. . . . 1 . . 1 . . 1 . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
`, SpriteKind.Enemy)
hoop.setPosition(80, 35)
// @highlight
info.startCountdown(30)
슛! (공 던지기)
A 버튼을 누르면 선수가 농구공을 던지게 해봅시다.
► ||controller:컨트롤러||에서 ||controller:[A] 버튼을 [누를 때]|| 블록을 가져옵니다.
► 그 안에 ||sprites:[projectile]을 [athlete]에서 발사하는 발사체로 설정|| 블록을 넣습니다.
► 공 이미지를 그리고, 위쪽으로 날아가도록 vy를 -100으로 설정합니다. (vx는 0)
let athlete: Sprite = null
let projectile: Sprite = null
controller.A.onEvent(ControllerButtonEvent.Pressed, function () {
// @highlight
projectile = sprites.createProjectileFromSprite(img`
. . 4 4 4 . .
. f 4 4 4 f .
4 4 f 4 f 4 4
f f f f f f f
4 4 f 4 f 4 4
. f 4 4 4 f .
. . 4 4 4 . .
`, athlete, 0, -100)
})
골인! (점수 획득)
공이 골대에 들어가면 점수를 얻어야겠죠?
► ||sprites:스프라이트||에서 ||sprites:스프라이트 종류가 [Projectile]인 ... [Enemy]과 닿았을 때|| 블록을 가져옵니다. (두 번째 종류를 Enemy로 꼭 바꿔주세요)
► 닿았을 때 ||info:점수 1 증가||시키고, 골대에 들어간 공(sprite)은 ||sprites:파괴||하여 사라지게 합니다.
sprites.onOverlap(SpriteKind.Projectile, SpriteKind.Enemy, function (sprite, otherSprite) {
// @highlight
info.changeScoreBy(1)
// @highlight
sprite.destroy()
})
게임 종료
시간이 다 되었을 때 게임을 끝내는 규칙을 확인합니다.
► ||info:정보|| 카테고리의 ||info:카운트다운이 종료되면|| 블록을 사용합니다.
► 그 안에 ||game:게임 종료 <승리>|| 블록을 넣어 게임을 마무리합니다.
info.onCountdownEnd(function () {
// @highlight
game.gameOver(true)
})
완성!
축하합니다! 프리 드로우 게임이 완성되었습니다.
30초 안에 몇 점이나 넣을 수 있는지 도전해보세요!
아래는 완성된 전체 블록 코드입니다.
controller.A.onEvent(ControllerButtonEvent.Pressed, function () {
projectile = sprites.createProjectileFromSprite(img`
. . 4 4 4 . .
. f 4 4 4 f .
4 4 f 4 f 4 4
f f f f f f f
4 4 f 4 f 4 4
. f 4 4 4 f .
. . 4 4 4 . .
`, athlete, 0, -100)
})
sprites.onOverlap(SpriteKind.Projectile, SpriteKind.Enemy, function (sprite, otherSprite) {
info.changeScoreBy(1)
sprite.destroy()
})
info.onCountdownEnd(function () {
game.gameOver(true)
})
let projectile: Sprite = null
let athlete: Sprite = null
scene.setBackgroundImage(img`.`)
athlete = sprites.create(img`
. . f f . . . . . . . .
. f f f f . . . . . . .
. f f f f f f . . . . .
. f 6 6 6 6 6 6 . . . .
. . f f a a a a . . . .
. . f f a f a f . . . .
. . f a a a a a . . . .
. . . a a a a a . . . .
. . . . a a a . . . . .
. a a 1 a a 1 a 4 4 4 a
. a a 1 6 6 1 4 f 4 f 4
. a a a 6 6 6 a a f 4 4
. a a a 6 6 a a a 4 f 4
. . a a a a a 6 4 4 4 .
. . 6 a a a 6 6 . . . .
. . 1 1 1 1 1 1 . . . .
. . 6 6 6 8 6 6 . . . .
. . 6 6 6 8 6 6 . . . .
. . 6 6 6 8 6 6 . . . .
. . a a . . a a . . . .
. . a a . . a a . . . .
. . 6 1 . . 6 1 . . . .
. . 1 1 1 . 1 1 1 . . .
. . . . . . . . . . . .
`, SpriteKind.Player)
athlete.setPosition(80, 90)
athlete.setVelocity(50, 0)
athlete.setBounceOnWall(true)
let hoop = sprites.create(img`
. . 3 3 4 4 4 4 4 4 4 3 3 . . .
. 3 4 4 1 1 . . . 1 1 4 4 3 . .
3 4 4 . 1 . 1 . 1 . 1 . 4 4 3 .
3 4 1 . 1 . . 1 . . 1 . 1 4 3 .
4 3 4 1 1 . 1 . 1 . 1 1 4 3 4 .
1 4 3 3 1 1 . . . 1 1 3 3 4 1 .
1 1 4 4 3 3 3 3 3 3 3 4 4 1 1 .
1 . 1 . 4 4 4 4 4 4 4 . 1 . 1 .
1 . . 1 1 . 1 . 1 . 1 1 . . 1 .
1 . 1 . 1 1 . . . 1 1 . 1 . 1 .
1 1 . . 1 . 1 . 1 . 1 . . 1 1 .
1 . 1 . 1 . . 1 . . 1 . 1 . 1 .
1 . . 1 1 . 1 . 1 . 1 1 . . 1 .
. . . . 1 1 . . . 1 1 . . . . .
. . . . 1 . 1 . 1 . 1 . . . . .
. . . . 1 . . 1 . . 1 . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
`, SpriteKind.Enemy)
hoop.setPosition(80, 35)
info.startCountdown(30)