Crossin的编程教室

标题: 【Pygame 第8课】 火力全开 [打印本页]

作者: crossin先生    时间: 2013-8-30 21:16
标题: 【Pygame 第8课】 火力全开
游戏中的几个主要角色我们都有了,接下来就是去完善它们,用它们来组成一个完整的游戏。

首先我们要处理的是子弹。只有一发子弹显然是不够的,群众表示要火力全开!

所以,我们要有一个list,这里list里面存放着一些Bullet的对象。但一个list的Bullet都按之前的方法创建是不行的,那样所有的子弹都会在同一时间发射出去,同时到达屏幕上方,又同时再次发射,这样的视觉效果和一发子弹没什么区别。所以我们要让它们按照一定的时间间隔,一个一个地发射。

另外,之前到了屏幕顶端就回头的方法也会带来问题,重新发射的子弹会和按时发射的子弹混在一起,打乱发射的节奏。所以,子弹“回收”的方法也要改。有种最简单的方法,就是不回收,每次发射都是创建一个新的Bullet对象,飞出屏幕之后就抛弃它。这当然是可以的,但每次都要创建对象,读取图片,并在list上做添加和删除的操作。这样会比较消耗资源,在游戏开发中一般都尽量避免。即使现在这个小游戏中它还不至于影响到体验,也应该养成节约的良好习惯。

我们今天要解决的就是两个问题:定时和回收。

python中有定时运行的方法。但这里,我不打算用它。我们有现成的循环在这儿,只要设定好隔多少次循环运行,就简单地实现了定时的效果。尽管在游戏中,每次循环的时间并不相同,这么做会有潜在的问题:间隔的真实时间会受电脑运行速度的影响。但暂时你可以忽略这个细节(它是有解决办法的)。

我们设定一个变量interval_b,作为Bullet的发射间隔。在每次循环中,让interval_b递减,当减到0以下时,便运行,并重置interval_b的间隔。
  1. interval_b = 0
  2. while True:
  3.     interval_b -= 1
  4.     #当间隔小于0时,激活一发子弹
  5.     if interval_b < 0:
  6.         ###(发射子弹代码)
  7.         interval_b = 100
复制代码
关于子弹的重复利用,我们增加一个变量active,只有active为True的子弹,我们才去处理它的运动。另外,为了依次使用list中有限的子弹,还需要一个变量index_b来记录下一颗子弹是第几号。每激活发射一颗子弹,就把index_b指向它的下一号,最后一号之后再回头使用第0号。

修改一下Bullet类,增加active,并根据active的状态处理运动。增加一个restart方法,用来重新发射子弹。
  1. class Bullet:
  2.     def __init__(self):
  3.         self.x = 0
  4.         self.y = -1
  5.         self.image = pygame.image.load('bullet.png').convert_alpha()
  6.         #默认不激活
  7.         self.active = False

  8.     def move(self):
  9.         #激活状态下,向上移动
  10.         if self.active:
  11.             self.y -= 3
  12.         #当飞出屏幕,就设为不激活
  13.         if self.y < 0:
  14.             self.active = False

  15.     def restart(self):
  16.         #重置子弹位置
  17.         mouseX, mouseY = pygame.mouse.get_pos()
  18.         self.x = mouseX - self.image.get_width() / 2
  19.         self.y = mouseY - self.image.get_height() / 2
  20.         #激活子弹
  21.         self.active = True
复制代码
在游戏中创建5发子弹的list(5发足够了,只要保证你的子弹数足够在打完一轮之前到达屏幕顶端)。
  1. #创建子弹的list
  2. bullets = []
  3. #向list中添加5发子弹
  4. for i in range(5):
  5.     bullets.append(Bullet())
  6. #子弹总数
  7. count_b = len(bullets)
  8. #即将激活的子弹序号
  9. index_b = 0
  10. #发射子弹的间隔
  11. interval_b = 0
复制代码
时间间隔到达时,restart一颗子弹,并将序号递增。
  1. while True:
  2.     #发射间隔递减
  3.     interval_b -= 1
  4.     #当间隔小于0时,激活一发子弹
  5.     if interval_b < 0:
  6.         bullets[index_b].restart()
  7.         #重置间隔时间
  8.         interval_b = 100
  9.         #子弹序号周期性递增
  10.         index_b = (index_b + 1) % count_b
  11.     #判断每个子弹的状态
  12.     for b in bullets:
  13.         #处于激活状态的子弹,移动位置并绘制
  14.         if b.active:
  15.             b.move()
  16.             screen.blit(b.image, (b.x, b.y))
