안녕하세요! 게임 만드는 잉여 쏘코입니다.
지난 포스팅에서는 집게가 시계추처럼 흔들릴 수 있도록 만들었는데요!

이번에는 집게가 원하는 각도가 되었을 때 발사하도록 만들어 보겠습니다!
이번 포스팅은 나도코딩님 영상의 1:09:39~1:24:51까지의 내용을 담고 있습니다!
0. 집게 발사
이제 집게로 보석을 집어오려면 집게가 발사될 수 있어야겠죠?
새로운 파이썬 파일을 하나 만듭니다.
8_claw_launch.py 파일을 만들고 7.claw_swing.py 파일을 copy&paste 해줍니다.

집게를 발사하는 동작은 현재 위치로부터 집게를 쭉 뻗는 동작과 같습니다.
그렇다면 우리가 설정해야 할 규칙은 무엇이 있을까요?
만약 쭉 뻗다가 보석을 잡지 못하고 화면 밖으로 집게가 나가버리는 상황이 되면 안되겠죠?
화면 밖으로 뻗어나가면 다시 돌아오도록 처리해야 합니다.
그리고 집게가 뻗을 때 속도와 돌아올 때 속도를 설정해야 합니다.
돌을 잡았을 때는 무거우니까 느리게 끌리고, 다이아몬드를 잡았을 때는 빠르게 끌려야겠죠?
이것도 보석의 종류, 보석의 크기에 따라 다르게 적용할 수 있습니다.
마우스가 클릭이 될 때 집게가 회전하는게 멈춰야겠죠?
while문으로 이동해서, 마우스가 클릭되면 claw의 방향이 고정되도록 만들어줍니다. (150~151줄)

STOP에 대한 설정을 하지 않았으니, 게임 관련 변수를 만든 곳에 가서 STOP에 숫자 0을 할당해줍시다!

direction을 설정하는 부분이 많아지다보니 매번 할당하는 것보다 아예 함수를 만들어서 처리하는 것이 낫다는 생각이 들었습니다.
그러면 바로 실행에 옮겨야겠죠?
rotate 메소드와 draw 메소드 사이에 새롭게 set_direction 메소드를 만들어줍니다.
set_direction 메소드는 매개변수로 direction을 받고, 받은 direction을 self.direction에 저장합니다. (60~61줄)

이제 위에서 direction에 직접 할당했던 부분들을 모두 메소드 사용으로 바꿔줍니다. (35, 38, 151줄)
이 부분은 클래스에 내재된 변수에 직접 접근하지 않고 값을 변경하는 함수를 이용하여 변수의 값을 바꿔줬기 때문에 객체 변수의 보안과 변수의 무결성에 있어서 더욱 좋은 방법이라고 볼 수 있습니다. (getter, setter 함수/메소드를 만드는 이유와도 같습니다)




이제 코드를 실행시킨 후에 마우스를 클릭하면 집게가 멈춥니다!!!

그 다음에는 집게가 뻗어나가야겠죠?
게임 관련 변수에 가서 to_x 변수를 만들고 0으로 초기화합니다. (105줄)
to_x는 좌표를 기준으로 집게 이미지를 이동시킬 값이 들어가는 변수입니다.
클릭하면 to_x가 점점 증가하면서 집게가 늘어나게 되는 방식으로 만들어 주겠습니다!
그리고 LEFT, STOP, RIGHT는 방향 변수로 따로 빼서 주석처리를 해 주겠습니다. (107~110줄)

마우스를 클릭했을 때 to_x가 증가하는 속도를 지정해야겠죠?
게임 관련 변수와 방향 변수 사이에 속도 변수 부분을 주석처리해서 새로 만들어줍니다.
그 아래에 move_speed를 설정합니다. (107~108줄)
저는 x 좌표를 기준으로 증가되는 값을 넣어주도록 할게요. - 이 부분은 아래에서 이해하실 수 있습니다!!

이제 아래에서 to_x값에 move_speed를 넣어주겠습니다. (158줄)

