下面的Sprite類繼承自海龜模塊的Turtle類,所以本程序屬於海龜畫圖,以下是代碼:
星空飛碟大戰_python精靈模塊例子
"""
星空飛碟大戰.py
本程序需要sprites模塊支持,它是繼承自Turtle模塊的。
安裝方法: pip install sprites
由於配音的需要, 本程序需要pygame的混音器支持,安裝方法爲在命令提示符裏輸入:pip install pygame --user
"""
from sprites import *
import pygame.mixer
def star_move():
"""動態星空背景函數"""
for star in stars:
star.move(0,-20)
if star.ycor() < -height//2:
star.ht()
x = random.randint(-width//2,width//2)
y = random.randint(10+height//2,height*2)
star.goto(x,y)
star.st()
def spawn_enemy():
"""不定時產生敵機函數"""
if random.randint(1,10)==1 and len(screen._turtles)<30:
x = random.randint(-200,200)
y = random.randint(100,300)
enemy = Sprite(shape='res/ufo.png',visible=False,pos=(x,y))
enemy._rotatemode = 1
enemy.tag = 'enemy'
enemy.scale(0.5)
enemy.setheading(random.randint(1,360))
enemy.show()
def enemymove():
"""ufo移動"""
for e in enemys:
e.fd(3)
# 設定一定的機率讓ufo朝向player
if random.randint(10,100) == 10 and \
abs(e.xcor())<200:
e.heading(player)
def bulletmove():
"""子彈的移動"""
for b in bullets:
b.move(0,10)
if b.collide_edge():b.remove()
def player_shoot():
"""玩家射擊函數"""
if player.alive == False : return
if m1.down and framecounter % 5 == 0 :
b = Sprite(shape='circle',visible=False)
b.scale(0.5)
b.color('yellow')
b.tag = 'bullet' # 設定標籤(用於分組)
b.goto(player.pos()) # 移到player座標
b.show() # 顯示子彈
shoot.play() # 播放射擊聲
# 播放背景音樂與生成聲效對象
pygame.mixer.init()
pygame.mixer.music.load('audio/FrozenJam.ogg')
pygame.mixer.music.play(-1,0)
explosion = pygame.mixer.Sound('audio/expl3.wav')
shoot = pygame.mixer.Sound('audio/pew.wav')
width,height = 480,640
screen = Screen() # 新建屏幕
screen.tracer(0,0) # 關閉自動刷新和設置繪畫延時爲0毫秒
screen.bgcolor('black') # 屏幕背景色爲黑
screen.setup(width,height)
screen.title("星空飛碟大戰by李興球")
screen.addshape('res/fighter.png')
screen.addshape('res/ufo.png')
frames = ['res/explosion0.png','res/explosion1.png']
[screen.addshape(frame) for frame in frames]
# 星星,用來做向下滾動背景,星星的移動也可以通過移動圖章實現
# 這樣可以有更多的星星。如果用克隆的話有數量限制,根據計算機配置不同而不同。
star = Turtle(shape='circle')
star.color('white')
star.shapesize(0.1,0.1)
stars = [star]
stars.extend([star.clone() for _ in range(20)])
for star in stars:
x = random.randint(-width//2,width//2)
y = random.randint(10+height//2,height*2)
star.goto(x,y)
# 玩家
player = Sprite(shape='res/fighter.png',pos=(0,-200))
player.scale(0.65)
player.alive = True # 表示player是活的
m1 = Mouse() # 鼠標左鍵檢測實例
clock = Clock() # 實鍾對象,用來控制fps
framecounter = 0
counter = 0 # 統計擊中的ufo數量
while 1:
framecounter += 1 # 幀計數器
spawn_enemy() # 不定時產生敵機UFO
player_shoot() # 單擊鼠標左鍵,射擊子彈
bullets = [b for b in screen.turtles() if b.tag=='bullet'] # 子彈組
enemys = [e for e in screen.turtles() if e.tag=='enemy'] # 敵機組
enemymove()
# 如果用了屏幕的tracer(0,0)命令的話,移動之後立即更新重畫,
# 否則bbox沒有得到實時的信息返回不正確的結果,導致碰撞檢測不正確,從而不會反彈(會粘滯在邊緣)
screen.update()
for e in enemys: # 對每架敵機進行碰撞檢測
if e.collide(player):
explode(e.position(),frames)
e.remove()
explode(player.pos(),frames)
player.remove()
player.alive = False
explosion.play() # 爆炸聲
break
# 敵機是否碰到任意一顆子彈
for b in bullets:
if e.collide(b): # 如果ufo碰到子彈
explode(e.position(),frames)
e.remove()
b.remove()
explosion.play() # 爆炸聲
counter +=1 # 進行統計
break
e.bounce_on_edge()
bulletmove() # 子彈的移動
player.goto(mousepos()) # 移到鼠標的座標
star_move() # 滾動背景
screen.title('星空飛碟大戰,當前擊斃:' + str(counter) + " 架UFO")
clock.tick(60)