复制代码
只处理active的子弹,绘制它们。

如此一来,你可以不停地向敌机开火了。根据你电脑的运行状况,适当调整一下子弹的移动速度和发射间隔,让它看起来更自然。

至于敌机的行为,比子弹要简单一些,因为不需要定时出现,所以之前用的回收方法可以继续使用,我们下次再说。

8-1.png

8-2.png

#==== Crossin的编程教室 ====#
微信ID:crossincode
论坛:http://crossin.me
QQ群:312723402(接近满员) 156630350

面向零基础初学者的编程课
每天5分钟,轻松学编程


作者: crossin先生    时间: 2013-8-30 21:18
PS:我们的QQ群眼看要接近满员了,所以我又新建了一个2号群,群号:156630350。继续欢迎大家来讨论。
作者: Victor    时间: 2013-8-30 22:28
消灭零回复~~
作者: piaoxu    时间: 2013-8-31 09:40
金币金币
作者: jpjlqone    时间: 2013-9-1 11:49
  1. pygame.mouse.set_visible(False)
复制代码
光标隐形是必要的哦。
作者: 匠逍之岿    时间: 2013-9-1 16:09
for i in range(5):
    bullets.append(Bullet())
这一句向bullets中添加Bullet()是什么意思啊?我print bullets的结果是
[<__main__.Bullet instance at 0x0205F2D8>, <__main__.Bullet instance at 0x020DE968>, <__main__.Bullet instance at 0x020DE990>, <__main__.Bullet instance at 0x020DE9B8>, <__main__.Bullet instance at 0x020DEC38>]
这又是什么呢?

作者: 匠逍之岿    时间: 2013-9-1 16:12
还有这一句
bullets[index_b].restart()
这里的restart()是调用类Bullet中的restart方法吗?但是又没有设定对象,这是怎么调用的呢?
作者: crossin先生    时间: 2013-9-1 22:48
匠逍之岿 发表于 2013-9-1 16:09
for i in range(5):
    bullets.append(Bullet())
这一句向bullets中添加Bullet()是什么意思啊?我print ...

Bullet()是创建了一个子弹的实例,把它append到bullets中,就有了一个Bullet实例组成的list,里面每一项都是一个Bullet的对象
作者: crossin先生    时间: 2013-9-1 22:48
匠逍之岿 发表于 2013-9-1 16:12
还有这一句
bullets.restart()
这里的restart()是调用类Bullet中的restart方法吗?但是又没有设定对象, ...

因为bullets里面存放的都是Bullet对象,所以取出其中一项,直接调用这个对象的方法就可以了
作者: waller516435165    时间: 2013-9-8 04:12
  1. # -*- coding: cp936 -*-
  2. import random
  3. import pygame
  4. from sys import exit

  5. class Enemy:
  6.     def restart(self):
  7.         self.x = random.randint(50,400)
  8.         self.y = random.randint(-200,-50)
  9.         self.speed = random.random() + 0.1

  10.     def __init__(self):
  11.         self.restart()
  12.         self.image = pygame.image.load('enemy.png').convert_alpha()

  13.     def move(self):
  14.         if self.y < 800:
  15.             self.y += self.speed
  16.         else:
  17.            self.restart()

  18. <span style="line-height: 1.5;">class Bullet:</span>
  19.     def __init__(self):
  20.         self.x = 0
  21.         self.y = -1
  22.         self.image = pygame.image.load('bullet.png').convert_alpha()
  23.         self.active = False
  24.         
  25.     def move(self):
  26.         if self.active:
  27.             self.y -= 3
  28.         if self.y < 0:
  29.             self.active = False

  30.     def restart(self):
  31.         mouseX,mouseY = pygame.mouse.get_pos()
  32.         self.x = mouseX - self.image.get_width()/2
  33.         self.y = mouseY - self.image.get_height()/2
  34.         self.active = True

  35. pygame.init()
  36. screen = pygame.display.set_mode((450,800),0,32)
  37. pygame.display.set_caption("Hello,World!")
  38. background = pygame.image.load('bg.jpg').convert()
  39. plane = pygame.image.load('plane.png').convert_alpha()

  40. #创建子弹的list
  41. bullet = []
  42. for i in range(5):
  43.     bullets.append(Bullet())
  44. count_b = len(bullets)
  45. index_b = 0
  46. interval_b = 0
  47.    
  48. enemy = Enemy()
  49. while True:

  50.     for event in pygame.event.get():
  51.         if event.type == pygame.QUIT:
  52.             pygame.quit()
  53.             exit()
  54.     screen.blit(background,(0,0))
  55.     interval_b -= 1
  56.     if interval_b < 0:
  57.         bullets[index_b].restart()
  58.         interval_b = 100
  59.         index_b = (index_b + 1) % count_b
  60.     for b in bullets:
  61.         if b.active:
  62.             b.move()
  63.             screen.blit(b.image,(b.x,b.y))

  64.     enemy.move()
  65.     screen.blit(enemy.image,(enemy.x,enemy.y))
  66.     x,y = pygame.mouse.get_pos()
  67.     x -= plane.get_width()/2
  68.     y -= plane.get_height()/2
  69.     screen.blit(plane,(x,y))
  70.     pygame.display.update()
