當我學習pygame的時候遇到了一個問題:pygame是否可以播放視頻?
于是我找到了pygame的對應功能函式
video = pygame.movie.Movie('<file_path>')
但是很明顯這個模塊被棄用了 QWQ
即使沒有它也有很多缺點,例如你不能做其他操作在播放的中途, 視頻格式的限制,
正當我一籌莫展時,我突然想到了逐幀播放
我用PR將視頻匯出為多張圖片,用iteration結構遍歷所有的圖片(一幀切換一次)
# PR教程就不做了【doge】

temp_list = range(0, 79)
for i,s in enumerate(temp_list):
pictures['BGP'+str(i)] = pygame.image.load(path+'\\material\\beginning\\%s.png'%i)
exec('BGP%s = pygame.transform.smoothscale(BGP%s, [790, 800])'%(i, i))
exec('BGP%s_rect = BGP%s.get_rect()'%(i, i))
exec('BGP%s_rect.x = 0'%i)
exec('BGP%s_rect.y = 0'%i)
知道這一刻我才真正明白exec的魅力!
問題來了如何回圈呼叫這些變數?
screen.blit(pictures['BGP' + str(index_bgp)], pictures['BGP' + str(index_bgp)+'_rect'])
我只能說懂得都懂【doge】
當然這個問題已經有一些博主給出了解決方案
比如用cv2將視頻轉成stream,再將image bilt在screen上(這種解法也是將視頻的問題轉化成圖片)Pygame 播放視頻【movie模塊已被棄用】_Enderman_xiaohei的博客-CSDN博客
因為圖片比較大,blit出來回卡頓 所以我們可以采用DOUBLE BUF的方式加速一下
至于原理的話官網并沒有很好的解釋

