티스토리 뷰
필자는 여러가지 생각을 해서 로직을 하나 떠올렸습니다
보드 판을 두개 준비해놓고, 하나는 이미 쌓여있는 블럭만 저장하고
하나에는 지금 떨어지는 블럭을 쌓여있는 블럭이 있는 부분에다가 삽입한 뒤,
삽입된 배열을 출력해주면 어떨까?
코드로 바로 진행해보겠습니다.
이전 상태의 게임보드... 라고 해서 gameBoard 와 똑같은 형식으로 새로 또 만들었습니다.
그리고 gameBoard 는 항상 낙하하고 있는 블럭을 하나씩 가지고 있습니다
gameBoard 클래스 내에 다음과 같이 선언해줍니다.
superblock 은 block 클래스를 가지고 있는것이고
block 변수는 superblock 에 저장된 블럭만을 가지고 있게 됩니다.
자 다음에는 블럭을 insert 하는 과정이 필요하겠지요...
자 이 함수로 블럭을 insert 해줍니다.
우선 gameBoard 배열에 prev_gameBoard 를 복사합니다
잠깐, 블럭이 어떻게 생겼는지 기억하시나요 4*4 행렬로(실제로는 16줄의 단일 배열로) 선언이 되어있었죠.
그래서 4칸씩 돌면서 블럭의 행렬에서 0 이 아닌값들을 행렬의 1,1 쪽의 x위치와 y 위치를 더해서 실제 게임 보드에다가 투사해주면
저런 코드가 적히게 되고 실제로 잘 작동합니다.
그리고 이 함수는 충돌 검출을 하지 않습니다
왜냐하면 insert 함수는 충돌하기 전에만 호출하는것이 보장된 함수입니다. 충돌하면 insert 가 일어나는게 아니라 블록의 fix 가 일어나고 새로운 블럭을 다시 만들어서 insert 할 것이기 때문입니다.
저 insert 함수가 좀 더러워 보일수도 있어서 한번쯤은 종이에 그려서 찍어보시면 이해가 될거에요....
(산문처럼 써서 읽기 편하게 하겠다는 목적은 어디간거지 핫산!)
자 다음에는 충돌 에 대해서 알아보겠습니다.
테트리스는 충돌하면 더이상 내려가면 안됩니다. 그리고 충돌하고 나서 일정시간 가만히 있거나 스페이스바를 누르는 등의 행위를 하면 블럭이 바로 충돌하는 위치까지 내려가서 fix 되어야하죠.
블럭이 충돌하는지 충돌하지 않는지는 진리값(True/False) 로 나타낼 수 있겠지요.
우선 충돌 검출 함수를 짜보고 이걸 어떻게 쓸것인가 생각해봅시다. (사실 먼저 생각하고 짜야합니다.)
네 이 함수가 충돌 함수인데요
필자는 어떠한 블럭이 move 했을때 충돌 하는지 안하는지가 궁금했습니다
그러면 기준 블럭에서 move 시킨 블럭이 충돌한다면 move 시키지 않는다면 간단하니까요
함수는 간단합니다 insert 시키는 블럭위치에 실제로 블럭이 존재한다면 (!=0 ) 이라면
충돌한다 True 를 반환하고
모두 검사했는데 충돌하지 않는다면 False 를 반환합니다.
그런데 이렇게 짜고 보니까 회전 충돌은 어떻게 검출할까요....
rotation 이 들어오면 새로운 임시 블럭을 만들어서 다시 검출해야합니다. (block) 이 하나의 다른 객체였으니까요
그럴바에야 회전시 충돌 검출 함수만 따로 만들어서 쓰겠습니다.
(이부분은 일부러 이렇게 설계했습니다 나중에 SRS 시스템을 심으려면 이 방법이 가장 좋다고 생각했거든요)
네 내용은 똑같습니다만, 회전 시 임시 블럭을 가지고 와서 검출 해주는 것만 다릅니다
이때 copy.deepcopy(self.superblock) 이라는 구문이 눈에 띕니다
예전에 파이썬의 얕은 복사 깊은 복사 에대해서 잠깐 언급했었는데요
파이썬은 객체를 = 로 할당하게 되면 얕은 복사, 즉 같은 블록으로 들어가게 됩니다
하지만 이 경우에 같은 블럭으로 들어가게 되고 임시 블럭을 회전시키면 어떻게 될까요
네 실제 블럭도 같이 회전해버립니다.
그런데 저희가 원한건 그런게 아니죠? 지금 있는 상황에서 블럭만 회전시켜서 확인해보고 버릴 내용이였습니다.
그렇기 때문에 임시로 생성한건 완전히 내용물은 똑같지만 다른 객체를 할당해서 회전시킨뒤 검사하고 버리는겁니다
(GC야 미안해 내가 잘못했어)
정리해서 말씀드리자면 얕은 복사는 내용이 a 이고 이름이 A 인것을 B 로 얕은 복사한다면
B 는 정확하게 A 가 되는것입니다. 거울이라고 생각하시면 되겠네요
깊은 복사는 내용이 a 이고 이름이 A인것을 B로 깊은 복사한다면
B는 A와 모양은 똑같지만 다른 사람이 됩니다. 지금의 저를 복사해서 평행 세계에 버린 다른 자기자신 라고 생각하시면 됩니다. 평행세계의 저는 는 제가 바뀌더라도 바뀌지 않겠죠.
설명이 난잡해졌는데 이해하셨나요
이해하지 못해도 괜찮습니다. 차차 이해되실거에요.
그럼 다음시간에 동작하는 테트리스를 완성시키도록 노력해봅시다. 한 두 포스트 정도면 완성은 끝날것같네요.
'Game with Python' 카테고리의 다른 글
테트리스 제작 - (6) (0) | 2017.07.01 |
---|---|
테트리스 제작 - (5) (0) | 2017.06.28 |
테트리스 제작 - (3) (0) | 2017.06.26 |
테트리스 제작 - (2) (0) | 2017.06.26 |
테트리스 제작 - (1) (0) | 2017.06.26 |