python-pygame的使用随笔

外星人大战---打飞机游戏

首先必须使用安装pygame库文件,而且必须是要跟python的版本一致性才能使用,不然会一直报错,具体的安装方法和使用方法见百度文库https://jingyan.baidu.com/article/3052f5a10b2d4297f31f861c.html
安装完成后有一个小插曲,一直提示我 pip install --upgrade pip出错
找了半天发现时我的pip的版本太老了,需要升级,

python -m pip install -U pip
这样才是正确的升级方式,详见python官方文档。

安装完成后就开始实现外星人大战游戏

alient_invasion.py 文件

import pygame  #首先第一步需要导入pygame文件

#第二步需要初始化程序并创建一个屏幕对象
pygame.init()
screen = pygame.display.set_mode((1200,800)) #创建游戏的屏幕,宽/高
pygame.display.set_caption("Alient_Invasion") #创建窗口显示的名称

#第三步需要创建飞船
#加载飞船图像并获取其外接矩形
image = pygame.image.load('images/ship.bmp') #相对路径文件下的图片,最好是bmp格式的
rect = self.image.get_rect()
#获得屏幕的外接矩形
screen_rect =screen.get_rect()
#将每艘飞船放在屏幕底部中央,其实就是给飞船的rect赋值
rect.centerx = self.screen_rect.centerx
rect.bottom = self.screen_rect.bottom
#飞船的移动速度
ship_speed_factor =1.5 
转换rect.centerx,只能取整数换成能够取小数
center = float(self.rect.centerx)
#移动标志
moving_right= False
moving_left = False
# 是否允许发射子弹
allow_bullet = False

#根据移动标识来不断的移动飞船
def update():
  #rect.right<screen_rect.right用来判断不会超出屏幕宽度,并根据移动标志来不断的移动飞船位置
  if moving_right and rect.right<screen_rect.right:
      center += ship_speed_factor
  if moving_left and rect.left>0:
      center -= ship_speed_factor
  #根据center 更新飞船的rect对象
  rect.centerx = center

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

#第四步:开始游戏的主循环   ps:之所以需要死循环,是因为需要不断的更新游戏窗口中的变动,包含子弹的移动,飞船的移动,事件的获取等等
while True:

    #遍历pygame.event.get()方法来获取事件并监听键盘和鼠标的事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
           sys.exit()
        #捕获到键盘按下时
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event,ship)  #此方法的实现在gamefunction.py 文件中,底部有写到
          # 捕获到键盘松开时
        elif event.type == pygame.KEYUP:
            check_keyup_events(event,ship)

    #不断获取键盘事件并移动飞船位置
    update()

    #每次循环时都重新绘制屏幕
    screen.fill(settings.bg_color)
    #调用绘制飞船的方法
    blitme()
    #使其可见
    pygame.display.flip()
gamefunction.py 文件
#响应按键时的处理
def check_keydown_events(event,ship):
    if event.key == pygame.K_RIGHT:
        # 向右移动飞船
        moving_right = True
    elif event.key == pygame.K_LEFT:
        # 向左移动飞船
        moving_left = True
    elif event.key == pygame.K_SPACE:
        #允许发射子弹
        allow_bullet = True
#响应按键松开时的处理
def check_keyup_events(event):
    if event.key == pygame.K_RIGHT:
        # 向右移动飞船
        moving_right = False
    elif event.key == pygame.K_LEFT:
        # 向左移动飞船
        moving_left = False
    elif event.key == pygame.K_SPACE:
        #允许发射子弹
        allow_bullet = True

这样,飞船和屏幕的处理以及响应按键就处理完成了,但是想要发射子弹怎么办?

首先需要创建一个子弹的类

bullet.py文件

from pygame.sprite import Sprite
class Bullet(Sprite):
    '''一个对飞船发射的子弹管理的类,继承Sprite类 '''
    def __init__(self,settings,screen,ship):
        '''在飞船所处的位置创建一个子弹类'''
        super(Bullet,self).__init__()
        self.screen = screen
        #在(0,0)处创建一个子弹的矩形,再设置其到正确的位置
        self.rect = pygame.Rect(0,0,settings.bullet_width,settings.bullet_height)
        self.rect.centerx = ship.center
        self.rect.top = ship.rect.top
        #存储用小数表示的子弹位置
        self.y = float(self.rect.y)

        self.color = settings.bullet_color
        self.speed_factor = 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)

创建完成后在主文件alient_invasion.py 文件中

#创建一个用于存储子弹的编组
bullets = Group()

#让飞船发射子弹
def allow_bullets():
    if allow_bullet:
        if len(bullets) == 0:
            new_bullet = Bullet(settings,screen,ship) #初始化子弹类
            bullets.add(new_bullet) #将初始化的子弹类放入存储子弹的编组中
        elif len(bullets)>0:
            #设置子弹的速度,让第一颗子弹移动到700时发射第二颗子弹,实际上让子弹的速度变快,最大不超过800
             for bullet in bullets:
                if(bullet.rect.bottom == 700):
                    new_bullet = Bullet(settings, screen, ship)
                    bullets.add(new_bullet)

然后在游戏的主循环中添加

#发射子弹

allow_bullets()
#不断的更新子弹移动

bullets.update()

#在飞船后面重绘所有子弹,
for bullet in bullets.sprites():
    bullet.draw_bullet()

# 删除已消失的子弹
for bullet in bullets:
    if bullet.rect.bottom <= 0:
        bullets.remove(bullet)

至此子弹设置完成,其实就是用for循环不断的把每一个子弹(继承Sprite类)的类初始化后,放入用于存储子弹的编组Group()中

然后用for循环 不断更新每一个Group()中的子弹的对象,比如删除,移动位置等

最后还是用for循环使每一个子弹可见。

参考飞船的实现,可以实现敌机,并且让敌机发射子弹,具体的实现方式不细诉。

第一次写,写的比较乱,这个是在不同的类中整合出来的,

可能看着不习惯,不过理解了原理就好了

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值