复制代码
为什么我的代码run了以后,python没有响应?跟第8课的代码一模一样啊。求教先生


作者: waller516435165    时间: 2013-9-8 04:16
waller516435165 发表于 2013-9-8 04:12
为什么我的代码run了以后,python没有响应?跟第8课的代码一模一样啊。求教先生

...

发现问题了...我的变量命名错了,bullets,我的是bullet....粗心要不得啊
作者: crossin先生    时间: 2013-9-8 12:45
waller516435165 发表于 2013-9-8 04:12
为什么我的代码run了以后,python没有响应?跟第8课的代码一模一样啊。求教先生

...

有报错吗?
图片文件都有吗?
之前几课代码有没有运行成功过?
作者: crossin先生    时间: 2013-9-8 16:03
waller516435165 发表于 2013-9-8 04:16
发现问题了...我的变量命名错了,bullets,我的是bullet....粗心要不得啊

一般都会遇到这种问题。所以一个好的ide会帮上大忙
作者: aresli    时间: 2013-9-10 22:20
crossin先生 发表于 2013-9-8 16:03
一般都会遇到这种问题。所以一个好的ide会帮上大忙

python 貌似没什么好的ide吧!
作者: crossin先生    时间: 2013-9-10 23:23
aresli 发表于 2013-9-10 22:20
python 貌似没什么好的ide吧!

呵呵。。。
作者: test777    时间: 2013-9-11 13:17
感觉让Bullet类自己管理实例的状态的也不错
  1. # -*- coding: utf-8 -*-
  2. import pygame,sys,random

  3. class Enemy:

  4.     def restart(self):
  5.         self.x = random.randint(50,400)
  6.         self.y = random.randint(-200,-50)
  7.         self.speed = random.random() + 0.1


  8.     def __init__(self):
  9.         self.restart()
  10.         self.image = pygame.image.load('enemy.png').convert_alpha()

  11.     def move(self):
  12.         if self.y < 800:
  13.             self.y += self.speed
  14.         else:
  15.             self.restart()

  16. class Bullet:

  17.     active_bullets = []
  18.     bullets = []

  19.     def __init__(self):
  20.         self.x = 0
  21.         self.y = -1
  22.         self.image = pygame.image.load('bullet.png').convert_alpha()
  23.         self.active = False
  24.         Bullet.bullets.append(self)
  25.         print(len(Bullet.bullets))

  26.     def move(self):
  27.         if self.y < 0:
  28.             Bullet.active_bullets.pop(Bullet.active_bullets.index(self))
  29.             Bullet.bullets.append(self)
  30.         if self in Bullet.active_bullets:
  31.             self.y -= 3

  32.     def restart(self):
  33.         mouseX,mouseY = pygame.mouse.get_pos()
  34.         self.x = mouseX - self.image.get_width()/2
  35.         self.y = mouseY - self.image.get_height()/2
  36.         self.active = True
  37.         Bullet.active_bullets.append(self)



  38. pygame.init()
  39. screen = pygame.display.set_mode((450,800),0,32)
  40. pygame.display.set_caption("Hello,Wrold!")
  41. background = pygame.image.load('back.jpg').convert()
  42. plane = pygame.image.load('plane.png').convert_alpha()


  43. for i in range(5):
  44.     Bullet()

  45. enemy = Enemy()
  46. interval_b = 0

  47. while True:
  48.     for event in pygame.event.get():
  49.         if event.type == pygame.QUIT:
  50.             pygame.quit()
  51.             sys.exit()
  52.     screen.blit(background,(0,0))

  53.     interval_b -= 1
  54.     if interval_b < 0:
  55.         if len(Bullet.bullets):
  56.             Bullet.bullets.pop(0).restart()
  57.         interval_b = 100

  58.     for b in Bullet.active_bullets:
  59.         b.move()
  60.         screen.blit(b.image,(b.x,b.y))

  61.     enemy.move()
  62.     screen.blit(enemy.image,(enemy.x,enemy.y))


  63.     x,y = pygame.mouse.get_pos()
  64.     x -= plane.get_width()/2
  65.     y -= plane.get_height()/2
  66.     screen.blit(plane,(x,y))
  67.     pygame.display.update()
