https://www.youtube.com/watch?v=Dkx8Pl6QKW0&list=LL&index=7
베이직(가운데 있는 공 피해 움직이기)
import pygame
pygame.init() #초기화 (필수!)
#화면 크기 설정
screenwidth = 480 #가로크기
screenheight = 640 #세로크기
screen = pygame.display.set_mode((screenwidth, screenheight))
#화면 타이틀 설정
pygame.display.set_caption("game") #게임 이름
#FPS
clock = pygame.time.Clock()
#배경 이미지 불러오기
background = pygame.image.load("C:/Users/User/Desktop/python workspace/pygame_basic/background.png")
#캐릭터(스프라이트) 불러오기
character = pygame.image.load("C:/Users/User/Desktop/python workspace/pygame_basic/character.png")
charactersize = character.get_rect().size #이미지 크기 구해옴
characterwidth = charactersize[0]
characterheight = charactersize[1]
characterxpos = (screenwidth / 2) - (characterwidth/2) #화면 가로 중앙
characterypos = screenheight-characterheight #화면 세로 크기 가장 아래
#이동할 좌표
tox = 0
toy = 0
#이동속도
characterspeed = 0.6
#적 enemy 캐릭터
enemy = pygame.image.load("C:/Users/User/Desktop/python workspace/pygame_basic/enemy.png")
enemysize = enemy.get_rect().size #이미지 크기 구해옴
enemywidth = enemysize[0]
enemyheight = enemysize[1]
enemyxpos = (screenwidth / 2) - (enemywidth/2) #화면 가로 중앙
enemyypos = (screenheight / 2) - (enemyheight/2)
#폰트 정의
gamefont = pygame.font.Font(None, 40) #폰트 객체 생성 (폰트, 크기)
#총시간
totaltime = 10
#시작시간 정보
startticks = pygame.time.get_ticks() #현재 tick 받아옴
#이벤트 루프
running = True #게임이 진행중인가
while running:
dt = clock.tick(60) #게임화면의 초당 프레임 수 설정
#캐릭터가 1초 동안 100만큼 이동해야 함
#10 fps : 1초 동안 10번 동작 => 1번에 10만큼 이동함 10*10
#20 fps : 1초 동안 20번 동작 => 1번에 5만큼 이동함 5*20
print("fps: " + str(clock.get_fps()))
for event in pygame.event.get(): #어떤 이벤트가 발생했는가
if event.type == pygame.QUIT: #창이 닫히는 이벤트가 발생했는가
running = False #게임 진행중 아님
if event.type == pygame.KEYDOWN: #키가 눌러졌는지 확인
if event.key == pygame.K_LEFT:
tox -= characterspeed
elif event.key == pygame.K_RIGHT:
tox += characterspeed
elif event.key == pygame.K_UP:
toy -= characterspeed
elif event.key == pygame.K_DOWN:
toy += characterspeed
if event.type == pygame.KEYUP: #방향키 떼면 멈춤
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
tox = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
toy = 0
characterxpos += tox * dt
characterypos += toy * dt
#가로 경계값 처리
if characterxpos < 0:
characterxpos = 0
elif characterxpos > screenwidth-characterwidth:
characterxpos = screenwidth-characterwidth
#세로 경계값 처리
if characterypos < 0:
characterypos = 0
elif characterypos > screenheight-characterheight:
characterypos = screenheight-characterheight
#충돌 처리를 위한 rect 정보 업데이트
characterrect= character.get_rect() #사각형 정보 불러오기
characterrect.left = characterxpos
characterrect.top = characterypos
enemyrect= enemy.get_rect()
enemyrect.left = enemyxpos
enemyrect.top = enemyypos
#충돌 체크
if characterrect.colliderect(enemyrect): #사각형 충돌 확인
print("충돌!")
running = False
screen.blit(background, (0,0)) #배경 그리기
# screen.fill((0,0,255))도 배경 채우기 가능
screen.blit(character, (characterxpos, characterypos))
screen.blit(enemy, (enemyxpos, enemyypos))
#타이머 집어넣기
#경과 시간 집어넣기
elapsedtime= (pygame.time.get_ticks()-startticks) / 1000 #경과시간(ms)을 1000으로 나누어 초단위 표시
timer = gamefont.render(str(int(totaltime-elapsedtime)), True, (255,255,255)) #10,9,8.. 본격 구현
screen.blit(timer, (10,10))
#만약 시간 0이하이면 게임 종료
if totaltime - elapsedtime <= 0:
print("타임아웃")
running = False
#잠시대기
pygame.time.delay(2000) #2초 정도 대기 (ms)
pygame.display.update() #게임화면 다시 그리기 (계속 호출하기)
#pygame 종료
pygame.quit()
프로젝트(똥피하기게임)
#1 모든 공을 없애면 게임 종료 (성공)
#2 캐릭터가 공에 닿으면 게임 종료 (실패)
#3 시간 제한 99초 초과 시 게임 종료 (실패)
import os
import pygame
#############################################################
pygame.init()
#화면 크기 설정
screenwidth = 640 #가로크기
screenheight = 480 #세로크기
screen = pygame.display.set_mode((screenwidth, screenheight))
#화면 타이틀 설정
pygame.display.set_caption("hello") #게임 이름
#FPS
clock = pygame.time.Clock()
#################################################################
#1. 사용자 게임 초기화 (배경 화면, 게임 이미지, 좌표, 속도, 폰트 등)
currentpath = os.path.dirname(__file__) #현재 파일 위치 반환
imagepath = os.path.join(currentpath, "images") #이미지 폴더 위치 반환
#배경 만들기
background = pygame.image.load(os.path.join(imagepath, "background.png"))
#스테이지 만들기
stage = pygame.image.load(os.path.join(imagepath, "stage.png"))
stagesize = stage.get_rect().size
stageheight = stagesize[1] #스테이지 높이 위에 캐릭터 두기 위해 사용
#캐릭터 만들기
character = pygame.image.load(os.path.join(imagepath, "character.png"))
charactersize = character.get_rect().size
characterwidth = charactersize[0]
characterheight = charactersize[1]
characterxpos = screenwidth/2 - characterwidth/2
characterypos = screenheight - stageheight - characterheight
#캐릭터 이동방향
charactertox = 0
#캐릭터 이동속도
characterspeed = 5
#무기 만들기
weapon = pygame.image.load(os.path.join(imagepath, "weapon.png"))
weaponsize = weapon.get_rect().size
weaponwidth = weaponsize[0]
#무기는 한번에 여러발 발사 가능
weapons = []
#무기 이동 속도
weaponspeed = 10
#공 만들기 (4개 크기 따로 처리)
ballimages = [
pygame.image.load(os.path.join(imagepath, "ball1.png")),
pygame.image.load(os.path.join(imagepath, "ball2.png")),
pygame.image.load(os.path.join(imagepath, "ball3.png")),
pygame.image.load(os.path.join(imagepath, "ball4.png"))]
#공 크기에 따른 최초 스피드
ballspeedy = [-18,-15, -12, -9] #공이 튀어오를 때 y값은 줄어들기 때문에 속도 마이너스 처리
#공들
balls = []
#최초 발생하는 큰 공 추가
balls.append({
"posx" : 50, #공의 x 좌표
"posy" : 50, #공의 y 좌표
"imgidx" : 0, #공의 이미지 인덱스
"tox" : 3, #x축 이동방향, -3이면 왼쪽 3이면 오른쪽 이동
"toy" : -6, #y축 이동방향,
"initspdy" : ballspeedy[0]}) #y 최초 속도
#사라질 무기, 공 정보 저장
weapontoremove = -1
balltoremove = -1
#Font 정의
gamefont = pygame.font.Font(None, 40)
totaltime = 100
startticks = pygame.time.get_ticks() #시작시간 정의
#게임 종료 메시지
# Time over(시간 초과 실패)
# Mission Complete(성공)
# Game over(캐릭터 공 충돌, 실패)
gameresult = "Game Over"
running = True
while running:
dt = clock.tick(30)
#2. 이벤트 처리(키보드, 마우스 등)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
charactertox -= characterspeed
elif event.key == pygame.K_RIGHT:
charactertox += characterspeed
elif event.key == pygame.K_SPACE: #무기 발사
weaponxpos = characterxpos + characterwidth/2 - weaponwidth/2
weaponypos = characterypos
weapons.append([weaponxpos, weaponypos])
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
charactertox = 0
#3. 게임 캐릭터 위치 정의
characterxpos += charactertox
if characterxpos < 0:
characterxpos = 0
if characterxpos > screenwidth - characterwidth:
characterxpos = screenwidth - characterwidth
#무기 위치 조정
#100,200 ->y만 180, 160, 140....
weapons =[ [w[0],w[1]-weaponspeed] for w in weapons] for in 문이 반복도 포함이었나..
#천장에 닿은 무기 없애기
weapons =[ [w[0],w[1]-weaponspeed] for w in weapons if w[1] > 0]
#공 위치 정의
for ballidx, ballval in enumerate(balls):
ballposx = ballval["posx"]
ballposy = ballval["posy"]
ballimgidx = ballval["imgidx"]
ballsize = ballimages[ballimgidx].get_rect().size
ballwidth = ballsize[0]
ballheight = ballsize[1]
#가로벽 부딪혔을 때 공 튕겨나오는 효과
if ballposx <= 0 or ballposx > screenwidth - ballwidth:
ballval["tox"] = ballval["tox"] * -1
#세로벽 부딪혔을 때 공 튕겨나오는 효과
if ballposy >= screenheight - stageheight - ballheight:
ballval["toy"] = ballval["initspdy"]
else: ballval["toy"] += 0.5 #그외 모든 경우 속도값 증가(속도값 마이너스기 때문에 느려짐)
ballval["posx"] += ballval["tox"]
ballval["posy"] += ballval["toy"]
#4. 충돌 처리
#캐릭터 rect 정보 업데이트
characterrect = character.get_rect()
characterrect.left = characterxpos
characterrect.top = characterypos
for ballidx, ballval in enumerate(balls):
ballposx = ballval["posx"]
ballposy = ballval["posy"]
ballimgidx = ballval["imgidx"]
#공 rect 정보 업데이트
ballrect = ballimages[ballimgidx].get_rect()
ballrect.left = ballposx
ballrect.top = ballposy
#공과 캐릭터 충돌 처리
if characterrect.colliderect(ballrect):
running = False
break
#공과 무기들 충돌 처리
for weaponidx, weaponval in enumerate(weapons):
weaponposx = weaponval[0]
weaponposy = weaponval[1]
#무기 rect 정보 업데이트
weaponrect = weapon.get_rect()
weaponrect.left = weaponposx
weaponrect.top = weaponposy
#충돌 체크
if weaponrect.colliderect(ballrect):
weapontoremove = weaponidx #해당 무기 없애기 위한 값 설정
balltoremove = ballidx
#가장 작은 크기 공이 아니라면 다음 단계의 공으로 나눠주기
if ballimgidx < 3:
#현재 공 크기 정보 불러오기
ballwidth = ballrect.size[0]
ballheight = ballrect.size[1]
#나눠진 공 정보
smallballrect = ballimages[ballimgidx + 1].get_rect()
smallballwidth = smallballrect.size[0]
smallballheight = smallballrect.size[1]
#왼쪽으로 튕겨나가는 작은 공
balls.append({
"posx" : ballposx + ballwidth/2 - smallballwidth/2 , #공의 x 좌표
"posy" : ballposy + ballheight/2 - smallballheight/2 , #공의 y 좌표
"imgidx" : ballimgidx + 1, #공의 이미지 인덱스
"tox" : -3, #x축 이동방향, -3이면 왼쪽 3이면 오른쪽 이동
"toy" : -6, #y축 이동방향,
"initspdy" : ballspeedy[ballimgidx + 1]}) #y 최초 속도
#오른쪽으로 튕겨나가는 작은 공
balls.append({
"posx" : ballposx + ballwidth/2 - smallballwidth/2 , #공의 x 좌표
"posy" : ballposy + ballheight/2 - smallballheight/2 , #공의 y 좌표
"imgidx" : ballimgidx + 1, #공의 이미지 인덱스
"tox" : 3, #x축 이동방향, -3이면 왼쪽 3이면 오른쪽 이동
"toy" : -6, #y축 이동방향,
"initspdy" : ballspeedy[ballimgidx + 1]}) #y 최초 속도
break
else: #계속 게임 진행
continue #안쪽 for문 조건 맞지 않으면 continue, 바깥 for 문 계속 수행
break #안쪽 for문에서 break를 만나면 여기로 진입 가능, 2중 for문을 한번에 탈출
#충돌된 공 or 무기 없애기
if balltoremove > -1 :
del balls[balltoremove]
balltoremove = -1
if weapontoremove > -1 :
del weapons[weapontoremove]
weapontoremove = -1
#모든 공 없앤 경우 게임 종료 (성공)
if len(balls) == 0 :
gameresult = "Mission Complete"
running=False
#5. 화면에 그리기
screen.blit(background,(0,0))
for weaponxpos, weaponypos in weapons:
screen.blit(weapon,(weaponxpos,weaponypos))
for idx, val in enumerate(balls):
ballposx = val["posx"]
ballposy = val["posy"]
ballimgidx = val["imgidx"]
screen.blit(ballimages[ballimgidx], (ballposx, ballposy))
screen.blit(stage, (0,screenheight-stageheight))
screen.blit(character,(characterxpos,characterypos))
#경과시간 계산
elapsedtime = (pygame.time.get_ticks() - startticks)/1000 #ms -> s
timer = gamefont.render("Time:{}".format(int(totaltime -elapsedtime)), True, (255,255,255))
screen.blit(timer, (10,10))
#시간초과했다면
if totaltime - elapsedtime <= 0:
gameresult = "Time Over"
running = False
pygame.display.update() #게임화면 다시 그리기 (계속 호출하기)
#게임오버 메시지
msg = gamefont.render(gameresult, True, (255,255,0))
msgrect = msg.get_rect(center=(int(screenwidth/2), int(screenheight/2)))
screen.blit(msg, msgrect)
pygame.display.update()
#2초 대기
pygame.time.delay(2000)
pygame.quit()
집중력이 낮아서 활용편 하나도 몇일을 보고 또 복습한 듯 하다. 하루에 다섯시간은 할애해서 2~3일만에 강의 수강, 복습, 2차 복습까지 하는 게 목표다. 헷갈리는 부분은 표시하고 다시 공부해봐야겠다.
'Programming > 파이썬' 카테고리의 다른 글
| 나도코딩 활용편2 GUI 프로그래밍 ft.백업의 중요성 (0) | 2022.02.10 |
|---|