728x90
반응형
이 글은 아래 영상을 참고했다.
https://www.youtube.com/watch?v=RchdRUkEWvI&list=PLz2iXe7EqJOMp5LozvYa0qca9E4OBkevW&index=9
- 캐릭터(객체 or 이미지)끼리 닿았을 때, 충돌시켜 튕겨내는 효과 만들기
import pygame
pygame.init()
background = pygame.display.set_mode((550, 382)) # 배경 이미지에 맞추어 화면크기 설정함
pygame.display.set_caption('PYGAME_8')
# 이미지 파일 준비
image_bg = pygame.image.load('./image/fungo.png')
image_ball = pygame.image.load('./image/ball_small.png')
image_glove = pygame.image.load('./image/glove_small.png')
# 배경의 사이즈 가져오기
size_bg_width = background.get_size()[0]
size_bg_height = background.get_size()[1]
# glove의 사이즈 가져오기
size_glove_width = image_glove.get_rect().size[0]
size_glove_height = image_glove.get_rect().size[1]
# glove의 좌표값 설정하기
x_pos_glove = size_bg_width/2 - size_glove_width/2 # x좌표값 상 중앙
y_pos_glove = size_bg_height - size_glove_height # 맨 아래 (전체 높이에서 이미지 높이 만큼 뺀 값)
# 키보드 움직임에 의한 좌표 변수 (양 옆으로만 움직일 것이므로 x좌표만)
to_x = 0
# ball의 사이즈 가져오기 (가로, 세로)
size_ball_width = image_ball.get_rect().size[0]
size_ball_height = image_ball.get_rect().size[1]
# ball의 좌표값 설정하기
x_pos_ball = size_bg_width/2 - size_ball_width/2 # 가운데
y_pos_ball = 0 # 맨 위
# ball의 x,y 축 속도 변수 (좌표에 더해줄 목적)
x_speed_ball = 1
y_speed_ball = 1
play = True
while play:
for event in pygame.event.get():
if event.type == pygame.QUIT:
play = False
if event.type == pygame.KEYDOWN: # 키보드가 눌렸을때
if event.key == pygame.K_RIGHT:
to_x = 1
elif event.key == pygame.K_LEFT:
to_x = -1
if event.type == pygame.KEYUP: # 키보드를 뗐을때
if event.key == pygame.K_RIGHT:
to_x = 0
elif event.key == pygame.K_LEFT:
to_x = 0
# glove가 화면 밖으로 벗어나지 않도록 제한
if x_pos_glove < 0:
x_pos_glove = 0
elif x_pos_glove > size_bg_width - size_glove_width:
x_pos_glove = size_bg_width - size_glove_width
else:
x_pos_glove += to_x
x_pos_ball += x_speed_ball
y_pos_ball += y_speed_ball
# x좌표값을 제한하고 speed변수를 음수로 바꿔 방향 전환하기
if x_pos_ball <= 0:
x_speed_ball = -x_speed_ball
x_pos_ball = 0
elif x_pos_ball >= size_bg_width - size_ball_width:
x_speed_ball = -x_speed_ball
x_pos_ball = size_bg_width - size_ball_width
if y_pos_ball <= 0:
y_speed_ball = -y_speed_ball
y_pos_ball = 0
elif y_pos_ball >= size_bg_height-size_ball_height:
y_speed_ball = -y_speed_ball
y_pos_ball = size_bg_height-size_ball_height
# ball의 현재 위치를 업데이트 하기위해 이미지의 좌표를 불러와 업데이트
rect_ball = image_ball.get_rect()
# ball의 왼쪽 위 가장자리 좌표를 업데이트
rect_ball.left = x_pos_ball
rect_ball.top = y_pos_ball
rect_glove = image_glove.get_rect()
rect_glove.left = x_pos_glove
rect_glove.top = y_pos_glove
if rect_glove.colliderect(rect_ball): # 객체 충돌 시 방향 전환
x_speed_ball = -x_speed_ball
y_speed_ball = -y_speed_ball
# 이미지 삽입 및 업데이트
background.blit(image_bg, (0,0))
background.blit(image_ball, (x_pos_ball, y_pos_ball))
background.blit(image_glove, (x_pos_glove, y_pos_glove))
pygame.display.update()
pygame.quit()
이전 코드를 거의 그대로 가져와 한 부분 만 추가하면 코드 구현이 가능하다.
코드가 이전보다 많이 길어졌기 때문에, 추가된 부분만 따로 가져와 본다.
# ball의 현재 위치를 업데이트 하기위해 이미지의 좌표를 불러와 업데이트
rect_ball = image_ball.get_rect()
# ball의 왼쪽 위 가장자리 좌표를 업데이트
rect_ball.left = x_pos_ball
rect_ball.top = y_pos_ball
rect_glove = image_glove.get_rect()
rect_glove.left = x_pos_glove
rect_glove.top = y_pos_glove
if rect_glove.colliderect(rect_ball): # 객체 충돌 시 방향 전환
x_speed_ball = -x_speed_ball
y_speed_ball = -y_speed_ball
- pygame에서의 이미지는 rect(), 즉 사각형이 그 이미지의 범위로 인식한다.
- 이미지끼리의 객체 충돌은 그 이미지를 감싸고 있는 사각형끼리의 충돌로 생각해야 한다.
- .colliderect() 메서드로 각 객체끼리 겹치는 부분이 있는지 알 수 있다.
위 점들을 이용해 객체(이미지)끼리의 충돌을 감지하고, 튕겨낼 수 있다.
시연 영상
본격적인 펑고 게임 만들기
- 펑고 게임의 목적에 맞게, 야구공과 글러브 충돌 시 공을 잡았다고 가정
- 공을 잡을 시 새로운 공이 랜덤좌표에서 새롭게 등장하도록 수정
import pygame
import numpy as np # np.random메서드를 위해 임포트
pygame.init()
background = pygame.display.set_mode((550, 382)) # 배경 이미지에 맞추어 화면크기 설정함
pygame.display.set_caption('PYGAME_8')
# 이미지 파일 준비
image_bg = pygame.image.load('./image/fungo.png')
image_ball = pygame.image.load('./image/ball_small.png')
image_glove = pygame.image.load('./image/glove_small.png')
# 배경의 사이즈 가져오기
size_bg_width = background.get_size()[0]
size_bg_height = background.get_size()[1]
# glove의 사이즈 가져오기
size_glove_width = image_glove.get_rect().size[0]
size_glove_height = image_glove.get_rect().size[1]
# glove의 좌표값 설정하기
x_pos_glove = size_bg_width/2 - size_glove_width/2 # x좌표값 상 중앙
y_pos_glove = size_bg_height - size_glove_height # 맨 아래 (전체 높이에서 이미지 높이 만큼 뺀 값)
# 키보드 움직임에 의한 좌표 변수 (양 옆으로만 움직일 것이므로 x좌표만)
to_x = 0
# ball의 사이즈 가져오기 (가로, 세로)
size_ball_width = image_ball.get_rect().size[0]
size_ball_height = image_ball.get_rect().size[1]
# ball의 좌표값 설정하기
x_pos_ball = size_bg_width/2 - size_ball_width/2 # 가운데
y_pos_ball = 0 # 맨 위
# ball의 x,y 축 속도 변수 (좌표에 더해줄 목적)
x_speed_ball = 1
y_speed_ball = 1
play = True
while play:
for event in pygame.event.get():
if event.type == pygame.QUIT:
play = False
if event.type == pygame.KEYDOWN: # 키보드가 눌렸을때
if event.key == pygame.K_RIGHT:
to_x = 1
elif event.key == pygame.K_LEFT:
to_x = -1
if event.type == pygame.KEYUP: # 키보드를 뗐을때
if event.key == pygame.K_RIGHT:
to_x = 0
elif event.key == pygame.K_LEFT:
to_x = 0
# glove가 화면 밖으로 벗어나지 않도록 제한
if x_pos_glove < 0:
x_pos_glove = 0
elif x_pos_glove > size_bg_width - size_glove_width:
x_pos_glove = size_bg_width - size_glove_width
else:
x_pos_glove += to_x
x_pos_ball += x_speed_ball
y_pos_ball += y_speed_ball
# x좌표값을 제한하고 speed변수를 음수로 바꿔 방향 전환하기
if x_pos_ball <= 0:
x_speed_ball = -x_speed_ball
x_pos_ball = 0
elif x_pos_ball >= size_bg_width - size_ball_width:
x_speed_ball = -x_speed_ball
x_pos_ball = size_bg_width - size_ball_width
if y_pos_ball <= 0:
y_speed_ball = -y_speed_ball
y_pos_ball = 0
elif y_pos_ball >= size_bg_height-size_ball_height:
y_speed_ball = -y_speed_ball
y_pos_ball = size_bg_height-size_ball_height
# ball의 현재 위치를 업데이트 하기위해 이미지의 좌표를 불러와 업데이트
rect_ball = image_ball.get_rect()
# ball의 왼쪽 위 가장자리 좌표를 업데이트
rect_ball.left = x_pos_ball
rect_ball.top = y_pos_ball
rect_glove = image_glove.get_rect()
rect_glove.left = x_pos_glove
rect_glove.top = y_pos_glove
if rect_glove.colliderect(rect_ball): # 객체 충돌 시 랜덤한 곳에서 새로운 공 등장
x_pos_ball = np.random.randint(550) # 배경화면의 가로길이(550) 중 랜덤한 정수 하나 반환
y_pos_ball = 0 # 맨 위
# 이미지 삽입 및 업데이트
background.blit(image_bg, (0,0))
background.blit(image_ball, (x_pos_ball, y_pos_ball))
background.blit(image_glove, (x_pos_glove, y_pos_glove))
pygame.display.update()
pygame.quit()
수정된건 크게없다. 객체가 충돌 시 ball의 좌표를 수정해주면 끝이다.
처음에는 ball을 삭제하고 다시 만들어야 하나 싶었지만, 영구적으로 없애는 것이 아니기에 좌표만 수정해주면 끝이다.
x좌표를 numpy를 이용해 랜덤값으로, y좌표는 최상단으로 고정해주었다.
시연 영상
생각보다 어렵다. 여기에 속도도 점점 빨라지면 난이도가 꽤 있는 게임이 될 것 같다.
반응을 빠르게 하기위해 글러브를 키보드 대신 마우스로 움직이게 해도 괜찮을 것 같다.
728x90
'Minding's Programming > Pygame' 카테고리의 다른 글
[Pygame] 11. 게임오버 화면 추가 및 게임 종료하기 (0) | 2023.02.09 |
---|---|
[Pygame] 10. 점수 추가하기 (0) | 2023.02.08 |
[Pygame] 08. 이미지 객체 추가 및 키보드로 움직이기 (0) | 2023.02.06 |
[Pygame] 07. 이미지 벽에 닿았을 때 튕기기 (0) | 2023.02.05 |
[Pygame] 06. 키보드와 마우스로 이미지 움직이기 (0) | 2023.02.04 |