复制代码

作者: crossin先生    时间: 2013-9-13 01:43
test777 发表于 2013-9-11 13:17
感觉让Bullet类自己管理实例的状态的也不错

是的,这样似乎更符合面向对象
作者: toddlerya    时间: 2014-7-17 22:49
Traceback (most recent call last):
  File "E:\feijidazhan\hello.py", line 106, in <module>
    if b.active():
TypeError: 'bool' object is not callable



这是为什么呢,先生,为什么无法调用呢?
作者: crossin先生    时间: 2014-7-18 14:15
toddlerya 发表于 2014-7-17 22:49
Traceback (most recent call last):
  File "E:\feijidazhan\hello.py", line 106, in
    if b.active() ...

你的这个b是个bool变量吧
作者: toddlerya    时间: 2014-7-18 20:25
crossin先生 发表于 2014-7-18 14:15
你的这个b是个bool变量吧

BUG已解决. 是书写错误... 唉得弄个好用的IDE.
作者: 孙飞    时间: 2014-10-24 19:36
IDE 请用pycharm,自动报错的哦,非常不错
作者: 冷月无声    时间: 2015-12-3 13:24
难道只有我发现了子弹无法发射出去么?
作者: catherinemic    时间: 2016-2-4 17:05
Crossin老师,index_b = (index_b + 1) % count_b这一句我不是很理解,%count_b的作用是什么?
作者: catherinemic    时间: 2016-2-4 18:59
本来还想不明白这样和之前的子弹效果上有什么区别,截图后就明白啦,现在视觉效果上的确是更强了~~我设置的5发子弹,interval_b=50~~

Python29.png (111.46 KB, 下载次数: 280)

Python29.png


作者: 一路向北    时间: 2016-3-25 10:51
不浪费每一个金币
作者: GoldenZhu    时间: 2016-11-17 16:27
catherinemic 发表于 2016-2-4 17:05
Crossin老师,index_b = (index_b + 1) % count_b这一句我不是很理解,%count_b的作用是什么? ...

余数的意思,例:1%5=1 6%5=1 可以print试验一下
作者: brahmagupta    时间: 2017-3-5 19:04
哦 竟然可以用 list来管理被创建的子弹!append,pop等方法都可以发挥作用!竟然没有想到
作者: aibuzhe    时间: 2017-6-11 14:23
很喜欢Crossin的文章,对萌新很友好。
作者: crossin先生    时间: 2017-6-11 21:46
aibuzhe 发表于 2017-6-11 14:23
很喜欢Crossin的文章,对萌新很友好。


作者: crazy31423    时间: 2017-8-3 15:21
请问: 在代码中, interval_b=100,这个100是什么意思,是指程序的循环次数,还是什么计时单位?
作者: crossin先生    时间: 2017-8-3 16:41
crazy31423 发表于 2017-8-3 15:21
请问: 在代码中, interval_b=100,这个100是什么意思,是指程序的循环次数,还是什么计时单位? ...

循环次数

