Python程式設計從入門到實踐習題12-5
阿新 • • 發佈:2019-01-10
12-5 側面射擊:編寫一個遊戲,將一艘飛船放置在螢幕左邊,並允許玩家上下移動飛船。在玩家按空格鍵時,讓飛船發射一顆在螢幕中央向右穿行的子彈,並在子彈離開螢幕而消失後將其刪除。
這個題和書上的程式類似,但自己寫的時候還是遇到了許多問題,磕磕碰碰實現了。
主程式:game
import pygame from settings import Settings import func as f from ship import Ship from bullet import Bullet from pygame.sprite import Group def run_game(): pygame.init() settings = Settings() screen = pygame.display.set_mode((settings.screen_width, settings.screen_height)) pygame.display.set_caption("Side Shoot") ship = Ship(screen) bullets = Group() while True: f.check_keys(settings, screen, ship, bullets) ship.update() bullets.update() #刪除已消失的子彈 for bullet in bullets.copy(): if bullet.rect.left > screen.get_rect().right: bullets.remove(bullet) f.update_screen(settings, screen, ship, bullets) run_game()
Settings類:
import pygame
class Settings():
"""所有設定的類"""
def __init__(self):
#設定螢幕的屬性
self.screen_width = 1200
self.screen_height = 600
self.bg_color = (230, 230, 230)
#設定子彈屬性
self.bullet_speed_factor = 1
self.bullet_width = 5
self.bullet_height = 5
self.bullet_color = 0, 0, 0
Ship類:
import pygame class Ship(): def __init__(self, screen): """設定飛船的屬性""" self.screen = screen#EEEE:忘記寫 self.image = pygame.image.load('ship.bmp')#讀取飛船圖片 self.image = pygame.transform.rotate(self.image, -90)#將飛船順時針旋轉90° self.rect = self.image.get_rect()#獲取飛船圖片外接矩形 self.screen_rect = screen.get_rect()#獲取螢幕的外接矩形 #設定飛船的位置,將飛船放置在螢幕左側中間 self.rect.centery = self.screen_rect.centery self.rect.left = self.screen_rect.left #初始化飛船上下移動屬性 self.moving_up = False self.moving_down = False def update(self): """更新飛船位置""" if self.moving_up and self.rect.top > 0: self.rect.centery -= 1 elif self.moving_down and self.rect.bottom < self.screen_rect.bottom: self.rect.centery += 1 def blitme(self): """繪製飛船""" self.screen.blit(self.image, self.rect)
Bullet類:
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
"""一個對子彈進行管理的類"""
def __init__(self, settings, screen, ship):
"""在飛船出建立一個子彈物件"""
#繼承父類的屬性
super().__init__()
self.screen = screen
#在(0, 0)處建立一個子彈的矩形,再設定其準確位置
self.rect = pygame.Rect(0, 0, settings.bullet_width, settings.bullet_height)
self.rect.centery = ship.rect.centery
self.rect.right = ship.rect.right
#儲存用小數表示的子彈位置
self.x = float(self.rect.x)
self.color = settings.bullet_color
self.speed_factor = settings.bullet_speed_factor
def update(self):
"""更新子彈位置"""
self.x += self.speed_factor
self.rect.x = self.x
def draw_bullet(self):
"""在螢幕上繪製子彈"""
pygame.draw.rect(self.screen, self.color, self.rect)
函式模組func:
import pygame
import sys
from ship import Ship
from bullet import Bullet
def check_keys(settings, screen, ship, bullets):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keys_down(event, settings, screen, ship, bullets)
elif event.type == pygame.KEYUP:
check_keys_up(event, ship)
def check_keys_down(event,settings, screen, ship, bullets):
if event.key == pygame.K_UP:
ship.moving_up = True
if event.key == pygame.K_DOWN:
ship.moving_down = True
elif event.key == pygame.K_SPACE:
#建立一顆子彈,並加入到Group編組中
new_bullet = Bullet(settings, screen, ship)
bullets.add(new_bullet)
def check_keys_up(event,ship):
if event.key == pygame.K_UP:
ship.moving_up = False
if event.key == pygame.K_DOWN:
ship.moving_down = False
def update_screen(settings, screen, ship, bullets):
screen.fill(settings.bg_color)
ship.blitme()
for bullet in bullets.sprites():
bullet.draw_bullet()
pygame.display.flip()
效果圖:
這子彈模型讓我想起了小時候掌機上一個像彈乒乓球的遊戲,呵呵!
問題與總結:
1.初始化Ship類時,忘記寫self.screen = screen
2.當按住↑鍵時,飛船直接到了螢幕頂部,經檢查是在check_keys_down()中,moving_up拼寫出錯
3.對編組bullets中的bullet使用for迴圈時,應寫成for bullet in bullet.sprites():
4.各處形參傳遞順序應一致,本次因為沒注意一直出現 AttributeError,值得注意