python-alien-invasion-game-spaceship

本来这篇文章我已经有思路了,并且其实已经写了一些了,但是因为有一些事情要去做,然后忘记这边还写得文章了,没保存直接关闭了。所以现在是我重新写的了!

最近我是在看《Python从入门到实践》,看的比较快,已经到项目部分了,开始做飞船大战外星人这个基本上入门必学的案例了,但是还是遇到了许多的问题,不过幸好基本上全部解决了了。其实对编程最大的挑战,就是仔细。这个东西确实,有的时候感觉就是控制不住自己,不是多敲了就是少敲了,下面先分析一下会出现什么样的问题。

首先呢其实就是英文大小写问题,还有加不加s,有的时候你前面定义的是有s的,但是后来下面调用的时候忘记了,或者前面没有s,后面加了。

再有就是符号问题,我发现我写Python很爱写分号;,搞得我很难受,用PyCharm一直有波浪线出现。

然后再就是其实真的,一些简单的小程序写上一个文档就好了,文档太多调用很麻烦的!不过说实在的,分的多了,找起来修改很容易,并且其实未来进行编程的时候,大多都不是小程序,还是需要重构一下代码的。不过其实,可以先把想要重构的先写出来,然后再找到合适的地方把它放进去,不是创建一个.py就是创建一个def,反正就是要把它放起来,让主文件空空荡荡最好!

我一般就是错名字,错参数!很难受的,有的找起来非常费劲!

super(Bullet,self).__init__(),比如说这一段,给继承的参数,容易出错。再比如说一些位置,不要理所应当,我今天把左右移动调成上下移动,一开始是我确实以为是up和down,没想到实际上却是top和bottom,虽然有的时候PyCharm没有提示,但是大多数没提示都是错误的。

下面上一下代码,把所有文件放在同一目录下即可,当然图片记得放好或者修改一下。

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
# 主文件:
import pygame
from setting import Settings
from ship import Ship
import game_functions as gf
from pygame.sprite import Group

def run_game():
# 初始化游戏并且创建一个屏幕对象
pygame.init()
# 初始化背景属性
ai_settings = Settings()
# 使类setting里的内容直接被调用
screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))
pygame.display.set_caption("aa") # 窗口名字
# 创建飞船
ship = Ship(ai_settings, screen)
# 创建储存子弹的编组
bullets = Group()
# 开始游戏的主循环
while True:
# 监视鼠标和键盘事件
gf.check_events(ai_settings, screen, ship, bullets)
ship.update()
bullets.update()
gf.update_bullets(bullets)
gf.update_screen(ai_settings, screen, ship, bullets)

run_game()

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
# game_functions.py
import sys
import pygame
from bullet import Bullet

def check_keydown_events(event, ai_settings, screen, ship, bullets):
"""响应按下"""
if event.key == pygame.K_RIGHT:
ship.moving_right = True
elif event.key == pygame.K_LEFT:
ship.moving_left = True
elif event.key == pygame.K_SPACE:
fire_bullet(ai_settings, screen, ship, bullets)

def fire_bullet(ai_settings, screen, ship, bullets):
# 创建一个子弹并将它加入编组bullets
if len(bullets) < ai_settings.bullet_allowed:
# 判断现存子弹数量是否小于设定值
new_bullet = Bullet(ai_settings, screen, ship)
bullets.add(new_bullet)

def check_keyup_events(event, ship):
"""响应松开"""
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False

def check_events(ai_settings, screen, ship, bullets):
"""响应按键和鼠标事件"""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event, ai_settings, screen, ship, bullets)
elif event.type == pygame.KEYUP:
check_keyup_events(event, ship)

def update_screen(ai_settings, screen, ship, bullets):
"""更新数据"""
screen.fill(ai_settings.bg_color)
# 绘制所有子弹
for bullet in bullets.sprites():
bullet.draw_bullet()
ship.blitme()
# 让最近绘制的屏幕可见
pygame.display.flip()

def update_bullets(bullets):
"""更新子弹位置,删除消失的子弹"""
# 更新子弹位置
bullets.update()
# 删除消失的子弹
for bullet in bullets.copy():
if bullet.rect.bottom < 0:
bullets.remove(bullet)

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
# ship.py
import pygame

class Ship():
def __init__(self, ai_settings, screen):
"""初始化飞船位置"""
self.screen = screen
self.ai_settings = ai_settings
# 加载飞船图像并获取其外接矩形
self.image = pygame.image.load("images/ship.bmp")
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
# 将每艘新飞船放在屏幕底部中央
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
# 在飞船的属性center中储存小数值
self.center = float(self.rect.centerx)
# 移动标志
self.moving_right = False
self.moving_left = False

def update(self):
"""根据移动标志调整位置"""
# 更新飞船的center值,而不是rect
if self.moving_right and self.rect.right < self.screen_rect.right:
self.center += self.ai_settings.ship_speed_factor
if self.moving_left and self.rect.left > 0:
self.center -= self.ai_settings.ship_speed_factor
# 根据self.center更新rect对象
self.rect.centerx = self.center

def blitme(self):
"""在指定位置绘制飞船"""
self.screen.blit(self.image, self.rect)

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
# bullet.py
import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):
"""一个对飞船发射的子弹进行管理的类"""

def __init__(self, ai_settings, screen, ship):
"""在飞船所处位置创建一个子弹"""
super(Bullet, self).__init__()
self.screen = screen
# 在(0,0)处创建一个表示子弹的矩形,再将位置进行转移(设置成改在的位置)
self.rect = pygame.Rect(0, 0, ai_settings.bullet_width, ai_settings.bullet_height)
self.rect.centerx = ship.rect.centerx
self.rect.top = ship.rect.top
# 储存用小数表示的子弹位置
self.y = float(self.rect.y)
self.color = ai_settings.bullet_color
self.speed_factor = ai_settings.bullet_speed_factor

def update(self):
"""向上移动子弹"""
# 更新子弹位置的小数值
self.y -= self.speed_factor
# 更新子弹的位置
self.rect.y = self.y

def draw_bullet(self):
"""在屏幕上绘制子弹"""
pygame.draw.rect(self.screen, self.color, self.rect)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# setting.py
class Settings():
"""储存外星人大战的所有设置"""

def __init__(self):
"""初始化游戏的设置"""
# 屏幕设置
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (230, 230, 230)
# 飞船的设置
self.ship_speed_factor = 1.5
# 子弹设置
self.bullet_speed_factor = 1
self.bullet_width = 3
self.bullet_height = 15
self.bullet_color = (60, 60, 60)
self.bullet_allowed = 3

效果图我就不放了,反正还可以吧,就这样!


希望这样的格式更容易阅读和理解你的博客内容。如果有任何其他需要或问题,请随时告诉我。

作者

datehoer

发布于

2020-11-08

更新于

2023-10-19

许可协议

评论