python/python_pygame
pygame 기초
몽자비루
2023. 3. 22. 01:05
##1 환경설정 & 프레임
######################################################################
# 무조건 해야하는 부분
######################################################################
import pygame
#1 초기화 (반드시 필요.)
pygame.init()
#1 화면 크기 설정
screen_width = 480 # 가로 크기
screen_height = 640 # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))
#1 화면 타이틀 설정
pygame.display.set_caption("rusharp Game") # 게임 이름
######################################################################
# 사용자 게임 초개화 (배경화면, 게임이미지, 좌표, 속도, 폰트 등)
######################################################################
##2 배경 이미지 불러오기
background = pygame.image.load("경로\\background.png")
##3 캐릭터(스프라이트) 불러오기
character = pygame.image.load("경로\\character.png")
#3 캐릭터 사이즈를 가져옴 (가로/세로 크기)
character_size = character.get_rect().size
character_width = character_size[0]
character_height = character_size[1]
#3 캐릭터가 움직일수 있는 가로/세로 범위
character_x_pos = (screen_width-character_width)/2
character_y_pos = screen_height-character_height
## 4 키보드 이벤트
#4 이동할 좌표
to_x = 0
to_y = 0
#5 이동속도
character_speed = 0.3
##5 FPS
# 프레임 수가 높을수록 부드럽다.
clock = pygame.time.Clock()
##6 충돌 처리
#6 적 (enemy) 캐릭터
enemy = pygame.image.load("경로\\enemy.png")
#6 캐릭터 사이즈를 가져옴 (가로/세로 크기)
enemy_size = enemy.get_rect().size
enemy_width = enemy_size[0]
enemy_height = enemy_size[1]
#6 캐릭터가 움직일수 있는 가로/세로 범위
enemy_x_pos = (screen_width-enemy_width)/2
enemy_y_pos = (screen_height-enemy_height)/2
##7 텍스트
#7 폰트 정의 : 폰트 객체 생성, (폰트, 크기)
game_fond = pygame.font.Font(None, 40)
total_time = 10
#7 시작 시간 정보를 받아옴.
start_ticks = pygame.time.get_ticks()
#1 이벤트 루프
#1 화면이 켜지자마자 꺼지지 않도록 함.
running = True # 게임이 진행중인가?
while running:
#5 게임화면의 초당 프레임수를 설정함.
dt = clock.tick(60)
######################################################################
# 이벤트 처리 (키보드, 마우스 등)
######################################################################
#1 사용자로부터 키보드/마우스 이벤트가 들어오는 지 체크함.
#1 들어온다면 액션에 맞는 이벤트를 진행함.
for event in pygame.event.get():
#1 여러 이벤트 중 들어온 이벤트가 QUIT이라면 runnig 은 False
#1 창이 닫히는 이벤트가 발생하였는지 확인함.
if event.type == pygame.QUIT:
running = False
#4 키보드가 눌렸는지 확인.
if event.type == pygame.KEYDOWN:
#4 캐릭터를 왼쪽으로
if event.key == pygame.K_LEFT:
to_x -=character_speed
#4 캐릭터를 오른쪽으로
elif event.key == pygame.K_RIGHT:
to_x +=character_speed
#4 캐릭터를 위쪽으로
elif event.key == pygame.K_UP:
to_y -=character_speed
#4 캐릭터를 아래쪽으로
elif event.key == pygame.K_DOWN:
to_y +=character_speed
#4 키보드에서 손을 떼면
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
to_x = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
to_y = 0
#4 이 부분이 for문 안에 들어가있으면 키 입력마다 작동하고
#4 이 부분이 for문 밖에 들어가있으면 연속 키누름에도 작동됨
#5 캐릭터가 1초에 100만큼 이동해야할 떄,
#5 10fps : 1초동안 10번 동작 > 1번에 10만큼 이동해야함
#5 20fps : 1초동안 20번 동작 > 1번에 5만큼 이동해야함.
#5 즉, 이동하는 곳에 dt를 곱하면 frame 관계없이 속도가 일정함.
character_x_pos +=to_x*dt
character_y_pos +=to_y*dt
#4 가로 경계값 처리
if character_x_pos < 0 :
character_x_pos = 0
elif character_x_pos > screen_width - character_width:
character_x_pos = screen_width - character_width
#4 세로 경계값 처리
if character_y_pos < 0 :
character_y_pos = 0
elif character_y_pos > screen_height - character_height:
character_y_pos = screen_height - character_height
#6 충돌 처리
#6 실제로 캐릭터 자체의 rect 이미지는 처음 호출한 위치에 고정되어 있다.
character_rect = character.get_rect()
character_rect.left = character_x_pos
character_rect.top = character_y_pos
enemy_rect = enemy.get_rect()
#6 직접적으로 enemy_rect 에 반영된 것이 아니기 때문에 직접 업데이트해야함.
enemy_rect.left = enemy_x_pos
enemy_rect.top = enemy_y_pos
#6 충돌 체크
#6 colliderect : Rect와 자신에게 겹침이 있는지 없는지(충돌)를 반환
if character_rect.colliderect(enemy_rect):
print("충돌했어요")
running = False
#2 원하는 rgb색상으로 화면을 채움.
#2 screen.fill((0,0,255))
#2 원하는 이미지(background)가 0.0 좌표를 시작으로 배경을 그려줌.
screen.blit(background, (0,0))
#3 캐릭터를 그려줌.
screen.blit(character, (character_x_pos, character_y_pos))
#6 적을 그려줌.
screen.blit(enemy, (enemy_x_pos, enemy_y_pos))
#7 타이머 집어넣기
#7 경과시간을 1000으로 나누어서 초단위로 표시
elspsed_time = (pygame.time.get_ticks() - start_ticks)//1000
# timer 에 GUI에서 열 수 있는 텍스트를 삽입함(character 처럼)
timer = game_fond.render(str(total_time - elspsed_time),True, (0,0,0))
#7 만약 시간이 0 이하이면 게임 종료
if total_time - elspsed_time <=0:
timer = game_fond.render("Time out",True, (0,0,0))
running = False
screen.blit(timer, (10,10))
# #7 만약 시간이 0 이하이면 게임 종료
# if total_time - elspsed_time <=0:
# print("타임아웃")
# running = False
#2 게임 화면을 다시 그리기
#2 아래 내용이 없는 경우, 화면이 한번 보여지고 바로 초기화(검정)됨.
pygame.display.update()
#7 종료 직전 잠시 대기할 수 있는 코드
pygame.time.delay(2000)
#1 pygame 종료
pygame.quit()
- 환경설정 & 프레임
- pygame.init(): pygame의 초기화
- screen = pygame.display.set_mode((x, y)) : 창을 x y 크기로 바꿈.
ㄴ screen.blit(객체, (x, y))로 x y 위치에 객체를 띄움. - pygame.display.set_caption("게임이름") : 타이틀바의 텍스트를 설정한다.
- while running: 이벤트 루프를 통해 명시적으로 종료시킴.
- for event in pygame.event.get() : 입력받은 값을 event에 in하게됨.
- event.type == pygame.QUIT : 닫기 버튼을 누르면
- pygame.quit() : 게임을 종료함.
- 배경
- background = pygame.image.load(”경로”) :
경로의 파일을 이미지로 불러와 background 변수에 삽입. - 객체.blit(background, (x,y)) : 객체를 x,y좌표에 출력함.
- pygame.display.update() : 화면이 계속 업데이트 되도록 다시 그림
ㄴ 추가로 display.flip()는 전체, display.update()는 특정부분만 업데이트.
- background = pygame.image.load(”경로”) :
- 캐릭터
- pygame의 전역 변수 중 size를 통해 객체의 크기를 가져올 수 있음.
ㄴ size = 객체.get_rect().size 를 통해 객체의 가로, 세로를 tuple로 가져옴
- pygame의 전역 변수 중 size를 통해 객체의 크기를 가져올 수 있음.
- 키보드 이벤트
- event.type == pygame.KEYDOWN : 키보드를 눌렀을 때
ㄴ event.type : 발생한 이벤트 종류를 나타내는 문자열. - event.key == pygame.K_LEFT/K_RIGHT/K_UP/K_DOWN : 왼/오/위/아래
ㄴ event.key : 키보드의 키릘 나타내는 값 - 객체가 화면 밖으로 넘어가지 않도록 가로/세로 경계값 설정
- event.type == pygame.KEYDOWN : 키보드를 눌렀을 때
- FPS
- pygame.time.Clock : 시간 추적 개체 생성
- clock.tick(n) : 프레임 당 한번씩 호출해야 함
ㄴ 이전 호출 이후 몇 밀리 초가 경과했는지 계산
ㄴ 초당 틱보다 느리게 실행되도록 지연해 프레임이 n을 초과하지 않음 - frame관계없이 이동속도를 동일하게 하고싶은 경우,
이동속도 x 초당 프레임수 (clock.tick(n)) 를 하면 된다.
- 충돌 처리
- 충돌처리를 위해서는 어떠한 객체의 실시간 위치를 받아와야 함
ㄴ 객체의 rect 좌표는 처음 호출한 위치에 고정되어 있다.
ㄴ 즉, 충돌처리를 위해선 객체.get_rect.left/top 을 주기적으로 갱신해야 함. - 객채1.colliderect(객체2) : 객체2와 객체1의 겹침 여부를 반환함.
- 충돌처리를 위해서는 어떠한 객체의 실시간 위치를 받아와야 함
- 텍스트
- text = pygame.font.Font(폰트, 크기) : 폰트 객체를 생성.
- start_ticks = pygame.time.get_ticks() pygame.init() 가 호출 된 이후의 밀리 초 수를 반환 .
파이 게임이 초기화되기 전에 항상 0이다 - pygame.time.get_ticks()-시작 시간으로 소요시간 계산(밀리초 단위)
- 폰트 객체.render(텍스트,antialias, color, background=None)
ㄴ 텍스트를 blit하기 위해서 위를 통해 surface 객체로 변환해야 함.
ㄴ 안티알리아싱 : 선을 부드럽게 만드는 그래픽 기법이다. - pygame.time.delay(2000) : 대기할 수 있는 코드(밀리초 단위)