이 to_x를 집게 객체에 반영해줘야겠죠?
claw.update 메소드에 to_x를 매개변수로 넣어서 값을 전달하도록 하겠습니다. (163줄)
그런데 claw.update 메소드는 매개변수를 하나도 받지 않게 만들었던 기억이 나죠?
그러므로 claw.update 메소드가 매개변수를 1개 받을 수 있도록 바꿔야 합니다!

우리는 생성자에서 offset 변수(pygame.math.Vector2로 만든 변수)를 이용해서 회전축에서 40만큼 떨어진 거리에 집게가 위치할 수 있도록 만들어줬습니다.
그리고 아래에서 rotate 메소드를 통해 회전처리가 되었죠?
그렇기 때문에 offset에서 x에 들어가는 값만 바꿔주면, 회전처리는 알아서 rotate 메소드가 알아서 해주겠죠?

update 메소드의 매개변수에 to_x를 추가해줍니다. (26줄)
그리고 self.offset.x(offset의 x변수)의 값에 to_x를 더해줍니다. (40줄)
이렇게 만들면 매 프레임마다 self.offset.x값은 to_x만큼 증가하게 되겠죠?

여기까지 만들고 실행한 후에 클릭해봅시다.
집게가 지구 끝까지 발사됩니다 ㅋㅋㅋㅋㅋㅋㅋ

