티스토리 뷰

반응형

youtu.be/l3Tm2aucU7Y

모든 강의 자료 : www.codingnow.co.kr/

간단한 게임을 만들어 보면서 프로그래밍 언어의 문법을 익혀봅니다.

 

여기에서는 기본적으로 반복문(for, while)을 사용하게 되고 조건문(if)과 기본 변수들을 사용하게 됩니다.

또한 list와 딕셔너리를 사용하여 데이타 관리를 하게 됩니다.

 

pygame의 내장 함수(colliderect)를 사용하여 간단하게 충돌 알고리즘을 사용할 수있습니다.

pygame의 화면 갱신과 이벤트 처리등을 학습 할 수 있으며,
프로그래밍의 흐름을 익힐 수 있습니다.

 

자세한 설명은 첨부된 동영상을 참고해주세요.

 

이미지 출처 : pixabay.com/

 

images.zip
4.05MB

 

import pygame
import random

pygame.init()
pygame.display.set_caption("codingnow.co.kr")

#키 이벤트 처리하기
def eventProcess():
    global isActive
    for event in pygame.event.get():         
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                isActive = False
            if infor['arrow'] > 0:
                if event.key == pygame.K_SPACE:
                    if infor['tickPlayer'] == 0:
                        infor['tickPlayer'] = pygame.time.get_ticks()
                        arrows.append(Arrow())
                        infor['arrow'] -= 1
            else:
                if event.key == pygame.K_RETURN:
                    infor['arrow'] = REMAINING_ARROW_MAX
                    infor['score'] = 0
##=================================================
def updatePlayer():
#Player 의 활 쏘는 장면 연출하기
    idex = 0
    if infor['tickPlayer'] > 0:
        elapsed_time = (pygame.time.get_ticks() - infor['tickPlayer'])
        if elapsed_time > 300:
            infor['tickPlayer'] = 0
        else:
            idex = 1
    screen.blit(playerImg[idex], playerImgRec)
#화살 날아가는 장면 연출
    for i, arr in enumerate(arrows):
        if arr.draw():
            del arrows[i]
##=================================================
def setText():
    mFont = pygame.font.SysFont("굴림", 40)
    mtext = mFont.render(f"score : {infor['score']}", True, 'yellow')
    screen.blit(mtext, (10, 10, 0, 0))
    mtext = mFont.render(f"arrows : {infor['arrow']}", True, 'yellow')
    screen.blit(mtext, (10, 42, 0, 0))

    if infor['arrow'] <= 0:  # Game Over 처리하기
        mFont = pygame.font.SysFont("굴림", 60)
        mtext = mFont.render(f'Game over!!', True, 'red')
        tRec = mtext.get_rect()
        tRec.centerx = SCREEN_WIDTH/2
        tRec.centery = SCREEN_HEIGHT/2 - 40
        screen.blit(mtext, tRec)

        mFont = pygame.font.SysFont("굴림", 40)
        mtext = mFont.render(f'(Re-challenge : enter)', True, 'green')
        tRec.centery = SCREEN_HEIGHT/2 + 80
        screen.blit(mtext, tRec)
##=================================================
def updateBoars():
    #멧돼지 업데이트
    for i, boar in enumerate(boars):
        if boar.draw():
            del boars[i]
            continue
        centerx, centery = boar.checkCollision(arrows)
        if centerx:
            wowRec.centerx = centerx
            wowRec.centery = centery
            infor['tickWow'] = pygame.time.get_ticks()
            del boars[i]
# 멧돼지가 화살에 맞았을때 효과
    if infor['tickWow'] > 0:
        elapsed_time = (pygame.time.get_ticks() - infor['tickWow'])
        if elapsed_time > 500:
            infor['tickWow'] = 0
        screen.blit(wowImg, wowRec)

#멧돼지 생성하기
    elapsed_time = (pygame.time.get_ticks() - infor['tickBoar'])
    if elapsed_time > 800:
        infor['tickBoar'] = pygame.time.get_ticks()
        boars.append(Boar())
##=================================================
#화살 생성하기
class Arrow(object):
    def __init__(self):        
        self.img = pygame.image.load('arrow.png')
        self.img = pygame.transform.scale(self.img , (int(2017/30), int(98/20)))
        self.rec = self.img.get_rect()
        self.rec.centerx = playerImgRec.centerx - 30 
        self.rec.centery = playerImgRec.centery - 40
    def draw(self):      
        if (self.rec.x) > 0:  
            self.rec.x -= 1
            screen.blit(self.img, self.rec)
            return False
        else:
            return True
##=================================================
#멧돼지 생성하기
class Boar(object):
    def __init__(self):        
        self.img = pygame.image.load('boar.png')
        self.img = pygame.transform.scale(self.img , (int(1920/20), int(1661/20)))
        self.rec = self.img.get_rect()
        self.rec.x = random.randint(0,40)
        self.rec.y = random.randint(0,SCREEN_HEIGHT) 
        self.ticks = pygame.time.get_ticks()
        self.pos = None    
    def draw(self): 
        elapsed_time = (pygame.time.get_ticks() - self.ticks)        
        if elapsed_time > 1:
            self.ticks = pygame.time.get_ticks()
            self.rec.x += random.randint(0,2)
            self.rec.y += random.randint(-8,8)                    
        if self.rec.y < SCREEN_HEIGHT and self.rec.y > 0:
            self.pos = screen.blit(self.img, self.rec)
            return False
        else:
            self.rec.y = -1
            return True            
    def checkCollision(self, arrows):
        for i, arr in enumerate(arrows):
            if arr.rec.y < 0:
                continue
            rec = arr.rec
            rec.width = 5
            rec.height = 5
            if self.pos.colliderect(arr.rec):
                infor['score'] += 10
                centerx = arr.rec.centerx
                centery = arr.rec.centery
                arr.rec.y = -1
                del arrows[i]
                return centerx,centery
        return None, None
##=================================================
#변수        
isActive = True
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 400

REMAINING_ARROW_MAX = 20
infor = {'score': 0,
         'arrow': REMAINING_ARROW_MAX,
         'tickPlayer':0,
         'tickBoar': pygame.time.get_ticks(),
         'tickWow':0}
arrows = []
boars = []

clock = pygame.time.Clock()   
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

#배경
bg = pygame.image.load('bg.png')
bg = pygame.transform.scale(bg, (SCREEN_WIDTH, SCREEN_HEIGHT))

#Player
playerFileNames = ["player_0.png", "player_1.png"]
playerImg = []
for i,name in enumerate(playerFileNames):
    playerImg.append(pygame.image.load(name))
    playerImg[i] = pygame.transform.scale(playerImg[i] , (int(623/10), int(961/10)))
playerImgRec = playerImg[0].get_rect()
playerImgRec.centerx = SCREEN_WIDTH - playerImgRec.width/2 - 10
playerImgRec.centery = SCREEN_HEIGHT/2

#wow
wowImg = pygame.image.load('wow.png')
wowImg = pygame.transform.scale(wowImg, (int(1280/20), int(873/20)))
wowRec = wowImg.get_rect()
##=================================================
#반복문
while(isActive):
    # screen.fill((0, 0, 0))
    screen.blit(bg, (0, 0, 0, 0))
    eventProcess()
    updatePlayer()
    updateBoars()
    setText()
    pygame.display.update()
    clock.tick(400)
반응형