22.04.25 파이썬 게임 과제 1일차.

김하진·2022년 4월 25일

파이썬 게임 과제 1일차이다.

Task 0. 파이썬 기초 문법 공부

https://velog.io/@gkwlsdl1/22.04.25-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%AC%B8%EB%B2%95-%EB%BD%80%EA%B0%9C%EA%B8%B0
<파이선 기본문법 개발일지>
게임 만들기전 파이썬 기초 문법 공부를 한번 더 하고 왔다.
블로그안에 따로 게시글로 기재 해놨다.
또한 튜터님께서 추천해주신 사이트가 유용한 것 같다.
https://github.com/gto76/python-cheatsheet#list
이 깃헙에 문법 내용이 잘 정리되어 있어 쓰기 좋다!

Task 1. 만들어 보고 싶은 게임 선정하기

나는 1945비행기 게임을 구현해 보기로 했다.
기본 토대는 유튜브를 참고로 하였다.
출처:https://www.youtube.com/watch?v=W92RjjptAsM
이수안컴퓨터연구소의 비행기게임 part 2이다.
기존 사전과제로 파이썬게임을 몇번 만들어 봐서 생각보다 이해가 잘 되었다.

과제 시작.

본격적으로 과제를 시작하였다. 처음 시작부터 영상을 천천히 보고 이해 될때 까지 문법을 찾아보고,
주석을 달아 코드리뷰 하는 식으로 작업을 시작하였다.
작업하면서 정리해볼만한 코드를 몇가지 정리해보자.

  • class 그려주기
# sprite 는 이미지,위치,충돌 처리를 통합해서 처리 가능하다.
class Fighter(pygame.sprite.Sprite): #상속 받아오기
    def __init__(self): #상속자처럼 쓰기위해 매직 메소드 사용 -> __init__ 생성자 인스턴가 생성될 때 파이썬 인터프리터에 자동으로 호출
        super(Fighter, self).__init__() #상속받았기 떄문에 super 로 상위 클래스 __init__ 호출
        self.image = pygame.image.load('fighter.png') # 이미지 로드
        self.rect = self.image.get_rect() # 크기를 가져오기
        self.rect.x = int(WINDOW_WIDTH /2 ) #위치, 가운데로 가져오기 위해 너비를 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
    # pygame 에서 좌표값은 스크린의 제일상단, 왼쪽이 기준이 된다. 따라서 스크린의 제일 왼쪽 상단을 기준점을 두고, 오른쪽(x)축은 양수, 왼쪽은 음수, 위쪽(y축)은 음수, 아래쪽은 양수가 된다.
    # Rect 은 Rectangle 을 의미한다. 좌표(X, Y)와 크기 (Width, Height)를 가진다.

우선 메직메소드, 그리고 상위 호출자에 대한 개념부터 공부를 시작하였다.
그리고 x,y 값 구하기 pygame 좌표값은 왼쪽 맨위 상단 부터 시작이다. 이걸 이해하면 좌표값에 대한 이해가 조금 수월해진다.

  • 이미지 그리기
    def draw(self, screen):
        screen.blit(self.image, self.rect) #blit()함수는 이미지를 복사해준다. 변수는 복사할이미지, 두번째는 그 대상. 이 함수는  screen 객체 안에 있다.
  • 이미지 충돌처리 과정
# 이미지에 충돌이 일어 났을 경우에
    def collide(self, sprites):
        for sprite in sprites:
            if pygame.sprite.collide_rect(self, sprite):#충돌 났는지 검사하고  self, sprite 에 하나씩 비교해보면서
                return sprite #충돌이 난 값을 리턴

이미지 충돌 함수 이다. colldie 를 이용
이부분도 조금은 더 완벽히 이해 할 필요가 있다.

  • 비행기 움직이는 처리
    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

이건 생각보다 단순하다. x,y 좌표값을 정확히 알고 지정해주면 된다.

오늘 상당히 애먹은 부분!

저위에 코드들 말고도 정리 할 것이 많지만. 천천히 해보기로 한다.
또한 강의 내용을 토대로 우선 완성을 하였다.
추가로 제일 먼저 작업을 하고 싶었던 것이 미사일 발사 개수 늘리기 이다.

  • 미사일 개수 추가 구현
                    if level_count == 1:
                        missile1 = Missile(fighter.rect.centerx +6, fighter.rect.y, 20)
                        missiles.add(missile, missile1)
                    if level_count == 2:
                        missile1 = Missile(fighter.rect.centerx +9, fighter.rect.y, 20)
                        missile2 = Missile(fighter.rect.centerx -17, fighter.rect.y, 20)
                        missiles.add(missile1,missile2)
                    if level_count >= 3:
                        missile1 = Missile(fighter.rect.centerx +12, fighter.rect.y, 20)
                        missile2 = Missile(fighter.rect.centerx -17, fighter.rect.y, 20)
                        missile3 = Missile(fighter.rect.centerx -30, fighter.rect.y, 20)
                        missiles.add(missile1,missile2,missile3)
                    if level_count >= 4:
                        missile1 = Missile(fighter.rect.centerx + 12, fighter.rect.y, 20)
                        missile2 = Missile(fighter.rect.centerx +27, fighter.rect.y, 20)
                        missile3 = Missile(fighter.rect.centerx -18, fighter.rect.y, 20)
                        missile4 = Missile(fighter.rect.centerx -32, fighter.rect.y, 20)
                        missiles.add(missile1,missile2,missile3,missile4)

우선 애먹은 만큼 구현을 하긴 했다. 허나 마음에 들지 않는다.
우선 미사일의 좌표가 정확히 구현하기 힘들다. 첫번째 missile = Missile(fighter.rect.centerx-3 , fighter.rect.y, 20)
미사일 값이 고정되어 있다 보니 다른 변수마다 발사위치를 맞추기가 너무 어렵다. 우선은 성공하긴 했지만 더 연구가 필요하다.
이 코드는 변수를 계속 만들어 주는 방법 밖에 없는가? 처음에는 for문으로 어떻게든 돌려 보려 했지만 내 지식으로 아직 구현이 불가능 했다. 내일 다시 도전 해보자.

  • 레벨 조정

미사일 개수 추가 구현이랑 같이 진행했던 부분이다. 이부분도 많은 애를 먹은 것 같다. 그 이유는 클린코드? 라고 뭐하지만
깔금한 코드를 원했지만 이부분도 아직은 불만족 스럽다.

                if shot_count == 5:
                    level_count += 1
                if shot_count == 10:
                    level_count += 1
                if shot_count == 20:
                    level_count += 1
                if shot_count == 40:
                    level_count += 1
                if shot_count == 60:
                    level_count += 1

우선 이렇게 단순하게 정리하긴 했지만, 분명 좋은 for 문이 있을 것 같은데 왜 안 떠오르지,,
그리고 또한 shot_count 로 난이도를 조정하다 보니 수학적 머리가 조금은 아파왔다 ㅎ
장애물의 개수와 스피드를 shot_count의 값으로 나눠서 조정하다 보니 생각보다 머리가 아팠지만 일단은 구현성공

마무리

우선 오늘 구현하려고 했던 기본코드와 구현해보고 싶던 기능 두개는 성공?.. 을 했다고 친다.
하지만 맘에 들지 않는다 코딩을 짜는 방식이 아직 매끄럽진 않고 쓸데없는 반복이 많은 느낌이다.
여러 반복문의 예시를 보면서 좀더 효율적으로, 좀더 괜찮은 방법으로 코드를 짜는 방법을 연구해보자.
내일도 화이팅.

profile
진킴

0개의 댓글