jQuery火箭图标返回顶部代码

[Python]简单的外星人入侵游戏

alien_invasion.py:

 

 1 import sys
 2 
 3 import pygame
 4 
 5 from setting import Settings
 6 from ship import Ship
 7 import game_function as gf
 8 from pygame.sprite import Group
 9 from  alien import Alien
10 from game_stats import GameStats
11 from button import Button
12 from scoreboard import ScoreBoard
13 
14 def run_game():
15     # 初始化游戏并创建于一个屏幕对象
16     pygame.init()
17     ai_setting = Settings()
18     screen = pygame.display.set_mode((ai_setting.screen_width, ai_setting.screen_height))
19     pygame.display.set_caption("Alien Invasion")
20 
21     # 创建一艘飞船、一个子弹编组和一个外星人编组
22     ship = Ship(ai_setting, screen)
23     bullets = Group()
24     aliens = Group()
25 
26     # 创建外星人群
27     gf.create_fleet(ai_setting, screen, ship, aliens)
28     stats = GameStats(ai_setting)
29     # 创建存储游戏统计信息的实例,并创建及分牌
30     sb = ScoreBoard(ai_setting, screen, stats)
31     # 创建Play按钮
32     play_button = Button(ai_setting, screen, "Play")
33 
34     # 开始游戏的主循环
35     while True:
36         gf.check_events(ai_setting, screen, stats, sb, play_button, ship, aliens, bullets)
37         if stats.game_active:
38             ship.update()
39             gf.update_bullets(ai_setting, screen, stats,  sb, ship, aliens, bullets)
40             gf.update_aliens(ai_setting, stats, screen, sb, ship, aliens, bullets)
41 
42         gf.update_screen(ai_setting, screen, stats, sb, ship, aliens, bullets, play_button)
43 
44 run_game()

 

game_stats.py:

 

 1 class GameStats():
 2     """跟踪游戏的统计信息"""
 3 
 4     def __init__(self, ai_setting):
 5         """初始化统计信息"""
 6         self.ai_setting = ai_setting
 7         self.reset_stats()
 8         self.game_active = False
 9         # 在任何情况下都不应该充值最高得分
10         self.high_score = 0
11 
12     def reset_stats(self):
13         """初始化在游戏运行期间可能变化的统计信息"""
14         self.ship_left = self.ai_setting.ship_limit
15         self.score = 0
16         self.level = 1

 

scoreboard.py:

 

 1 import pygame.font
 2 from pygame.sprite import Group
 3 from ship import Ship
 4 
 5 class ScoreBoard():
 6     """现实得分信息的类"""
 7 
 8     def __init__(self, ai_setting, screen, stats):
 9         """初始化现实得分涉及的属性"""
10         self.screen = screen
11         self.screen_rect = screen.get_rect()
12         self.ai_setting = ai_setting
13         self.stats =stats
14 
15         # 显示得分信息时使用的设置
16         self.text_color = (30, 30, 30)
17         self.font = pygame.font.SysFont(None, 48)
18 
19         # 准备包含最高得分和当前得分的图像
20         self.prep_score()
21         self.prep_high_score()
22         self.prep_level()
23         self.prep_ships()
24 
25     def prep_ships(self):
26         """显示还有下多少艘飞船"""
27         self.ships = Group()
28         for ship_number in range(self.stats.ship_left):
29             ship = Ship(self.ai_setting, self.screen)
30             ship.rect.x = 10 + ship_number * ship.rect.width
31             ship.rect.y = 10
32             self.ships.add(ship)
33 
34     def prep_score(self):
35         """将得分转换为一幅渲染的图像"""
36         rounded_score = int(round(self.stats.score, -1))
37         score_str = "{:,}".format(rounded_score)
38         self.score_image = self.font.render(score_str, True, self.text_color, self.ai_setting.bg_color)
39 
40         # 将得分放在屏幕右上角
41         self.score_rect = self.score_image.get_rect()
42         self.score_rect.right = self.screen_rect.right - 20
43         self.score_rect.top = 20
44 
45     def show_score(self):
46         """在屏幕上显示得分"""
47         self.screen.blit(self.score_image, self.score_rect)
48         self.screen.blit(self.high_score_image, self.high_score_rect)
49         self.screen.blit(self.level_image, self.level_rect)
50         # 绘制飞船
51         self.ships.draw(self.screen)
52 
53     def prep_high_score(self):
54         """将最高得分转化为渲染的图像"""
55         high_score = int(round(self.stats.high_score, -1))
56         high_score_str = "{:,}".format(high_score)
57         self.high_score_image = self.font.render(high_score_str, True, self.text_color, self.ai_setting.bg_color)
58 
59         #将最高分放在屏幕顶部中央
60         self.high_score_rect = self.high_score_image.get_rect()
61         self.high_score_rect.centerx = self.screen_rect.centerx
62         self.high_score_rect.top = self.score_rect.top
63 
64     def prep_level(self):
65         """降等级转化为渲染的图像"""
66         self.level_image = self.font.render(str(self.stats.level), True, self.text_color, self.ai_setting.bg_color)
67 
68         # 降等级放在得分下方
69         self.level_rect = self.level_image.get_rect()
70         self.level_rect.right = self.score_rect.right
71         self.level_rect.top = self.score_rect.bottom + 10

 

