非常无聊的作品:怎么把pygame的过程录制到mp4
首先,用的是cv2模块,也就是没有音频,只是动画,不过mp4压缩比大,体积小,windows支持自动播放(比如flash格式flv是不支持的)。所谓录制,就是一帧一帧图像写入video,想想很简单,不过有个数据接口问题,代码如下(插入到pygame的刷新一帧函数的结束部分即可):
def printAll(self):
#。。。。。。。pygame表示各种物体代码块
if CMG.step == 1:
fps = 12
size = (800,570)
file_path = r"C:\Users\Administrator\Desktop\aa1" + str(int(time.time())) + ".mp4v"#导出路径
fourcc = cv2.VideoWriter_fourcc('I','4','2','0')#不同视频编码对应不同视频格式(例:'I','4','2','0' 对应avi格式)
CMG.video = cv2.VideoWriter( file_path, fourcc, fps, size )
else:
imagestring = pygame.image.tostring(CMG.screen.subsurface(0,0,800,570),"RGB")
pilImage = Image.frombytes("RGB", (800,570), imagestring)
img = cv2.cvtColor(numpy.asarray(pilImage),cv2.COLOR_RGB2BGR)
CMG.video.write(img) #把图片写进视频
if CMG.step == len(CMG.gameAnswer)+1:
CMG.video.release() #释放
完整例子代码(解迷宫过程录制成mp4)
import pygame
import sys
import os
import random
import time
from pygame.locals import *
import tkinter as tk
from tkinter import *
import tkinter.messagebox# 要使用messagebox先要导入模块
import cv2
import numpy
from PIL import Image, ImageDraw
from PIL import ImageFont
class Maze:
size = None
print_str=(('##',''),('#',' '))
map = None
direct = ((-2,0),(2,0),(0,2),(0,-2),(-2,0),(2,0),(0,2))
@staticmethod
def check_move(map,yx):
for d in range(0,4):
if(map+Maze.direct]+Maze.direct] == 0):
return True
return False
@staticmethod
def create_maze(size_para):
WAY = 1
size=*2+3,size_para*2+3]
Maze.size = size
direct = Maze.direct
center=-1)//2*2,random.randint(1,size-1)//2*2]
map= [*size for i in range(size)]
for y in range(size_para):
for x in range(size_para):
map = 0
step0_nodes =
map]] = WAY
step1_nodes = []
while len(step0_nodes) > 0:
node_no = random.randint(0,len(step0_nodes)-1)
yx= step0_nodes
if not Maze.check_move(map,yx):
step0_nodes.pop(node_no)
continue
direct_start = random.randint(0,3)
for d in range(direct_start,direct_start+4):
y=yx+direct
x=yx+direct
if(map == 0):
step1_nodes.append((y,x))
map+direct//2]+direct//2] = WAY
map = WAY
break
step0_nodes.extend(step1_nodes)
step1_nodes.clear()
Maze.map = map
@staticmethod
def solve_maze(startY,endYX):
WAY = 1
direct = Maze.direct
center=(startY*2+2,2,-1)
map = Maze.map
steps_nodes = []
step0_nodes =
map]] = 0
step1_nodes = []
while len(step0_nodes) > 0:
steps_nodes.append(step0_nodes)
for n in range(0,len(step0_nodes)):
yx= step0_nodes
for d in range(0,4):
y=yx+direct
x=yx+direct
y3=yx+direct//2
x3=yx+direct//2
if(map != 100 and map == WAY ):
step1_nodes.append((y,x,n))
map+direct]+direct] = 0
if y == endYX*2 and x== endYX*2:
steps_nodes.append(step1_nodes)
return steps_nodes
step0_nodes = step1_nodes[:]
step1_nodes.clear()
return None
class CMG: #画面显示管理
screen = None
map = None
gameAnswer = None
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
blocksize = 0
step = 0
back_ground = None
def __init__(self,screen,map,gameAnswer):
if CMG.screen == None:
#print("#############OS.PATH=%s"% os.path.dirname(os.path.abspath(__file__)))
CMG.screen = screen
CMG.map = map
CMG.gameAnswer = gameAnswer
if 800//len(map) > 570//len(map):
CMG.blocksize = 570//len(map)
else:
CMG.blocksize = 800//len(map)
#如果存在对象成员
self.init_game_info()
def init_game_info(self):
pass
def printAll(self):
if CMG.step > len(CMG.gameAnswer):
return
CMG.screen.fill((0, 0, 0))
size = Maze.size
if CMG.back_ground == None:
for y in range(1,size-1):
for x in range(1,size-1):
val = CMG.map
if y%2==1 and x%2==0 and val == 100:
#start_pos = [(y*CMG.blocksize,x*CMG.blocksize)]
end_pos = [((x-1)*CMG.blocksize,y*CMG.blocksize),((x+1)*CMG.blocksize,y*CMG.blocksize)]
pygame.draw.lines(CMG.screen, CMG.GREEN,0 , end_pos, 2)
elif y%2==0 and x%2==1 and val == 100:
end_pos = [(x*CMG.blocksize,(y-1)*CMG.blocksize),(x*CMG.blocksize,(y+1)*CMG.blocksize)]
pygame.draw.lines(CMG.screen, CMG.GREEN,0 , end_pos, 2)
select_rect = CMG.screen.subsurface(0,0,800,570)
CMG.back_ground = select_rect.copy()
else:
self.screen.blit(CMG.back_ground,(0,0))
if CMG.step == len(CMG.gameAnswer):
step = CMG.step - 1
step_node = CMG.gameAnswer
yx = step_node
while(yx!=-1):
y = yx
x = yx
step -= 1
step_node = CMG.gameAnswer
yx = step_node]
pygame.draw.rect(CMG.screen, CMG.WHITE, (((x-1)*CMG.blocksize+2,(y-1)*CMG.blocksize+2), (CMG.blocksize*2-4, CMG.blocksize*2-4)), 0)
else:
step_node = CMG.gameAnswer
for s in range(0,len(step_node)):
yx = step_node
y = yx
x = yx
#pygame.draw.rect(background, (0, 255, 0), ((200, 5), (100, 100)), 3)
pygame.draw.rect(CMG.screen, CMG.WHITE, (((x-1)*CMG.blocksize+2,(y-1)*CMG.blocksize+2), (CMG.blocksize*2-4, CMG.blocksize*2-4)), 0)
CMG.step += 1
if CMG.step == 1:
fps = 12
size = (800,570)
file_path = r"C:\Users\Administrator\Desktop\aa1" + str(int(time.time())) + ".mp4v"#导出路径
fourcc = cv2.VideoWriter_fourcc('I','4','2','0')#不同视频编码对应不同视频格式(例:'I','4','2','0' 对应avi格式)
CMG.video = cv2.VideoWriter( file_path, fourcc, fps, size )
else:
imagestring = pygame.image.tostring(CMG.screen.subsurface(0,0,800,570),"RGB")
pilImage = Image.frombytes("RGB", (800,570), imagestring)
img = cv2.cvtColor(numpy.asarray(pilImage),cv2.COLOR_RGB2BGR)
CMG.video.write(img) #把图片写进视频
if CMG.step == len(CMG.gameAnswer)+1:
CMG.video.release() #释放
def moveAll(self):
pass
#------------------------------------------------
#tkinter,pygame混合区 START
#------------------------------------------------
root = tk.Tk()
root.resizable(0,0)
embed = tk.Frame(root, width = 800, height = 570) #creates embed frame for pygame window
embed.grid(columnspan = (800), rowspan = 730) # Adds grid
embed.pack(side = TOP) #packs window to the left
buttonwin = tk.Frame(root, width = 800, height = 150)
buttonwin.pack(side = BOTTOM)
os.environ['SDL_WINDOWID'] = str(embed.winfo_id())
os.environ['SDL_VIDEODRIVER'] = 'windib'
screen = pygame.display.set_mode((800,570))
#pygame.init()
pygame.display.init()
pygame.mixer.init()
#------------------------------------------------
#tkinter,pygame混合区 END
#------------------------------------------------
#参数,因为函数内要使用之外的变量,需要globe,因此全部打包
class PARAM:
STATUS = 0
TICK_NORMAL = 5
#按钮动作区 =====================================
def exit_game():
global param
param.STATUS = 100
#控件定义区 =====================================
button_exit_b = Button(buttonwin,text = '退出画面', width=7, command=exit_game)
button_exit_b.place(x=740,y=100)
#状态,参数,循环中使用,比如STATUS=0:初次进入,1:...100:退出
param = PARAM()
Maze.create_maze()
steps_nodes = Maze.solve_maze(0,(49,69))
param.cmg = CMG(screen,Maze.map,steps_nodes)
#------------------------------------------------
#主函数,使用pygame框架,无限LOOP对各种事件然后相应处理
#------------------------------------------------
def main():
global param
#pygame.mixer.music.play(-1)
clock = pygame.time.Clock()
while True:
#这段event代码是必须的,哪怕在这个程序中不需要,不执行的话整个框架转不动
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
#画面按钮按下后,修改param.STATUS,实际动作这里实现
ifparam.STATUS == 100:
#退出按钮
if tk.messagebox.askokcancel('提示', '要退出画面吗'):
break
param.STATUS = 0
elif param.STATUS == 10:
pass
param.cmg.printAll()
#显示游戏画面
pygame.display.flip()
#设置帧率:长期画面不操作,设置成最闲
clock.tick(param.TICK_NORMAL)
root.update()
main()
页:
[1]