파이썬 활용

클래스, 멤버변수, 메소드, 상속, 다중상속, 메소드, 오버라이딩, pass, super를 활용한 예시 프로젝트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
from random import *
 
# 일반 유닛
 
 
class Unit:
    def __init__(self, name, hp, speed):
        self.name = name
        self.hp = hp
        self.speed = speed
        print("{0} 유닛이 생성되었습니다".format(name))
 
    def move(self, location):
        print("{0} : {1} 방향으로 이동합니다[속도 {2}]".format(
            self.name, location, self.speed))
 
    def damaged(self, damage):
        print("{0} : {1} 데미지를 입었습니다".format(self.name, damage))
        self.hp -= damage
        print("{0} : 현재 체력은 {1} 입니다".format(self.name, self.hp))
        if self.hp <= 0:
            print("{0} : 파괴되었습니다".format(self.name))
 
# 공격 유닛
 
 
class AttackUnit(Unit):
    def __init__(self, name, hp, speed, damage):
        Unit.__init__(self, name, hp, speed)
        self.damage = damage
 
    def attack(self, location):
        print("{0} : {1} 방향으로 적군을 공격합니다 [공격력 {2}]".format(
            self.name, location, self.damage))
 
# 마린
 
 
class Marine(AttackUnit):
    def __init__(self):
        AttackUnit.__init__(self"마린"4015)
 
    # 스팀팩
    def stimpack(self):
        if self.hp > 10:
            self.hp -= 10
            print("{0} : 스팀팩을 사용합니다 (HP 10 감소)".format(self.name))
        else:
            print("{0} : 체력이 부족하여 스팀팩을 사용하지 않습니다".format(self.name))
 
 
class Tank(AttackUnit):
    # 시즈모드
    seize_developed = False  # 시즈 모드 개발 여부
 
    def __init__(self):
        AttackUnit.__init__(self"탱크"150135)
        self.seize_mode = False
 
    def set_seize_mode(self):
        if Tank.seize_developed == False:
            return
 
        # 현재 시즈모드가 아닐 때 -> 시즈모드
        if self.seize_mode == False:
            print("{0} : 시즈 모드로 전환합니다".format(self.name))
            self.damage *= 2
            self.seize_mode = True
        # 현재 시즈모드 일 때 -> 해제
        else:
            print("{0} : 시즈 모드로 해제합니다".format(self.name))
            self.damage /= 2
            self.seize_mode = False
 
 
class Flyable:
    def __init__(self, flying_speed):
        self.flying_speed = flying_speed
 
    def fly(self, name, location):
        print("{0} : {1} 방향으로 날아갑니다 [속도 {2}]".format(
            name, location, self.flying_speed))
 
 
class FlyableAttackUnit(AttackUnit, Flyable):
    def __init__(self, name, hp, damage, flying_speed):
        AttackUnit.__init__(self, name, hp, 0, damage)  # 지상 스피드는 0
        Flyable.__init__(self, flying_speed)
 
    def move(self, location):
        self.fly(self.name, location)
 
 
# 레이스
class Wraith(FlyableAttackUnit):
    def __init__(self):
        FlyableAttackUnit.__init__(self"레이스"80205)
        self.clocked = False  # 클로킹 모드(해제 상태)
 
    def clocking(self):
        if self.clocked == True:
            print("{0} : 클로킹 모드 해제 합니다".format(self.name))
            self.clocked = False
        else:  # 클로킹 해제 -> 모드 설정
            print("{0} : 클로킹 모드 설정 합니다".format(self.name))
            self.clocked = True
 
 
def game_start():
    print("[알림] 새로운 게임을 시작합니다")
 
 
def game_over():
    print("Player : gg")
    print("[Player] 님이 게임에서 퇴장하셨습니다")
 
 
# 실제 게임 시작
game_start()
 
m1 = Marine()
m2 = Marine()
m3 = Marine()
 
t1 = Tank()
t2 = Tank()
 
w1 = Wraith()
 
# 유닛 일괄 관리
attack_units = []
attack_units.append(m1)
attack_units.append(m2)
attack_units.append(m3)
attack_units.append(t1)
attack_units.append(t2)
attack_units.append(w1)
 
# 전군 이동
for unit in attack_units:
    unit.move("1시")
 
