Skip to content

Commit 7f7295b

Browse files
committed
pyhon编程:从入门到实战游戏案例代码。
0 parents  commit 7f7295b

File tree

790 files changed

+162092
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

790 files changed

+162092
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__pycache__/

README.rd

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
在游戏《外星人入侵》中,玩家控制着一艘最初出现在屏幕底部中央的飞船。玩家
2+
可以使用箭头键左右移动飞船,还可使用空格键进行射击。游戏开始时,一群外星人出
3+
现在天空中,他们在屏幕中向下移动。玩家的任务是射杀这些外星人。玩家将所有外星
4+
人都消灭干净后,将出现一群新的外星人,他们移动的速度更快。只要有外星人撞到了
5+
玩家的飞船或到达了屏幕底部,玩家就损失一艘飞船。玩家损失三艘飞船后,游戏结束。

alien.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import pygame
2+
from pygame.sprite import Sprite
3+
4+
5+
class Alien(Sprite):
6+
"""表示单个外星人的类"""
7+
8+
def __init__(self, ai_settings, screen):
9+
"""初始化外星人并设置其起始位置"""
10+
11+
super().__init__()
12+
self.screen = screen
13+
self.ai_settings = ai_settings
14+
15+
# 每个外星人图像,并设置其rect属性
16+
self.image = pygame.image.load('images/alien.bmp')
17+
self.rect = self.image.get_rect()
18+
19+
# 每个外星人最初都在屏幕左上角附近
20+
self.rect.x = self.rect.width
21+
self.rect.y = self.rect.height
22+
23+
# 存储外星人的准确位置
24+
self.x = float(self.rect.x)
25+
26+
def blitme(self):
27+
"""在指定位置绘制外星人"""
28+
29+
self.screen.blit(self.image, self.rect)
30+
31+
def check_edges(self):
32+
"""如果外星人位于屏幕边缘,就返回True"""
33+
34+
screen_rect = self.screen.get_rect()
35+
if self.rect.right >= screen_rect.right:
36+
return True
37+
elif self.rect.left <= 0:
38+
return True
39+
40+
def update(self):
41+
"""向左或向右移动外星人"""
42+
self.x += (self.ai_settings.alien_speed_factor *
43+
self.ai_settings.fleet_direction)
44+
self.rect.x = self.x

alien_invasion.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import pygame
2+
from pygame.sprite import Group
3+
4+
from settings import Settings
5+
from game_stats import GameStats
6+
from ship import Ship
7+
import game_functions as gf
8+
9+
10+
def run_game():
11+
# 初始化pygame、设置和屏幕对象
12+
pygame.init()
13+
ai_settings = Settings()
14+
screen = pygame.display.set_mode((ai_settings.screen_width,
15+
ai_settings.screen_height))
16+
pygame.display.set_caption("Aline_Invasion")
17+
18+
# 创建一个用于存储游戏统计信息的实例
19+
stats = GameStats(ai_settings)
20+
21+
# 创建一艘飞船、一个子弹编组和一个外星人编组
22+
ship = Ship(ai_settings, screen)
23+
bullets = Group()
24+
aliens = Group()
25+
26+
# 创建外星人群
27+
gf.create_fleet(ai_settings, screen, ship, aliens)
28+
29+
# 开始游戏的主循环
30+
while True:
31+
gf.check_events(ai_settings, screen, ship, bullets)
32+
33+
if stats.game_active:
34+
ship.update()
35+
gf.update_bullets(ai_settings, screen, ship, aliens, bullets)
36+
gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets)
37+
38+
gf.update_screen(ai_settings, screen, ship, aliens, bullets)
39+
40+
41+
run_game()