# 8_claw_launch.py
# 집게 발사
# 현재 위치로부터 집게를 쭉 뻗는 동작
# 화면 밖으로 뻗어나가면 다시 돌아오도록 처리
# 뻗을 때 속도, 돌아올 때 속도 서로 다르게 적용
import os # 경로를 위해 os 라이브러리 불러오기
import pygame # 파이게임 라이브러리 불러오기
# 집게 클래스 (보석 클래스와 거의 동일!)
class Claw(pygame.sprite.Sprite):
def __init__(self, image, position):
super().__init__()
self.image = image # 회전한 이미지를 가질 예정!
self.original_image = image # 처음 이미지를 그대로 가지고 있는다!
self.rect = image.get_rect(center = position)
self.offset = pygame.math.Vector2(default_offset_x_claw, 0) # x위치는 100만큼 이동, y위치는 그대로
self.position = position
self.direction = LEFT # 집게의 이동 방향 (숫자값)
self.angle_speed = 2.5 # 1프레임당 집게의 각도 변경폭 (좌우 이동 속도)
self.angle = 10 # 최초 각도 정의 (오른쪽 끝)
def update(self, to_x): # 보통 게임을 만들 때 캐릭터가 가만히 있을 때 숨쉬는 동작을 담당하는 부분!
if self.direction == LEFT : # 왼쪽 방향으로 이동하고 있다면
self.angle += self.angle_speed # 이동 속도만큼 각도를 증가
elif self.direction == RIGHT : # 오른쪽 방향으로 이동하고 있다면
self.angle -= self.angle_speed #이동 속도만큼 각도를 감소
# 만약에 허용 각도 범위를 벗어나면?
if self.angle > 170:
self.angle = 170
self.set_direction(RIGHT)
elif self.angle < 10:
self.angle = 10
self.set_direction(LEFT)
self.offset.x += to_x
self.rotate()
# print(self.angle, self.direction) 테스트용
# rect_center = self.position + self.offset # 위에서 만든 두 변수를 더해줌!!
# self.rect = self.image.get_rect(center = rect_center) # update 메소드를 실행하면 self.rect가 업데이트 되고, draw를 하면 바뀐 rect를 기준으로 화면에 출력!
def rotate(self): # 원본 이미지가 아닌 새로운 이미지를 만드는 메소드!
self.image = pygame.transform.rotozoom(self.original_image, -self.angle, 1)
# 기본 사진을 주어진 각도만큼 회전 (실제로는 반시계방향으로 각도가 계산되지만, 우리는 시계방향으로 거꾸로 적용하기 위해 -를 붙였다!), 이미지의 크기 변동은 X(1)
# self.image는 회전을 하고 나서 새롭게 만들어진 이미지를 넣기 위한 변수!! (rotozoom은 이미지 회전, 크기설정을 할 수 있는 메소드!)
# rotozoom은 회전 대상 이미지, 회전 각도, 이미지 크기(scale)을 매개변수로 받는다!
offset_rotated = self.offset.rotate(self.angle) # Vector2를 이용해 받아온 offset 데이터를 각도에 맞춰서 회전시킨 offset을 받아온다 (40으로 설정한 것을 기억하자!)
# print(offset_rotated) # 확인용
self.rect = self.image.get_rect(center = self.position + offset_rotated) # 집게의 중심점 기준으로 회전하게 만들어준다!
# print(self.rect) # 확인용
pygame.draw.rect(screen, RED, self.rect, 1)
def set_direction(self, direction):
self.direction = direction # 매개변수로 받은 direction을 self.direction으로 설정
def draw(self, screen):
screen.blit(self.image, self.rect) # 스크린의 blit을 이용해 Claw 클래스로 만든 객체의 이미지와 위치 정보를 이용해 그 내용을 화면에 출력한다!
pygame.draw.circle(screen, RED, self.position, 3) # screen에 빨간 점을 적겠다, 위치는 self.position, 반지름은 3으로 하겠다! - 중심점 표시
pygame.draw.line(screen, BLACK, self.position, self.rect.center, 5) # 직선 그리기
# 스크린에 선을 그릴 것이고, 검은 색이고, self.position(중심점)부터 rect.center(집게의 중심점)까지 직선의 두께는 5로 연결하겠다!
# 보석 클래스
class Gemstone(pygame.sprite.Sprite): # pygame의 Sprite를 상속해와서 사용한다!!
def __init__(self, image, position): # 생성자 (사진인 image와 보석의 위치인 position을 매개변수로 받는다!)
super().__init__() # 상속받은 Sprite의 생성자를 불러온다! (상속 받았으니 뭔지는 몰라도 초기화 해준다!)
# 아래 2개의 변수는 Sprite 메소드를 사용하기 위해서 반드시 정의해야 함!!
self.image = image # 캐릭터가 가진 이미지 정보 - 매개변수로 받아온다!
self.rect = image.get_rect(center = position) # 캐릭터가 가지는 좌표, 크기 정보
# 보석마다 위치가 달라져야 하기 때문에 받아온 이미지의 중앙이 매개변수로 받은 position에 맞춰서 rect를 가져오도록 설정한다!
def setup_gemstone(): # 보석 클래스에서 설정한 보석의 사진과 위치 정보를 gemstone_group에 넣는 함수! 작은 금은 이해를 위해 나눠서 작성했고, 큰 금부터는 한번에 작성!
# 작은 금
small_gold = Gemstone(gemstone_images[0], (200, 380)) # 0번째 이미지를 (200, 300) 위치에 둬라
gemstone_group.add(small_gold) # 그룹에 추가
# 큰 금
gemstone_group.add(Gemstone(gemstone_images[1], (300,500)))
# 돌
gemstone_group.add(Gemstone(gemstone_images[2], (300,380)))
# 다이아몬드
gemstone_group.add(Gemstone(gemstone_images[3], (900,420)))
pygame.init() # 파이게임 초기화
# 스크린 크기 지정
screen_width = 1280
screen_height = 720
screen = pygame.display.set_mode((screen_width, screen_height)) # 이걸 통해 게임의 창 크기를 설정
pygame.display.set_caption("Gold Miner") # 게임 제목 설정 "Gold Miner"
clock = pygame.time.Clock() # 프레임값을 조정하기 위한 clock변수 설정
# 게임 관련 변수
default_offset_x_claw = 40 # 중심점으로부터 집게까지의 기본 x 간격
to_x = 0 # x 좌표 기준으로 집게 이미지를 이동시킬 값을 저장하는 변수
# 속도 변수
move_speed = 12 # 발사할 때 이동 스피드 (x 좌표 기준으로 증가되는 값)
# 방향 변수
LEFT = -1 # 왼쪽 방향
STOP = 0 # 이동 방향이 좌우가 아닌 고정인 상태 (집게를 뻗음)
RIGHT = 1 # 오른쪽 방향
# 색깔 변수
RED = (255, 0, 0) # RGB값, 빨간색
BLACK = (0, 0, 0) # 검은색
# 배경 이미지 불러오기
current_path = os.path.dirname(__file__) # os.path.dirname을 이용해서 현재 파일의 위치(2_background.py 위치) 반환
background = pygame.image.load(os.path.join(current_path, "background.png")) # 현재 위치의 파일이 있는 폴더의 background.png파일을 선택하게 됨!!
# 4개 보석 이미지 불러오기 (작은 금, 큰 금, 돌, 다이아몬드) - 배경을 가져오는 과정과 동일!!
gemstone_images = [
pygame.image.load(os.path.join(current_path, "small_gold.png")), # 작은 금
pygame.image.load(os.path.join(current_path, "big_gold.png")), # 큰 금
pygame.image.load(os.path.join(current_path, "stone.png")), # 돌
pygame.image.load(os.path.join(current_path, "diamond.png")) # 다이아몬드
]
# 보석 그룹
gemstone_group = pygame.sprite.Group() # 젬스톤 그룹 생성
setup_gemstone() # 게임에 원하는 만큼의 보석을 정의
# 집게 이미지 불러오기 (보석 이미지 불러오는 방식과 동일!)
claw_image = pygame.image.load(os.path.join(current_path, "claw.png"))
claw = Claw(claw_image, (screen_width // 2, 110)) # Claw 클래스를 이용해서 객체 생성!!
# 가로 위치는 화면 가로 크기 기준으로 절반, 위에서 110px에 위치
# 게임이 반복해서 수행될 수 있도록 게임 루프를 만든다!
running = True
while running: # 게임이 진행중이라면? while문을 계속해서 반복하게 된다!
clock.tick(30) # FPS 값이 30으로 고정
for event in pygame.event.get(): # 이벤트를 받아오고
if event.type == pygame.QUIT: # 게임이 꺼지는 이벤트가 발생했다면
running = False # running 변수를 False로 바꿔준다!
if event.type == pygame.MOUSEBUTTONDOWN: # 마우스 버튼이 눌렸을 때 집게를 뻗음
claw.set_direction(STOP) # 좌우 멈춤
to_x = move_speed # move_speed 만큼 빠르게 쭉 뻗음
screen.blit(background, (0, 0)) # 맨 왼쪽 맨 위부터 ((0,0) 좌표부터)그림을 그려주도록 만들어준다!
gemstone_group.draw(screen) # gemstone_group에 있는 모든 Sprite를 screen에다가 그려라!
claw.update(to_x)
claw.draw(screen)
pygame.display.update() # 설정한 배경화면 이미지를 pygame에 반영! (display에 업데이트!!)
pygame.quit() # while문을 빠져나가면 게임이 끝나도록 설정
1. 집게 돌아오기
발사를 시켰는데, 돌아오지 않는다면 보석은 저 멀리 밀려가버리고 말 것입니다 ㅋㅋㅋㅋ
그걸 방지하기 위해서 돌아오는 동작을 구현해 보도록 하겠습니다.
구현하기 전에, 먼저 중심점을 나타내 주는 부분과 rect를 나타내는 빨간 네모를 그려주는 부분을 없애겠습니다.
이해를 돕기 위해 테스트로 만든 부분이었으니 실제 게임에는 필요가 없는 부분이니까요!
주석 처리를 하셔도 되고, 아예 없애셔도 됩니다.
저는 공부를 위해 주석처리만 해 두도록 하겠습니다! (59, 68줄)


이제 돌아오는 동작을 진짜로!! 구현해 보도록 하겠습니다.
집게가 왼쪽, 오른쪽, 아래의 끝에 도달하면 to_x가 -가 되면 되겠죠? (위로 갈 가능성은 없으니 제외합니다!)
먼저 돌아오는 스피드를 정의합니다. 발사할 때보다 조금 빠르게 돌아오도록 설정해볼게요! (111줄)

if문을 이용해서 집게의 위치가 왼쪽 끝, 오른쪽 끝, 아랫쪽 끝에 위치하면 to_x가 -return_speed만큼 이동하도록 코드를 짭니다.
return_speed가 양수이기 때문에 -를 붙여서 음수 처리를 해 줘야겠죠?

여기까지 만들고 실행시키면, 끝까지 돌아갔을 때 다시 돌아오게 됩니다.
다만 원래 위치에서 안멈추고 다시 지구 끝까지 반대로 가버리고 맙니다...
(실제로 확인할 때는 조건을 3개 걸어줬으므로 왼쪽, 오른쪽, 아래쪽 끝에 도달했을 때 모두 잘 돌아오는지 3번 이상 확인해야합니다!)

이제 원위치로 돌아오면 다시 원래대로 rotate할 수 있도록 만들어줘야 합니다.
만약 claw.offset.x가 default_offset_x_claw(40)보다 작아지게 되면
to_x(이동 속도)를 0으로 만들어서 더 이상 이동하지 못하도록 하고,
claw.set_init_state 메소드를 작동하여 각도와 이동 방향을 초기화할 수 있도록 만들어주겠습니다.

set_init_state 메소드를 정의하지 않았죠?
set_init_state 메소드에는 매개변수가 필요하지 않습니다.
그리고 self.offset.x를 원위치로 돌려주고, angle을 10으로 바꿔주고, direction도 LEFT로 돌려줍니다. 이게 초기 상태였죠?
(TMI : 집게가 원래 어느 각도에서 어느 방향으로 회전하고 있었는지를 기억해 뒀다가 그 정보를 사용하면 보다 자연스럽게 집게의 이동을 구현할 수 있을 것 같습니다! 완강 후 업그레이드하는 과정에서 시도해보도록 하겠습니다!)

여기까지 만들고 실행하면 어느 정도 게임의 구색은 갖춘 모습이 됩니다!!
정상적으로 집게가 늘어났다가 줄어들었다가 다시 회전합니다!! 🤗

# 8_claw_launch.py
# 집게 발사
# 현재 위치로부터 집게를 쭉 뻗는 동작
# 화면 밖으로 뻗어나가면 다시 돌아오도록 처리
# 뻗을 때 속도, 돌아올 때 속도 서로 다르게 적용
import os # 경로를 위해 os 라이브러리 불러오기
import pygame # 파이게임 라이브러리 불러오기
# 집게 클래스 (보석 클래스와 거의 동일!)
class Claw(pygame.sprite.Sprite):
def __init__(self, image, position):
super().__init__()
self.image = image # 회전한 이미지를 가질 예정!
self.original_image = image # 처음 이미지를 그대로 가지고 있는다!
self.rect = image.get_rect(center = position)
self.offset = pygame.math.Vector2(default_offset_x_claw, 0) # x위치는 100만큼 이동, y위치는 그대로
self.position = position
self.direction = LEFT # 집게의 이동 방향 (숫자값)
self.angle_speed = 2.5 # 1프레임당 집게의 각도 변경폭 (좌우 이동 속도)
self.angle = 10 # 최초 각도 정의 (오른쪽 끝)
def update(self, to_x): # 보통 게임을 만들 때 캐릭터가 가만히 있을 때 숨쉬는 동작을 담당하는 부분!
if self.direction == LEFT : # 왼쪽 방향으로 이동하고 있다면
self.angle += self.angle_speed # 이동 속도만큼 각도를 증가
elif self.direction == RIGHT : # 오른쪽 방향으로 이동하고 있다면
self.angle -= self.angle_speed #이동 속도만큼 각도를 감소
# 만약에 허용 각도 범위를 벗어나면?
if self.angle > 170:
self.angle = 170
self.set_direction(RIGHT)
elif self.angle < 10:
self.angle = 10
self.set_direction(LEFT)
self.offset.x += to_x
self.rotate()
# print(self.angle, self.direction) 테스트용
# rect_center = self.position + self.offset # 위에서 만든 두 변수를 더해줌!!
# self.rect = self.image.get_rect(center = rect_center) # update 메소드를 실행하면 self.rect가 업데이트 되고, draw를 하면 바뀐 rect를 기준으로 화면에 출력!
def rotate(self): # 원본 이미지가 아닌 새로운 이미지를 만드는 메소드!
self.image = pygame.transform.rotozoom(self.original_image, -self.angle, 1)
# 기본 사진을 주어진 각도만큼 회전 (실제로는 반시계방향으로 각도가 계산되지만, 우리는 시계방향으로 거꾸로 적용하기 위해 -를 붙였다!), 이미지의 크기 변동은 X(1)
# self.image는 회전을 하고 나서 새롭게 만들어진 이미지를 넣기 위한 변수!! (rotozoom은 이미지 회전, 크기설정을 할 수 있는 메소드!)
# rotozoom은 회전 대상 이미지, 회전 각도, 이미지 크기(scale)을 매개변수로 받는다!
offset_rotated = self.offset.rotate(self.angle) # Vector2를 이용해 받아온 offset 데이터를 각도에 맞춰서 회전시킨 offset을 받아온다 (40으로 설정한 것을 기억하자!)
# print(offset_rotated) # 확인용
self.rect = self.image.get_rect(center = self.position + offset_rotated) # 집게의 중심점 기준으로 회전하게 만들어준다!
# print(self.rect) # 확인용
# pygame.draw.rect(screen, RED, self.rect, 1) # rect 확인용
def set_direction(self, direction):
self.direction = direction # 매개변수로 받은 direction을 self.direction으로 설정
def draw(self, screen):
screen.blit(self.image, self.rect) # 스크린의 blit을 이용해 Claw 클래스로 만든 객체의 이미지와 위치 정보를 이용해 그 내용을 화면에 출력한다!
# pygame.draw.circle(screen, RED, self.position, 3) # screen에 빨간 점을 적겠다, 위치는 self.position, 반지름은 3으로 하겠다! - 중심점 표시
pygame.draw.line(screen, BLACK, self.position, self.rect.center, 5) # 직선 그리기
# 스크린에 선을 그릴 것이고, 검은 색이고, self.position(중심점)부터 rect.center(집게의 중심점)까지 직선의 두께는 5로 연결하겠다!
def set_init_state(self): # 각도와 이동방향을 초기화하는 메소드
self.offset.x = default_offset_x_claw # 원위치
self.angle = 10 # 오른쪽 끝에서 다시 실행하도록 설정
self.direction = LEFT # 왼쪽으로 이동하도록 설정
# 보석 클래스
class Gemstone(pygame.sprite.Sprite): # pygame의 Sprite를 상속해와서 사용한다!!
def __init__(self, image, position): # 생성자 (사진인 image와 보석의 위치인 position을 매개변수로 받는다!)
super().__init__() # 상속받은 Sprite의 생성자를 불러온다! (상속 받았으니 뭔지는 몰라도 초기화 해준다!)
# 아래 2개의 변수는 Sprite 메소드를 사용하기 위해서 반드시 정의해야 함!!
self.image = image # 캐릭터가 가진 이미지 정보 - 매개변수로 받아온다!
self.rect = image.get_rect(center = position) # 캐릭터가 가지는 좌표, 크기 정보
# 보석마다 위치가 달라져야 하기 때문에 받아온 이미지의 중앙이 매개변수로 받은 position에 맞춰서 rect를 가져오도록 설정한다!
def setup_gemstone(): # 보석 클래스에서 설정한 보석의 사진과 위치 정보를 gemstone_group에 넣는 함수! 작은 금은 이해를 위해 나눠서 작성했고, 큰 금부터는 한번에 작성!
# 작은 금
small_gold = Gemstone(gemstone_images[0], (200, 380)) # 0번째 이미지를 (200, 300) 위치에 둬라
gemstone_group.add(small_gold) # 그룹에 추가
# 큰 금
gemstone_group.add(Gemstone(gemstone_images[1], (300,500)))
# 돌
gemstone_group.add(Gemstone(gemstone_images[2], (300,380)))
# 다이아몬드
gemstone_group.add(Gemstone(gemstone_images[3], (900,420)))
pygame.init() # 파이게임 초기화
# 스크린 크기 지정
screen_width = 1280
screen_height = 720
screen = pygame.display.set_mode((screen_width, screen_height)) # 이걸 통해 게임의 창 크기를 설정
pygame.display.set_caption("Gold Miner") # 게임 제목 설정 "Gold Miner"
clock = pygame.time.Clock() # 프레임값을 조정하기 위한 clock변수 설정
# 게임 관련 변수
default_offset_x_claw = 40 # 중심점으로부터 집게까지의 기본 x 간격
to_x = 0 # x 좌표 기준으로 집게 이미지를 이동시킬 값을 저장하는 변수
# 속도 변수
move_speed = 12 # 발사할 때 이동 스피드 (x 좌표 기준으로 증가되는 값)
return_speed = 20 # 아무것도 없이 돌아올 때의 이동 스피드
# 방향 변수
LEFT = -1 # 왼쪽 방향
STOP = 0 # 이동 방향이 좌우가 아닌 고정인 상태 (집게를 뻗음)
RIGHT = 1 # 오른쪽 방향
# 색깔 변수
RED = (255, 0, 0) # RGB값, 빨간색
BLACK = (0, 0, 0) # 검은색
# 배경 이미지 불러오기
current_path = os.path.dirname(__file__) # os.path.dirname을 이용해서 현재 파일의 위치(2_background.py 위치) 반환
background = pygame.image.load(os.path.join(current_path, "background.png")) # 현재 위치의 파일이 있는 폴더의 background.png파일을 선택하게 됨!!
# 4개 보석 이미지 불러오기 (작은 금, 큰 금, 돌, 다이아몬드) - 배경을 가져오는 과정과 동일!!
gemstone_images = [
pygame.image.load(os.path.join(current_path, "small_gold.png")), # 작은 금
pygame.image.load(os.path.join(current_path, "big_gold.png")), # 큰 금
pygame.image.load(os.path.join(current_path, "stone.png")), # 돌
pygame.image.load(os.path.join(current_path, "diamond.png")) # 다이아몬드
]
# 보석 그룹
gemstone_group = pygame.sprite.Group() # 젬스톤 그룹 생성
setup_gemstone() # 게임에 원하는 만큼의 보석을 정의
# 집게 이미지 불러오기 (보석 이미지 불러오는 방식과 동일!)
claw_image = pygame.image.load(os.path.join(current_path, "claw.png"))
claw = Claw(claw_image, (screen_width // 2, 110)) # Claw 클래스를 이용해서 객체 생성!!
# 가로 위치는 화면 가로 크기 기준으로 절반, 위에서 110px에 위치
# 게임이 반복해서 수행될 수 있도록 게임 루프를 만든다!
running = True
while running: # 게임이 진행중이라면? while문을 계속해서 반복하게 된다!
clock.tick(30) # FPS 값이 30으로 고정
for event in pygame.event.get(): # 이벤트를 받아오고
if event.type == pygame.QUIT: # 게임이 꺼지는 이벤트가 발생했다면
running = False # running 변수를 False로 바꿔준다!
if event.type == pygame.MOUSEBUTTONDOWN: # 마우스 버튼이 눌렸을 때 집게를 뻗음
claw.set_direction(STOP) # 좌우 멈춤
to_x = move_speed # move_speed 만큼 빠르게 쭉 뻗음
# 화면의 양 옆과 아랫쪽 끝에 도달했을 때 다시 되돌아오도록 설정
if claw.rect.left < 0 or claw.rect.right > screen_width or claw.rect.bottom > screen_height:
to_x = -return_speed
# 원위치에 오면 다시 원래대로 rotate하도록 설정
if claw.offset.x < default_offset_x_claw:
to_x = 0 # to_x 다시 초기화
claw.set_init_state() # 각도와 이동 방향도 함께 초기화 하기 위해 set_init_state 메소드 실행
screen.blit(background, (0, 0)) # 맨 왼쪽 맨 위부터 ((0,0) 좌표부터)그림을 그려주도록 만들어준다!
gemstone_group.draw(screen) # gemstone_group에 있는 모든 Sprite를 screen에다가 그려라!
claw.update(to_x)
claw.draw(screen)
pygame.display.update() # 설정한 배경화면 이미지를 pygame에 반영! (display에 업데이트!!)
pygame.quit() # while문을 빠져나가면 게임이 끝나도록 설정
어렵게만 생각했던 게임 속 예외 처리가 실제로는 노가다의 연속이라는 것을 알게 되었습니다.. ㅋㅋㅋㅋㅋㅋ
이제 집게의 움직임도 하나하나 설정했으니, 보석과 집게가 만나야겠죠?
다음 포스팅에서는 충돌처리에 대한 내용으로 다시 찾아뵙겠습니다!
그렇다면 다음 포스팅에서 다시 뵙겠습니다 :) 감사합니다!
최근댓글