Console Tetris 만들기 (1)
사이드 프로잭트로 console에 테트리스를 만드는 시간을 가지고 있습니다. 이 편은 3~5편 사이로 예상하고 있으며, 코드가 구현될 때마다 분류하여 정리해서 올려보도록 하겠습니다. 1편은 키보드 입력을 받는 부분을 만들어 보겠습니다. console 라이브러리
중에 콘솔에 색깔을 출력하고, 키보드 입력을 받는 termbox-go
를 통해서 만들어 보도록 하겠습니다.
1편 요약
이번 편에는 입력을 받고, 입력을 수행하는 스레드가 두개가 필요하여 시분할 처리를 수행하는 고루틴을 통해서 만들겠습니다.
먼저, 입력을 받는 go routine 1
, 입력을 받아서 명령을 수행하는 go routine 2
, 를 만들어서 수행하도록
할 것 입니다. 먼저 go routine1
을 만들것 입니다.
go routine1
고루틴 시작전에 sync
로 go routine이 main 함수보다 늦게
끝날 것을 고려해 설정해야하기 떄문에 wait.Add(2)
로
메인 함수가 기달려달라고 설정해야합니다.
// sync wait 버전을 만듭니다.
var wait sync.WaitGroup
wait.Add(2)
// termbox 초기 시작
err := termbox.Init()
if err != nil {
panic(err)
}
defer termbox.Close()
// termbox event Queue, go routine1 생성
// 이벤트를 지속적으로 받아옵니다.
eventQueue := make(chan termbox.Event)
go func() {
for {
defer wait.Done()
eventQueue <- termbox.PollEvent()
}
}()
go routine2
고루틴 2는 앞서 만든 eventQueue를 통해서, 받고 그 Type에 따라서 명령어 타임을 진행해주면 됩니다.
그 과정에서 go-routine으로 받은 값이기 떄문에, select가 필요합니다.
// goroutine2 생성합니다.
go func() {
for {
// 채널을 통해서 받아오므로 select문
select {
case qu := <- eventQueue:
// Type에 따라서 분류하여 작동
if qu.Type == termbox.EventKey {
switch {
case qu.Key == termbox.KeyArrowLeft:
fmt.Println("left")
case qu.Key == termbox.KeyArrowRight:
fmt.Println("right")
case qu.Key == termbox.KeyArrowUp:
fmt.Println("up")
case qu.Key == termbox.ArrowDown:
fmt.Println("down")
case qu.Key == termbox.KeySpace:
fmt.Println("space")
case qu.Key == termbox.KeyEsc:
wait.Done()
}
}
default:
time.Sleep(tetrisSpeed)
}
}
}()
wait
전체코드
package main
import (
"fmt"
"sync"
"time"
"github.com/nsf/termbox-go"
)
const tetirisSpeed = 10 * time.Millisecond
func main() {
var wait sync.WaitGroup
wait.Add(2)
err := termbox.Init()
if err != nil {
panic(err)
}
defer termbox.Close()
eventQueue := make(chan termbox.Event)
go func() {
for {
eventQueue <- termbox.PollEvent()
}
}()
go func() {
for {
// go routine에 의해서, switch문을 select로 대체
select {
case qu := <-eventQueue:
// Type에 따라서 분류
if qu.Type == termbox.EventKey {
switch {
case qu.Key == termbox.KeyArrowLeft:
fmt.Println("left")
case qu.Key == termbox.KeyArrowRight:
fmt.Println("right")
case qu.Key == termbox.KeyArrowUp:
fmt.Println("up")
case qu.Key == termbox.KeySpace:
fmt.Println("space")
case qu.Key == termbox.KeyArrowDown:
fmt.Println("down")
case qu.Key == termbox.KeyEsc:
fmt.Println("done")
wait.Done()
wait.Done()
}
}
default:
time.Sleep(tetrisSpeed)
}
}
}()
// go routine 끝날 떄까지, 기다리기
wait.Wait()
}
이렇게 하면, 종료키, 위, 아래, 스페이스, 오른쪽, 왼쪽 키가 정상적으로 입력되는 것을 확인할 수 있다.
tetrisSpeed는 블락이 떨어지는 속도를 의미합니다. 이것을 통해서 난이도를 변경하거나 할 수 있을 것 입니다.
다음 편에는 golang 본판을 짜보는 시간을 가지겠습니다.
- github code
https://github.com/woong-s/console_go_tetris/commit/4641bcb0a3ea21ab810970e428fb7131e55d2279
'언어 > GO' 카테고리의 다른 글
GO - errors new 에러 핸들링 (0) | 2021.11.30 |
---|