def s8v(fn, data, fps, t): "Convert frames to compressed bytes; save recording in S8V format" t[0] = 0 vid = Video().config(size=data[0].size, frameTimes=t) # vid.meta["frameRate"] = fps print("Compressing...") i = 0 for frame in data: vid._costumes.append(PixelData(frame, True)) i += 1 if i % 50 == 0: print(i) fps = 30 vid.removeGaps(2 * 0.3, 1 / fps).sync(fps).save(fn)
def open(self): fn = ask(askopenfilename, filetypes=VIDEOTYPES) if fn: if "Video" in self: self -= self["Video"] if self.s8v(fn): vid = Video(fn, progress=self.progress) else: vid = ImageIO.decodev(fn, self.progress) vid.originalSize = self.size = vid.size self["Video"] = vid.config(anchor=TOPLEFT) vid.layer = 0 self.frameRate = vid.meta.get("frameRate", 30) self.clip = [0, len(vid) - 1] self.caption = fn
def __init__(self, towers, speed, record): self.towers = towers self.disks = len(towers[0]) self.hanoi = moveDisks(towers, self.disks) self.moves = 0 self.paused = False if speed >= 15: self.frameRate = speed self.interval = 1 else: self.interval = round(30 / speed) self.frameRate = round(speed * self.interval) self.update = self.interval if record: self.vid = Video().autoSave(record) else: self.vid = None super().__init__((768, 432))
def play(size=(720, 480), record="", auto=4096): sk = Game(size).config(imgFldr=resolvePath("img", __file__)) if record: sk.capture = Video().config(interval=2).autoSave(record, auto) sk.play("Asteroid Shield", sk.imgFldr + "/target.png") if record: sk.capture.autoSave()
class Hanoi(Sketch): "Animation of the Towers of Hanoi problem" def __init__(self, towers, speed, record): self.towers = towers self.disks = len(towers[0]) self.hanoi = moveDisks(towers, self.disks) self.moves = 0 self.paused = False if speed >= 15: self.frameRate = speed self.interval = 1 else: self.interval = round(30 / speed) self.frameRate = round(speed * self.interval) self.update = self.interval if record: self.vid = Video().autoSave(record) else: self.vid = None super().__init__((768, 432)) def setup(self): "Add random-color rectangles to the sketch to represent the disks" h = min(14, max(1, self.height // self.disks - 1)) self.height = max(self.height, self.disks * (h + 1)) width = lambda i: self.width * (0.07 + 0.24 * i / (self.disks - 1)) for i in range(self.disks): w = width(i) img = Image((2 * w, 2 * h), False) self += img.snapshot(weight=2).config(anchor=BOTTOM, size=(w, h)) self.setDiskPositions() def ondraw(self): "Move one disk at the specified frame interval" if self.hanoi and not self.paused and self.frameCount == self.update: try: vid = self.vid if vid is not None: vid += self self.moves += 1 self.update += self.interval printState(next(self.hanoi), self.moves) self.setDiskPositions() except StopIteration: self.hanoi = None def onquit(self, ev): "Write unsaved frames before quitting" self.quit = True if self.vid: self.vid.autoSave() def setDiskPositions(self): "Update disk positions to match the current state of the towers" dx = self.width / 3 x = dx / 2 for t in self.towers: y = self.height - 1 for disk in t: img = self[disk - 1] img.pos = x, y y -= img.height - 1 x += dx def onclick(self, ev): "Pause/Resume animation on mouse click" if self.paused: self.update = self.frameCount + 1 self.paused = not self.paused
class Hanoi(Sketch): "Animation of the Towers of Hanoi problem" def __init__(self, towers, speed, record): self.towers = towers self.disks = len(towers[0]) self.hanoi = moveDisks(towers, self.disks) self.moves = 0 self.paused = False if speed >= 15: self.frameRate = speed self.interval = 1 else: self.interval = round(30 / speed) self.frameRate = round(speed * self.interval) self.update = self.interval if record: self.vid = Video().autoSave(record) else: self.vid = None super().__init__((768, 432)) def setup(self): "Add random-color rectangles to the sketch to represent the disks" h = min(14, max(1, self.height // self.disks - 1)) self.height = max(self.height, self.disks * (h + 1)) width = lambda i: self.width * (0.07 + 0.24 * i / (self.disks - 1)) for i in range(self.disks): w = width(i) img = Image((2*w, 2*h), False) self += img.snapshot(weight=2).config(anchor=BOTTOM, size=(w,h)) self.setDiskPositions() def ondraw(self): "Move one disk at the specified frame interval" if self.hanoi and not self.paused and self.frameCount == self.update: try: vid = self.vid if vid is not None: vid += self self.moves += 1 self.update += self.interval printState(next(self.hanoi), self.moves) self.setDiskPositions() except StopIteration: self.hanoi = None def onquit(self, ev): "Write unsaved frames before quitting" self.quit = True if self.vid: self.vid.autoSave() def setDiskPositions(self): "Update disk positions to match the current state of the towers" dx = self.width / 3 x = dx / 2 for t in self.towers: y = self.height - 1 for disk in t: img = self[disk - 1] img.pos = x, y y -= img.height - 1 x += dx def onclick(self, ev): "Pause/Resume animation on mouse click" if self.paused: self.update = self.frameCount + 1 self.paused = not self.paused