bullet.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import pygame
2+
from pygame.sprite import Sprite
3+
4+
5+
class Bullet(Sprite):
6+
"""一个对飞船发射的子弹进行管理的类"""
7+
8+
def __init__(self, ai_settings, screen, ship):
9+
"""在飞船所处的位置创建一个子弹对象"""
10+
super().__init__()
11+
self.screen = screen
12+
13+
# 在(0,0)处创建一个表示子弹的矩形,再设置正确的位置
14+
self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,
15+
ai_settings.bullet_height)
16+
self.rect.centerx = ship.rect.centerx
17+
self.rect.top = ship.rect.top
18+
19+
# 存储用小数表示的子弹位置
20+
self.y = float(self.rect.y)
21+
22+
self.color = ai_settings.bullet_color
23+
self.speed_factor = ai_settings.bullet_speed_factor
24+
25+
def update(self):
26+
"""向上移动子弹"""
27+
28+
# 更新表示子弹位置的小数值
29+
self.y -= self.speed_factor
30+
31+
# 更新表示子弹的rect的位置
32+
self.rect.y = self.y
33+
34+
def draw_bullet(self):
35+
"""在屏幕上绘制子弹"""
36+
37+
pygame.draw.rect(self.screen, self.color, self.rect)

game_functions.py

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
import sys
2+
from time import sleep
3+
4+
import pygame
5+
from bullet import Bullet
6+
from alien import Alien
7+
8+
9+
def check_keydown_events(event, ai_settings, screen, ship, bullets):
10+
"""响应按键按下"""
11+
if event.key == pygame.K_RIGHT:
12+
ship.moving_right = True
13+
elif event.key == pygame.K_LEFT:
14+
ship.moving_left = True
15+
elif event.key == pygame.K_SPACE:
16+
fire_bullet(ai_settings, screen, ship, bullets)
17+
18+
elif event.key == pygame.K_q:
19+
sys.exit()
20+
21+
22+
def fire_bullet(ai_settings, screen, ship, bullets):
23+
"""如果还没有到达限制,就发射一颗子弹"""
24+
25+
# 创建一颗子弹,并将其加入到编组bullets中
26+
if len(bullets) < ai_settings.bullets_allowed:
27+
new_bullet = Bullet(ai_settings, screen, ship)
28+
bullets.add(new_bullet)
29+
30+
31+
def check_keyup_events(event, ship):
32+
"""响应按键弹起"""
33+
if event.key == pygame.K_RIGHT:
34+
ship.moving_right = False
35+
elif event.key == pygame.K_LEFT:
36+
ship.moving_left = False
37+
38+
39+
def check_events(ai_settings, screen, ship, bullets):
40+
"""响应按键和鼠标事件"""
41+
42+
for event in pygame.event.get():
43+
if event.type == pygame.QUIT:
44+
sys.exit()
45+
46+
elif event.type == pygame.KEYDOWN:
47+
check_keydown_events(event, ai_settings, screen, ship, bullets)
48+
elif event.type == pygame.KEYUP:
49+
check_keyup_events(event, ship)
50+
51+
52+
def update_screen(ai_settings, screen, ship, aliens, bullets):
53+
"""更新屏幕上的图像,并切换到新屏幕"""
54+
55+
# 每次循环时都重绘屏幕
56+
screen.fill(ai_settings.bg_color)
57+
58+
# 在飞船和外星人后面重绘所有子弹
59+
for bullet in bullets.sprites():
60+
bullet.draw_bullet()
61+
62+
ship.blitme()
63+
aliens.draw(screen)
64+
65+
# 让最近绘制的屏幕可见
66+
pygame.display.flip()
67+
68+
69+
def update_bullets(ai_settings, screen, ship, aliens, bullets):
70+
"""更新子弹的位置,并删除已消失的子弹"""
71+
72+
# 更新子弹的位置
73+
bullets.update()
74+
75+
# 删除已消失的子弹
76+
for bullet in bullets.copy():
77+
if bullet.rect.bottom <= 0:
78+
bullets.remove(bullet)
79+
80+
check_bullet_alien_collisions(ai_settings, screen, ship, aliens, bullets)
81+
82+
83+
def check_bullet_alien_collisions(ai_settings, screen, ship, aliens, bullets):
84+
"""响应子弹和外星人的碰撞"""
85+
86+
# 删除发生碰撞的子弹和外星人
87+
collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
88+
89+
if len(aliens) == 0:
90+
# 删除现有的子弹并新建一群外星人
91+
bullets.empty()
92+
create_fleet(ai_settings, screen, ship, aliens)
93+
94+
95+
def get_number_aliens_x(ai_settings, alien_width):
96+
"""计算每行可容纳多少个外星人"""
97+
98+
available_space_x = ai_settings.screen_width - 2 * alien_width
99+
number_aliens_x = int(available_space_x / (2 * alien_width))
100+
return number_aliens_x
101+
102+
103+
def get_number_rows(ai_settings, ship_height, alien_height):
104+
"""计算屏幕可容纳多少行外星人"""
105+
106+
available_space_y = (ai_settings.screen_height - (3 * alien_height) -
107+
ship_height)
108+
number_rows = int(available_space_y / (2 * alien_height))
109+
return number_rows
110+
111+
112+
def create_alien(ai_settings, screen, aliens, alien_number, row_number):
113+
""" 创建一个外星人并将其加入当前行"""
114+
alien = Alien(ai_settings, screen)
115+
alien_width = alien.rect.width
116+
alien.x = alien_width + 2 * alien_width * alien_number
117+
alien.rect.x = alien.x
118+
alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
119+
aliens.add(alien)
120+
121+
122+
def create_fleet(ai_settings, screen, ship, aliens):
123+
"""创建外星人群"""
124+
125+
# 创建一个外星人,并计算一行可容纳多少个外星人
126+
alien = Alien(ai_settings, screen)
127+
number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width)
128+
number_rows = get_number_rows(ai_settings, ship.rect.height,
129+
alien.rect.height)
130+
131+
# 创建外星人群
132+
for row_number in range(number_rows):
133+
for alien_number in range(number_aliens_x):
134+
create_alien(ai_settings, screen, aliens, alien_number, row_number)
135+
136+
137+
def check_fleet_edges(ai_settings, aliens):
138+
"""有外星人到达边缘时采取相应的措施"""
139+
for alien in aliens.sprites():
140+
if alien.check_edges():
141+
change_fleet_direction(ai_settings, aliens)
142+
break
143+
144+
145+
def change_fleet_direction(ai_settings, aliens):
146+
"""将整群外星人下移,并改变它们的方向"""
147+
148+
for alien in aliens.sprites():
149+
alien.rect.y += ai_settings.fleet_drop_speed
150+
ai_settings.fleet_direction *= -1
151+
152+
153+
def ship_hit(ai_settings, stats, screen, ship, aliens, bullets):
154+
"""响应被外星人撞到的飞船"""
155+
156+
if stats.ships_left > 0:
157+
# 将ships_left减1
158+
stats.ships_left -= 1
159+
160+
# 清空外星人列表和子弹列表
161+
aliens.empty()
162+
bullets.empty()
163+
164+
# 创建一群新的外星人,并将飞船放到屏幕底端中央
165+
create_fleet(ai_settings, screen, ship, aliens)
166+
ship.center_ship()
167+
168+
# 暂停
169+
sleep(0.5)
170+
171+
else:
172+
stats.game_active = False
173+
174+
175+
def check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets):
176+
"""检查是否有外星人到达屏幕底端"""
177+
178+
screen_rect = screen.get_rect()
179+
for alien in aliens.sprites():
180+
if alien.rect.bottom >= screen_rect.bottom:
181+
# 像飞船被撞到一样进行处理
182+
ship_hit(ai_settings, stats, screen, ship, aliens, bullets)
183+
break
184+
185+
186+
def update_aliens(ai_settings, stats, screen, ship, aliens, bullets):
187+
"""
188+
检查是否右外星人位于屏幕边缘,并更新整群外星人的位置
189+
"""
190+
191+
check_fleet_edges(ai_settings, aliens)
192+
aliens.update()
193+
194+
# 检测外星人和飞船之间的碰撞
195+
if pygame.sprite.spritecollideany(ship, aliens):
196+
ship_hit(ai_settings, stats, screen, ship, aliens, bullets)
197+
198+
#检查是否有外星人到达屏幕底端
199+
check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets)

game_stats.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class GameStats():
2+
"""跟踪游戏的统计信息"""
3+
4+
def __init__(self, ai_settings):
5+
"""初始化统计信息"""
6+
self.ai_settings = ai_settings
7+
self.reset_stats()
8+
9+
# 游戏刚启动时处于活动状态
10+
self.game_active = True
11+
12+
def reset_stats(self):
13+
"""初始化在游戏运行期间可能变化的统计信息"""
14+
self.ships_left = self.ai_settings.ship_limit

images/alien.bmp

2.38 KB
Binary file not shown.
23.8 KB
Loading

images/ship_dark.jpg

29.5 KB
Loading

0 commit comments

Comments
 (0)