[PYGAME] TUTORIAL

문승환·2022년 8월 9일
0

[PYGAME]

목록 보기
1/8

프로젝트 개요

  • pygame을 사용하여 Pixel Runner 제작
  • Youtube Clear Code의 The ultimate introduction to Pygame을 따라하며 진행
  • 주요 과제: python과 pygame의 사용에 익숙해지는 것

프로젝트 내용

Default Setting

import pygame
from sys import exit

pygame.init()   # initialize all imported pygame modules

screen = pygame.display.set_mode((800, 400))    # initialize a window or screen for display
clock = pygame.time.Clock()                     # create an object to help track time (for fps)

# loop for the game
while True:
    for event in pygame.event.get():    # get events from the queue
        if event.type == pygame.QUIT:   # quit the game
            pygame.quit()
            exit()
            
    pygame.display.update()     # update portions of the screen for software displays
    clock.tick(60)              # update the clock: 60fps

Pixel Runner

  • pygame 내의 sprite class를 사용해 게임 완성
import pygame
from sys import exit
from random import randint, choice

# sprite classes
# pygame module with basic game object classes
# this module contains several simple classes to be used within games
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        player_walk1 = pygame.image.load('graphics/Player/player_walk_1.png').convert_alpha()
        player_walk2 = pygame.image.load('graphics/Player/player_walk_2.png').convert_alpha()

        self.player_walk = [player_walk1, player_walk2]
        self.player_index = 0
        self.player_jump = pygame.image.load('graphics/player/jump.png').convert_alpha()

        self.image = self.player_walk[self.player_index]
        self.rect = self.image.get_rect(midbottom = (80, 300))
        self.gravity = 0

        self.jump_sound = pygame.mixer.Sound('audio/jump.mp3')
        self.jump_sound.set_volume(0.1)

    def player_input(self):
        # if enter space and on floor then jumps
        # only allow a jump
        keys = pygame.key.get_pressed()
        if keys[pygame.K_SPACE] and self.rect.bottom >= 300:
            self.gravity = -20
            self.jump_sound.play()

    def apply_gravity(self):
        # implement gravity and make floor
        self.gravity += 1
        self.rect.y += self.gravity
        if self.rect.bottom >= 300: self.rect.bottom = 300

    def animation_state(self):
        # if jump then display jump motion
        # if on floor then display walk motion by changing two different images repeatedly
        if self.rect.bottom < 300: self.image = self.player_jump
        else:
            self.player_index += 0.1
            if self.player_index >= len(self.player_walk): self.player_index = 0
            self.image = self.player_walk[int(self.player_index)]

    def update(self):
        # update all methods
        self.player_input()
        self.apply_gravity()
        self.animation_state()

class Obstacle(pygame.sprite.Sprite):
    def __init__(self, type):
        super().__init__()
        if type == 'fly':
            fly_1 = pygame.image.load('graphics/Fly/Fly1.png').convert_alpha()
            fly_2 = pygame.image.load('graphics/Fly/Fly2.png').convert_alpha()
            self.frames = [fly_1, fly_2]
            y_pos = 210

        else:
            snail_1 = pygame.image.load('graphics/snail/snail1.png').convert_alpha()
            snail_2 = pygame.image.load('graphics/snail/snail2.png').convert_alpha()
            self.frames = [snail_1, snail_2]
            y_pos = 300

        self.animation_index = 0
        self.image = self.frames[self.animation_index]
        self.rect = self.image.get_rect(midbottom = (randint(900, 1100), y_pos))

    def animation_state(self):
        # make obstacle animation by changing two different images repeatedly
        self.animation_index += 0.1
        if self.animation_index >= len(self.frames): self.animation_index = 0
        self.image = self.frames[int(self.animation_index)]

    def destroy(self):
        # if obstacle moves to out of the range then remove the Sprite from all groups
        if self.rect.x <= -100: self.kill()

    def update(self):
        # update all methods
        self.animation_state()
        self.rect.x -= 5
        self.destroy()

def display_score():
    # display score by measuring times
    current_time = int(pygame.time.get_ticks() / 500) - start_time
    score_surf = game_font.render(f'SCORE: {current_time}', False, (64, 64, 64))
    score_rect = score_surf.get_rect(center = (400, 50))
    screen.blit(score_surf, score_rect)
    return current_time

def collide_sprite():
    # check sprite and group collide
    if pygame.sprite.spritecollide(player.sprite, obstacle_group, False):
        obstacle_group.empty()
        return False
    else: return True

pygame.init()