作者: crazy31423    时间: 2017-8-3 19:22
crossin先生 发表于 2017-8-3 16:41
循环次数

谢谢,再请问下,我把您的Python课程和pygame学完了,下面开始干什么好呢(其实就是想您给点建议,我想用python工作赚钱,往哪个方向学好一点呢,谢谢)
作者: crossin先生    时间: 2017-8-4 23:32
crazy31423 发表于 2017-8-3 19:22
谢谢,再请问下,我把您的Python课程和pygame学完了,下面开始干什么好呢(其实就是想您给点建议,我想用 ...

web方面,做点爬虫,开发个网站,差不多可以试试找工作了
作者: 很好吃    时间: 2017-12-27 16:42
crossin先生,问一个逻辑问题
按照思路,设置子弹速度比较慢,导致一轮打完后第一发子弹还没到达屏幕上端
第五颗子弹发射后就会出现第一颗子弹被重置重新发射,如此循环,导致这一轮子弹永远无法到达屏幕上端
但实际运行结果是,这一轮子弹会一直往上走,中间出现空子弹期
当第一颗子弹运行到屏幕最上端后,就会立即重置重新发射
这是怎么回事呢?
作者: crossin先生    时间: 2017-12-28 10:32
很好吃 发表于 2017-12-27 16:42
crossin先生,问一个逻辑问题
按照思路,设置子弹速度比较慢,导致一轮打完后第一发子弹还没到达屏幕上端
...

检查你的代码逻辑,调试
作者: 很好吃    时间: 2017-12-28 12:11
crossin先生 发表于 2017-12-28 10:32
检查你的代码逻辑,调试

谢谢crossin先生,问题已解决
我在restart函数里用了if y < 0这个判断条件,导致了这个效果
作者: 不是啤酒肚    时间: 2018-1-17 19:57
先生,这里if b.active可以把判断注释掉吗,因为子弹move方法中已经有判断了

#判断每科子弹的状态   
    for b in bullets:
        if b.active:#如果子弹处于激活状态,那就开始移动并绘制
            b.move()#调用move方法,处理子弹的运动
            screen.blit(b.image,(b.x,b.y))#把子弹滑到屏幕上,数据来自成员变量

def move(self):
        #激活状态下,向上移动
        if self.active:
            self.y -=2
        #当飞出屏幕,就设为不激活   
        if self.y < 0:
            self.active = False
作者: crossin先生    时间: 2018-1-18 11:10
不是啤酒肚 发表于 2018-1-17 19:57
先生,这里if b.active可以把判断注释掉吗,因为子弹move方法中已经有判断了

#判断每科子弹的状态   

那也会被绘制出来
作者: calf_in_cup    时间: 2018-1-23 15:59
  1. # -*- coding:utf-8 -*-
  2. import random
  3. from sys import exit

  4. import pygame


  5. # 子弹类
  6. class Bullet:
  7.     def __init__(self):

  8.         self.x1 = 0
  9.         self.y1 = -1

  10.         self.x2 = -1
  11.         self.y2 = -1

  12.         self.x3 = 1
  13.         self.y3 = -1
  14.         self.image = pygame.image.load('bullet.png').convert_alpha()
  15.         # 默认不激活
  16.         self.active = False

  17.     def move(self):
  18.         # 激活状态下,向上移动
  19.         if self.active:
  20.             self.y1 -= 3
  21.             self.y2 -= 3
  22.             self.y3 -= 3
  23.         # 当飞出屏幕,就设为不激活
  24.         if self.y1 < 0:
  25.             self.active = False

  26.     def restart(self):
  27.         # 重置子弹位置
  28.         mouseX, mouseY = pygame.mouse.get_pos()
  29.         pygame.mouse.set_visible(False)
  30.         self.x1 = mouseX - self.image.get_width() / 2 - 10
  31.         self.y1 = mouseY - self.image.get_height() / 2

  32.         self.x2 = mouseX - self.image.get_width() / 2
  33.         self.y2 = mouseY - self.image.get_height() / 2

  34.         self.x3 = mouseX - self.image.get_width() / 2 + 10
  35.         self.y3 = mouseY - self.image.get_height() / 2
  36.         # 激活子弹
  37.         self.active = True


  38. # 敌机类
  39. class Enemy:
  40.     def __init__(self):
  41.         self.restart()
  42.         self.image = pygame.image.load('enemy.png').convert_alpha()

  43.     def move(self):
  44.         if self.y < 800:
  45.             self.y += self.speed
  46.         else:
  47.             self.restart()

  48.     def restart(self):
  49.         self.x = random.randint(50, 400)
  50.         self.y = random.randint(-200, -50)
  51.         self.speed = random.random() + 0.1


  52. pygame.init()
  53. screen = pygame.display.set_mode((450, 800), 0, 32)
  54. pygame.display.set_caption("天空,超爱你!")
  55. # 加载相关图像
  56. sky = pygame.image.load('back.jpg').convert()
  57. plane = pygame.image.load('plane.png').convert_alpha()
  58. # 创建子弹的list
  59. bullets = []
  60. # 向list中添加5发子弹
  61. for i in range(5):
  62.     bullets.append(Bullet())
  63. # 子弹总数
  64. count_b = len(bullets)
  65. # 即将激活的子弹序号
  66. index_b = 0
  67. # 发射子弹的间隔
  68. interval_b = 0
  69. # 创建子弹对象和敌机对象
  70. enemy = Enemy()

  71. while True:
  72.     for event in pygame.event.get():
  73.         if event.type == pygame.QUIT:
  74.             pygame.quit()
  75.             exit()
  76.     screen.blit(sky, (0, 0))

  77.     # 发射间隔递减
  78.     interval_b -= 1
  79.     # 当间隔小于0时,激活一发子弹
  80.     if interval_b < 0:
  81.         bullets[index_b].restart()
  82.         # 重置间隔时间
  83.         interval_b = 100
  84.         # 子弹序号周期性递增
  85.         index_b = (index_b + 1) % count_b
  86.     # 判断每个子弹的状态
  87.     for b in bullets:
  88.         # 处于激活状态的子弹,移动位置并绘制
  89.         if b.active:
  90.             b.move()
  91.             screen.blit(b.image, (b.x1, b.y1))
  92.             screen.blit(b.image, (b.x2, b.y2))
  93.             screen.blit(b.image, (b.x3, b.y3))

  94.     # 敌机开始运动
  95.     enemy.move()
  96.     screen.blit(enemy.image, (enemy.x, enemy.y))
  97.     x, y = pygame.mouse.get_pos()
  98.     x -= plane.get_width() / 2
  99.     y -= plane.get_height() / 2
  100.     screen.blit(plane, (x, y))
  101.     pygame.display.update()
复制代码

微信截图_20180123155723.png (120.83 KB, 下载次数: 305)

微信截图_20180123155723.png


作者: 粒子爆炸鸡    时间: 2018-4-2 20:06
请问老师:我这样为什么不会有子弹发射出去呀?感觉问题出在bullet.move()里面,但是一用bullet.active就没有子弹了
  1. import pygame
  2. from sys import exit
  3. from alien import Alien
  4. from random import randint
  5. from random import random

  6. class Alien:
  7.     def restart(self):
  8.         self.x = randint(50,350)
  9.         self.y = randint(-200,-50)
  10.         self.speed = random()+1
  11.     def __init__(self):
  12.         self.restart()
  13.         self.image = pygame.image.load('image/alien.bmp')
  14.     def move(self):
  15.         if self.y < 700:
  16.             self.y += self.speed
  17.         else:
  18.             self.restart()

  19. class Bullet():
  20.     def __init__(self):
  21.         self.x = 0
  22.         self.y = 0
  23.         self.image = pygame.image.load('image/bullet.bmp')
  24.         self.active = False
  25.     def restart(self):
  26.         self.active = True
  27.         (mouse_x,mouse_y) = pygame.mouse.get_pos()
  28.         self.x = mouse_x - self.image.get_width()/2
  29.         self.y = mouse_y - self.image.get_height()/2
  30.     def move(self):
  31.         if self.active == True:
  32.             self.y -= 5
  33.         if self.y <0:
  34.             self.active = False

  35. pygame.init()
  36. screen = pygame.display.set_mode((400,700))
  37. pygame.display.set_caption('打飞机')
  38. background = pygame.image.load('image/bg.bmp')
  39. ship = pygame.image.load('image/ship.bmp')
  40. bullet = Bullet()
  41. alien = Alien()
  42. while True:
  43.     for event in pygame.event.get():
  44.         if event.type == pygame.QUIT:
  45.             pygame.quit()
  46.             exit()
  47.         if event.type == pygame.MOUSEBUTTONDOWN:
  48.             background = pygame.image.load('image/bg2.bmp')
  49.     (x,y) = pygame.mouse.get_pos()
  50.     x -= (ship.get_width()/2)
  51.     y -= (ship.get_width()/2)
  52.     bullet.move()
  53.     alien.move()
  54.     screen.blit(background,(0,0))
  55.     screen.blit(ship,(x,y))
  56.     screen.blit(bullet.image,(bullet.x,bullet.y))
  57.     screen.blit(alien.image,(alien.x,alien.y))
  58.     pygame.display.update()
复制代码

作者: crossin先生    时间: 2018-4-3 13:40
粒子爆炸鸡 发表于 2018-4-2 20:06
请问老师:我这样为什么不会有子弹发射出去呀?感觉问题出在bullet.move()里面,但是一用bullet.active就没 ...

你好像并没有去restart你的子弹
参考下上面别人的代码看看
作者: yby15    时间: 2019-1-15 17:03
# -*- coding: cp936 -*-
import pygame
import random
from sys import exit
class Bullet:
    def __init__(self):
        self.x = 0
        self.y = -1
        self.image = pygame.image.load('bullet.png').convert_alpha()
        #默认不激活
        self.active = False
    def move(self):
        #激活状态下,向上移动
        if self.active:
            self.y -= 3
        #当飞出屏幕,就设为不激活
        if self.y < 0:
            self.active = False
    def restart(self):
        #重置子弹位置
        mouseX, mouseY = pygame.mouse.get_pos()
        self.x = mouseX - self.image.get_width() / 2
        self.y = mouseY - self.image.get_height() / 2
        #激活子弹
        self.active = True
class Enemy:
    def restart(self):
        self.x=random.randint(50,400)
        self.y=random.randint(-200,-50)
        self.speed=random.random()+0.1
    def __init__(self):
        self.restart()
        self.image=pygame.image.load('enemy.png').convert_alpha()
                                    
    def move(self):
        if self.y<800:
            self.y+=self.speed                          
        else:
            self.restart()
pygame.init()
screen = pygame.display.set_mode((450, 800), 0, 32)
pygame.display.set_caption("hello woeld")
# 加载相关图像
sky = pygame.image.load('back.jpg').convert()
plane = pygame.image.load('plane.png').convert_alpha()           
#创建子弹的list
bullets = []
#向list中添加5发子弹
for i in range(5):
    bullets.append(Bullet())
#子弹总数
count_b = len(bullets)
#即将激活的子弹序号
index_b = 0
#发射子弹的间隔
interval_b = 0
enemy=Enemy()
while True:
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            pygame.quit()
            exit()
    screen.blit(sky,(0,0))
    interval_b -= 1
    #当间隔小于0时,激活一发子弹
    if interval_b < 0:
        bullets[index_b].restart()
        #重置间隔时间
        interval_b = 100
        #子弹序号周期性递增
        index_b = (index_b + 1) % count_b
    #判断每个子弹的状态
    for b in bullets:
        #处于激活状态的子弹,移动位置并绘制
        if b.active:
            b.move()
            screen.blit(b.image, (b.x, b.y))            
     # 敌机开始运动
    enemy.move()
    screen.blit(enemy.image, (enemy.x, enemy.y))
    x, y = pygame.mouse.get_pos()
    x -= plane.get_width() / 2
    y -= plane.get_height() / 2
    screen.blit(plane, (x, y))
    pygame.display.update()

老师,为什么我run出来的结果还是只有一颗子弹呢,看了好多遍都没找到问题...


作者: crossin先生    时间: 2019-1-16 15:28
yby15 发表于 2019-1-15 17:03
# -*- coding: cp936 -*-
import pygame
import random

代码应该没有问题,估计只是你电脑上运行的速度较慢,
interval_b = 100
你把间隔调小就会有多个子弹了




欢迎光临 Crossin的编程教室 (https://bbs.crossincode.com/) Powered by Discuz! X2.5