找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

查看: 9762|回复: 5

[求助] 书上的外星人入侵小游戏 发射不了子弹

2

主题

5

帖子

5

积分

贫民

积分
5
学渣爱讲题 发表于 2017-6-6 11:20:36 | 显示全部楼层 |阅读模式
游戏可以运行,但是发射不了子弹,看了两天,不知道哪里错了。还有就是为什么ship类里 要写self.ai_settings = ai_settings, 而bullet类里就不用写了呢。
alien_invasion.py:
import pygame
from bullet import Bullet
from pygame.sprite import Group
from settings import Settings
import game_functions as gf
from ship import Ship

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("外星人入侵")
       
        #创建一艘飞船
        ship = Ship(ai_settings, screen)
       
        #创建子弹编组
        bullets = Group()
       
       
        #开始游戏主循环
        while True:
               
                gf.check_events(ai_settings, screen, ship, bullets) #监视键盘和鼠标事件
               
                ship.update() #控制飞船移动
               
                gf.update_bullets(bullets) #更新子弹
                               
                gf.update_screen(ai_settings, screen, ship, bullets) #刷新屏幕

run_game()                               
                       
settings.py:
class Settings():
        """创建一个全局设置类"""
        def __init__(self):
                #屏幕设置
                self.screen_width = 900
                self.screen_height = 500
                self.bg_color = (230, 230, 230)
               
                #ship设置
                self.ship_speed_factor = 1.5
               
                #bullet设置
                self.bullet_width = 3
                self.bullet_height = 15
                self.bullet_color =(60, 60, 60)
                self.bullet_speed_factor = 1
                self.bullets_allowed = 3
       
       

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):
        """如果还没有达到限制,就发射一颗子弹"""
        if len(bullets) < ai_settings.bullets_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_bullets(bullets):
        """更新子弹位置,并删除已消失的子弹"""
        bullets.update()
        for bullet in bullets.copy():
                if bullet.rect.bottom <= 0:
                        bullets.remove(bullet)
       
       
                       
def update_screen(ai_settings, screen, ship, bullets):
        """刷新屏幕"""
        screen.fill(ai_settings.bg_color)
        ship.blitme()
        for bullet in bullets.sprites():
                bullet.draw_bullet()
        pygame.display.flip()                       
                       

bullet.py:
import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):
        """继承Sprite类的子弹类,Sprite类有编组功能"""
        def __init__(self, ai_settings, screen, ship):
                super().__init__()
                self.screen = screen
               
                self.rect = pygame.Rect(0, 0, ai_settings.bullet_width, ai_settings.bullet_height) #在原点创建子弹
                self.color = ai_settings.bullet_color
                self.speed_factor = ai_settings.bullet_speed_factor
               
                self.rect.centerx = ship.rect.centerx    #设定子弹位置
                self.rect.top = ship.rect.top
               
                self.y = float(self.rect.y)  #设定存储小数值的子弹位置
               
        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)       
               
               
               
ship.py:
import pygame

class Ship():
        def __init__(self, ai_settings, screen):
                self.screen = screen  #飞船显示在游戏的屏幕上
                self.ai_settings = ai_settings
               
                #载入ship图像 并获取ship和屏幕矩形(计算机容易运算矩形,因为矩形最简单)
                self.image = pygame.image.load('images/ship.bmp')
                self.rect = self.image.get_rect()
                self.screen_rect = self.screen.get_rect()
               
                #设定ship位置
                self.rect.centerx = self.screen_rect.centerx
                self.rect.bottom = self.screen_rect.bottom
               
                #设置移动标志
                self.moving_right = False
                self.moving_left = False
               
                #在飞船属性center中储存小数值
                self.center = float(self.rect.centerx)
               
        def update(self):
                """调整飞船移动"""
                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.rect.centerx = self.center #将self.center储存的位置赋予self.rect.centerx                       
               
        def blitme(self):
                """将ship绘制到屏幕上"""
                self.screen.blit(self.image, self.rect)
                       
               
               
               
               
                       
               
               
               
       
       


               
               
       







回复

使用道具 举报

0

主题

3

帖子

3

积分

贫民

积分
3
hebay 发表于 2017-6-6 17:23:21 | 显示全部楼层
[img]file:///C:\Users\Apple\AppData\Roaming\Tencent\Users\895287879\QQ\WinTemp\RichOle\$6G5)TL`H([7TF{ZAN)EJ[W.png[/img][img=0,1]file:///C:\Users\Apple\AppData\Roaming\Tencent\Users\895287879\QQ\WinTemp\RichOle\$6G5)TL`H([7TF{ZAN)EJ[W.png[/img][img=0,1]file:///C:\Users\Apple\AppData\Roaming\Tencent\Users\895287879\QQ\WinTemp\RichOle\$6G5)TL`H([7TF{ZAN)EJ[W.png[/img][img=0,1]file:///C:\Users\Apple\AppData\Roaming\Tencent\Users\895287879\QQ\WinTemp\RichOle\$6G5)TL`H([7TF{ZAN)EJ[W.png[/img]import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):
    """继承Sprite类的子弹类,Sprite类有编组功能"""
    def __init__(self, ai_settings, screen, ship):
        super(Bullet, self).__init__()
        self.screen = screen

        self.rect = pygame.Rect(0, 0, ai_settings.bullet_width, ai_settings.bullet_height) #在原点创建子弹
        self.color = ai_settings.bullet_color
        self.speed_factor = ai_settings.bullet_speed_factor

        self.rect.centerx = ship.rect.centerx    #设定子弹位置
        self.rect.top = ship.rect.top

        self.y = float(self.rect.y)  #设定存储小数值的子弹位置

    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)

回复 支持 反对

使用道具 举报

2

主题

5

帖子

5

积分

贫民

积分
5
学渣爱讲题  楼主| 发表于 2017-6-6 18:40:58 | 显示全部楼层
hebay 发表于 2017-6-6 17:23
import pygame
from pygame.sprite import Sprite

super().__init__()是python3的写法 ,和super(Bullet, self).__init__()效果一样啊。
还有下面那个pygame.draw.rect(self.screen, self.color, self.rect)和我的一样啊。
改了之后还是没子弹
回复 支持 反对

使用道具 举报

0

主题

3

帖子

3

积分

贫民

积分
3
hebay 发表于 2017-6-7 10:03:48 | 显示全部楼层
super().__init__()是python3的写法,如果这个没问题,那就是下面
"""在屏幕上绘制子弹"""
pygame.draw.rect = (self.screen, self.color, self.rect)   
你的多了个 = 号     ,
我用的是 python27调试的
回复 支持 反对

使用道具 举报

2

主题

5

帖子

5

积分

贫民

积分
5
学渣爱讲题  楼主| 发表于 2017-6-7 11:22:21 | 显示全部楼层
hebay 发表于 2017-6-7 10:03
super().__init__()是python3的写法,如果这个没问题,那就是下面
"""在屏幕上绘制子弹"""
pygame.draw.r ...

谢谢你,真的是多了个等号。 想不到困扰了这么久的问题,出在一个小地方。 请问大神运行程序发现有bug时,是如何思考 如何检测的呢?我想学习一下。
回复 支持 反对

使用道具 举报

0

主题

3

帖子

3

积分

贫民

积分
3
hebay 发表于 2017-6-9 16:48:15 | 显示全部楼层
大概思路就是,子弹不能发射,就看下子弹相关的地方,一是创建, 另一个就是绘制了, 查看是否创建成功可以 print len(bullets),发现 >0 说明创建是没问题的, 再看下 draw方法
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表