button.py:

 

 1 import pygame.font
 2 
 3 class Button():
 4     def __init__(self, ai_setting, screen, msg):
 5         """初始化按钮的属性"""
 6         self.screen = screen
 7         self.screen_rect = screen.get_rect()
 8 
 9         # 设置按钮的尺寸和其他属性
10         self.width = 200
11         self.height = 50
12         self.button_color = (0, 255, 0)
13         self.text_color = (255, 255, 255)
14         self.font = pygame.font.SysFont(None, 48)
15 
16         # 创建按钮的rect对象,并使其居中
17         self.rect = pygame.Rect(0, 0, self.width, self.height)
18         self.rect.center = self.screen_rect.center
19 
20         # 按钮的标签只需创建一次
21         self.prep_msg(msg)
22 
23     def prep_msg(self, msg):
24         """将msg渲染为图像并使其在按钮上居中"""
25         self.msg_image = self.font.render(msg, True, self.text_color, self.button_color)
26         self.msg_image_rect = self.msg_image.get_rect()
27         self.msg_image_rect.center = self.rect.center
28 
29     def draw_button(self):
30         # 绘制一个用颜色填充的按钮,在绘制文本
31         self.screen.fill(self.button_color, self.rect)
32         self.screen.blit(self.msg_image, self.msg_image_rect)

 

game_function.py:

 

  1 import sys
  2 
  3 import pygame
  4 from bullet import Bullet
  5 from alien import Alien
  6 from time import sleep
  7 
  8 def check_events(ai_setting, screen, stats, sb, play_button, ship, aliens, bullets):
  9     """响应按键和鼠标事件"""
 10     for event in pygame.event.get():
 11         if event.type == pygame.QUIT:
 12             sys.exit()
 13 
 14         elif event.type == pygame.KEYDOWN:
 15             if event.key == pygame.K_RIGHT:
 16                 # 向右移动飞船
 17                 ship.moving_right = True
 18             elif event.key == pygame.K_LEFT:
 19                 ship.moving_left = True
 20             elif event.key == pygame.K_SPACE:
 21                 # 创建一颗子弹,并将其加入到编组bullets中
 22                 if len(bullets) < ai_setting.bullets_allowed:
 23                     new_bullet = Bullet(ai_setting, screen, ship)
 24                     bullets.add(new_bullet)
 25             elif event.key == pygame.K_q:
 26                 sys.exit()
 27         elif event.type == pygame.MOUSEBUTTONDOWN:
 28             mouse_x, mouse_y = pygame.mouse.get_pos()
 29             check_play_button(ai_setting, screen, stats, sb, play_button, ship, aliens, bullets, mouse_x, mouse_y)
 30 
 31         elif event.type == pygame.KEYUP:
 32             if event.key == pygame.K_RIGHT:
 33                 ship.moving_right = False
 34             elif event.key == pygame.K_LEFT:
 35                 ship.moving_left = False
 36 
 37 def check_play_button(ai_setting, screen, stats, sb, play_button, ship, aliens, bullets, mouse_x, mouse_y):
 38     """玩家单击Play按钮时开始新游戏"""
 39     button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
 40     if button_clicked and not stats.game_active:
 41         #重置游戏设置
 42         ai_setting.initialize_dynamic_settings()
 43 
 44         # 隐藏光标
 45         pygame.mouse.set_visible(False)
 46         # 重置游戏信息
 47         stats.reset_stats()
 48         stats.game_active = True
 49 
 50         # 重置记分牌图像
 51         sb.prep_score()
 52         sb.prep_high_score()
 53         sb.prep_level()
 54         sb.prep_ships()
 55 
 56         # 清空外星人列表和子弹列表
 57         aliens.empty()
 58         bullets.empty()
 59 
 60         # 创建一群新的外星人,并让飞船居中
 61         create_fleet(ai_setting, screen, ship, aliens)
 62         ship.center_ship()
 63 
 64 def update_screen(ai_setting, screen, stats, sb, ship,alien, bullets, play_button):
 65     """更新屏幕上的图像,并切换到新屏幕"""
 66     # 每次循环时都重绘屏幕
 67     screen.fill(ai_setting.bg_color)
 68     # 在飞船和外星人后面重绘所有子弹
 69     for bullet in bullets.sprites():
 70         bullet.draw_bullet()
 71     ship.blitme()
 72     alien.draw(screen)
 73     # 显示得分
 74     sb.show_score()
 75 
 76     # 如果游戏处于非活动状态,绘制Play按钮
 77     if not stats.game_active:
 78         play_button.draw_button()
 79 
 80     # 让最近绘制的屏幕可见
 81     pygame.display.flip()
 82 
 83 def update_bullets(ai_setting, screen, stats,  sb, ship, aliens, bullets):
 84     """更新子弹位置,并删除已消失的子弹"""
 85     # 删除子弹的位置
 86     bullets.update()
 87     # 删除已消失的子弹
 88     for bullet in bullets.copy():
 89         if bullet.rect.bottom <= 0:
 90             bullets.remove(bullet)
 91     check_bullet_alien_colisions(ai_setting, screen, stats,  sb, ship, aliens, bullets)
 92 
 93 def check_high_score(stats, sb):
 94     """检查是否诞生了新的最高得分"""
 95     if stats.score > stats.high_score:
 96         stats.high_score = stats.score
 97         sb.prep_high_score()
 98 
 99 def check_bullet_alien_colisions(ai_setting, screen, stats,  sb, ship, aliens, bullets):