# 탱크 시즈모드 개발
Tank.seize_developed = True
print("[알림] 탱크 시즈모드 개발 완료")
 
# 공격 모드준비 (마린 : 스팀팩, 탱크 : 시즈 모드 , 레이스 : 클로킹)
for unit in attack_units:
    if isinstance(unit, Marine):
        unit.stimpack()
    elif isinstance(unit, Tank):
        unit.set_seize_mode()
    elif isinstance(unit, Wraith):
        unit.clocking()
 
# 전국 공격
for unit in attack_units:
    unit.attack("1시")
 
# 전군 피해
for unit in attack_units:
    unit.damaged(randint(520))  # 공격은 랜덤으로 받음(5~20)
 
# 게임 종료
game_over()
 
cs

 

 

출처 유튜브 '나도코딩' [파이썬 코딩 무료강의 (기본편)]

youtu.be/kWiCuklohdY

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
import os
import pygame
######################
# 기본 초기화 (반드시 해야 하는 것들)
 
pygame.init() #초기화
 
# 화면 크기 설정
screen_width = 640 #가로 크기
screen_height = 480 #세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))
 
# 화면 타이틀 설정
pygame.display.set_caption("Pang"#게임 이름
 
#FPS
clock = pygame.time.Clock()
######################
 
#1. 사용자 게임 초기화 (배경 화면,게임 이미지,좌표,속도,폰트 등)
current_path = os.path.dirname(__file__) #현재 파일의 위치 반환
image_path = os.path.join(current_path,"images")
 
# 배경만들기
background = pygame.image.load(os.path.join(image_path,"background.png"))
 
#스테이지 만들기
stage = pygame.image.load(os.path.join(image_path,"stage.png"))
stage_size = stage.get_rect().size
stage_height = stage_size[1#스테이지의 높이 위에 캐릭터를 두기 위해 사용
 
#캐릭터
character = pygame.image.load(os.path.join(image_path,"character.png"))
character_size = character.get_rect().size
character_width = character_size[0]
character_height = character_size[1]
character_x_pos = (screen_width/2- (character_width/2)
character_y_pos = screen_height - character_height - stage_height
 
#캐릭터 이동
character_to_x = 0
 
# 캐릭터 이속
character_speed = 5
 
# 무기 만들기
weapon = pygame.image.load(os.path.join(image_path,"weapon.png"))
weapon_size = weapon.get_rect().size
weapon_width = weapon_size[0]
 
# 무기는 한번에 여러 발 가능
 
weapons = []
 
# 무기 이속
weapon_speed = 10
 
# 공만들기
ball_images = [
    pygame.image.load(os.path.join(image_path,"balloon1.png")),
    pygame.image.load(os.path.join(image_path,"balloon2.png")),
    pygame.image.load(os.path.join(image_path,"balloon3.png")),
    pygame.image.load(os.path.join(image_path,"balloon4.png")) ]
 
# 공 크기에 따른 최초 스피드
ball_speed_y = [-18,-15,-12,-9#index 0,1,2,3 에 해당하는 값
 
#공들
balls = []
balls.append({
    "pos_x" : 50,
    "pos_y" : 50,
    "img_idx" : 0,
    "to_x":3,
    "to_y":-6,
    "init_spd_y": ball_speed_y[0]})
 
#사라질 무기, 공 정보 저장 변수
weapon_to_remove = -1
ball_to_remove = -1
 
game_font = pygame.font.Font(None,40)
total_time = 100
start_ticks = pygame.time.get_ticks()
 
#게임 종료 메시지 / Time out , Mission Complete , Game Over
game_result = "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:
                character_to_x -= character_speed
            elif event.key == pygame.K_RIGHT:
                character_to_x += character_speed
            elif event.key == pygame.K_SPACE:
                weapon_x_pos = character_x_pos + (character_width/2- (weapon_width/2)
                weapon_y_pos = character_y_pos
                weapons.append([weapon_x_pos, weapon_y_pos])
 
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                character_to_x = 0
 
    # 3. 게임 케릭터 위치 정의    
    character_x_pos += character_to_x
    
    if character_x_pos < 0:
        character_x_pos = 0
    elif character_x_pos > screen_width - character_width:
        character_x_pos = screen_width - character_width
 
    # 무기 위치 조정
    # 100,200 -> 180,160.. 
    # 500,200 -> 180,160...
 
    weapons = [ [w[0], w[1- weapon_speed] for w in weapons]
    
    weapons = [ [w[0], w[1] ] for w in weapons if w[1> 0]
    
    # 공 위치 정의
    for ball_idx, ball_val in enumerate(balls):
        ball_pos_x= ball_val["pos_x"]
        ball_pos_y= ball_val["pos_y"]
        ball_img_idx = ball_val["img_idx"]
 
        ball_size = ball_images[ball_img_idx].get_rect().size
        ball_width = ball_size[0]
        ball_height = ball_size[1]
 
        #가로벽에 닿았을 때 공 이동 위치 변경
        if ball_pos_x < 0 or ball_pos_x > screen_width - ball_width:
            ball_val["to_x"= ball_val["to_x"* -1
 
        #세로 위치
        if ball_pos_y >= screen_height - stage_height - ball_height:
            ball_val["to_y"= ball_val["init_spd_y"]
        else:
            ball_val["to_y"]+= 0.5
 
        ball_val["pos_x"+= ball_val["to_x"]
        ball_val["pos_y"+= ball_val["to_y"]
 
 
    # 4. 충돌 처리
 
    #캐릭터 rect 정보 업데이트
    character_rect = character.get_rect()
    character_rect.left = character_x_pos
    character_rect.top = character_y_pos
 
    for ball_idx, ball_val in enumerate(balls):
        ball_pos_x= ball_val["pos_x"]
        ball_pos_y= ball_val["pos_y"]
        ball_img_idx = ball_val["img_idx"]
        #공 rect 정보 업데이트
        ball_rect = ball_images[ball_img_idx].get_rect()
        ball_rect.left = ball_pos_x
        ball_rect.top = ball_pos_y
        #공과 캐릭터 충돌 처리
        if character_rect.colliderect(ball_rect):
            running = False
            break
 
        # 공과 무기들 충돌처리
        for weapon_idx,weapon_val in enumerate(weapons):
            weapon_pos_x = weapon_val[0]
            weapon_pos_y = weapon_val[1]
 
            # 무기 rect 정보 업데이트
            weapon_rect = weapon.get_rect()
            weapon_rect.left = weapon_pos_x
            weapon_rect.top = weapon_pos_y
 
            #충돌 체크
            if weapon_rect.colliderect(ball_rect):
                weapon_to_remove = weapon_idx
                ball_to_remove = ball_idx
                #가장 작은 공이 아니라면 다음 단계의 공으로 나눠주기
 
                if ball_img_idx <3 :
                    #현재 공크기 정보
                    ball_width = ball_rect.size[0]
                    ball_height = ball_rect.size[1]
 
                    #나눠진 공 정보
                    small_ball_rect = ball_images[ball_img_idx + 1].get_rect()
                    small_ball_width = small_ball_rect.size[0]
                    small_ball_height = small_ball_rect.size[1]
 
                    #왼쪽으로 튕겨나가는 작은공
                    balls.append({
                        "pos_x" : ball_pos_x + (ball_width/2- (small_ball_width/2),
                        "pos_y" : ball_pos_y + (ball_height/2- (small_ball_height/2),
                        "img_idx" : ball_img_idx +1,
                        "to_x":-3,
                        "to_y":-6,
                        "init_spd_y": ball_speed_y[ball_img_idx + 1]})
                        
                    #오른쪽으로 튕겨나가는 작은공
                    balls.append({
                        "pos_x" : ball_pos_x + (ball_width/2- (small_ball_width/2),
                        "pos_y" : ball_pos_y + (ball_height/2- (small_ball_height/2),
                        "img_idx" : ball_img_idx +1,
                        "to_x":3,
                        "to_y":-6,
                        "init_spd_y": ball_speed_y[ball_img_idx + 1]})
 
 
                break
        else#계속 게임을 진행
            continue # 안쪽 for 문 조건이 맞지 않으면 continue 
        break #안쪽 for 문에서 break 를 만나면 여기로 진입 가능
 
    
    #충돌된 공 or 무기 없애기
    if ball_to_remove > -1:
        del balls[ball_to_remove]
        ball_to_remove = -1
 
    if weapon_to_remove > -1:
        del weapons[weapon_to_remove]
        weapon_to_remove = -1
    
    #모든 공을 없앤 경우 게임 종료
    if len(balls) == 0:
        game_result = "Mission Complete"
        running = False
    # 5. 화면에 그리기
    screen.blit(background,(0,0))
 
    for weapon_x_pos, weapon_y_pos in weapons:
        screen.blit(weapon,(weapon_x_pos,weapon_y_pos))
    
    for idx, val in enumerate(balls):
        ball_pos_x = val["pos_x"]
        ball_pos_y = val["pos_y"]
        ball_img_idx = val["img_idx"]
        screen.blit(ball_images[ball_img_idx], (ball_pos_x,ball_pos_y))
    
    screen.blit(stage,(0,screen_height - stage_height))
    screen.blit(character, (character_x_pos, character_y_pos))
 
    #경과시간 계산
    elapsed_time = (pygame.time.get_ticks() - start_ticks) / 1000
    timer = game_font.render("Time : {}".format(int(total_time - elapsed_time)), True, (255,255,255))
    screen.blit(timer, (10,10)) 
 
    #시간 초과했다면
    if total_time - elapsed_time <= 0:
        game_result = "Time Over"
        running = False
    pygame.display.update() #게임화면을 다시 그리기   
 
#게임 오버 메시지
msg = game_font.render(game_result, True, (255,255,0))
msg_rect = msg.get_rect(center=(int(screen_width/2), int(screen_height /2 )))
screen.blit(msg, msg_rect)
pygame.display.update()
 
# 2초 대기
pygame.time.delay(2000)
 
# pygame 종료
pygame.quit()
cs

2021/02/20 - [python/pygame] - pygame 활용한 게임 만들기

 

pygame 활용한 게임 만들기

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 import pygame ###################### # 기본 초기화 (반드시 해야..

clear-memo.tistory.com

위 링크는 앞에서 했던 활용 1 입니다

 

 

활용 2 에서는 공튕기기, 충돌 처리, 충돌된 공 분리, 게임 오버조건 3가지 등 다양한 코드를 사용했습니다

 

 

 

출처 유튜브 "나도코딩" 강의 : youtu.be/Dkx8Pl6QKW0

'python > pygame' 카테고리의 다른 글

pygame 활용한 게임 만들기  (0) 2021.02.20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import pygame
######################
# 기본 초기화 (반드시 해야 하는 것들)
 
pygame.init() #초기화
 
# 화면 크기 설정
screen_width = 480 #가로 크기
screen_height = 640 #세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))
 
# 화면 타이틀 설정
pygame.display.set_caption("게임 이름"#게임 이름
 
#FPS
clock = pygame.time.Clock()
######################
 
#1. 사용자 게임 초기화 (배경 화면,게임 이미지,좌표,속도,폰트 등)
 
 
 
# 이벤트 루프
running = True #게임이 진행중인가?
while running:
    dt = clock.tick(30#게임화면 초당 프레임수
 
    #2. 이벤트 처리(키보드,마우스)
    for event in pygame.event.get(): #어떤 이벤트가 발생하였는가?
        if event.type == pygame.QUIT: #창이 닫히는 이벤트가 발생하였는가?
            running = False # 게임이 진행중이 아님
 
    # 3. 게임 케릭터 위치 정의    
 
    # 4. 충돌 처리
 
    # 5. 화면에 그리기
 
 
 
    pygame.display.update() #게임화면을 다시 그리기   
 
 
 
# pygame 종료
pygame.quit()
cs

# 기본 초기화 (반드시 해야 하는 것들)

 

먼저 import pygame을 통해 pygame을 불러오고 시작합니다

(만약 설치 되있지 않다면 터미널에 C:/>pip install pygame 입력)

 

초기화

pygame.init()

 

화면 크기 설정

screen_width =  #가로 크기

screen_height =  #세로 크기

screen = pygame.display.set_mode((screen_width, screen_height))

 

화면 타이틀(게임이름)

pygame.display.set_caption("게임 이름"#게임 이름

 

FPS(Frames Per Second)

clock = pygame.time.Clock()

 

#1. 사용자 게임 초기화

 

배경 이미지

background = pygame.image.load("배경 이미지 경로")

 

캐릭터(적 캐릭터 등도 같은 방법)

character = pygame.image.load("캐릭터 이미지 경로")

character_size = character.get_rect().size #이미지의 크기를 구해옴

character_width = character_size[0#캐릭터의 가로 크기

character_height = character_size[1#캐릭터의 세로 크기

character_x_pos = #캐릭터 위치

character_y_pos = #캐릭터 위치

 

좌표 (움직일때 필요한 좌표값)

to_x = 0

to_y = 0

 

속도(캐릭터 이동속도)

character_speed = 0.6

 

폰트(폰트,크기)

game_font = pygame.font.Font(None,40)

 

시간

총시간

total_time = 

시작 시간

start_ticks = pygame.time.get_ticks() # 시작 tick 을 받아옴

 

이벤트 루프

running = True 게임의 진행중 여부

while running:

    dt = clock.tick(60#게임화면 초당 프레임수

 

#2. 이벤트 처리(키보드, 마우스)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
for event in pygame.event.get(): 
        if event.type == pygame.QUIT: #창닫기를 누를 경우
            running = False # 게임이 진행중이 아님
 
        if event.type == pygame.KEYDOWN: #키가 눌러졌는지 확인
            if event.key == pygame.K_LEFT:
                to_x -= character_speed
            elif event.key == pygame.K_RIGHT:
                to_x += character_speed
            elif event.key == pygame.K_UP:
                to_y -= character_speed
            elif event.key == pygame.K_DOWN:
                to_y += character_speed
 
        if event.type == pygame.KEYUP: #키에서 손땔때
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                to_x = 0
            elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                to_y = 0
 
    character_x_pos += to_x *dt #프레임이 달라져도 속도를 같게 하기 위함
    character_y_pos += to_y *dt
cs

위와 같이 어떤 이벤트가 발생하는지(key up,down and click) 설정합니다

#3. 게임 케릭터 위치 정의

1
2
3
4
5
6
7
8
9
10
11
#가로 경계값 처리
    if character_x_pos <0:
        character_x_pos = 0
    elif character_x_pos > screen_width - character_width:
        character_x_pos = screen_width - character_width
 
    #세로 경계값 처리
    if character_y_pos <0:
        character_y_pos = 0
    elif character_y_pos > screen_height - character_height:
        character_y_pos = screen_height - character_height
cs

캐릭터가 화면 밖으로 나가지 않게 하기위해 위와 같이 설정합니다 

#4.충돌처리

1
2
3
4
5
6
7
8
9
10
11
12
13
# 충돌 처리를 위한 rect 정보 업데이트
    character_rect = character.get_rect()
    character_rect.left = character_x_pos
    character_rect.top = character_y_pos
 
    enemy_rect = enemy.get_rect()
    enemy_rect.left = enemy_x_pos
    enemy_rect.top = enemy_y_pos
    
    #충돌 체크
    if character_rect.colliderect(enemy_rect):
        print("충돌함")
        running = False
cs

위의 예시와 같이 충돌을 체크하고 처리합니다

#5. 화면에 그리기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
screen.blit(background,(0,0)) #배경 그리기
 
    screen.blit(character,(character_x_pos,character_y_pos))
 
    screen.blit(enemy,(enemy_x_pos,enemy_y_pos)) #적 그리기
 
    #타이머 집어 넣기
    #경과 시간 계산
    elapsed_time = (pygame.time.get_ticks() - start_ticks) /1000
    # 경과 시간을 1000으로 나눠서 초 단위로 표시
 
    timer = game_font.render(str(int(total_time- elapsed_time)),True,(255,255,255))
    #출력할 글자, True, 글자 색상
    screen.blit(timer, (10,10))
 
    # 시간이 0 이하면 게임 종료
    if total_time- elapsed_time <= 0:
        print("Time Out")
        running = False
 
 
 
    pygame.display.update() #게임화면을 다시 그리기   
 
cs

위와 같은 방법으로 배경 이미지,캐릭터,시간 등을 화면에 표시합니다

 

'python > pygame' 카테고리의 다른 글

pygame 활용한 게임 만들기 2 (오락실 게임 pang)  (0) 2021.02.21

+ Recent posts