经过测试修改后,成功的将游戏《sing际争霸》的子弹设置为自定义的图片,效果图如下所示:
更大杀伤力的子弹,及其图片之间更搭配= =
源代码:
import pygame
import sys
from settings import Settings
from ship import Ship
#1 from bullet import Bullet
from bullet2 import Bullet
class AlienInvasion:
def __init__(self):
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
pygame.display.set_caption(self.settings.caption)
self.ship = Ship(self)
#1 self.bullets = Bullet(self)
self.bullet2 = Bullet(self) #2
self.bullet2 = pygame.sprite.Group() #2
# 1 self.bullets = pygame.sprite.Group()
def run_game(self):
while True:
self._check_events()
self.ship.update()
self.bullet2.update()
self._update_screen()
def _check_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
self._check_keydown_events(event)
elif event.type == pygame.KEYUP:
self._check_keyup_events(event)
def _check_keydown_events(self, event):
if event.key == pygame.K_ESCAPE:
sys.exit()
if event.key == pygame.K_RIGHT:
self.ship.moving_right = True
if event.key == pygame.K_LEFT:
self.ship.moving_left = True
if event.key == pygame.K_UP:
self.ship.moving_up = True
if event.key == pygame.K_DOWN:
self.ship.moving_down = True
if event.key == pygame.K_SPACE:
self._fire_bullet()
def _check_keyup_events(self, event):
if event.key == pygame.K_RIGHT:
self.ship.moving_right = False
elif event.key == pygame.K_LEFT:
self.ship.moving_left = False
elif event.key == pygame.K_UP:
self.ship.moving_up = False
elif event.key == pygame.K_DOWN:
self.ship.moving_down = False
def _update_screen(self):
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
for bullet in self.bullet2.sprites():
bullet.blitme()
pygame.display.flip()
def _fire_bullet(self):
new_bullet = Bullet(self)
self.bullet2.add(new_bullet)
if __name__ == '__main__':
ai = AlienInvasion()
ai.run_game()
import pygame
from pygame.sprite import Sprite
from settings import Settings
class Bullet(Sprite):
def __init__(self, ai_game):
super().__init__()
self.screen = ai_game.screen
self.screen_rect = ai_game.screen.get_rect()
self.settings = ai_game.settings
self.image = pygame.image.load(r'C:/Users/TOMMY/Desktop/bullet2.bmp')
self.rect = self.image.get_rect()
self.rect.midtop = ai_game.ship.rect.midtop
self.y = float(self.rect.y)
def update(self):
self.y -= self.settings.bullet_speed
self.rect.y = self.y
def blitme(self):
self.screen.blit(self.image, self.rect)
class Settings:
def __init__(self):
self.bg_color = (255, 255, 255)
self.screen_width = 1200
self.screen_height = 800
self.caption = 'sing际争霸'
self.ship_speed = 0.5
self.bullet_speed = 1.0
self.bullet_color = (153, 51, 204)
self.bullet_heigh = 15
self.bullet_width = 5
import pygame
class Ship:
def __init__(self, ai_game):
self.screen = ai_game.screen
self.screen_rect = ai_game.screen.get_rect()
self.settings = ai_game.settings
self.image = pygame.image.load(r'C:/Users/TOMMY/Desktop/people1.bmp')
self.rect = self.image.get_rect()
self.rect.midbottom = self.screen_rect.midbottom
self.moving_right = False
self.moving_left = False
self.moving_up = False
self.moving_down = False
self.x = float(self.rect.x)
self.y = float(self.rect.y)
def blitme(self):
self.screen.blit(self.image, self.rect)
def update(self):
if self.moving_right and self.rect.right < self.screen_rect.right:
self.x += self.settings.ship_speed
if self.moving_left and self.rect.left > 0:
self.x -= self.settings.ship_speed
self.rect.x = self.x
if self.moving_up and self.rect.top > 0:
self.y -= self.settings.ship_speed
if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
self.y += self.settings.ship_speed
self.rect.y = self.y
发射的这些子弹,会在屏幕上方消失,但是实际上是因为screen不够大,不足以绘制他们,实际上这些子弹是存在的,所以仍然会占用内存和处理能力,所以当子弹到达屏幕上部时,应该及时的将其清除。
在实现后,外加一个print,每次输出屏幕上存在的子弹数效果如下图所示:
子弹数为6
子弹数为0了,说明子弹的确被删除了
实现删除的语句也很简单,在开始游戏的主循环内嵌套一个循环,再在循环内加一个判断语句即可:
代码如下:
while True:
---snip--
for bullet in self.bullet2.copy():
if bullet.rect.bottom <= 0:
self.bullet22.remove(bullet)
print(len(self.bullet2))
python要求列表的长度在for循环内必须保持不变,如果直接利用储存bullet2的列表进行循环,那么中间一旦有一个元素被删除,那么将无法正常的进行循环,会报错。这里用副本copy来进行for循环,以保证循环正常进行