2/2 모각소 3주차 스터디 팀명: 데이터란 무엇인가

박종일·2023년 2월 2일
1
post-thumbnail

아주대학교 인공지능융합학과 학생들이 모여 진행하는 pygame

2/2 아주대학교 팔달관 317호
활동시간 : 13:40 ~ 17:20

<주제> 파이썬 pygame - 우주 슈팅 게임

실행 코드
import pygame
import random
from time import sleep
from pygame.locals import *

# 전역 변수
WINDOW_WIDTH = 480
WINDOW_HEIGHT = 640

BLACK = (0,0,0)
WHITE = (255,255,255)
YELLOW = (250,250,0)
RED = (250,0,0)

FPS = 60

class Fighter(pygame.sprite.Sprite):
    def __init__(self):
        super(Fighter,self).__init__()
        self.image = pygame.image.load('fighter.png')
        self.rect = self.image.get_rect()
        self.rect.x = int(WINDOW_WIDTH / 2)
        self.rect.y = WINDOW_HEIGHT - self.rect.height
        self.dx = 0
        self.dy = 0
    
    def update(self):
        self.rect.x += self.dx
        self.rect.y += self.dy
        
        if self.rect.x < 0 or self.rect.x + self.rect.width > WINDOW_WIDTH :
            self.rect.x -= self.dx
        
        if self.rect.y < 0 or self.rect.y + self.rect.height > WINDOW_HEIGHT:
            self.rect.y -= self.dy
            
    def draw(self, screen):
        screen.blit(self.image, self.rect)
    
    def collide(self, sprites):
        for sprite in sprites:
            if pygame.sprite.collide_rect(self,sprite):
                return sprite


class Missile(pygame.sprite.Sprite):
    def __init__(self, xpos, ypos, speed):
        super(Missile, self).__init__()
        self.image = pygame.image.load('missile.png')
        self.rect = self.image.get_rect()
        self.rect.x = xpos
        self.rect.y = ypos
        self.speed = speed
        self.sound = pygame.mixer.Sound('missile.wav')
        
    def Launch(self):
        self.sound.play()
        
    def update(self):
        self.rect.y -= self.speed
        if self.rect.y + self.rect.height < 0:
            self.kill()
    
    def collide(self, sprites):
        for sprite in sprites:
            if pygame.sprite.collide_rect(self,sprite):
                return sprite
            
            
class Rock(pygame.sprite.Sprite):
    def __init__(self, xpos, ypos, speed):
        super(Rock,self).__init__()
        rock_images = ('rock01.png','rock02.png','rock03.png','rock04.png','rock05.png',\
            'rock06.png','rock07.png','rock08.png','rock09.png','rock10.png',\
            'rock11.png','rock12.png','rock13.png','rock14.png','rock15.png',\
            'rock16.png','rock17.png','rock18.png','rock19.png','rock20.png',\
            'rock21.png','rock22.png','rock23.png','rock24.png','rock25.png',\
            'rock26.png','rock27.png','rock28.png','rock29.png','rock30.png')
        self.image = pygame.image.load(random.choice(rock_images))
        self.rect = self.image.get_rect()
        self.rect.x = xpos
        self.rect.y = ypos
        self.speed = speed
    
    def update(self):
        self.rect.y += self.speed
    
    def out_of_screen(self):
        if self.rect.y > WINDOW_HEIGHT:
            return True


def draw_text(text, font, surface,x,y,main_color):
    text_obj = font.render(text, True, main_color)
    text_rect = text_obj.get_rect()
    text_rect.centerx = x
    text_rect.centery = y
    surface.blit(text_obj, text_rect)


def occur_explosion(surface,x,y):
    explosion_image = pygame.image.load('explosion.png')
    explosion_rect = explosion_image.get_rect()
    explosion_rect.x = x
    explosion_rect.y = y
    surface.blit(explosion_image, explosion_rect)
    
    explosion_sounds = ('explosion01.wav','explosion02.wav','explosion03.wav')
    explosion_sound = pygame.mixer.Sound(random.choice(explosion_sounds))
    explosion_sound.play()
    

def game_loop():
    default_font = pygame.font.Font('NanumGothic.ttf', 28)
    background_image = pygame.image.load('background.png')
    gameover_sound = pygame.mixer.Sound('gameover.wav')
    pygame.mixer.music.load('music.wav')
    pygame.mixer.music.play(-1) # 무한 반복
    fps_clock = pygame.time.Clock()
    
    fighter = Fighter()
    missiles = pygame.sprite.Group()
    rocks = pygame.sprite.Group()
    
    occer_prob = 40
    shot_count = 0
    count_missed = 0
    
    done = False
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    fighter.dx -= 5
                elif event.key == pygame.K_RIGHT:
                    fighter.dx += 5
                elif event.key == pygame.K_UP:
                    fighter.dy -= 5
                elif event.key == pygame.K_DOWN:
                    fighter.dy += 5
                elif event.key == pygame.K_SPACE:
                    missile = Missile(fighter.rect.centerx, fighter.rect.y, 10)
                    missile.Launch()
                    missiles.add(missile)
            
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                    fighter.dx = 0
                elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                    fighter.dy = 0
                    
        screen.blit(background_image, background_image.get_rect())
        
        occer_of_rocks = 1 + int(shot_count / 300)
        min_rock_speed = 1 + int(shot_count / 200)
        max_rock_speed = 1 + int(shot_count / 100)
        
        if random.randint(1, occer_prob) == 1:
            for i in range(occer_of_rocks):
                speed = random.randint(min_rock_speed , max_rock_speed)
                rock = Rock(random.randint(0,WINDOW_WIDTH - 30), 0, speed)
                rocks.add(rock)
        
        draw_text('파괴한 운석: {}'.format(shot_count),default_font,screen,100,20, YELLOW)
        draw_text('놓친 운석: {}'.format(count_missed),default_font,screen,400,20, RED)
        
        for missile in missiles:
            rock = missile.collide(rocks)
            if rock:
                missile.kill()
                rock.kill()
                occur_explosion(screen, rock.rect.x, rock.rect.y)
                shot_count += 1
                
        for rock in rocks:
            if rock.out_of_screen():
                rock.kill()
                count_missed += 1
        
        rocks.update()
        rocks.draw(screen)
        missiles.update()
        missiles.draw(screen)
        fighter.update()
        fighter.draw(screen)
        pygame.display.flip()
        
        
        if fighter.collide(rocks) or count_missed >= 3:
            pygame.mixer_music.stop()
            occur_explosion(screen, fighter.rect.x, fighter.rect.y)
            pygame.display.update()
            gameover_sound.play()
            sleep(1)
            done = True
        fps_clock.tick(FPS)
    
    return 'game_menu'