100     """响应是否有子弹击中了外星人"""
101     # 如果是这样,就删除相应的子弹和外星人
102     collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
103 
104     if collisions:
105         for aliens in collisions.values():
106             stats.score += ai_setting.alien_points * len(aliens)
107             sb.prep_score()
108         check_high_score(stats, sb)
109 
110     if len(aliens) == 0:
111         # 删除现在的子弹,加快游戏节奏,并新建一群外星人
112         bullets.empty()
113         ai_setting.increase_speed()
114 
115         # 提高一个等级
116         stats.level += 1
117         sb.prep_level()
118 
119         create_fleet(ai_setting, screen, ship, aliens)
120 
121 
122 def get_number_alien_x(ai_setting, alien_width):
123     """计算每行可容纳多少个个外星人"""
124     available_space_x = ai_setting.screen_width - 2 * alien_width
125     number_aliens_x = int(available_space_x / (2 * alien_width))
126     return number_aliens_x
127 
128 def create_alien(ai_setting, screen, aliens, alien_number, row_number):
129     # 创建一个外星人并将其加入当前行
130     alien = Alien(ai_setting, screen)
131     alien_width = alien.rect.width
132     alien.x = alien_width + 2 * alien_width * alien_number
133     alien.rect.x = alien.x
134     alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
135     aliens.add(alien)
136 
137 def create_fleet(ai_setting, screen, ship, aliens):
138     """创建外星人群"""
139     # 创建一个外星人,并计算一行可容纳多少个外星人
140     # 外星人间距为外星人宽度
141     alien = Alien(ai_setting, screen)
142     number_aliens_x = get_number_alien_x(ai_setting, alien.rect.width)
143     number_rows = get_number_rows(ai_setting, ship.rect.height, alien.rect.height)
144 
145     # 创建第一行外星人
146     for row_number in range(number_rows):
147         for alien_number in range(number_aliens_x):
148             create_alien(ai_setting, screen, aliens, alien_number, row_number)
149 
150 
151 def get_number_rows(ai_setting, ship_height, alien_height):
152     """计算屏幕可容纳多少行外星人"""
153     available_space_y = (ai_setting.screen_height - (3 * alien_height) - ship_height)
154     number_rows = int(available_space_y / (2 * alien_height))
155     return number_rows
156 
157 def check_fleet_edges(ai_setting, aliens):
158     """有外星人到达边缘时采取相应的措施"""
159     for alien in aliens.sprites():
160         if alien.check_edges():
161             change_fleet_direction(ai_setting, aliens)
162             break
163 
164 def change_fleet_direction(ai_setting, aliens):
165     """将整群外星人下移"""
166     for alien in aliens.sprites():
167         alien.rect.y += ai_setting.fleet_drop_speed
168     ai_setting.fleet_direction *= -1
169 
170 def update_aliens(ai_setting, stats, screen, sb, ship, aliens, bullets):
171     check_fleet_edges(ai_setting, aliens)
172     aliens.update()
173 
174     # 检测外星人和飞船之间的碰撞
175     if pygame.sprite.spritecollideany(ship, aliens):
176         ship_hit(ai_setting, stats, screen, sb, ship, aliens, bullets)
177     # 检查是否有外星人大大屏幕底端
178     check_aliens_bottom(ai_setting, stats, screen, sb, ship, aliens, bullets)
179 
180 def ship_hit(ai_setting, stats, screen, sb, ship, aliens, bullets):
181     """响应被外星人撞到的飞船"""
182     if stats.ship_left > 0:
183         # 将ship_left减1
184         stats.ship_left -= 1
185 
186         # 更新记分牌
187         sb.prep_ships()
188 
189         #清空外星人列表和子弹列表
190         aliens.empty()
191         bullets.empty()
192 
193         # 创建一群新的外星人,并将飞船放到屏幕低端中央
194         create_fleet(ai_setting, screen, ship, aliens)
195         ship.center_ship()
196 
197         # 暂停
198         sleep(0.5)
199     else:
200         stats.game_active = False
201 
202 def check_aliens_bottom(ai_setting, stats, screen, sb, ship, aliens, bullets):
203     """检查是否有外星人到达了屏幕底端"""
204     screen_rect = screen.get_rect()
205     for alien in aliens.sprites():
206         if alien.rect.bottom >= screen_rect.bottom:
207             # 像飞船被撞到一样进行处理
208             ship_hit(ai_setting, stats, screen, sb, ship, aliens, bullets)
209             break

 

