signed

QiShunwang

“诚信为本、客户至上”

游戏更新

2021/5/14 20:47:08   来源:

经过测试修改后,成功的将游戏《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循环,以保证循环正常进行