def game_menu():
    start_image = pygame.image.load('background.png')
    screen.blit(start_image, [0,0])
    draw_x = int(WINDOW_WIDTH / 2)
    draw_y = int(WINDOW_HEIGHT / 4) 
    font_70 = pygame.font.Font('NanumGothic.ttf', 70)
    font_50 = pygame.font.Font('NanumGothic.ttf', 50)
    font_40 = pygame.font.Font('NanumGothic.ttf', 40)
    
    draw_text('아주대를 지켜라!', font_50, screen, draw_x, draw_y, YELLOW)
    draw_text('엔터키를 누르면',font_40, screen, draw_x, draw_y + 200, WHITE) 
    draw_text('게임이 시작됩니다.',font_40, screen, draw_x, draw_y + 250, WHITE)
    
    pygame.display.update()
    
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RETURN:
                return 'play'
        
        if event.type == QUIT:
            return  'quit'
    
    return 'game_menu'

def main():
    global screen
    
    pygame.init()
    screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
    pygame.display.set_caption('아주대 모각소 슈팅게임')
    
    action = 'game_menu'
    while action != 'quit':
        if action == 'game_menu':
            action = game_menu()
        elif action == 'play':
            action = game_loop()
    
    pygame,quit() 


if __name__ == "__main__":
    main()

동영상링크
누르면 해당 게임실행 동영상이 나옵니다.

<팀원 github 주소>
< 깃허브 주소 >
박종일 :https://github.com/aosdbfc/every_software
김산 : https://github.com/3n952/every_soft.git
임재환 : https://github.com/Jxxhwan/mogakso
최강인 : https://github.com/ganggri
최웅환 : https://github.com/dnstjr4567

또 다른 공부자료 블로그 : https://velog.io/@dorwhale

2/2 2월 시작과 함께 다시 모였다.
세번째 주차로, 자료구조와 함께 배우는 알고리즘 입문 with 파이썬 책 4-5장을 공부하고 알고리즘에서 어려운 부분을 얘기하며 다루었다.
4장에서 스택, 큐 자료구조에 대해 공부하며
각각 어떻게 구현되는지 확인하였다.
이 자료구조 마다 각각의 함수의 메소드가 있는데, 이를 아는 것이 가장 중요한 부분이다.

collections.deque로 스택 구현하기

파이썬 내장 컨테이너는 딕셔너리,리스트, 집합(set), 튜플이 있다. 이외에도 여러 컨테이너를 collections 모듈로 제공한다. 주요한 것은 namedtuple(), deque(),Counter(), defalutdict, UserList, UserString 같은 컬렉션입니다. 이 가운데 deque 모듈을 사용하면 스택을 간단하게 구현할 수 있습니다. collection.deque 는 맨 앞과 맨 끝 양쪽에서 원소를 추가,삭제하는 자료구조인 덱을 구현하는 컨테이너이다. 이 내용은 지금 암기하는 건 아니지만 필요할 경우 꼭 꺼내쓸 수 있도록 해야겠다.

python의 pygame 모듈을 이용한 고전 게임 만들기(우주 슈팅게임)에서 객체지향과 pygame 모듈에서 사용할 수 있는 것을 좀 더 알아보았다.

객체지향 복습코드도 github에 첨부하였다.

https://github.com/aosdbfc/every_software/tree/main/mogakso_pygame/workspace

객제치향 개념은 한 학기 분량이지만 이를 방학에 모두 공부하기 보단 객체지향이란 무엇인가 확실히 말할 수 있다는 것에 목표를 두고 있다.

객체지향은 무엇인가...?
https://www.youtube.com/watch?v=m6VgooV_JSY\
이를 참고해보록 했다.

다음 스터디 계획은 자료구조와 함께 배우는 알고리즘 입문 책 5,6장 및 앞에 내용 복습 공부 및
모각소 4,5주차에는 개인의 프로젝트를 시작하며 python에 대해 깊이 있게 알아보도록 하고 있다.

profile
존경하는 인물: 스토브리그 백승수 단장(남궁민)

1개의 댓글

comment-user-thumbnail
2023년 2월 4일

게임 재밌어요

답글 달기