screen = pygame.display.set_mode((800, 400))
pygame.display.set_caption('Pixel Runner')
clock = pygame.time.Clock()

game_active = False
score = 0
start_time = 0
# bg_Music = pygame.mixer.Sound('audio/music.wav')
# bg_Music.set_volume(0.1)
# bg_Music.play(loops=-2)

player = pygame.sprite.GroupSingle()
player.add(Player())

obstacle_group = pygame.sprite.Group()

sky_surf = pygame.image.load('graphics/Sky.png').convert()
ground_surf = pygame.image.load('graphics/ground.png').convert()

game_font = pygame.font.Font('font/Pixeltype.ttf', 50)

game_name = game_font.render('Pixel Runner', False, (64, 64, 64))
game_name_rect = game_name.get_rect(center = (400, 50))

game_message = game_font.render('Press space to run', False, (111, 196, 169))
game_message_rect = game_message.get_rect(center = (400, 330))

player_walk1 = pygame.image.load('graphics/Player/player_walk_1.png').convert_alpha()
player_walk2 = pygame.image.load('graphics/Player/player_walk_2.png').convert_alpha()
player_walk = [player_walk1, player_walk2]
player_index = 0
player_jump = pygame.image.load('graphics/player/jump.png')

player_surf = player_walk[player_index]
player_rect = player_surf.get_rect(midbottom = (80, 300))
player_gravity = 0

player_stand_surf = pygame.image.load('graphics/Player/player_stand.png').convert_alpha()
player_stand_surf = pygame.transform.rotozoom(player_stand_surf, 0, 2)
player_stand_rect = player_stand_surf.get_rect(center = (400, 200))

snail_frame1 = pygame.image.load('graphics/snail/snail1.png').convert_alpha()
snail_frame2 = pygame.image.load('graphics/snail/snail2.png').convert_alpha()
snail_frames = [snail_frame1, snail_frame2]
snail_frame_index = 0
snail_surf = snail_frames[snail_frame_index]

fly_frame1 = pygame.image.load('graphics/Fly/Fly1.png').convert_alpha()
fly_frame2 = pygame.image.load('graphics/Fly/Fly2.png').convert_alpha()
fly_frames = [fly_frame1, fly_frame2]
fly_frame_index = 0
fly_surf = fly_frames[fly_frame_index]

obstacle_timer = pygame.USEREVENT + 1   # custom event
pygame.time.set_timer(obstacle_timer, 1500)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

        if game_active:
            if event.type == obstacle_timer:
                obstacle_group.add(Obstacle(choice(['fly', 'snail', 'snail', 'snail'])))    # apply weight

        else:
            if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                game_active = True
                start_time = int(pygame.time.get_ticks() / 500)

    if game_active:
        screen.blit(sky_surf, (0, 0))
        screen.blit(ground_surf, (0, 300))

        player.draw(screen)
        player.update()

        obstacle_group.draw(screen)
        obstacle_group.update()

        game_active = collide_sprite()

        score = display_score()

    else:
        screen.fill((94, 129, 162))
        screen.blit(player_stand_surf, player_stand_rect)
        screen.blit(game_name, game_name_rect)

        score_message = game_font.render(f'YOUR SCORE: {score}', False, (111, 196, 169))
        score_message_rect = score_message.get_rect(center = (400, 330))

        if score == 0: screen.blit(game_message, game_message_rect)
        else: screen.blit(score_message, score_message_rect)

    pygame.display.update()
    clock.tick(60)

KEEP

  • 게임을 제작하는 동시에 파이썬의 기본 문법에 많이 익숙해지면서 코드를 작성하고 구현하는 시간이 줄어들고 전체적인 구조를 파악하는 능력이 향상됨을 느낌
  • pygame을 사용해 게임을 만들 경우, default setting과 sprite class를 사용함에 있어 그 사용법과 예시를 잘 기억해야함을 느낌

PROBLEM

  • 아무리 간단한 게임이어도 직접 기획하고 디자인한 게임이 아니다보니 게임 내에서 물리적 요소를 구현하기 위해 정의한 함수들을 이해하는데에 시간이 많이 소요됨
  • 게임의 몇가지 이벤트들을 구성하는 것에 있어서 다소 복잡하다고 느낌

TRY

  • Clear Code에서 업로드한 영상들을 보며 다른 게임 제작과정과 python을 활용한 간단한 툴 개발 등을 계속해서 시도
  • 물리적 요소를 구현하기 위한 함수작성 시 미리 생각해보고 진행
    -알고리즘 작성 능력 향상을 위해 문제들 풀어보기
profile
아직 모자란 수학과생

0개의 댓글