Player Sprite 만들기
Sprite란 Screen에 있는 모든 object입니다.
하지만 이러한 Sprite를 하나하나 update하고 draw해주기에는 너무 일이 많아지기때문에
pygame에서 제공해주는 sprite.Group()을 이용해 모든 sprite를 제어해주겠습니다.
1. sprite그룹 만들어주기
pygame.display.set_caption("My Game") #그리고 screen의 캡션, 웹페이지의 title과 비슷한 부분도 설정해준다.
clock = pygame.time.Clock() #게임내 시간을 우리가 원하는대로 환경의 구분없이 일정하게 유지하기 위해서 설정해주었다.
all_sprites = pygame.sprite.Group()
all_sprites를 이용해서 sprite들을 group화 해서 편하게 관리해줍니다.
2. Sprite(Player) Class 생성해주기
BLUE = (0, 0, 255)
#Sprite 생성
class Player(pygame.sprite.Sprite): #Sprite는 객체이므로 우리가 만들고자 하는 Sprite의 Class를 만들어줍니다
def __init__(self): #객체가 만들어질때마다 실행되는 __init__ 메서드입니다
pygame.sprite.Sprite.__init__(self) #Sprite클래스의 initializer를 실행합니다.
self.image = pygame.Surface((50, 50)) #화면에 표시할 Sprite의 image 즉 50*50인 사각형을 만듭니다
self.image.fill(GREEN) #그리고 내부를 GREEN으로 채웁니다
self.rect = self.image.get_rect() #만들어준 image의 get_rect()를 이용해 좌표를 추적합니다
self.rect.center = (WIDTH / 2, HEIGHT / 2) #그리고 해당 좌표의 center가 화면 중앙에 오게끔 설정해준 것입니다.
Sprite는 객체 이므로 Class로 Player Class를 선언해주겠습니다.
pygame의 Sprite Class를 상속 받아서 만들어 준것을 알 수 있습니다.
아래 Sprite객체의 rect좌표 관련하여 참고 image를 첨부하겠습니다.
출처:http://kidscancode.org/blog/2016/08/pygame_1-2_working-with-sprites/ |
3. Player객체 생성해주기
all_sprites = pygame.sprite.Group()
player = Player() #플레이어 객체를 만들어 줍니다
all_sprites.add(player) #Sprite를 모아둔 그룹에다가 player객체를 추가해줍니다.
Player() 생성자를 이용해 player객체를 만들어 주고 만들어진 sprite객체를 group에 추가해줍니다.
4. Sprite그룹 화면에 표시해주기
# Update #해당 frame내에서 업데이트 될 사항에
all_sprites.update()
# Draw / render #그리고 업데이트 된 부분을 화면에 그려주는 역할을 한다
screen.fill(BLACK) #스크린을 BLACK으로 채우라는 말입니다.
all_sprites.draw(screen)
Game loop가 돌아갈때마다(한 프레임 마다)
sprite 그룹들의 update 메서드를 실행해주고
sprite 그룹들을 screen에 그려줍니다.
5. Player Class에 위치정보 추가해주기
self.image.fill(GREEN) #그리고 내부를 GREEN으로 채웁니다
self.rect = self.image.get_rect() #만들어준 image의 get_rect()를 이용해 좌표를 추적합니다
self.rect.centerx = WIDTH / 2 #rect의 중심의 x좌표가 WIDTH / 2이면 화면의 중심선에 놓이게 되고
self.rect.bottom = HEIGHT - 10 #rect의 밑부분 좌표는 높이 - 10 을 해줌으로써 screen의 밑에서 10px만큼 올라간 곳에 위치한다
self.speedx = 0 #Player가 가지고 있는 초기 스피드는 0이다(움직이지 않는다)
player 객체가 생성되는 위치를 설정해줍니다.
6. Player Class의 update 메서드에 속도 변수 추가해주기
self.speedx = 0 #Player가 가지고 있는 초기 스피드는 0이다(움직이지 않는다)
def update(self): #Game loop 내에서 all_sprite.update가 실행되면 실행되는 메서드
self.rect.x += self.speedx #update때 마다 인스턴스의 x좌표에 speedx값을 더해서 프레임이 바뀔때마다 움직이는 것처럼 보이게 한다
7. Key를 눌러 이동하는 로직넣기
7-1. Game loop 내에 event 처리 구문을 넣는 경우(지양)
for event in pygame.event.get():
# check for closing window
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN: #Key를 누르면
if event.key == pygame.K_LEFT: #만약 누른 key가 방향키 왼쪽(LEFT)일때
player.speedx = -8 #player객체가 가지고 있는 객체변수 speedx를 -8로 해준다.
#여기서 -8을 해준 이유는 screen을 기준으로 오른쪽이 +의 기호를 가지고 왼쪽이 -의 기호를 가지기 때문이다.
if event.key == pygame.K_RIGHT:
player.speedx = 8
Game loop가 돌면서 입력받은 event에 대해 type을 검사하고
key의 종류를 if문으로 검사하여 객체의 speedx를 변경시켜준다
이때 주의해야할 점이 player의 speedx를 변경시켜주면 다음 키 입력전까지 speedx가 고정되어있어서
한번의 키입력으로도 키 방향으로 Sprite가 계속 움직이게 된다.
7-2. Player Class 내에서 update를 처리하는 경우(권고)
def update(self):
self.speedx = 0 #update가 실행되면 조아 속도가 기본적으로 0으로 시작한다. 이는 우리가 key를 누르지 않으면 멈춤을 의미한다.
keystate = pygame.key.get_pressed() #key를 누른 값들을 dictionary의 형태로 keystate에 저장해두는데
if keystate[pygame.K_LEFT]: #만약 keystate에 pygame.K_LEFT의 key가 존재하면
self.speedx = -8 #인스턴스의 speedx를 -8로 수정하고
if keystate[pygame.K_RIGHT]:
self.speedx = 8
self.rect.x += self.speedx #sprite객체의 x좌표를 speedx를 통해서 변화시켜준다.
이렇게 Sprite Class의 update 메서드부분에 추가해주게 되면
Game_loop 내 all_sprite.update가 실행 될때마다
해당 메서드가 실행되게 되는데
실행될때마다 객체의 speedx를 0으로 초기화 시키고
키의 입력이 있을때만 speedx를 변경시켜 rect를 이동시켜준다
따라서 매 프레임 마다 update가 실행되고 키의 입력이 없으면 speedx는 0이므로
한번의 키입력으로 한번의 이동만을 제한해 줄 수 있다.
8. Player Sprite의 범위 제한하기(Player Class의 update메서드 수정)
self.speedx = 8
self.rect.x += self.speedx #sprite객체의 x좌표를 speedx를 통해서 변화시켜준다.
if self.rect.right > WIDTH: #sprite의 rigth좌표가 WIDTH보다 크다는 것은 sprite가 화면밖으로 나갔다는 의미이고
self.rect.right = WIDTH #right의 좌표를 WIDTH 즉 화면의 오른쪽 boundary로 고정 해준다.
if self.rect.left < 0: #sprite의 left좌표가 0보다 작은경우도 왼쪽 screen 밖으로 나갔다는 의미이다.
self.rect.left = 0
일반적으로 우리는 화면내 객체(조종 대상)가 screen 밖으로 나가기를 원하지 않습니다.
따라서 Player Sprite의 범위를 제한하여 좌우 screen 밖으로 나가지 않게 해줍니다.
위의 코드들을 이용하면 좌우 이동 뿐만아니라 상하 이동도 가능하게 할수 있습니다.
이 경우에는 screen 하단의 범위를 제한해주는게 좋습니다.
그럼 다음 포스팅에서는 Enemy Sprite에 대해서 알아보도록 합시다.