Rewind Feature. Gets Slower As Time Goes On.

What I’m trying to create is a rewind feature that basically rewinds game play.

The problem is that the longer I want before pressing the key the slower the rewind gets.

This is the code I’m using to do this.

import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.task.Task import *
from direct.showbase.DirectObject import *
import sys, random, os, math
from direct.interval.IntervalGlobal import *
from direct.interval.FunctionInterval import *

class Main(DirectObject):
	
	def __init__(self):
	
		globalClock.setMode(ClockObject.MLimited)
		globalClock.setFrameRate(30)
	
		base.win.setClearColor(Vec4(0,0,0,1))
		
		base.disableMouse()
		base.camera.setPos(0,-200,0)
		
		self.keyMap = { "Rewind":0}
		
		self.accept("r", self.setKey,["Rewind",1])
		self.accept("r-up",self.setKey,["Rewind",0])
		
		self.BBModelInit()
		self.PCModelInit()
		
		self.velocity = 0.0
				
		#Rewind Variables#
		
		self.RewindFreeze = False
		self.elapsedFrames = 0.0
		self.BrickStartPos = 30
		self.StartTime = 0.0
		self.CurrentPos = 0.0
		self.CurrentTime = 0.0
		self.FinishedMove = False
		self.EndTime = 0.0
		
		self.ResetTimer()
		
		Interval1 = Func(self.CollisionD)
		Interval2 = Func(self.CompoundTimer)
		Interval3 = Func(self.Rewind)
		
		self.MyInterval = Parallel(Interval1,Interval2,Interval3)
		
		taskMgr.add(self.ParallelKeeper,"Keeper")
		
		
	def ParallelKeeper(self, task):
		self.MyInterval.start()
		
		return Task.cont
		
	
	def BBModelInit(self):
	
		Sphere = CollisionSphere(0,0,0,3)
	
		self.bBrick = loader.loadModel("Brick")
		self.bBrick.reparentTo(render)
		self.bBrick.setPos(0,50,0)
		
		self.bBrickPC = self.bBrick.attachNewNode(CollisionNode('bBrickPC'))
		self.bBrickPC.node().addSolid(Sphere)
		self.bBrickPC.node().setIntoCollideMask(BitMask32.bit(29))
		self.bBrickPC.node().setFromCollideMask(BitMask32.bit(29))
		
		
	def PCModelInit(self):
		
		Sphere = CollisionSphere(0,0,0,3)
		
		self.pBrick = loader.loadModel("Block")
		self.pBrick.reparentTo(render)
		self.pBrick.setPos(0,50,30)
		
		self.pBrickPC = self.pBrick.attachNewNode(CollisionNode('pBrickPC'))
		self.pBrickPC.node().addSolid(Sphere)
		self.pBrickPC.node().setIntoCollideMask(BitMask32.bit(29))
		self.pBrickPC.node().setFromCollideMask(BitMask32.bit(29))
				
		
	def CollisionD(self):
		
		if(self.RewindFreeze == False):
			self.collTrav = CollisionTraverser()
			self.collTrav.showCollisions(render)
			
			queue = CollisionHandlerQueue()
			
			self.collTrav.addCollider(self.pBrickPC,queue)
			self.collTrav.traverse(render)
			
			entries = []
			
			for i in range(queue.getNumEntries()):
				entry = queue.getEntry(i)
				entries.append(entry)
				
			entries.sort(lambda x, y: cmp(y.getSurfacePoint(render).getZ(), x.getSurfacePoint(render).getZ()))
			
			if(len(entries) > 0) and (entries[0].getFromNode().getName() == 'pBrickPC'):
				self.velocity = 0.0
			
				if(self.FinishedMove == False):
					self.FinishedMove = True
					self.EndTime = self.elapsedFrames
			
			else:
				self.velocity = 1.0
				
	
			self.pBrick.setZ(self.pBrick,-(self.velocity))
				
			self.CurrentPos = self.pBrick.getZ()
		
		
		
	def ResetTimer(self):
	
		self.elapsedFrames = 0
	
	def CompoundTimer(self):
	
		if(self.RewindFreeze == False):
			self.elapsedFrames += 1
			self.CurrentTime = self.elapsedFrames

	def Rewind(self):
		if(self.keyMap["Rewind"]!=0):
			self.RewindFreeze = True
			
			if(self.CurrentTime != self.StartTime):
				self.CurrentTime -= 1
			if(self.CurrentTime <= self.EndTime) and (self.pBrick.getZ() != self.BrickStartPos):
				self.pBrick.setZ(self.pBrick,+(1.0))
				self.elapsedFrames = self.CurrentTime
				
			if(self.CurrentTime == self.StartTime):
				self.ResetTimer()
		
		else:
			self.RewindFreeze = False
	
	
		
	def setKey(self,key, value):
		self.keyMap[key] = value
		
		
m = Main()
run()

It works just like normal if i do it with a few seconds of the block hitting. But if I want say ten seconds, it gets really slow and takes longer than originally.

Any help or suggestions would be great!

My initial reaction was “well, duh, the more state you build up,the longer it will take to wade through” but… it doesn’t look like you’re storing state, just reversing the physics.

My next observation is that you don’t appear to be time-regulating the rewind, just backing up 1 unit per frame regardless, so if enough overall game state changes during runtime, it may be that you have different framerates, and hence different execution speeds, at any given time. Pstats would be a good way to look into this.

I’m also mildly unclear as to what the game is about, and what the rewind feature is supposed to accomplish as such. Providing the shortest code sample needed to reproduce the problem and/or a longer description of what the code does / how to read it is generally useful when you want answers on a specific implementation.