原理簡單來說,就是原本用主記憶體儲存畫圖,現在用顯卡上的硬體,主存盤器和視頻存盤器之間的帶寬往往很慢,所以可以減少卡頓,
如果還是卡頓就是電腦性能或圖片過大的問題了
這是當時隨手做的四子棋(很多不足勿噴謝謝【卑微】):
import pygame
from pygame import *
import sys, os
import time
class Dot(pygame.sprite.Sprite):
def __init__(self, x, y):
super(Dot, self).__init__()
self.image = pygame.image.load(path+'\\material\empty.png')
self.image = pygame.transform.smoothscale(self.image, (20, 20))
self.rect = self.image.get_rect(center=(x, y))
self.x = x
self.y = y
self.indentifier = (int((x-60)/113), int((y-60)/113))
dots_group.add(self)
self.timer1 = time.time()
self.up = True # 滑鼠是否彈起
self.click = False # 是否被點擊
self.red = False
def update(self, mouse_x, mouse_y, times):
self.x = self.rect.centerx
self.y = self.rect.centery
global times1, type
if times % 2 == 0 and self.click != True:
self.red = True
elif self.click != True:
self.red = False
a = 20
if self.rect.bottom-a >= mouse_y and self.rect.top+a <= mouse_y and self.rect.left+a <= mouse_x and self.rect.right-a >= mouse_x:
if self.red:
self.image = pygame.image.load(path+'\\material\\red.png')
else:
self.image = pygame.image.load(path+'\\material\\blue.png')
self.image = pygame.transform.smoothscale(self.image, (95, 95))
self.rect = self.image.get_rect(center=self.rect.center)
if pygame.mouse.get_pressed(3)[0] and self.up:
self.up = False
if stituation[self.indentifier[0]][self.indentifier[1]] == -1:
self.click = True
stituation[self.indentifier[0]][self.indentifier[1]] = str(self.red) # False-blue True-red
stituation[self.indentifier[0]][self.indentifier[1]-1] = -1 # update the position that could be placed
times1 += 1
type = detect_if_win(stituation)
if not pygame.mouse.get_pressed(3)[0]: # 檢測是否彈起
self.up = True
elif not self.click:
self.image = pygame.image.load(path+'\material\empty.png')
self.rect = self.image.get_rect(center=self.rect.center)
def detect_if_win(stituation):
win = False
type = 'playing'
for index_x in range(3): # —— 檢測
for index_y in range(7):
blue_counter = 0
red_counter = 0
for increment in range(4):
if stituation[index_x+increment][index_y] == 'True':
red_counter += 1
if stituation[index_x+increment][index_y] == 'False':
blue_counter += 1
if blue_counter == 4:
type = 'blue win'
if red_counter == 4:
type = 'red win'
for index_x in range(6): # | 檢測
for index_y in range(4):
blue_counter = 0
red_counter = 0
for increment in range(4):
if stituation[index_x][index_y+increment] == 'True':
red_counter += 1
if stituation[index_x][index_y+increment] == 'False':
blue_counter += 1
if blue_counter == 4:
type = 'blue win'
if red_counter == 4:
type = 'red win'
for index_x in range(3): # \ 檢測
for index_y in range(4):
blue_counter = 0
red_counter = 0
for increment in range(4):
if stituation[index_x+increment][index_y+increment] == 'True':
red_counter += 1
if stituation[index_x+increment][index_y+increment] == 'False':
blue_counter += 1
if blue_counter == 4:
type = 'blue win'
break
elif red_counter == 4:
type = 'red win'
for index_x in range(3, 6): # / 檢測
for index_y in range(4):
blue_counter = 0
red_counter = 0
for increment in range(4):
if stituation[index_x-increment][index_y+increment] == 'True':
red_counter += 1
if stituation[index_x-increment][index_y+increment] == 'False':
blue_counter += 1
if blue_counter == 4:
type = 'blue win'
break
elif red_counter == 4:
type = 'red win'
return type
pygame.init()
size = width, height = pygame.display.list_modes()[0]
screen = pygame.display.set_mode(size, FULLSCREEN, DOUBLEBUF)
pygame.display.set_caption('connecting four 2D')
fclock = pygame.time.Clock()
stituation = []
path = str(os.path.dirname(os.path.realpath(__file__)))[:-18]
for i in range(6):
stituation.append([0, 0, 0, 0, 0, 0, -1])
dots_group = pygame.sprite.Group()
for i in range(7):
for j in range(6):
dot = Dot(60+j*113, 60+i*113)
delta = 113
delta2 = 113
times1 = 1
click = [0]
font = pygame.font.Font('freesansbold.ttf', 60)
type = 'menu' # type
index_bgp = 0
# 預加載
pictures = locals()
temp_list = range(0, 79)
#預加載8.967s
pygame.mixer.music.load(path + '\\material\\BGmusic.mp3')
pygame.mixer.music.play()
'''
for i,s in enumerate(temp_list):
pictures['BGP'+str(i)] = pygame.image.load(path+'\\material\\beginning\\%s.png'%i)
exec('BGP%s = pygame.transform.smoothscale(BGP%s, [790, 800])'%(i, i))
exec('BGP%s_rect = BGP%s.get_rect()'%(i, i))
exec('BGP%s_rect.x = 0'%i)
exec('BGP%s_rect.y = 0'%i)
'''
texts = locals()
# 選單界面 menu ------------------------------------------------
up = False
down = False
text_contain1 = 'GAME START'
BG = pygame.image.load(path+'\\material\\BGP.png')
BG = pygame.transform.smoothscale(BG, (900, 900))
BG_rect = BG.get_rect()
BG_rect.left = 700
LOGE = pygame.image.load(path+'\\material\\哮天作業室 loge.png')
LOGE = pygame.transform.smoothscale(LOGE, (300, 300))
LOGE_rect = LOGE.get_rect()
LOGE_rect.left = 800
LOGE_rect.top = 100
while type == 'menu':
text1 = font.render(text_contain1, 1, 'royalblue')
text1_rect = text1.get_rect()
text1_rect.center = [950, 600]
if index_bgp < 78:
index_bgp += 1
else:
index_bgp = 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
sys.exit()
if event.key == K_UP and up == False:
up = True
if time.time() - timer_1 > 0.3:
timer_1 = time.time()
if event.key == K_RETURN:
type = 'playing'
if text1_rect.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed(3)[0]:
type = 'playing'
screen.blit(pictures['BGP' + str(index_bgp)], pictures['BGP' + str(index_bgp)+'_rect'])
screen.blit(BG, BG_rect)
screen.blit(LOGE, LOGE_rect)
screen.blit(text1, text1_rect)
fclock.tick(20)
pygame.display.flip()
for i,s in enumerate(temp_list):
pictures['BGP'+str(i)] = 0
timer = time.time()
while type == 'playing':
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
sys.exit()
mouse_x, mouse_y = pygame.mouse.get_pos()
# pygame.mouse.set_visible(False)
# screen.blit(mouse_cursor, (x, y))
dots_group.update(mouse_x, mouse_y, times1)
screen.fill('black')
rim1_h = pygame.draw.rect(screen, 'white', [0, 0, 680, 10])
rim2_h = pygame.draw.rect(screen, 'white', [0, delta*1, 680, 10])
rim3_h = pygame.draw.rect(screen, 'white', [0, delta*2, 680, 10])
rim4_h = pygame.draw.rect(screen, 'white', [0, delta*3, 680, 10])
rim5_h = pygame.draw.rect(screen, 'white', [0, delta*4, 680, 10])
rim6_h = pygame.draw.rect(screen, 'white', [0, delta*5, 680, 10])
rim7_h = pygame.draw.rect(screen, 'white', [0, delta*6, 680, 10])
rim8_h = pygame.draw.rect(screen, 'white', [0, delta*7, 680, 10])
rim1_s = pygame.draw.rect(screen, 'white', [0, 0, 10, 1000])
rim2_s = pygame.draw.rect(screen, 'white', [0+delta2*1, 0, 10, 1000])
rim3_s = pygame.draw.rect(screen, 'white', [0+delta2*2, 0, 10, 1000])
rim4_s = pygame.draw.rect(screen, 'white', [0+delta2*3, 0, 10, 1000])
rim5_s = pygame.draw.rect(screen, 'white', [0+delta2*4, 0, 10, 1000])
rim6_s = pygame.draw.rect(screen, 'white', [0+delta2*5, 0, 10, 1000])
rim7_s = pygame.draw.rect(screen, 'white', [0+delta2*6, 0, 10, 1000])
dots_group.draw(screen)
text1 = font.render('Timer: ' + str(-timer+time.time())[:str(-timer+time.time()).find('.')], 1, 'royalblue')
text1_rect = text1.get_rect()
text1_rect.center = [1000, 200]
screen.blit(text1, text1_rect)
fclock.tick(30)
pygame.display.update()
pygame.mixer.music.load(path + '\\material\\winning music.mp3')
pygame.mixer.music.play()
font = pygame.font.Font('freesansbold.ttf', 80)
while type =='blue win':
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
sys.exit()
text1 = font.render('Blue Win!!!', 1, 'royalblue')
text1_rect = text1.get_rect()
text1_rect.center = [625, 400]
screen.blit(text1, text1_rect)
fclock.tick(30)
pygame.display.update()
while type =='red win':
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
exit()
text1 = font.render('red Win!!!', 1, 'red')
text1_rect = text1.get_rect()
text1_rect.center = [625, 400]
screen.blit(text1, text1_rect)
fclock.tick(30)
pygame.display.update()
總結:
缺點:1. 檔案大, 加載慢
2. 部分需要有顯存要求
優點:1. 可以在中途進行操作
2. 有和視頻一樣的流暢度
3. more flexible
不是說這種trick的解決方法有多好,只是這次的思考和另辟蹊徑的方式讓我受益匪淺
----‘有時打破常規會給你意想不到的結果’----
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/341978.html
標籤:其他
