找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

查看: 4870|回复: 1

[求助] pygame的打飞机游戏运行报错

1

主题

1

帖子

1

积分

贫民

积分
1
Eshen 发表于 2017-9-24 11:28:29 | 显示全部楼层 |阅读模式
这是《python从入门到实践》里面的一个项目,跟着做下来,这个错误我解释不了。。。。有没有大神帮忙分析分析


完整错误信息如下:
Traceback (most recent call last):
  File "E:\personal\eclipse-workspace\Alien_Invasion\alien_invasion\alien_invasion.py", line 43, in <module>
    run_game()
  File "E:\personal\eclipse-workspace\Alien_Invasion\alien_invasion\alien_invasion.py", line 28, in run_game
    gf.check_events(init_setting,screen,gun,bullets)
  File "E:\personal\eclipse-workspace\Alien_Invasion\alien_invasion\game_functions.py", line 40, in check_events
    check_fire(init_setting,screen,gun,bullets,event)
  File "E:\personal\eclipse-workspace\Alien_Invasion\alien_invasion\game_functions.py", line 30, in check_fire
    new_bullet = Bullet(init_setting,screen,gun)
  File "E:\personal\eclipse-workspace\Alien_Invasion\alien_invasion\bullet.py", line 24, in __init__
    self.bullet_speed =init_setting.bullet_speed
AttributeError: 'pygame.Surface' object has no attribute 'bullet_speed'


程序文件如下:
game_function.py

#!/usr/bin/env python
#_*_ coding:utf-8 _*_

import sys
import pygame
from bullet import Bullet

def check_left(event,gun):
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_LEFT:
                #向左移动飞船
                gun.moving_left = True
    elif event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                gun.moving_left = False

def check_right(event,gun):
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_RIGHT:
                # 向右移动飞船
                gun.moving_right = True
    elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                gun.moving_right = False

def check_fire(init_setting,screen,gun,bullets,event):
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_SPACE:
            #创建新子弹
            new_bullet = Bullet(init_setting,screen,gun)
            bullets.add(new_bullet)

def check_events(init_setting,screen,gun,bullets):
    '''响应按键和鼠标输入'''
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        check_left(event, gun)
        check_right(event,gun)
        check_fire(init_setting,screen,gun,bullets,event)



def update_screen(setting,screen,gun,bullets):
    '''更新屏幕上的图像,并换到新屏幕'''
    #每次循环时重绘屏幕
    screen.fill(setting.bg_color)

    bullets.draw(screen)
    gun.blitme()
    #让最近绘制的屏幕可见
    pygame.display.flip()

setting.py

#!/usr/bin/env python
#_*_ coding:utf-8 _*_

class Setting(object):
    '''
    储存外星人入侵的所有设置的类
    '''
    def __init__(self):
        #初始化游戏设置
        #设置屏幕
        self.screen_width = 800
        self.screen_height = 600
        self.bg_color = (0,100,150)
        self.caption = 'Alien Invasion'
        self.gun_speed = 1
        #设置子弹属性
        #self.bullet_width = 3
        #self.bullet_height = 15
        #self.bullet_color = (60,60,60)
        self.bullet_speed = 1

bullet.py

#!/usr/bin/env python
#_*_ coding:utf-8 _*_

import pygame
from pygame.sprite import Sprite
from setting import Setting

class Bullet(Sprite):
    '''管理发射出的子弹的类'''  
    def __init__(self,screen,init_setting,gun):
        '''在枪所在的位置创建一个子弹对象'''
        super(Bullet,self).__init__()
        self.screen = screen
        #此处的pygame.Rect创建的对象不是一个pygame.Surface对象造成了后面的一系列错误
        self.image = pygame.image.load('images/hahaha.bmp')

        self.rect = self.image.get_rect()
        self.rect.centerx = gun.rect.centerx
        self.rect.top = gun.rect.top
        self.y = float(self.rect.y)

        #self.color = (60,60,60)
        #这里是程序报错的点,语法逻辑上看不出来什么问题呀!用gun.py文件内的那种速度赋值方法就不会报错,可是为什么呢。。。
        self.bullet_speed =init_setting.bullet_speed

    def update(self):
        '''向上移动子弹'''
        self.y -=self.bullet_speed
        self.rect.y = self.y

gun.py

#!/usr/bin/env python
#_*_ coding:utf-8 _*_

import pygame
from setting import Setting

class Gun(object):
    '''
    初始化枪,并设置其初始位置
    '''
    def __init__(self,screen):
        self.screen = screen

        #加载枪的图像并获取其外接矩形
        self.image = pygame.image.load('images/lalala.bmp')
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()
        #将每艘新飞船放在屏幕底部中央
        self.rect.centerx = self.screen_rect.centerx
        #以浮点数储存中心值
        self.center = float(self.rect.centerx)
        self.rect.bottom = self.screen_rect.bottom
        #设置移动标志
        self.moving_right = False
        self.moving_left = False
        #设置移动速度,此处与枪的速度设置类似,用这种方法就不会报错。。。。但是为什么呢
        self.speed = Setting().gun_speed

    def update(self):
        '''根据移动标志调整飞船位置'''
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.center += self.speed   
        elif self.moving_left and self.rect.left > 0:
            self.center -= self.speed

        #根据改变值更新位置
        self.rect.centerx = self.center

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


主程序:
#!/usr/bin/env python
#_*_ coding:utf-8 _*_


import game_functions as gf
import pygame
from setting import Setting
from gun import Gun
from pygame.sprite import Group


def run_game():
    #初始化游戏并创建一个屏幕对象
    pygame.init()
    init_setting = Setting()
    #创建屏幕对象
    screen = pygame.display.set_mode(
        (init_setting.screen_width,init_setting.screen_height))
    pygame.display.set_caption(init_setting.caption)
   
    #创建一个枪
    gun = Gun(screen)
    #创建一个子弹的组
    bullets = Group()
   
   
    while True:
        #开始游戏主循环
        #检测输入
        gf.check_events(init_setting,screen,gun,bullets)
        #刷新枪的位置
        gun.update()
        #刷新子弹的位置
        bullets.update()
        #删除已消失的子弹
        for bullet in bullets:
            if bullet.rect.bottom <= 0:
                bullets.remove(bullet)
        
        #刷新屏幕        
        gf.update_screen(init_setting,screen,gun,bullets)
        


if __name__ == '__main__':     
    run_game()
   






回复

使用道具 举报

0

主题

1

帖子

1

积分

贫民

积分
1
丁东来 发表于 2017-9-27 11:16:55 | 显示全部楼层
错误信息提示:AttributeError: 'pygame.Surface' object has no attribute 'bullet_speed'
就是说你请求了'pygame.Surface'对象上的'bullet_speed'属性,这个属性不存在。而你原本要使用init_setting上的'bullet_speed'
错误出在调用bullet的init方法时参数次序错了。
这是你bullet的init方法
def __init__(self,screen,init_setting,gun):
这是你创建bullet对象时的调用。
new_bullet = Bullet(init_setting,screen,gun)

很明显init_setting和screen颠倒了。
回复 支持 1 反对 0

使用道具 举报

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

本版积分规则

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