alien.py:

 

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

 

setting.py:

 

 1 class Settings():
 2     """存储《外星人入侵》的所有设置的类"""
 3 
 4     def __init__(self):
 5         """初始化游戏的设置"""
 6         # 屏幕设置
 7         self.screen_width = 900
 8         self.screen_height = 600
 9         self.bg_color = (230, 230, 230)
10         # 飞船的设置
11         self.ship_speed_factor = 1.5
12         # 子弹设置
13         self.bullet_speed_factor = 3
14         self.bullet_width = 3
15         self.bullet_height = 15
16         self.bullet_color = 60, 60, 60
17         self.bullets_allowed = 3
18         self.alien_speed_factor = 1
19         self.fleet_drop_speed = 10
20         self.fleet_direction = 1
21         self.ship_limit = 3
22         # 以什么样的速度加快游戏的节奏
23         self.speedup_scale = 1.1
24         #外星人点数的提高速度
25         self.score_scale = 1.5
26 
27         self.initialize_dynamic_settings()
28 
29     def initialize_dynamic_settings(self):
30         """初始化随游戏进行而变化的位置"""
31         self.ship_speed_factor = 1.5
32         self.bullet_speed_factor = 3
33         self.alien_speed_factor = 1
34 
35         # fleet_direction为1表示向右;为-1表示向左
36         self.fleet_direction =1
37         # 记分
38         self.alien_points = 50
39 
40     def increase_speed(self):
41         """提高速度设置"""
42         self.ship_speed_factor *= self.speedup_scale
43         self.bullet_speed_factor *= self.speedup_scale
44         self.bullet_speed_factor *= self.speedup_scale
45         self.alien_points = int(self.alien_points * self.score_scale)

 

bullet.py:

 

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

 

ship.py:

 

 1 import  pygame
 2 from pygame.sprite import Sprite
 3 
 4 class Ship(Sprite):
 5 
 6     def __init__(self, ai_setting, screen):
 7         """初始化飞船并设置其初始位置"""
 8         super(Ship, self).__init__()
 9         self.screen = screen
10         self.ai_setting = ai_setting
11 
12         """加载飞船图像并获取其外接矩阵"""
13         self.image = pygame.image.load('images/ship.bmp')
14         self.rect = self.image.get_rect()
15         self.screen_rect = screen.get_rect()
16 
17         # 将每艘新飞船放在屏幕底部中央
18         self.rect.centerx = self.screen_rect.centerx
19         self.rect.bottom = self.screen_rect.bottom
20 
21         # 在飞船的属性center中存储小数值
22         self.center = float(self.rect.centerx)
23 
24         # 移动标志
25         self.moving_right = False
26         self.moving_left = False
27 
28     def update(self):
29         """根据移动标志调增飞船的位置"""
30         if self.moving_right and self.rect.right < self.screen_rect.right:
31             self.center += self.ai_setting.ship_speed_factor
32         if self.moving_left and self.rect.left > 0:
33             self.center -= self.ai_setting.ship_speed_factor
34 
35         """根据self.center调整飞船的位置"""
36         self.rect.centerx = self.center
37 
38     def blitme(self):
39         """在指定为这绘制飞船"""
40         self.screen.blit(self.image, self.rect)
41 
42     def center_ship(self):
43         self.center = self.screen_rect.centerx

 

 

图片:

 

posted @ 2018-08-03 14:13  迷途纸鸢  阅读(1732)  评论(0编辑  收藏  举报