当前位置:   article > 正文

基于pygame的射击小游戏制作(二)射击子弹_bullet_super

bullet_super
在本篇文章中,将学习如何创建子弹移动的元素,如何在屏幕中让子弹向上飞驰,如何删除超过屏幕边界的子弹。

1.编程思路

1.1 创建一个子弹

功能描述:玩家将按空格键时发射子弹,子弹在屏幕中向上穿行,抵达屏幕边缘后消失。
在settings.py文件中,的init方法中加入子弹(Bullet)的值:速度,宽度、高度、颜色、允许发射的最大子弹数量

#子弹设置
        self.bullet_speed_factor = 1
        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = (60,60,60)
        self.bullets_allowed = 3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在project中新建一个bullet.py ,用来存储Bullet类。该类主要用于在游戏中同时操作编组中的所有元素,为创建子弹实例,传递参数,并调用了super()来继承Sprite。
用小矩形框来代替子弹,使用pygame.Rect(),从空白创建一个宽为3,高为15像素的矩形,子弹的初始位置取决于飞船的当前位置,并应从飞船顶部射出,将子弹的top属性设置为飞船的top属性,让子弹看起来像是从飞船中射击的。将子弹的y坐标设为小数,并把子弹的颜色和速度设置分别存储在self.color和self.speed_factor中。

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
1.2 将子弹发射出来

接下来我们要让子弹更新在屏幕中,方法update()管理子弹的位置。发射出去后,子弹在屏幕中向上移动,这意味着y坐标将不断减小,因此为更新子弹的位置,我们从self.y中减去self.speed_factor的值。子弹发射后,其x坐标始终不变,因此子弹将沿直线垂直地往上穿行。
调用draw_bullet()来绘制子弹。self.color中的颜色填充表示子弹占据的屏幕部分。

def update(self):
    """向上移动子弹"""
    #更新表示子弹位置的小数值
    self.y -= self.speed_factor
    #更新表示子弹的rect的位置
    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
1.3 将子弹添加进弹膛

在玩家每次按空格键时都射出一发子弹。首先,我们将在alien_invasion.py中创建一个编组(group),用于存储所有有效的子弹,以便能够管理发射出去的所有子弹。在主循环中,我们将使用这个编组在屏幕上绘制子弹,以及更新每颗子弹的位置:

"""游戏主循环"""
    while True:
        """监视键鼠事件"""
        gf.check_events(ai_settings, screen, ship, bullets)
        ship.update()
        #print(len(bullets))
        gf.update_bullets(bullets)
        gf.update_screen(ai_settings, screen, ship, bullets)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
1.4 开火

在game_functions.py中,我们需要修改check_keydown_events(),以便在玩家按空格键时发射一颗子弹。还要把超出屏幕的子弹删除,控制子弹的发射数量

def fire_bullet(ai_settings, screen, ship, bullets):
    """如果还没有达到限制,就发射一颗子弹"""
    # 创建一颗子弹,并将其加入到编组bullets
    if len(bullets) < ai_settings.bullets_allowed:
        new_bullet = Bullet(ai_settings, screen, ship)
        bullets.add(new_bullet)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
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
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在check_keydown_events()中,检测到空格键按下时,就会发射出一颗子弹,并且子弹的数量不能超过3颗。

3.源代码

alien_invasion.py
import sys    #退出游戏
import pygame #包含开发所需功能
from settings import Settings
from ship import Ship
import game_functions as gf
from pygame.sprite import Group
def run_game():
    # 初始化背景设置
    pygame.init()
    ai_settings = Settings()
    # 创建游戏窗口
    screen = pygame.display.set_mode(
        (ai_settings.screen_width, ai_settings.screen_height))
    pygame.display.set_caption("Alien Invasion")
    """创建一艘飞船"""
    ship = Ship(ai_settings, screen)
    """创建一个用于存储子弹的编组"""
    bullets = Group()
    """设置背景色"""
    bg_color = (230,230,230)
    """游戏主循环"""
    while True:
        """监视键鼠事件"""
        gf.check_events(ai_settings, screen, ship, bullets)
        ship.update()
        #print(len(bullets))
        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
game_functions.py
import sys
import pygame
from bullet import Bullet
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 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 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 update_screen(ai_settings, screen, ship, bullets):
    #更新屏幕图像
    # 每次循环时都重绘屏幕
    screen.fill(ai_settings.bg_color)

    #在飞船和外星人后面重绘所有子弹
    for bullets in bullets.sprites():
        bullets.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)

def fire_bullet(ai_settings, screen, ship, bullets):
    """如果还没有达到限制,就发射一颗子弹"""
    # 创建一颗子弹,并将其加入到编组bullets
    if len(bullets) < ai_settings.bullets_allowed:
        new_bullet = Bullet(ai_settings, screen, ship)
        bullets.add(new_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
  • 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
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
        #更新表示子弹的rect的位置
        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
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
settings.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.bullets_allowed = 3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

4.实现效果

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/123175
推荐阅读
相关标签
  

闽ICP备14008679号