class LabTask03(DirectObject): #define the state of the game and level gameState = 'INIT' gameLevel = 1 cameraState = 'STARTUP' count = 0 attempts = 3 posX = -200 posY = 20 posZ = 30 score = 0 contacts = 0 pause = False fire = True desiredCamPos = Vec3(-200,30,20) def __init__(self): self.imageObject = OnscreenImage(image = 'models/splashscreen.png', pos=(0,0,0), scale=(1.4,1,1)) preloader = Preloader() self.musicLoop = loader.loadSfx("music/loop/EndlessBliss.mp3") self.snowmansHit = loader.loadSfx("music/effects/snowball_hit.wav") self.candleThrow = loader.loadSfx("music/effects/snowball_throw.wav") self.presentHit = loader.loadSfx("music/effects/present_hit.wav") self.loseSound = loader.loadSfx("music/effects/Failure-WahWah.mp3") self.winSound = loader.loadSfx("music/effects/Ta Da-SoundBible.com-1884170640.mp3") self.nextLevelSound = loader.loadSfx("music/effects/button-17.wav") self.loseScreen = OnscreenImage(image = 'models/losescreen.png', pos=(0,0,0), scale=(1.4,1,1)) self.loseScreen.hide() self.winScreen = OnscreenImage(image = 'models/winscreen.png', pos=(0,0,0), scale=(1.4,1,1)) self.winScreen.hide() self.helpScreen = OnscreenImage(image = 'models/helpscreen.jpg', pos=(0,0,0.1), scale=(1,1,0.8)) self.helpScreen.hide() self.backBtn = DirectButton(text=("Back"), scale = 0.1, pos = (0,0,-0.8), command = self.doBack) self.retryBtn = DirectButton(text="Retry", scale = 0.1, pos = (0,0,0), command = self.doRetry) self.retryBtn.hide() self.menuBtn = DirectButton(text="Main Menu", scale = 0.1, pos = (0,0,0), command = self.doBack) self.menuBtn.hide() self.backBtn.hide() base.setBackgroundColor(0.1, 0.1, 0.8, 1) #base.setFrameRateMeter(True) # Position the camera base.cam.setPos(0, 30, 20) base.cam.lookAt(0, 30, 0) # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, 1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = render.attachNewNode(dlight) render.clearLight() render.setLight(alightNP) render.setLight(dlightNP) # Input self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) self.accept('f', self.doShoot, [True]) self.accept('p', self.doPause) inputState.watchWithModifiers('forward', 'w') inputState.watchWithModifiers('left', 'a') inputState.watchWithModifiers('reverse', 's') inputState.watchWithModifiers('right', 'd') inputState.watchWithModifiers('turnLeft', 'q') inputState.watchWithModifiers('turnRight', 'e') inputState.watchWithModifiers('moveLineUp', 'i') inputState.watchWithModifiers('moveLineDown','k') inputState.watchWithModifiers('moveLineRight','l') inputState.watchWithModifiers('moveLineLeft','j') self.font = loader.loadFont('models/SHOWG.TTF') self.font.setPixelsPerUnit(60) self.attemptText = OnscreenText(text='', pos = (0.9,0.8), scale = 0.07, font = self.font) self.levelText = OnscreenText(text='', pos=(-0.9,0.9), scale = 0.07, font = self.font ) self.scoreText = OnscreenText(text='', pos = (0.9,0.9), scale = 0.07, font = self.font) self.text = OnscreenText(text = '', pos = (0, 0), scale = 0.07, font = self.font) self.pauseText = OnscreenText(text='P: Pause', pos= (0.9,0.7), scale = 0.05, font = self.font) self.pauseText.hide() # Task taskMgr.add(self.update, 'updateWorld') # Physics self.setup() # _____HANDLER_____ def doRetry(self): self.loseScreen.hide() self.levelText.clearText() self.scoreText.clearText() self.attemptText.clearText() self.playGame() self.retryBtn.hide() self.cleanup() self.setup() def doExit(self): self.cleanup() sys.exit(1) def doReset(self): self.attempts = 3 self.cameraState = 'STARTUP' base.cam.setPos(0,30,20) self.arrow.removeNode() self.scoreText.clearText() self.levelText.clearText() self.attemptText.clearText() self.cleanup() self.setup() def toggleWireframe(self): base.toggleWireframe() def toggleTexture(self): base.toggleTexture() def toggleDebug(self): if self.debugNP.isHidden(): self.debugNP.show() else: self.debugNP.hide() def doScreenshot(self): base.screenshot('Bullet') def doShoot(self, ccd): if(self.fire and self.attempts > 0 and self.gameState == 'PLAY'): self.cameraState = 'LOOK' self.fire = False self.candleThrow.play() self.attempts -= 1 #get from/to points from mouse click ## pMouse = base.mouseWatcherNode.getMouse() ## pFrom = Point3() ## pTo = Point3() ## base.camLens.extrude(pMouse, pFrom, pTo) ## pFrom = render.getRelativePoint(base.cam, pFrom) ## pTo = render.getRelativePoint(base.cam, pTo) # calculate initial velocity v = self.pTo - self.pFrom ratio = v.length() / 40 v.normalize() v *= 70.0 * ratio torqueOffset = random.random() * 10 #create bullet shape = BulletSphereShape(0.5) shape01 = BulletSphereShape(0.5) shape02 = BulletSphereShape(0.5) shape03 = BulletSphereShape(0.5) body = BulletRigidBodyNode('Candle') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape, TransformState.makePos(Point3(0,0,0))) bodyNP.node().addShape(shape01, TransformState.makePos(Point3(0,0.5,-0.5))) bodyNP.node().addShape(shape02,TransformState.makePos(Point3(0,1,-1))) bodyNP.node().addShape(shape03,TransformState.makePos(Point3(0,1.5,-1.5))) bodyNP.node().setMass(100) bodyNP.node().setFriction(1.0) bodyNP.node().setLinearVelocity(v) bodyNP.node().applyTorque(v*torqueOffset) bodyNP.setPos(self.pFrom) bodyNP.setCollideMask(BitMask32.allOn()) visNP = loader.loadModel('models/projectile.X') visNP.setScale(0.7) visNP.clearModelNodes() visNP.reparentTo(bodyNP) #self.bird = bodyNP.node() if ccd: bodyNP.node().setCcdMotionThreshold(1e-7) bodyNP.node().setCcdSweptSphereRadius(0.5) self.world.attachRigidBody(bodyNP.node()) #remove the bullet again after 1 sec self.bullets = bodyNP taskMgr.doMethodLater(5, self.removeBullet, 'removeBullet', extraArgs=[bodyNP], appendTask = True) def removeBullet(self, bulletNP, task): self.cameraState = 'STAY' self.fire = True self.world.removeRigidBody(bulletNP.node()) bulletNP.removeNode() if(self.attempts <= 0 and len(self.snowmans)>0): self.gameState = 'LOSE' self.doContinue() return task.done # ____TASK___ def processInput(self, dt): force = Vec3(0, 0, 0) torque = Vec3(0, 0, 0) #print self.pTo.getY() if inputState.isSet('forward'): if(self.pTo.getZ() < 40): self.pTo.addZ(0.5) if inputState.isSet('reverse'): if(self.pTo.getZ() > 0 ): self.pTo.addZ(-0.5) if inputState.isSet('left'): if(self.pTo.getY() < 100): self.pTo.addY(0.5) self.arrow.setScale(self.arrow.getSx(),self.arrow.getSy()-0.006,self.arrow.getSz()) if inputState.isSet('right'): if(self.pTo.getY() > 60): self.pTo.addY(-0.5) self.arrow.setScale(self.arrow.getSx(),self.arrow.getSy()+0.006,self.arrow.getSz()) self.arrow.lookAt(self.pTo) def processContacts(self, dt): for box in self.boxes: for snowman in self.snowmans: result = self.world.contactTestPair(box, snowman.node()) if (result.getNumContacts() > 0): self.snowmansHit.play() self.score += 100 self.text.setPos(0,0.7) self.text.setText("HIT") self.snowmans.remove(snowman) self.world.removeRigidBody(snowman.node()) snowman.removeNode() if(len(self.snowmans) <= 0): self.gameState = "NEXT" self.text.setText('Nice! Press space to continue') for box in self.boxes: for present in self.presents: result01 = self.world.contactTestPair(box,present.node()) if(result01.getNumContacts() > 0): self.presents.remove(present) self.world.removeRigidBody(present.node()) present.removeNode() self.presentHit.play() self.score += 500 def doContinue(self): if(self.gameState == 'INIT'): self.gameState = 'MENU' self.text.clearText() self.musicLoop.setLoop(True) self.musicLoop.setVolume(0.5) self.musicLoop.play() self.startBtn = DirectButton(text=("Play"), scale = 0.1, pos = (0,0,0),command=self.playGame) self.helpBtn = DirectButton(text=("Help"), scale = 0.1, pos = (0,0,-0.2),command=self.help) self.exitBtn = DirectButton(text=("Exit"), scale = 0.1, pos = (0,0,-0.4), command = self.doExit) return if self.gameState == 'NEXT': self.nextLevelSound.play() self.fire = True self.gameLevel += 1 self.score += (self.attempts * 100) self.doReset() self.gameState = 'PLAY' return if self.gameState == 'LOSE': self.loseSound.play() self.arrow.removeNode() self.loseScreen.show() self.levelText.hide() self.attemptText.hide() self.scoreText.hide() self.text.hide() self.pauseText.hide() self.retryBtn.show() return if self.gameState == 'WIN': self.levelText.hide() self.attemptText.hide() self.scoreText.clearText() self.scoreText.setPos(0,0.6) self.scoreText.setText("%s"%self.score) self.winScreen.show() self.winSound.play() self.menuBtn.show() self.pauseText.hide() return def playGame(self): print "Play Game" self.attempts = 3 self.score = 0 self.gameLevel = 1 self.gameState = 'PLAY' self.musicLoop.setVolume(0.3) self.imageObject.hide() self.startBtn.hide() self.exitBtn.hide() self.helpBtn.hide() self.cleanup() self.setup() def doBack(self): self.gameState = 'MENU' self.scoreText.setPos(0.9,0.9) self.scoreText.hide() self.imageObject.show() self.startBtn.show() self.exitBtn.show() self.helpBtn.show() self.helpScreen.hide() self.backBtn.hide() self.menuBtn.hide() self.winScreen.hide() def help(self): self.gameState = 'HELP' self.startBtn.hide() self.exitBtn.hide() self.helpBtn.hide() self.backBtn.show() self.helpScreen.show() return def doPause(self): self.pause = not self.pause if(self.pause): self.text.setText("Pause") else: self.text.clearText() def update(self, task): dt = globalClock.getDt() if(not self.pause): if self.gameState == 'INIT': self.text.setPos(0,0) self.text.setText('Press space to continue') self.accept('space',self.doContinue) if self.gameState == 'PLAY': #print self.posZ #if(self.posX < -120): # self.posX += 0.03 # self.posZ -= 0.02 #elif(self.posZ < 70): # self.posZ += 0.02; #elif(self.posZ > 70 and self.posX > -120): # self.posZ -= 0.02 # self.posX -= 0.03 #base.cam.setPos(self.posX, self.posZ, self.posY) self.levelText.setText('Level: %s'%self.gameLevel) self.attemptText.setText('Tries Left: %s'%self.attempts) self.scoreText.setText('Score: %s'%self.score) self.pauseText.show() self.processContacts(dt) self.world.doPhysics(dt, 20, 1.0/180.0) #self.drawLines() self.processInput(dt) if self.cameraState == 'STARTUP': oldPos = base.cam.getPos() pos = (oldPos*0.9) + (self.desiredCamPos*0.1) base.cam.setPos(pos) base.cam.lookAt(0,30,0) elif self.cameraState == 'STAY': #oldPos = base.cam.getPos() #currPos = (oldPos*0.9) + (self.desiredCamPos*0.1) #base.cam.setPos(currPos) base.cam.lookAt(0,30,0) elif self.cameraState == 'LOOK': base.cam.lookAt(self.bullets) #base.cam.setPos(-200,self.bullets.getZ(),20) if self.gameState == 'NEXT': self.world.doPhysics(dt, 20, 1.0/180.0) ## self.raycast() return task.cont def raycast(self): # Raycast for closest hit tsFrom = TransformState.makePos(Point3(0,0,0)) tsTo = TransformState.makePos(Point3(10,0,0)) shape = BulletSphereShape(0.5) penetration = 1.0 result = self.world.sweepTestClosest(shape, tsFrom, tsTo, penetration) if result.hasHit(): torque = Vec3(10,0,0) force = Vec3(0,0,100) ## for hit in result.getHits(): ## hit.getNode().applyTorque(torque) ## hit.getNode().applyCentralForce(force) result.getNode().applyTorque(torque) result.getNode().applyCentralForce(force) ## print result.getClosestHitFraction() ## print result.getHitFraction(), \ ## result.getNode(), \ ## result.getHitPos(), \ ## result.getHitNormal() def cleanup(self): self.world = None self.worldNP.removeNode() self.arrow.removeNode() self.lines.reset() self.text.clearText() def setup(self): self.attemptText.show() self.levelText.show() self.scoreText.show() self.text.show() self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) #arrow self.scaleY = 10 self.arrow = loader.loadModel('models/arrow.X') self.arrow.setScale(0.5,0.5,0.5) self.arrow.setAlphaScale(0.5) #self.arrow.setTransparency(TransparencyAttrib.MAlpha) self.arrow.reparentTo(render) #SkyBox skybox = loader.loadModel('models/skybox.X') skybox.reparentTo(render) # Ground shape = BulletPlaneShape(Vec3(0, 0, 1), 0) np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground')) np.node().addShape(shape) np.setPos(0, 0, -1) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) visualNP = loader.loadModel('models/ground.X') visualNP.clearModelNodes() visualNP.reparentTo(np) #some boxes self.boxes = [] self.snowmans = [] self.platforms = [] self.presents = [] #TODO: Make a table #Table Top #self.createBox(Vec3(),Vec3()) if(self.gameLevel == 1): self.createBox(Vec3(5,7,1),Vec3(0,5,10),1.0) #2 legs self.createBox(Vec3(4,1,4),Vec3(0,11,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-1,5),1.0) # Pigs self.createSnowman(2.0,Vec3(0, 5, 2.0),10.0) self.createSnowman(1.5, Vec3(0,-10,4.0),10.0) if(self.gameLevel == 2): #table01 self.createBox(Vec3(5,14,1),Vec3(0,-2,12),2.0) self.createBox(Vec3(5,7,1),Vec3(0,5,10),2.0) self.createBox(Vec3(4,1,4),Vec3(0,11,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-1,5),1.0) #table02 self.createBox(Vec3(5,7,1),Vec3(0,-9,10),2.0) self.createBox(Vec3(4,1,4),Vec3(0,-3,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-15,5),1.0) #table03 self.createBox(Vec3(1,1,1), Vec3(0,-1,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,-3,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,3,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,-5,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,5,14), 2.0) #pigs self.createSnowman(2.0,Vec3(0, 5, 2.0),10.0) self.createSnowman(2.0, Vec3(0,-9,2.0), 10.0) self.createSnowman(2.0,Vec3(0,-23,2.0),10.0) if(self.gameLevel == 3): #table01 self.createBox(Vec3(4,2,2),Vec3(0,12,12),1.0) self.createBox(Vec3(4,1,4),Vec3(0,11,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,13,5),1.0) #table02 self.createBox(Vec3(4,2,2),Vec3(0,-15,12),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-14,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-16,5),1.0) #table03 self.createBox(Vec3(4,10,1),Vec3(0,-1,12),1.0) self.createBox(Vec3(4,10,1),Vec3(0,-1,14),1.0) self.createBox(Vec3(4,2,4),Vec3(0,-2,5),0.1) #table04 self.createPlatform(Vec3(4,8,1),Vec3(0,7,16),1.0) self.createPlatform(Vec3(4,8,1),Vec3(0,-9,16),1.0) self.createBox(Vec3(4,1,3),Vec3(0,13,20),1.0) self.createBox(Vec3(4,1,3),Vec3(0,-16,20),1.0) #table05 self.createBox(Vec3(4,15,1),Vec3(0,-1,24),1.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,2,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,-2,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,4,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,8,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,6,20),5.0) #pigs self.createSnowman(2.0,Vec3(0, 5, 2.0),10.0) self.createSnowman(2.0,Vec3(0,-8.5,2.0),10.0) self.createSnowman(1.5, Vec3(0,-9,19.5), 7.0) #presents self.createPresent(Vec3(2,2,2),Vec3(0,-20,5)) if(self.gameLevel == 4): #wall self.createStoneBox(Vec3(4,1.5,10), Vec3(0,20,10),20) #table01 self.createBox(Vec3(4,1,5), Vec3(0,7,7),1) self.createBox(Vec3(4,1,5), Vec3(0,0,7),1) self.createBox(Vec3(4,1,4), Vec3(0,3,7),1) self.createPlatform(Vec3(5,8,1), Vec3(0,4,13),1) self.createBox(Vec3(4,1,3), Vec3(0,11,18),1) self.createBox(Vec3(4,1,3), Vec3(0,-3,18),1) self.createBox(Vec3(4,8,1), Vec3(0,4,25),1) self.createStoneBox(Vec3(1,1,1), Vec3(0,4,27),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,7,27),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,2,27),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,2,29),2) #stairs self.createPlatform(Vec3(4,50,4), Vec3(0,-55,5),100) #table02 self.createBox(Vec3(4,1,5), Vec3(0,-13,15),1) self.createBox(Vec3(4,1,5), Vec3(0,-20,15),1) self.createBox(Vec3(4,1,4), Vec3(0,-17,15),1) self.createPlatform(Vec3(4,8,1), Vec3(0,-16,22),1) self.createBox(Vec3(4,1,3), Vec3(0,-9,28),1) self.createBox(Vec3(4,1,3), Vec3(0,-23,28),1) self.createBox(Vec3(4,8,1), Vec3(0,-16,33),1) self.createStoneBox(Vec3(1,1,1), Vec3(0,-16,35),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-13,35),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-18,35),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-18,37),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-14,37),2) #snowman self.createSnowman(2.0,Vec3(0,30,5),1.0) self.createSnowman(1.5,Vec3(0,4,18),1.0) self.createSnowman(1.5,Vec3(0,-13,26),1.0) self.createSnowman(1.5,Vec3(0,-19,26),1.0) self.createSnowman(2.0,Vec3(0,12,5),1.0) self.createPresent(Vec3(2,2,2),Vec3(0,-25,13)) self.createPresent(Vec3(3,3,3),Vec3(0,-30,13)) self.createPresent(Vec3(4,4,4),Vec3(0,-36,13)) #self.createSnowman(1.5,Vec3(0,4,20),1.0) if(self.gameLevel == 5): #table01 self.createStoneBox(Vec3(4,7,3), Vec3(0,30,5),10.0) self.createStoneBox(Vec3(4,7,3), Vec3(0,-30,5),10.0) self.createBox(Vec3(4,1,3), Vec3(0,0,5), 1.0) self.createSnowman(1.5,Vec3(0,-6,5),1.0) self.createSnowman(1.5,Vec3(0,6,5),1.0) self.createBox(Vec3(4,1,3), Vec3(0,-12,5), 1.0) self.createBox(Vec3(4,1,3), Vec3(0,12,5), 1.0) self.createSnowman(1.5,Vec3(0,-18,5),1.0) self.createSnowman(1.5,Vec3(0,18,5),1.0) self.createStoneBox(Vec3(4,6,1),Vec3(0,-18,10), 0.1) self.createStoneBox(Vec3(4,6,1),Vec3(0,-6,10), 0.1) self.createStoneBox(Vec3(4,6,1),Vec3(0,6,10), 0.1) self.createStoneBox(Vec3(4,6,1),Vec3(0,18,10), 0.1) self.createStoneBox(Vec3(4,1,3),Vec3(0,23,14), 1.0) self.createStoneBox(Vec3(4,1,3),Vec3(0,-23,14), 1.0) self.createBox(Vec3(4,1,3),Vec3(0,18,14),1.0) self.createBox(Vec3(4,1,3),Vec3(0,-18,14),1.0) self.createStoneBox(Vec3(4,1,7),Vec3(0,13,20), 2.0) self.createStoneBox(Vec3(4,1,7),Vec3(0,-13,20), 2.0) self.createBox(Vec3(4,1,3),Vec3(0,8,14),1.0) self.createBox(Vec3(4,1,3),Vec3(0,-8,14),1.0) self.createStoneBox(Vec3(4,1,3),Vec3(0,3,14), 1.0) self.createStoneBox(Vec3(4,1,3),Vec3(0,-3,14), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,-20 ,20), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,20 ,20), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,-5 ,20), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,5 ,20), 1.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,-18,25), 2.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,18,25), 2.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,-7.5,25), 2.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,7.5,25), 2.0) self.createStoneBox(Vec3(4,6,1),Vec3(0,-12,30), 2.0) self.createStoneBox(Vec3(4,6,1),Vec3(0,12,30), 2.0) self.createBox(Vec3(4,1,5),Vec3(0,-5,30), 2.0) self.createBox(Vec3(4,1,5),Vec3(0,5,30), 2.0) self.createBox(Vec3(4,5,1),Vec3(0,0,40), 2.0) self.createPlatform(Vec3(4,2,0.5),Vec3(0,0,42), 2.0) self.createStoneBox(Vec3(4,0.5,2),Vec3(0,-3.5,45), 2.0) self.createStoneBox(Vec3(4,0.5,2),Vec3(0,3.5,45), 2.0) self.createStoneBox(Vec3(4,4,0.5),Vec3(0,0,48), 2.0) self.createPresent(Vec3(1.5,1.5,1.5),Vec3(0,22,30)) self.createPresent(Vec3(1.5,1.5,1.5),Vec3(0,-22,30)) self.createPresent(Vec3(2,2,1),Vec3(0,0,44)) self.createPresent(Vec3(3,3,4),Vec3(0,0,33)) if(self.gameLevel > 5): self.gameState = 'WIN' self.doContinue() return # drawing lines between the points ## self.lines = LineNodePath(parent = render, thickness = 3.0, colorVec = Vec4(1, 0, 0, 1)) ## self.pFrom = Point3(-4, 0, 0.5) ## self.pTo = Point3(4, 0, 0.5) # Aiming line self.lines = LineNodePath(parent = render, thickness = 3.0, colorVec = Vec4(1, 0, 0, 1)) self.pFrom = Point3(0, 100, 0.5) self.pTo = Point3(0, 60, 10) self.arrow.setPos(self.pFrom) def drawLines(self): # Draws lines for the ray. self.lines.reset() self.lines.drawLines([(self.pFrom,self.pTo)]) self.lines.create() def createBox(self,size,pos,mass): shape = BulletBoxShape(size) body = BulletRigidBodyNode('Obstacle') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(mass) bodyNP.node().setFriction(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setPos(pos) bodyNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(bodyNP.node()) visNP = loader.loadModel('models/crate.X') visNP.setScale(size*2) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.boxes.append(body) def createStoneBox(self,size,pos,mass): shape = BulletBoxShape(size) body = BulletRigidBodyNode('Obstacle') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(mass) bodyNP.node().setFriction(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setPos(pos) bodyNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(bodyNP.node()) visNP = loader.loadModel('models/stone.X') visNP.setScale(size*2) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.boxes.append(body) def createSnowman(self, size, pos, mass): shape = BulletBoxShape(Vec3(size,size,size)) shape01 = BulletSphereShape(size/2) body = BulletRigidBodyNode('Snowman') np = self.worldNP.attachNewNode(body) np.node().setMass(mass) np.node().addShape(shape, TransformState.makePos(Point3(0,0,-1))) np.node().addShape(shape01, TransformState.makePos(Point3(0,0,1))) np.node().setFriction(10.0) np.node().setDeactivationEnabled(False) np.setPos(pos) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) visualNP = loader.loadModel('models/snowman.X') visualNP.setScale(size) visualNP.clearModelNodes() visualNP.reparentTo(np) self.snowmans.append(np) def createPlatform(self,size,pos,mass): shape = BulletBoxShape(size) body = BulletRigidBodyNode('Platform') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(mass) bodyNP.node().setFriction(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setPos(pos) bodyNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(bodyNP.node()) visNP = loader.loadModel('models/crate.X') visNP.setScale(size*2) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.platforms.append(body) def createPresent(self,size,pos): shape = BulletBoxShape(size*0.7) body = BulletRigidBodyNode('Present') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setFriction(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setPos(pos) bodyNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(bodyNP.node()) visNP = loader.loadModel('models/present.X') visNP.setScale(size*2) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.presents.append(bodyNP)
class TunnelPinchTask(ShowBase, GripStateMachine): DATA_DIR = 'data' def __init__(self, id, session, hand, block, mode, wrist): ShowBase.__init__(self) GripStateMachine.__init__(self) base.disableMouse() wp = WindowProperties() wp.setSize(1920,1080) wp.setFullscreen(True) wp.setUndecorated(True) base.win.requestProperties(wp) self.sub_id = str(id) self.sess_id = str(session) self.hand = str(hand) self.block = str(block) self.mode = str(mode) self.wrist = str(wrist) self.prev_blk = os.path.join(self.DATA_DIR,'exp_2',self.sub_id,self.sess_id,self.wrist,self.hand,"B0") self.exp_blk0 = os.path.join(self.DATA_DIR,'exp_1',self.sub_id,self.sess_id,self.wrist,self.hand,"B0") self.table = np.loadtxt('src/tunnel_pinch_task/trialtable_flex.csv',dtype='str',delimiter=',',skiprows=1) indices = {} try: self.prev_table = np.loadtxt(os.path.join(self.prev_blk, 'final_targets.csv'),dtype='str',delimiter=',',skiprows=1) except: try: self.prev_table = np.loadtxt(os.path.join(self.exp_blk0, 'final_targets.csv'),dtype='str',delimiter=',',skiprows=1) except: print('Previous target file not found, results may be suboptimal') try: for i in range(self.prev_table.shape[0]): indices[self.prev_table[i,1]] = int(self.prev_table[i,0])-1 for i in range(self.table.shape[0]): self.table[i,11] = self.prev_table[indices[self.table[i,1].strip()],11] self.table[i,12] = self.prev_table[indices[self.table[i,1].strip()],12] self.table[i,13] = self.prev_table[indices[self.table[i,1].strip()],13] except: print('Invalid target file') self.table = np.array([[item.strip() for item in s] for s in self.table]) ################################################### #only use rows relevant to this block #HARDCODED! NOTE IN LOG SHEET spec_table = [] for i in range(self.table.shape[0]): if int(self.block)%5 == 0: #block 0 to adjust positions if "(p)" in self.table[i,2]: spec_table.append(self.table[i]) elif int(self.block)%5 == 1: if "(L)" in self.table[i,2]: spec_table.append(self.table[i]) elif int(self.block)%5 == 2: if "(L+t)" in self.table[i,2]: spec_table.append(self.table[i]) elif int(self.block)%5 == 3: if "(S)" in self.table[i,2]: spec_table.append(self.table[i]) elif int(self.block)%5 == 4: if "(S+t)" in self.table[i,2]: spec_table.append(self.table[i]) ################################################### self.table = np.array(spec_table) self.session_dir = os.path.join(self.DATA_DIR,'exp_2',self.sub_id,self.sess_id,self.wrist,self.hand) self.subjinfo = self.sub_id + '_' + self.sess_id + '_' + self.hand + '_log.yml' self.p_x,self.p_y,self.p_a = GET_POS(self.session_dir,self.subjinfo,self.hand,self.wrist) self.rotmat = ROT_MAT(self.p_a,self.hand) self.setup_text() self.setup_lights() self.setup_camera() self.trial_counter = 0 self.load_models() self.load_audio() self.update_trial_command() self.countdown_timer = CountdownTimer() self.hold_timer = CountdownTimer() self.cTrav = CollisionTraverser() self.chandler = CollisionHandlerEvent() self.chandler.addInPattern('%fn-into-%in') self.chandler.addOutPattern('%fn-outof-%in') self.chandler.addAgainPattern('%fn-again-%in') self.attachcollnodes() taskMgr.add(self.read_data, 'read') for i in range(5): taskMgr.add(self.move_player, 'move%d' % i, extraArgs = [i], appendTask=True) taskMgr.add(self.log_data, 'log_data') taskMgr.add(self.update_state, 'update_state', sort=1) self.accept('space', self.space_on) self.accept('escape', self.clean_up) self.space = False self.statenum = list() self.max_time = 20 self.med_data = None self.grip_dir = os.path.join(self.DATA_DIR,'exp_2',self.sub_id,self.sess_id,self.wrist,self.hand,"B"+self.block) if not os.path.exists(self.grip_dir): print('Making new folders: ' + self.grip_dir) os.makedirs(self.grip_dir) self.dev = MpDevice(RightHand(calibration_files=['calibs/cal_mat_70_v2.mat', 'calibs/cal_mat_73_v2.mat', 'calibs/cal_mat_56.mat', 'calibs/cal_mat_58_v2.mat', 'calibs/cal_mat_50.mat'], clock=mono_clock.get_time)) ############ #SET UP HUD# ############ def setup_text(self): self.bgtext = OnscreenText(text='Not recording.', pos=(-0.8, 0.8), scale=0.08, fg=(0, 0, 0, 1), bg=(1, 1, 1, 1), frame=(0.2, 0.2, 0.8, 1), align=TextNode.ACenter) self.bgtext.reparentTo(self.aspect2d) self.dirtext = OnscreenText( pos=(-0.6, 0.65), scale=0.08, fg=(0, 0, 0, 1), bg=(1, 1, 1, 1), frame=(0.2, 0.2, 0.8, 1), align=TextNode.ACenter) self.dirtext.reparentTo(self.aspect2d) ########################## #SET UP SCENE AND PLAYERS# ########################## def setup_lights(self): pl = PointLight('pl') pl.setColor((1, 1, 1, 1)) plNP = self.render.attachNewNode(pl) plNP.setPos(-10, -10, 10) self.render.setLight(plNP) pos = [[[0, 0, 50], [0, 0, -10]], [[0, -50, 0], [0, 10, 0]], [[-50, 0, 0], [10, 0, 0]]] for i in pos: dl = Spotlight('dl') dl.setColor((1, 1, 1, 1)) dlNP = self.render.attachNewNode(dl) dlNP.setPos(*i[0]) dlNP.lookAt(*i[1]) dlNP.node().setShadowCaster(False) self.render.setLight(dlNP) def setup_camera(self): self.cam.setPos(0, 0, 12) self.cam.lookAt(0, 2, 0) self.camLens.setFov(90) def load_models(self): self.back_model = self.loader.loadModel('models/back') self.back_model.setScale(10, 10, 10) if self.hand == "Left": self.back_model.setH(90) self.back_model.reparentTo(self.render) self.player_offsets = [[self.p_x[0]-5, self.p_y[0]+3, 0], [self.p_x[1]-2.5, self.p_y[1]+4.5, 0], [self.p_x[2], self.p_y[2]+5, 0], [self.p_x[3]+2.5, self.p_y[3]+4.5, 0], [self.p_x[4]+5, self.p_y[4]+3, 0]] self.p_col =[[0,0,250],[50,0,200],[125,0,125],[200,0,50],[250,0,0]] if self.hand == 'Left': self.p_col = self.p_col[::-1] self.players = list() self.contacts = list() for counter, value in enumerate(self.player_offsets): self.players.append(self.loader.loadModel('models/target')) self.contacts.append(False) self.players[counter].setPos(*value) self.players[counter].setScale(0.2, 0.2, 0.2) self.players[counter].setColorScale( self.p_col[counter][0]/255, self.p_col[counter][1]/255, self.p_col[counter][2]/255, 1) self.players[counter].reparentTo(self.render) self.players[counter].show() self.target_select() def load_audio(self): self.pop = self.loader.loadSfx('audio/Blop.wav') self.buzz = self.loader.loadSfx('audio/Buzzer.wav') ############################ #SET UP COLLISION MECHANICS# ############################ def attachcollnodes(self): self.inside = [False]*5 for i in range(5): self.fromObject = self.players[i].attachNewNode(CollisionNode('colfromNode'+str(i))) self.fromObject.node().addSolid(CollisionSphere(0,0,0,1)) self.cTrav.addCollider(self.fromObject, self.chandler) for i in range(5): self.accept('colfromNode%d-into-colintoNode' % i, self.collide1,[i]) self.accept('colfromNode%d-again-colintoNode' % i, self.collide2,[i]) self.accept('colfromNode%d-outof-colintoNode' % i, self.collide3,[i]) def collide1(self,f,collEntry): if f in self.highlighted_indices: self.players[f].setColorScale(0,1,0,1) self.tar.setColorScale(0.2,0.2,0.2,1) self.tar.setAlphaScale(0.7) self.contacts[f] = True taskMgr.doMethodLater(self.delay,self.too_long,'too_long%d' % f,extraArgs = [f]) def collide2(self,f,collEntry): for i in self.highlighted_indices: if self.contacts[i] == False: return taskMgr.remove('too_long%d' % f) def collide3(self,f,collEntry): taskMgr.remove('too_long%d' % f) self.reset_fing(f) self.tar.setColorScale(0.1,0.1,0.1,1) self.tar.setAlphaScale(0.7) def too_long(self,f): self.reset_fing(f) self.tar.setColorScale(0.5,0.2,0.2,1) self.tar.setAlphaScale(0.7) def reset_fing(self,f): self.players[f].setColorScale( self.p_col[f][0]/255, self.p_col[f][1]/255, self.p_col[f][2]/255, 1) self.contacts[f] = False ############### #TARGET THINGS# ############### def show_target(self): self.target_select() self.intoObject = self.tar.attachNewNode(CollisionNode('colintoNode')) if self.table[self.trial_counter,7] == "sphere": self.intoObject.node().addSolid(CollisionSphere(0,0,0,1)) elif self.table[self.trial_counter,7] == "cylinder": self.intoObject.node().addSolid(CollisionTube(0,0,-2,0,0,2,1)) else: raise NameError("No such collision type") self.tar.show() self.occSolid.show() self.occLines.show() for i in range(5): if i not in self.highlighted_indices: self.players[i].hide() def target_select(self): self.tgtscx=float(self.table[self.trial_counter,14]) self.tgtscy=float(self.table[self.trial_counter,15]) self.tgtscz=float(self.table[self.trial_counter,16]) tgttsx=float(self.table[self.trial_counter,11]) tgttsy=float(self.table[self.trial_counter,12]) tgttsz=float(self.table[self.trial_counter,13]) tgtrx=float(self.table[self.trial_counter,17]) tgtry=float(self.table[self.trial_counter,18]) tgtrz=float(self.table[self.trial_counter,19]) if self.hand == 'Left': tgttsx *= -1 tgtrx *= -1 self.static_task = (str(self.table[self.trial_counter,5]) == "True") self.target_model = str(self.table[self.trial_counter,6]) self.highlighted_indices=[int(s)-1 for s in self.table[self.trial_counter,4].split(' ')] if self.hand == 'Left': self.highlighted_indices=[4-i for i in self.highlighted_indices] self.tgtposx = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][[-2,-1],0]) + tgttsx self.tgtposy = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][[0,1],1]) + tgttsy if self.hand == 'Left': self.tgtposx = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][[0,1],0]) + tgttsx self.tgtposy = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][[-2,-1],1]) + tgttsy #self.tgtposx = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][:,0]) #self.tgtposy = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][:,1]) self.tgtposz = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][:,2]) + tgttsz self.tar = self.loader.loadModel(self.target_model) self.tar.setScale(self.tgtscx,self.tgtscy,self.tgtscz) self.tar.setPos(self.tgtposx,self.tgtposy,self.tgtposz) self.tar.setHpr(tgtrx,tgtry,tgtrz) self.tar.setColorScale(0.1, 0.1, 0.1, 1) self.tar.setAlphaScale(0.7) self.tar.setTransparency(TransparencyAttrib.MAlpha) self.tar.reparentTo(self.render) self.tar.hide() if len(self.highlighted_indices) == 2: dx = self.players[self.highlighted_indices[0]].getX() - self.players[self.highlighted_indices[1]].getX() dy = self.players[self.highlighted_indices[0]].getY() - self.players[self.highlighted_indices[1]].getY() angle = math.degrees(math.atan(dy/dx)) self.table[self.trial_counter,9] = str(angle) + ' ' + str(angle-180) self.angs=self.table[self.trial_counter,9].split(' ') self.angs = [float(a) for a in self.angs] self.tunn_width=float(self.table[self.trial_counter,10]) self.r = 1.5 if int(self.block) == 0: self.r = 0 self.x = [self.r*math.cos(math.radians(a)) for a in self.angs] self.y = [self.r*math.sin(math.radians(a)) for a in self.angs] self.occ = draw_shape(self.angs,self.tunn_width,self.r) self.occSolid = render.attachNewNode(self.occ[0]) self.occSolid.setPos(self.tgtposx,self.tgtposy,self.tgtposz) self.occSolid.setColorScale(0,1,1,0) self.occSolid.setTransparency(TransparencyAttrib.MAlpha) self.occSolid.setAlphaScale(0.6) self.occLines = render.attachNewNode(self.occ[1]) self.occLines.setPos(self.tgtposx,self.tgtposy,self.tgtposz) self.occSolid.hide() self.occLines.hide() self.delay=float(self.table[self.trial_counter,8]) self.distances = [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]] #change camera to be on top of target self.cam.setPos(self.tgtposx, self.tgtposy - 2, 12) self.back_model.setPos(self.tgtposx,self.tgtposy - 2,0) self.cam.lookAt(self.tgtposx, self.tgtposy, 0) ############## #MOVE FINGERS# ############## def read_data(self,task): error, data = self.dev.read() if data is not None: data *= 0.001 self.ts = data.time data = np.dot(data,self.rotmat) self.data = data if self.med_data is None: self.med_data = np.median(data, axis=0) if self.space: self.statenum.extend(([self.checkstate()])*len(data.time)) return task.cont def move_player(self,p,task): if self.data is not None : k = p*3 new_x = 10*np.mean(self.data[-1,k]) + self.player_offsets[p][0] - 10*self.med_data[k] new_y = 10*np.mean(self.data[-1,k + 1]) + self.player_offsets[p][1] - 10*self.med_data[k + 1] new_z = 10*np.mean(self.data[-1,k + 2]) + self.player_offsets[p][2] - 10*self.med_data[k + 2] #make sure digits do not cross each other if ((p in range(1,3) and p+1 in self.highlighted_indices and new_x > self.players[p+1].getX()) or (p in range(2,4) and p-1 in self.highlighted_indices and new_x < self.players[p-1].getX())): new_x = self.players[p].getX() #make sure digits do not cross into target if self.space == True and p in self.highlighted_indices: self.distances[p][0] = new_x - self.tar.getX() self.distances[p][1] = new_y - self.tar.getY() self.distances[p][2] = new_z - self.tar.getZ() self.check_pos(p) self.players[p].setPos(new_x, new_y, new_z) return task.cont def check_pos(self, p): x = self.distances[p][0] y = self.distances[p][1] z = self.distances[p][2] hit = True for i in range(len(self.angs)): p_ang = math.acos((x*self.x[i]+y*self.y[i])/(self.r*(x**2+y**2)**0.5)) if math.sin(p_ang)*(x**2+y**2)**0.5 < self.tunn_width and p_ang < math.pi/2: hit = False break if (abs(z) <= 1.2 #check z location and x**2 + y**2 <= self.r**2 #within radius of circle and hit == True): if self.inside[p] is False: self.ignore('colfromNode%d-into-colintoNode' % p) self.ignore('colfromNode%d-again-colintoNode' % p) self.players[p].setColorScale(1,1,0,1) self.inside[p] = True else: if self.inside[p] is True and x**2 + y**2 > self.r**2: self.accept('colfromNode%d-into-colintoNode' % p, self.collide1,[p]) self.accept('colfromNode%d-again-colintoNode' % p, self.collide2,[p]) self.players[p].setColorScale( self.p_col[p][0]/255, self.p_col[p][1]/255, self.p_col[p][2]/255, 1) self.inside[p] = False ################## #CHECK COMPLETION# ################## def close_to_target(self): for i in self.highlighted_indices: if self.contacts[i] == False: return False self.tar.setColorScale(0,1,1,1) return True def check_hold(self): if not self.close_to_target(): self.hold_timer.reset(0.5) return False return self.hold_timer.elapsed() < 0 def adjust_targets(self): #no adjustment if more than 2 fingers or position is prone if len(self.highlighted_indices) > 2 or self.wrist == 'pron': return xadj,yadj,zadj = np.mean(np.asarray(self.distances)[self.highlighted_indices],0) #xadj = np.mean(np.asarray(self.distances)[self.highlighted_indices][0]) #yadj = np.mean(np.asarray(self.distances)[self.highlighted_indices][1]) #zadj = np.mean(np.asarray(self.distances)[self.highlighted_indices][2]) #do adjustment on all tasks with same name if self.hand == 'Left': xadj = -xadj for i in range(self.trial_counter+1,self.table.shape[0]): if self.table[i,1] == self.table[self.trial_counter,1]: self.table[i,11] = float(self.table[i,11]) + xadj self.table[i,12] = float(self.table[i,12]) + yadj self.table[i,13] = float(self.table[i,13]) + zadj ######### #LOGGING# ######### def play_success(self): if int(self.block) == 0: self.adjust_targets() self.pop.play() self.tar.hide() self.highlighted_indices = [0,1,2,3,4] def log_text(self): self.bgtext.setText('Now logging...') def log_data(self, task): if (self.trial_counter + 1) <= self.table.shape[0]: if self.space: self.log_file_name = os.path.join(self.grip_dir, self.sub_id+"_"+self.sess_id+"_"+self.hand+"_"+ str(self.table[self.trial_counter,1])+"_"+str(self.table[self.trial_counter,0])+".csv" ) self.movvars = np.column_stack((self.ts, self.statenum, self.data)) self.statenum = [] if self.mode=='task': with open(self.log_file_name, 'ab') as f: np.savetxt(f, self.movvars, fmt='%10.5f', delimiter=',') return task.cont else: pass def stoplog_text(self): self.dirtext.clearText() self.bgtext.setText('Done logging!') for i in range(5): self.players[i].show() ####### #RESET# ####### def delete_file(self): if (self.trial_counter + 1) <= self.table.shape[0]: self.log_file_name = os.path.join(self.grip_dir, self.sub_id+"_"+self.sess_id+"_"+self.hand+"_"+ str(self.table[self.trial_counter,1])+"_"+str(self.table[self.trial_counter,0])+".csv" ) try: os.remove(self.log_file_name) except OSError: pass else: pass def reset_baseline(self): self.med_data = None def reset_keyboard_bool(self): self.space = False def hide_target(self): self.tar.hide() self.occSolid.hide() self.occLines.hide() self.intoObject.removeNode() self.imageObject.destroy() def update_trial_command(self): self.dirtext.setText(str(self.table[self.trial_counter,2])) if self.hand == 'Left': xfac = -0.25 else: xfac = 0.25 self.imageObject = OnscreenImage(image = str(self.table[self.trial_counter,3]),scale=(xfac,0.25,0.25),pos=(-0.8, 0, 0.3)) def increment_trial_counter(self): self.trial_counter += 1 self.update_trial_command() ######## #TIMERS# ######## def start_trial_countdown(self): self.countdown_timer.reset(self.max_time) def start_hold_countdown(self): self.hold_timer.reset(0.5) def start_post_countdown(self): self.countdown_timer.reset(2) def time_elapsed(self): return self.countdown_timer.elapsed() < 0 ######### #MACHINE# ######### def update_state(self, task): self.step() return task.cont def wait_for_space(self): return self.space def space_on(self): self.space = True ##### #END# ##### def trial_counter_exceeded(self): return (self.trial_counter+1) > self.table.shape[0]-1 def clean_up(self): #write last known positions to 'final_targets' file f = open('src/pinch_task/trialtable_flex.csv') header = f.readline().rstrip() np.savetxt(self.grip_dir + '/final_targets.csv',self.table,fmt='%s',header = header, delimiter=',') f.close() sys.exit()
class PenaltyKick(ShowBase): #angleD global co co = 0 def __init__(self): #try: #if(co == 0): ShowBase.__init__(self) # co += 1 self.disableMouse() base.setBackgroundColor(0, 0, 1) #camera.setPosHpr(45, -45, 45, 45, -45, 45) self.accept("escape", sys.exit) # Escape quits # Disable default mouse-based camera control. This is a method on the # ShowBase class from which we inherit. #self.disableMouse() camera.setPosHpr(-10, -50, 10, -10, -7, 0) #camera.setPosHpr(-50, 40, 0, 270, 0, 0) #base.setBackgroundColor(0,1,0) #base net = loader.loadModel("models/drawnNet") net.setColor(1, 1, 0) net.setScale(2.5, 2.5, 1.5) net.setPosHpr(0, 53, -2, 0, -10, 0) net.reparentTo(render) global targetY targetY = 40 postR = loader.loadModel("models/box") postR.setColor(0.75, 0, 0.25) postR.setScale(0.03, 0.03, 1) LidR = postR.find('**/lid') PandaR = postR.find('**/turningthing') HingeNodeR = postR.find('**/box').attachNewNode('nHingeNode') HingeNodeR.setPos(.8659, 6.5, 5.4) LidR.wrtReparentTo(HingeNodeR) HingeNodeR.setHpr(0, 90, 0) lidCloseR = Parallel( LerpHprInterval(HingeNodeR, 2.0, (0, 90, 0), blendType='easeInOut')) postR.setPosHpr(18, 55.5, -2, 0, 0, 0) postR.reparentTo(render) postGR = loader.loadModel("models/box") postGR.setColor(0.75, 0, 0.25) postGR.setScale(0.03, 0.03, 1) lidGR = postGR.find('**/lid') PandaGR = postGR.find('**/turningthing') HingeNodeGR = postGR.find('**/box').attachNewNode('nHingeNode') HingeNodeGR.setPos(.8659, 6.5, 5.4) #lidGR.wrtReparentTo(HingeNodeR) HingeNodeGR.setHpr(0, 90, 0) lidCloseGR = Parallel( LerpHprInterval(HingeNodeGR, 2.0, (0, 90, 0), blendType='easeInOut')) postGR.setPosHpr(18, 58.5, -4, 90, 0, 90) postGR.reparentTo(render) postL = loader.loadModel("models/box") postL.setColor(0.75, 0, 0.25) postL.setScale(0.03, 0.03, 2) LidL = postL.find('**/lid') PandaL = postL.find('**/turningthing') HingeNodeL = postL.find('**/box').attachNewNode('nHingeNode') HingeNodeL.setPos(.8659, 6.5, 5.4) LidL.wrtReparentTo(HingeNodeL) HingeNodeL.setHpr(0, 90, 0) lidCloseL = Parallel( LerpHprInterval(HingeNodeL, 2.0, (90, 0, 0), blendType='easeInOut')) postL.setPosHpr(-18, 55.5, -1, 0, 0, 0) postL.reparentTo(render) postGL = loader.loadModel("models/box") postGL.setColor(0.75, 0, 0.25) postGL.setScale(0.03, 0.03, 1) lidGL = postGL.find('**/lid') PandaGL = postGL.find('**/turningthing') HingeNodeGL = postGL.find('**/box').attachNewNode('nHingeNode') HingeNodeGL.setPos(.8659, 6.5, 5.4) #lidGR.wrtReparentTo(HingeNodeR) HingeNodeGL.setHpr(0, 90, 0) lidCloseGL = Parallel( LerpHprInterval(HingeNodeGL, 2.0, (0, 90, 0), blendType='easeInOut')) postGL.setPosHpr(-18, 58.5, -4.5, 90, 0, 90) postGL.reparentTo(render) #camera.setPosHpr(20, 45, 0, 90, 0, 0) postT = loader.loadModel("models/box") postT.setColor(0.75, 0, 0.25) postT.setScale(1.70, 0.03, 0.03) LidT = postL.find('**/lid') PandaT = postT.find('**/turningthing') HingeNodeT = postT.find('**/box').attachNewNode('nHingeNode') HingeNodeT.setPos(.8659, 6.5, 5.4) LidT.wrtReparentTo(HingeNodeT) HingeNodeT.setHpr(0, 90, 0) lidCloseT = Parallel( LerpHprInterval(HingeNodeT, 2.0, (0, 90, 0), blendType='easeInOut')) postT.setPosHpr(0, 55.5, 9.8, 0, 0, 0) postT.reparentTo(render) global ball ballRoot = render.attachNewNode("ballRoot") ball = loader.loadModel("models/ball") ball.reparentTo(ballRoot) #ball.setColor(0.5, 0, 1) ball.setScale(6, 6, 6) ball.setPosHpr(0, -12, -3, 0, -20, 0) #self.kick.setPos(0, 40, 0) ballTex = loader.loadTexture("pictures/ball.jpg") ball.setTexture(ballTex) ball.reparentTo(render) ballSphere = ball.find("**/ball") ballSphere.node().setFromCollideMask(BitMask32.bit(0)) ballSphere.node().setIntoCollideMask(BitMask32.allOff()) ambientLight = AmbientLight("ambientLight") ambientLight.setColor((.55, .55, .55, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(LVector3(0, 0, -1)) directionalLight.setColor((0.375, 0.375, 0.375, 1)) directionalLight.setSpecularColor((1, 1, 1, 1)) ballRoot.setLight(render.attachNewNode(ambientLight)) ballRoot.setLight(render.attachNewNode(directionalLight)) m = Material() m.setSpecular((1, 1, 1, 1)) m.setShininess(96) ball.setMaterial(m, 1) cs = CollisionSphere(0, 0, 0, 0.41) cNodePath = ball.attachNewNode(CollisionNode('cnode')) cNodePath.node().addSolid(cs) #cNodePath.show() #0, 53, -2 cW = CollisionPolygon(Point3(-1, 40, -4), Point3(-1, 40, 8), Point3(1, 40, 8), Point3(1, 40, -4)) cwNodePath = net.attachNewNode(CollisionNode('cwnode')) cwNodePath.node().addSolid(cW) #cwNodePath.show() #queue = CollisionHandlerQueue() #traverser.addCollider(cs, queue) #traverser.traverse(render) ground = loader.loadModel("models/square") ground.setPosHpr(0, 35, -5, 0, 0, 0) ground.setScale(120, 120, 120) #ground.setColor(0.2, 1, 0) grass = loader.loadTexture("pictures/grass_1.jpg") ground.setTexture(grass) ground.reparentTo(render) wall = loader.loadModel("models/square") wall.setPosHpr(5, 100, 18, 0, 90, 0) wall.setScale(90, 50, 75) #camera.setPos(0, -150, 0) #wall.setColor(0.5, 0.5, 0.5) crowd = loader.loadTexture("pictures/crowd.png") wall.setTexture(crowd) wall.reparentTo(render) rightWall = loader.loadModel("models/square") rightWall.setPosHpr(48, 45, 0, -90, 90, 0) rightWall.setScale(100, 100, 100) rightWall.setColor(0.75, 0.75, 0.75) rightWall.reparentTo(render) global angle angle = loader.loadModel("models/box") angle.setColor(0.25, 0.25, 0.25) angle.setScale(1.0, 0.25, 0.03) LidA = angle.find('**/lid') PandaA = angle.find('**/turningthing') HingeNodeA = angle.find('**/box').attachNewNode('nHingeNode') HingeNodeA.setPos(.8659, 6.5, 5.4) LidA.wrtReparentTo(HingeNodeA) HingeNodeA.setHpr(0, 90, 0) lidCloseA = Parallel( LerpHprInterval(HingeNodeA, 2.0, (0, 90, 0), blendType='easeInOut')) angle.setPosHpr(0, 10.5, -3, 0, 90, 0) #bar = loader.loadTexture("pictures/bar.png") #angle.setTexture(bar) angle.reparentTo(render) global angleD angleD = loader.loadModel("models/box") angleD.setColor(0, 0, 1) angleD.setScale(0.1, 0.25, 0.03) LidD = angleD.find('**/lid') PandaD = angleD.find('**/turningthing') HingeNodeD = angleD.find('**/box').attachNewNode('nHingeNode') HingeNodeD.setPos(.8659, 6.5, 5.4) LidD.wrtReparentTo(HingeNodeD) HingeNodeD.setHpr(0, 90, 0) lidCloseD = Parallel( LerpHprInterval(HingeNodeD, 2.0, (0, 90, 0), blendType='easeInOut')) angleD.setPosHpr(0, 10.4, -3, 0, 90, 0) angleD.reparentTo(render) global power power = loader.loadModel("models/box") power.setColor(0.25, 0.25, 0.25) power.setScale(0.12, 2.2, 0.03) LidP = power.find('**/lid') PandaP = power.find('**/turningthing') HingeNodeP = power.find('**/box').attachNewNode('nHingeNode') HingeNodeP.setPos(.8659, 6.5, 5.4) LidP.wrtReparentTo(HingeNodeP) HingeNodeP.setHpr(0, 90, 0) lidCloseP = Parallel( LerpHprInterval(HingeNodeP, 2.0, (0, 90, 0), blendType='easeInOut')) power.setPosHpr(-18, 10.5, -3, 0, 90, 0) global powerD powerD = loader.loadModel("models/box") powerD.setColor(1, 0, 0) powerD.setScale(0.12, 0.05, 0.03) LidD = power.find('**/lid') PandaD = power.find('**/turningthing') HingeNodeD = power.find('**/box').attachNewNode('nHingeNode') HingeNodeD.setPos(.8659, 6.5, 5.4) LidD.wrtReparentTo(HingeNodeD) HingeNodeD.setHpr(0, 90, 0) lidCloseD = Parallel( LerpHprInterval(HingeNodeD, 2.0, (0, 90, 0), blendType='easeInOut')) powerD.setPosHpr(-18, 10, -4.5, 0, 50, 0) global bishop bishop = loader.loadModel("models/bishop") bs = loader.loadTexture("pictures/bishop.png") bishop.setTexture(bs) bishop.setScale(10, 10, 10) #bishop.setColor(0, 0.4, 1) bishop.setPosHpr(0, 42, -5, 90, 0, 0) bishop.reparentTo(render) global bArmL bArmL = loader.loadModel("models/bishop") bArmL.setScale(2, 2, 4) bishop.setTexture(bs) #bArmL.setColor(0, 0.4, 1) bArmL.setPos(-1, 55, 6) #bArmL.reparentTo(render) global bArmR bArmR = loader.loadModel("models/bishop") bArmR.setScale(2, 2, 4) bishop.setTexture(bs) #bArmR.setColor(0, 0.4, 1) bArmR.setPos(1, 55, 6) #bArmR.reparentTo(render) global start start = loader.loadModel("models/square") start.setPosHpr(5, -25, 18, 0, 90, 0) start.setScale(90, 50, 75) #camera.setPos(0, -150, 0) start.setColor(0.5, 0.5, 0.5) #crowd = loader.loadTexture("pictures/crowd.png") #start.setTexture(crowd) start.reparentTo(render) title = TextNode('title') title.setText("Welcome to Penalty Kick!") global textNodePath textNodePath = aspect2d.attachNewNode(title) textNodePath.setScale(0.25) title.setWordwrap(8) title.setCardColor(0, 0, 0, 0) title.setCardAsMargin(0, 0, 0, 0) title.setCardDecal(True) textNodePath.setPos(-0.75, 0, 0.5) self.instructions = \ OnscreenText(text="Press any key to begin", parent=base.a2dBottomRight, align=TextNode.ARight, pos=(-1, +0.08), fg=(1, 1, 1, 1), scale=.06, shadow=(0, 0, 0, 0.5)) #self.accept('ball-into-net', ballCollideHandler) base.buttonThrowers[0].node().setKeystrokeEvent('keystroke') self.accept('keystroke', self.next) #textNodePath.reparentTo(render) def ballCollideHandler(self, entry): ballLerp = Sequence( Parallel( LerpPosInterval(ball, 0.75, Point3(ball.getX(), 0, ball.getZ()), Point3(ball.getX(), ball.getY(), ball.getZ()), None, 'noBlend', 0, 1, 'bLerp'))) if (counter < 5): self.score = \ score.clear() OnscreenText(text=counter + "/5", parent=base.a2dTopRight, align=TextNode.ARight, fg=(1, 1, 1, 1), pos=(-0.1, 0.1), scale=.1, shadow=(0, 0, 0, 0.5)) counter += 1 #camera.setPosHpr(-15, -85, 0, -20, -10, 0) def nothing(self, x): pass counter = 0 def blank_(self): pass def next(self, x): base.buttonThrowers[0].node().setKeystrokeEvent('keystroke') self.accept('keystroke', self.nothing) self.accept('enter', self.blank_) start.setPos(0, -100, 0) #self.instructions.clearText() textNodePath.setPos(-100, -100, 0) self.instructions.clearText() self.title = \ OnscreenText(text="Penalty Kick", parent=base.a2dBottomRight, align=TextNode.ARight, fg=(1, 1, 1, 1), pos=(-0.1, 0.1), scale=0.15, shadow=(0, 0, 0, 0.5)) self.instructions = \ OnscreenText(text="Choose your angle with the space bar", parent=base.a2dTopLeft, align=TextNode.ALeft, pos=(0.05, -0.08), fg=(1, 1, 1, 1), scale=.1, shadow=(0, 0, 0, 0.5)) self.angleText = \ OnscreenText(text="Angle", parent=base.a2dBottomRight, align=TextNode.ARight, pos=(-1.3, +.82), fg=(1, 1, 1, 1), scale=0.15, shadow=(0, 0, 0, 0.5)) #self.score = \ # OnscreenText(text="0/5", # parent=base.a2dTopRight, align=TextNode.ARight, # fg=(1, 1, 1, 1), pos=(-0.1, 0.1), scale=.08, shadow=(0, 0, 0, 0.5)) global bLerp bLerp = Sequence( Parallel( LerpPosInterval(bishop, 0.6, Point3(-15, 57, -5), Point3(15, 57, -5), None, 'easeInOut', 0, 1, 'bLerp')), LerpPosInterval(bishop, 0.5, Point3(15, 57, -5), Point3(-15, 57, -5), None, 'easeInOut', 0, 1, 'bLerp')) #bishopInterval = bishop.posInterval bLerp.loop() #ball sims until location reached, then sims a drop down. no collision check needed global angleDLerp angleDLerp = Sequence( Parallel( LerpPosInterval(angleD, 0.6, Point3(-9.5, 10.4, -3), Point3(9.5, 10.4, -3), None, 'easeInOut', 0, 1, 'bLerp')), LerpPosInterval(angleD, 0.8, Point3(10, 10.4, -3), Point3(-10, 10.4, -3), None, 'easeInOut', 0, 1, 'bLerp')) angleDLerp.loop() global powerDLerp powerDLerp = Sequence( Parallel( LerpPosInterval(powerD, 0.3, Point3(-18, 10, -4.5), Point3(-18, 10, 11), None, 'easeInOut', 0, 1, 'bLerp')), LerpPosInterval(powerD, 0.5, Point3(-18, 10, 11), Point3(-18, 10, -4.5), None, 'easeInOut', 0, 1, 'bLerp')) x = 1 self.accept('space', self.angleDis) #place #print("hi") #inp = input("") # Get the input #while inp != "": # Loop until it is a blank line # print("??") # inp = input() # angleD.setFluidPos(-10, 10.4, -3) # angleD.setFuildPos(10, 10.4, -3) #pause = input('') #click event, fire ball global oneToFive oneToFive = 0 global oneOrTwo oneOrTwo = 0 def angleDis(self): self.angleText.clearText() ballPos = ball.getPos(render) angleDPos = angleD.getPos(render) direction = ballPos - angleDPos #fn = ForceNode('push') #p = LinearVectorForce((direction + ballPos) * 2) #fn.addForce(p) #ball.addLinearForce(pull) #self.setVelocity(ball, LVector3(ballPos-angleDPos)) #print(ballPos, angleDPos) ballX = ball.getX(render) #print(ballPos, ballX) #ball.setFluidPos(ballPos + direction * 1) ballX = ball.getX(render) ballY = ball.getY(render) ballZ = ball.getZ(render) angleDX = angleD.getX(render) angleDY = angleD.getY(render) angleDZ = angleD.getZ(render) angleDD = (angleDX + 9.5) / (19) #print(angleDX) if (angleDD <= 0.2): oneToFive = 1 elif (angleDD <= 0.4): oneToFive = 2 elif (angleDD <= 0.6): oneToFive = 3 elif (angleDD <= 0.8): oneToFive = 4 else: oneToFive = 5 #print(oneToFive) #global ballLerp #ballLerp = Sequence(Parallel(LerpPosInterval(ball, 1, Point3(ball.getX(), 70, ball.getZ() + 10), ball.getPos(), None, 'easeInOut', 0, 1, 'bLerp'))) #ballLerp.start() #ballLerp.finish() #print(angleDPos, angleDX, angleDY, angleDZ) #print(angleD.getPos(render), direction, ballPos, ballX, ballY, ballZ) #print self.instructions.clearText() self.instructions = \ OnscreenText(text="Choose the power with the space bar", parent=base.a2dTopLeft, align=TextNode.ALeft, pos=(0.05, -0.08), fg=(1, 1, 1, 1), scale=.06, shadow=(0, 0, 0, 0.5)) self.powerText = \ OnscreenText(text="Power", parent=base.a2dBottomRight, align=TextNode.ARight, pos=(-2.2, 1.6), fg=(1, 1, 1, 1), scale=.15, shadow=(0, 0, 0, 0.5)) power.reparentTo(render) #angle.setPos(0,0, -100) angleDLerp.finish() angleD.setPos(angleDX, angleDY, angleDZ) powerD.reparentTo(render) powerDLerp.loop() self.accept('space', self.powerDis, [oneToFive]) def powerDis(self, oTF): self.powerText.clearText() powerDX = powerD.getX(render) powerDY = powerD.getY(render) powerDZ = powerD.getZ(render) powerDLerp.finish() powerD.setPos(powerDX, powerDY, powerDZ) #print(11-(15.5/2), powerDZ) if (powerDZ > 11 - (15.5 / 2)): oneOrTwo = 2 else: oneOrTwo = 1 #go in direction that angle bar says, in relative speed ballKZ = 2 #print(oTF) ballKX = oTF * (0.2 * 19) if (oneOrTwo == 2): #print("hi") ballKZ += 8 fifth = (1 / 3) * 19 # print(-9.5 + (oTF * fifth)) tmp1 = -9.5 - fifth tmp2 = 9.5 + fifth #print(-9.5 + (oTF * (0.2*(tmp2-tmp1))), tmp2-tmp1, 0.2*(tmp2-tmp1), oTF*(0.2*(tmp2-tmp1))) #print(1/3) #ball.setX(ball.getX() + 5) goalieX = bishop.getX() goalieY = bishop.getY() goalieZ = bishop.getZ() if (abs(goalieX - ballKX) < 0.5): self.ballDown() bLerp.finish() bishop.setPos(goalieX, goalieY, goalieZ) #pt = #Point3(2*(-9.5 + (oTF * (0.2*(tmp2-tmp1))) # pt.setY(-1) tmp = 1.7 * (-9.5 + (oTF * (0.2 * (tmp2 - tmp1)))) num = 63 num2 = 65 if (oneOrTwo == 2): num = 55 rand = random.randrange(1, 2, 1) #print(rand) global blocked blocked = False if (abs(goalieX - tmp) < 5): if ((rand == oneOrTwo) or abs(goalieX - tmp) - 3): if (oneOrTwo == 2): yyy = tmp - 1.5 * 0.6 #print(yyy, tmp) bArmL.setX(yyy) if (oneToFive == 1): bArmR.setX(yyy - 2) elif (oneToFive == 2): bArmR.setX(yyy - 1) elif (oneToFive == 3): bArmR.setX(yyy + 0) elif (oneToFive == 4): bArmR.setX(yyy + 1) else: bArmR.setX(yyy + 2) bArmL.reparentTo(render) bArmR.reparentTo(render) bishop.setX(tmp) num = 55 num2 = 55 blocked = True elif (oneOrTwo == 1): blocked = True #else: # print(goalieX, tmp) #print(goalieX, tmp, abs(goalieX-tmp)) ballLerp = Sequence( Parallel( LerpPosInterval(ball, 0.5, Point3(tmp, num, ballKZ), ball.getPos(), None, 'easeInOut', 0, 1, 'bLerp')), LerpPosInterval(ball, 0.75, Point3(tmp, num2, -3), Point3(tmp, num, ballKZ), None, 'easeInOut', 0, 1, 'bLerp'), Func(self.blockedC)) angle.setPos(0, 0, -100) angleD.setPos(0, 0, -100) power.setPos(0, 0, -111) powerD.setPos(0, 0, -111) self.instructions.clearText() self.title.clearText() ballLerp.start() #self.__init__() #power is according to length of awwor #goalie moves in random direction, speed on click #if ball/goalie collide, no points for that round. #out of five points. Whoever has more at end wins. kicked = False #def mousemove(event): # print("1") #def mousedown(event): # if not kicked: # print("") def bC(self): #print("l") pass def blockedC(self): if (blocked): self.title.clearText() self.instructions.clearText() start.setPosHpr(5, -25, 18, 0, 90, 0) start.setColor(1, 0, 0) title1 = TextNode('game-over') title1.setText("You Failed. Try Again?") global tNP1 tNP1 = aspect2d.attachNewNode(title1) tNP1.setScale(0.25) title1.setWordwrap(5) title1.setCardColor(0, 0, 0, 0) title1.setCardAsMargin(0, 0, 0, 0) title1.setCardDecal(True) tNP1.setPos(-0.65, 0, 0.5) self.instructions = \ OnscreenText(text="Press any key to restart", parent=base.a2dBottomRight, align=TextNode.ARight, pos=(-1, +0.08), fg=(1, 1, 1, 1), scale=.08, shadow=(0, 0, 0, 0.5)) #base.buttonThrowers[0].node().setKeystrokeEvent('keystroke') #self.accept('keystroke', self.myFunc) #yes = TextNode('yes') #yes.setText("Yes") #global tNPy #tNPy = aspect2d.attachNewNode(yes) #tNPy.setScale(0.25) #yes.setWordwrap(10) #yes.setCardColor(0, 0, 0, 0) #yes.setCardAsMargin(0, 0, 0, 0) #yes.setCardDecal(True) #yes.setCardBorder(2,2) #tPNy.setPos(-1.0, 1.0, 1) #self.yes_ = \ #OnscreenText(text="Yes", # parent=base.a2dBottomLeft, align=TextNode.ALeft, # pos=(0.05, 0.05), fg=(1, 1, 1, 1), scale=.35, # shadow=(0, 0, 0, 0.5)) #self.enableMouse() #camera.setPosHpr(-10, -50, 10, -10, -7, 0) #self.accept('mouse1', self.yesno_) base.buttonThrowers[0].node().setKeystrokeEvent('keystroke') self.accept('keystroke', self.myFunc) else: self.title.clearText() self.instructions.clearText() start.setPosHpr(5, -25, 18, 0, 90, 0) start.setColor(0, 1, 0) title2 = TextNode('congrats') title2.setText("Congratulations! Do it again?") global tNP2 tNP2 = aspect2d.attachNewNode(title2) tNP2.setScale(0.25) title2.setWordwrap(8) title2.setCardColor(0, 0, 0, 0) title2.setCardAsMargin(0, 0, 0, 0) title2.setCardDecal(True) tNP2.setPos(-1, 0, 0.5) self.instructions = \ OnscreenText(text="Press any key to restart", parent=base.a2dBottomRight, align=TextNode.ARight, pos=(-1, +0.08), fg=(1, 1, 1, 1), scale=.08, shadow=(0, 0, 0, 0.5)) base.buttonThrowers[0].node().setKeystrokeEvent('keystroke') self.accept('keystroke', self.myFunc) #self.no_ = \ #OnscreenText(text="No", # parent=base.a2dBottomRight, align=TextNode.ALeft, # pos=(0, 0.05), fg=(1, 1, 1, 1), scale=.35, # shadow=(0, 0, 0, 0.5)) #self.enableMouse() #camera.setPosHpr(-10, -50, 10, -10, -7, 0) #self.accept('mouse1', self.yesno_) def ballDown(self): pass def myFunc(self, x): os.execl(sys.executable, sys.executable, *sys.argv) #os.startfile(sys.argv[0]) #os.execl(sys.executable,'"%s"'%sys.argv[0]) #ShowBase.restart(False, None) #ShowBase.destroy() #ShowBase.__init__(self) def yesno_(self): pass def onclick(event): #ctypes.windll.user32.MessageBoxW(0, "hi", "title", 1) print("clicked", event.x, event.y)
class PinchTask(ShowBase, GripStateMachine): DATA_DIR = 'data' def __init__(self, id, session, hand, block, mode, wrist): ShowBase.__init__(self) GripStateMachine.__init__(self) base.disableMouse() wp = WindowProperties() wp.setSize(1920,1080) wp.setFullscreen(True) base.win.requestProperties(wp) self.sub_id = str(id) self.sess_id = str(session) self.hand = str(hand) self.block = str(block) self.mode = str(mode) self.wrist = str(wrist) self.prev_blk = os.path.join(self.DATA_DIR,'exp_1',self.sub_id,self.sess_id,self.wrist,self.hand,"B0") if self.wrist == 'pron': self.table = np.loadtxt('src/pinch_task/trialtable_pron.csv',dtype='str',delimiter=',',skiprows=1) elif self.wrist == 'flex': self.table = np.loadtxt('src/pinch_task/trialtable_flex.csv',dtype='str',delimiter=',',skiprows=1) else: raise NameError('Wrist position not found') try: self.prev_table = np.loadtxt(os.path.join(self.prev_blk, 'final_targets.csv'),dtype='str',delimiter=',',skiprows=1) indices = {} for i in range(self.prev_table.shape[0]): indices[self.prev_table[i,1]] = int(self.prev_table[i,0])-1 for i in range(self.table.shape[0]): self.table[i,11] = self.prev_table[indices[self.table[i,1].strip()],11] self.table[i,12] = self.prev_table[indices[self.table[i,1].strip()],12] self.table[i,13] = self.prev_table[indices[self.table[i,1].strip()],13] except: print('Previous target file not found') self.table = np.array([[item.strip() for item in s] for s in self.table]) ################################################## #only use rows relevant to this block #HARDCODED! NOTE IN LOG SHEET spec_table = [] for i in range(self.table.shape[0]): if int(self.block)%4 == 0: if "(p)" in self.table[i,2]: spec_table.append(self.table[i]) elif int(self.block)%4 == 1: if "(t)" in self.table[i,2]: spec_table.append(self.table[i]) elif int(self.block)%4 == 2: if "(s)" in self.table[i,2]: spec_table.append(self.table[i]) elif int(self.block)%4 == 3: if "(t+s)" in self.table[i,2]: spec_table.append(self.table[i]) ################################################### self.table = np.array(spec_table) self.session_dir = os.path.join(self.DATA_DIR,'exp_1',self.sub_id,self.sess_id,self.wrist,self.hand) self.subjinfo = self.sub_id + '_' + self.sess_id + '_' + self.hand + '_log.yml' self.p_x,self.p_y,self.p_a = GET_POS(self.session_dir,self.subjinfo,self.hand,self.wrist) self.rotmat = ROT_MAT(self.p_a,self.hand) self.setup_text() self.setup_lights() self.setup_camera() self.trial_counter = 0 self.load_models() self.load_audio() self.update_trial_command() self.countdown_timer = CountdownTimer() self.hold_timer = CountdownTimer() self.cTrav = CollisionTraverser() self.chandler = CollisionHandlerEvent() self.chandler.addInPattern('%fn-into-%in') self.chandler.addAgainPattern('%fn-again-%in') self.chandler.addOutPattern('%fn-outof-%in') self.attachcollnodes() taskMgr.add(self.read_data, 'read') for i in range(5): taskMgr.add(self.move_player, 'move%d' % i, extraArgs = [i], appendTask=True) taskMgr.add(self.log_data, 'log data') taskMgr.add(self.update_state, 'update_state', sort=1) self.accept('space', self.space_on) self.accept('escape', self.clean_up) self.space = False self.statenum = list() self.max_time = 20 self.med_data = None self.grip_dir = os.path.join(self.DATA_DIR,'exp_1',self.sub_id,self.sess_id,self.wrist,self.hand,"B"+self.block) if not os.path.exists(self.grip_dir): print('Making new folders: ' + self.grip_dir) os.makedirs(self.grip_dir) self.dev = MpDevice(RightHand(calibration_files=['calibs/cal_mat_15.mat', # thumb 'calibs/cal_mat_31.mat', 'calibs/cal_mat_8.mat', 'calibs/cal_mat_21.mat', 'calibs/cal_mat_13.mat'], clock=mono_clock.get_time)) self.init_ser() ############ #SET UP HUD# ############ def setup_text(self): #OnscreenImage(parent=self.cam2dp, image='models/background.jpg') self.bgtext = OnscreenText(text='Not recording.', pos=(-0.8, 0.8), scale=0.08, fg=(0, 0, 0, 1), bg=(1, 1, 1, 1), frame=(0.2, 0.2, 0.8, 1), align=TextNode.ACenter) self.bgtext.reparentTo(self.aspect2d) self.dirtext = OnscreenText( pos=(-0.6, 0.65), scale=0.08, fg=(0, 0, 0, 1), bg=(1, 1, 1, 1), frame=(0.2, 0.2, 0.8, 1), align=TextNode.ACenter) self.dirtext.reparentTo(self.aspect2d) ########################## #SET UP SCENE AND PLAYERS# ########################## def setup_lights(self): pl = PointLight('pl') pl.setColor((1, 1, 1, 1)) plNP = self.render.attachNewNode(pl) plNP.setPos(-10, -10, 10) self.render.setLight(plNP) pos = [[[0, 0, 50], [0, 0, -10]], [[0, -50, 0], [0, 10, 0]], [[-50, 0, 0], [10, 0, 0]]] for i in pos: dl = Spotlight('dl') dl.setColor((1, 1, 1, 1)) dlNP = self.render.attachNewNode(dl) dlNP.setPos(*i[0]) dlNP.lookAt(*i[1]) dlNP.node().setShadowCaster(False) self.render.setLight(dlNP) def setup_camera(self): self.cam.setPos(0, -4, 12) self.cam.lookAt(0, 2, 0) self.camLens.setFov(90) def load_models(self): self.back_model = self.loader.loadModel('models/back') self.back_model.setScale(10, 10, 10) if self.hand == "Left": self.back_model.setH(90) self.back_model.reparentTo(self.render) self.player_offsets = [[self.p_x[0]-5, self.p_y[0]+3, 0], [self.p_x[1]-2.5, self.p_y[1]+4.5, 0], [self.p_x[2], self.p_y[2]+5, 0], [self.p_x[3]+2.5, self.p_y[3]+4.5, 0], [self.p_x[4]+5, self.p_y[4]+3, 0]] self.p_col =[[0,0,250],[50,0,200],[125,0,125],[200,0,50],[250,0,0]] if self.hand == 'Left': self.p_col = self.p_col[::-1] self.players = list() self.contacts = list() for counter, value in enumerate(self.player_offsets): self.players.append(self.loader.loadModel('models/target')) self.contacts.append(False) self.players[counter].setPos(*value) self.players[counter].setScale(0.2, 0.2, 0.2) self.players[counter].setColorScale( self.p_col[counter][0]/255, self.p_col[counter][1]/255, self.p_col[counter][2]/255, 1) self.players[counter].reparentTo(self.render) self.players[counter].show() self.target_select() def load_audio(self): self.pop = self.loader.loadSfx('audio/Blop.wav') self.buzz = self.loader.loadSfx('audio/Buzzer.wav') ############################ #SET UP COLLISION MECHANICS# ############################ def attachcollnodes(self): for i in range(5): self.fromObject = self.players[i].attachNewNode(CollisionNode('colfromNode'+str(i))) self.fromObject.node().addSolid(CollisionSphere(0,0,0,1)) self.cTrav.addCollider(self.fromObject, self.chandler) for i in range(5): self.accept('colfromNode%d-into-colintoNode' % i, self.collide1,[i]) self.accept('colfromNode%d-again-colintoNode' % i, self.collide2,[i]) self.accept('colfromNode%d-outof-colintoNode' % i, self.collide3,[i]) def collide1(self,f,collEntry): if f in self.highlighted_indices: self.players[f].setColorScale(0,1,0,0) self.tar.setColorScale(0.2,0.2,0.2,1) self.tar.setAlphaScale(0.7) self.contacts[f] = True taskMgr.doMethodLater(self.delay,self.too_long,'too_long%d' % f,extraArgs = [f]) self.sendsig(1,f,100) def collide2(self,f,collEntry): if f in self.highlighted_indices: dist = np.sqrt(self.distances[f][1]^2+self.distances[f][2]^2+self.distances[f][3]^2) self.sendsig(2,f,int(10/dist)+100) for i in self.highlighted_indices: if self.contacts[i] == False: return taskMgr.remove('too_long%d' % f) def collide3(self,f,collEntry): taskMgr.remove('too_long%d' % f) self.reset_fing(f) self.tar.setColorScale(0.1,0.1,0.1,1) self.tar.setAlphaScale(0.7) def too_long(self,f): self.reset_fing(f) self.tar.setColorScale(0.5,0.2,0.2,1) self.tar.setAlphaScale(0.7) def reset_fing(self,f): self.players[f].setColorScale( self.p_col[f][0]/255, self.p_col[f][1]/255, self.p_col[f][2]/255, 1) self.contacts[f] = False self.sendsig(3,f,0) ############### #TARGET THINGS# ############### def show_target(self): self.target_select() self.intoObject = self.tar.attachNewNode(CollisionNode('colintoNode')) if self.table[self.trial_counter,7] == "sphere": self.intoObject.node().addSolid(CollisionSphere(0,0,0,1)) elif self.table[self.trial_counter,7] == "cylinder": self.intoObject.node().addSolid(CollisionTube(0,0,-2,0,0,2,1)) else: raise NameError("No such collision type") self.tar.show() #hide players not related to target for i in range(5): if i not in self.highlighted_indices: self.players[i].hide() def target_select(self): self.tgtscx=float(self.table[self.trial_counter,14]) self.tgtscy=float(self.table[self.trial_counter,15]) self.tgtscz=float(self.table[self.trial_counter,16]) tgttsx=float(self.table[self.trial_counter,11]) tgttsy=float(self.table[self.trial_counter,12]) tgttsz=float(self.table[self.trial_counter,13]) tgtrx=float(self.table[self.trial_counter,17]) tgtry=float(self.table[self.trial_counter,18]) tgtrz=float(self.table[self.trial_counter,19]) if self.hand == 'Left': tgttsx *= -1 tgtrx *= -1 self.static_task = (str(self.table[self.trial_counter,5]) == "True") self.target_model = str(self.table[self.trial_counter,6]) self.highlighted_indices=[int(s)-1 for s in self.table[self.trial_counter,4].split(' ')] if self.hand == 'Left': self.highlighted_indices=[4-i for i in self.highlighted_indices] #NOTE:this position finding is present in all three tasks # it is somewhat hacky and can be improved upon self.tgtposx = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][[-2,-1],0]) + tgttsx self.tgtposy = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][[0,1],1]) + tgttsy if len(self.highlighted_indices) > 3: #for sphere, return to just average of all fingers self.tgtposx = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][:,0]) + tgttsx #self.tgtposy = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][:,1]) self.tgtposz = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][:,2]) + tgttsz self.tar = self.loader.loadModel(self.target_model) self.tar.setScale(self.tgtscx,self.tgtscy,self.tgtscz) self.tar.setPos(self.tgtposx,self.tgtposy,self.tgtposz) self.tar.setHpr(tgtrx,tgtry,tgtrz) self.tar.setColorScale(0.1, 0.1, 0.1, 1) self.tar.setAlphaScale(0.7) self.tar.setTransparency(TransparencyAttrib.MAlpha) self.tar.reparentTo(self.render) self.tar.hide() self.delay=float(self.table[self.trial_counter,8]) self.loc_angle=math.radians(float(self.table[self.trial_counter,9])) self.invf=float(self.table[self.trial_counter,10]) self.distances = [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]] ############## #MOVE FINGERS# ############## def read_data(self,task): error, data = self.dev.read() if data is not None: data *= 0.001 self.ts = data.time data = np.dot(data,self.rotmat) self.data = data if self.med_data is None: self.med_data = np.median(data, axis=0) if self.space: self.statenum.extend(([self.checkstate()])*len(data.time)) return task.cont def move_player(self,p,task): if self.data is not None : k = p*3 new_x = 10*np.mean(self.data[-1,k]) + self.player_offsets[p][0] - 10*self.med_data[k] new_y = 10*np.mean(self.data[-1,k + 1]) + self.player_offsets[p][1] - 10*self.med_data[k + 1] new_z = 10*np.mean(self.data[-1,k + 2]) + self.player_offsets[p][2] - 10*self.med_data[k + 2] #make sure digits do not cross each other if ((p in range(1,3) and p+1 in self.highlighted_indices and new_x > self.players[p+1].getX()) or (p in range(2,4) and p-1 in self.highlighted_indices and new_x < self.players[p-1].getX())): new_x = self.players[p].getX() #make sure digits do not cross into target if self.space == True and p in self.highlighted_indices: self.distances[p][0] = new_x - self.tar.getX() self.distances[p][1] = new_y - self.tar.getY() self.distances[p][2] = new_z - self.tar.getZ() self.check_pos(p) self.players[p].setPos(new_x, new_y, new_z) return task.cont def check_pos(self,p): if (abs(self.distances[p][0]) < self.invf*self.tgtscx and abs(self.distances[p][1]) < self.invf*self.tgtscy and abs(self.distances[p][2]) < self.invf*self.tgtscz): self.too_long(p) ################## #CHECK COMPLETION# ################## def close_to_target(self): for i in self.highlighted_indices: if self.contacts[i] == False: return False if not self.check_angle(): self.tar.setColorScale(0.1,0.1,0.1,1) self.tar.setAlphaScale(0.7) return False self.tar.setColorScale(0,1,1,1) return True def check_hold(self): if not self.close_to_target(): self.hold_timer.reset(0.5) return False return self.hold_timer.elapsed() < 0 def check_angle(self): #hardcoded condition may be able to be assimilated into old angle method somehow if self.table[self.trial_counter,1] == 'pts': vec = np.subtract(self.players[self.highlighted_indices[1]].getPos(), self.players[self.highlighted_indices[0]].getPos()) xvec = [1,0,0] if self.hand == 'Left': xvec = [-1,0,0] print(math.degrees(math.acos(np.dot(vec,xvec)/(np.linalg.norm(vec)*np.linalg.norm(xvec))))) if math.acos(np.dot(vec,xvec)/(np.linalg.norm(vec)*np.linalg.norm(xvec))) < self.loc_angle: return True else: return False thumbindx = 0 if self.hand == "Left": thumbindx = 4 for i in self.highlighted_indices: if i == thumbindx: continue th = self.distances[thumbindx] fg = self.distances[i] if math.acos(np.dot(th,fg)/(np.linalg.norm(th)*np.linalg.norm(fg))) > self.loc_angle: return True return False def adjust_targets(self): #no adjustment if more than 2 fingers or position is prone if len(self.highlighted_indices) > 2 or self.wrist == 'pron': return xadj,yadj,zadj = np.mean(np.asarray(self.distances)[self.highlighted_indices],0) #yadj = np.mean(np.asarray(self.distances)[self.highlighted_indices][1]) #zadj = np.mean(np.asarray(self.distances)[self.highlighted_indices][2]) #do adjustment on all tasks with same name if self.hand == 'Left': xadj = -xadj for i in range(self.trial_counter+1,self.table.shape[0]): if self.table[i,1] == self.table[self.trial_counter,1]: self.table[i,11] = float(self.table[i,11]) + xadj self.table[i,12] = float(self.table[i,12]) + yadj self.table[i,13] = float(self.table[i,13]) + zadj ######### #LOGGING# ######### def play_success(self): if int(self.block) == 0: self.adjust_targets() self.pop.play() self.tar.hide() self.highlighted_indices = [0,1,2,3,4] def log_text(self): self.bgtext.setText('Now logging...') def log_data(self, task): if (self.trial_counter + 1) <= self.table.shape[0]: if self.space: self.log_file_name = os.path.join(self.grip_dir, self.sub_id+"_"+self.sess_id+"_"+self.hand+"_"+ str(self.table[self.trial_counter,1])+"_"+str(self.table[self.trial_counter,0])+".csv" ) self.movvars = np.column_stack((self.ts, self.statenum, self.data)) self.statenum = [] if self.mode=='task': with open(self.log_file_name, 'ab') as f: np.savetxt(f, self.movvars, fmt='%10.5f', delimiter=',') return task.cont else: pass def stoplog_text(self): self.dirtext.clearText() self.bgtext.setText('Done logging!') for i in range(5): self.players[i].show() ####### #RESET# ####### def delete_file(self): if (self.trial_counter + 1) <= self.table.shape[0]: self.log_file_name = os.path.join(self.grip_dir, self.sub_id+"_"+self.sess_id+"_"+self.hand+"_"+ str(self.table[self.trial_counter,1])+"_"+str(self.table[self.trial_counter,0])+".csv" ) try: os.remove(self.log_file_name) except OSError: pass else: pass def reset_baseline(self): self.med_data = None def reset_keyboard_bool(self): self.space = False def hide_target(self): self.tar.hide() self.intoObject.removeNode() self.imageObject.destroy() def update_trial_command(self): self.dirtext.setText(str(self.table[self.trial_counter,2])) if self.hand == 'Left': xfac = -0.25 else: xfac = 0.25 self.imageObject = OnscreenImage(image = str(self.table[self.trial_counter,3]),scale=(xfac,0.25,0.25),pos=(-1.2, 0, 0.3)) def increment_trial_counter(self): self.trial_counter += 1 self.update_trial_command() ######## #TIMERS# ######## def start_trial_countdown(self): self.countdown_timer.reset(self.max_time) def start_hold_countdown(self): self.hold_timer.reset(0.5) def start_post_countdown(self): self.countdown_timer.reset(2) def time_elapsed(self): return self.countdown_timer.elapsed() < 0 ######### #MACHINE# ######### def update_state(self, task): self.step() return task.cont def wait_for_space(self): return self.space def space_on(self): self.space = True ##### #END# ##### def trial_counter_exceeded(self): return (self.trial_counter+1) > self.table.shape[0]-1 def clean_up(self): #write last known positions to 'final_targets' file f = open('src/pinch_task/trialtable_flex.csv') header = f.readline().rstrip() np.savetxt(self.grip_dir + '/final_targets.csv',self.table,fmt='%s',header = header, delimiter=',') f.close() sys.exit() ######## #SERIAL# ######## def init_ser(self): #CONNECT TO HAPTIC DEVICE ports = list_ports.comports() mydev = next((p.device for p in ports if p.pid == 1155)) self.ser = serial.Serial(mydev,9600,timeout=.1) def sendsig(self,signal,finger,intensity): #would read from table, but table not available yet if intensity > 255: intensity = 255 dur_int = [signal,finger,intensity] data = struct.pack('3B',*dur_int) self.ser.write(data)
class SpaceFlight(ShowBase): def __init__(self): ShowBase.__init__(self) self.text = OnscreenText \ ( parent = base.a2dBottomCenter, align=TextNode.ARight, fg=(1, 1, 1, 1), pos=(0.2, 1.), scale=0.1, shadow=(0, 0, 0, 0.5) ) self.setBackgroundColor(0, 0, 0) self.disableMouse() self.fog = Fog('distanceFog') self.fog.setColor(0, 0, 0) self.fog.setExpDensity(.002) # self.queue = CollisionHandlerQueue() self.trav = CollisionTraverser('traverser') base.cTrav = self.trav self.loadSky() self.reloadGame() self.keyMap = {'left' : 0, 'right' : 0, 'up' : 0, 'down' : 0} self.gamePause = False # self.accept('escape', sys.exit) self.accept('p', self.pause) self.accept('r', self.reloadGame) self.accept('arrow_left', self.setKey, ['left', True]) self.accept('arrow_right', self.setKey, ['right', True]) self.accept('arrow_up', self.setKey, ['up', True]) self.accept('arrow_down', self.setKey, ['down', True]) self.accept('arrow_left-up', self.setKey, ['left', False]) self.accept('arrow_right-up', self.setKey, ['right', False]) self.accept('arrow_up-up', self.setKey, ['up', False]) self.accept('arrow_down-up', self.setKey, ['down', False]) # taskMgr.add(self.moveShip, 'moveShip') taskMgr.add(self.moveAsteroids, 'moveAsteroids') taskMgr.add(self.handleCollisions, 'handleCollisions') # if DEBUG: self.trav.showCollisions(render) render.find('**/ship_collision').show() for asteroid in render.findAllMatches('**/asteroid_collision*'): asteroid.show() def loadSky(self): self.sky = loader.loadModel('models/solar_sky_sphere.egg.pz') self.sky_tex = loader.loadTexture('models/stars_1k_tex.jpg') self.sky.setTexture(self.sky_tex, 1) self.sky.reparentTo(render) self.sky.setScale(500) def loadShip(self): self.ship = loader.loadModel('models/alice-scifi--fighter/fighter.egg') self.ship.reparentTo(render) self.ship.setPos(START_X, START_Y, START_Z) self.ship.setScale(0.25) # add some physics ship_col = self.ship.attachNewNode(CollisionNode('ship_collision')) col_sphere = CollisionSphere(START_X, START_Y, 0, SHIP_SPHERE_RADIUS) ship_col.node().addSolid(col_sphere) self.trav.addCollider(ship_col, self.queue) def spawnAsteroid(self): asteroid = loader.loadModel(choice(ASTEROID_SHAPES)) asteroid_tex = loader.loadTexture('models/rock03.jpg') asteroid.setTexture(asteroid_tex, 1) asteroid.reparentTo(render) asteroid.setFog(self.fog) self.asteroids.append(asteroid) self.asteroids_rotation.append(randint(ASTEROID_ROTATE_MIN, ASTEROID_ROTATE_MAX)) # num = len(self.asteroids) - 1 asteroid_col = asteroid.attachNewNode(CollisionNode('asteroid_collision_%d' % num)) col_sphere = CollisionSphere(0, 0, 0, ASTEROID_SPHERE_RADIUS) asteroid_col.node().addSolid(col_sphere) # asteroid.setX(randint(MIN_X, MAX_X)) asteroid.setY(randint(ASTEROID_SPAWN_MIN_Y, ASTEROID_SPAWN_MAX_Y)) asteroid.setZ(randint(MIN_Z, MAX_Z)) def setKey(self, key, value): self.keyMap[key] = value if key in ['left', 'right'] and value == False: self.ship.setH(0) if key in ['up', 'down'] and value == False: self.ship.setP(0) def updateCamera(self): x, y, z = self.ship.getPos() self.camera.setPos(x, y - 40, z + 25) self.camera.lookAt(x, y, z + 10) def moveAsteroids(self, task): dt = globalClock.getDt() if not self.gamePause: for num, asteroid in enumerate(self.asteroids): asteroid.setY(asteroid.getY() - ASTEROID_SPEED * dt) rotation = self.asteroids_rotation[num] asteroid.setH(asteroid.getH() - rotation * ASTEROID_SPEED * dt) if asteroid.getY() < self.camera.getY() + 10: asteroid.setX(randint(MIN_X, MAX_X)) asteroid.setY(randint(ASTEROID_SPAWN_MIN_Y, ASTEROID_SPAWN_MAX_Y)) asteroid.setZ(randint(MIN_Z, MAX_Z)) return task.cont def rollbackOnBoard(self, minPos, maxPos, getFunc, setFunc): if getFunc() < minPos: setFunc(minPos) if getFunc() > maxPos: setFunc(maxPos) def applyBound(self): self.rollbackOnBoard(MIN_X, MAX_X, self.ship.getX, self.ship.setX) self.rollbackOnBoard(MIN_Z, MAX_Z, self.ship.getZ, self.ship.setZ) def moveShip(self, task): dt = globalClock.getDt() if not self.gamePause: if self.keyMap['left']: self.ship.setX(self.ship.getX() - SHIP_SPEED * dt) self.ship.setH(TURN_SPEED) elif self.keyMap['right']: self.ship.setX(self.ship.getX() + SHIP_SPEED * dt) self.ship.setH(-TURN_SPEED) elif self.keyMap['up']: self.ship.setZ(self.ship.getZ() + SHIP_SPEED * dt) self.ship.setP(TURN_SPEED) elif self.keyMap['down']: self.ship.setZ(self.ship.getZ() - 5 * SHIP_SPEED * dt) self.ship.setP(-TURN_SPEED) self.sky.setP(self.sky.getP() - dt * 10) self.applyBound() self.updateCamera() return task.cont def handleCollisions(self, task): if not self.gamePause: for entry in self.queue.getEntries(): node = entry.getFromNodePath() if node.getName() == 'ship_collision': self.gamePause = True self.text.setText('You lose :(') return task.cont def pause(self): self.gamePause = not self.gamePause def reloadGame(self): self.gamePause = False self.text.clearText() if hasattr(self, 'asteroids'): for asteroid in self.asteroids: asteroid.removeNode() self.asteroids = [] self.asteroids_rotation = [] if hasattr(self, 'ship'): self.ship.removeNode() self.loadShip() for _ in xrange(ASTEROID_MAX_CNT): self.spawnAsteroid()
class WorldBase(DirectObject): """ Basic 3D world with logging and 2D display """ def __init__(self, controller, mem_logger, display_categories): self.display_categories = display_categories self.labels = OnscreenText( "", style = 1, fg = ( 1, 1, 1, 1 ), pos = ( -1.0, 0.9 ), scale = .05 ) self.txt = OnscreenText( "", style = 1, fg = ( 1, 1, 1, 1 ), pos = ( -0.5, 0.9 ), scale = .05 ) taskMgr.add( self.loop, "loop" ) self.enable_screen_updates = True self.log = KeplerLogger(mem_logger) self.logging = False self.accept("p", self.key_p) self.accept( "escape", self.quit ) self.accept("arrow_up", self.key_up) self.accept("arrow_down", self.key_down) self.accept("arrow_left", self.key_left) self.accept("arrow_right", self.key_right) self.accept("l", self.key_l) self.accept("s", self.key_s) self.accept("a", self.key_a) self.accept("f", self.key_f) self.accept("g", self.key_g) self.accept("d", self.key_d) self.accept("o", self.log_start_stop) self.accept("q", self.key_q) self.accept("w", self.key_w) self.accept("z", self.key_z) self.accept("x", self.key_x) self.accept("c", self.key_c) self.accept("v", self.key_v) self.accept("b", self.key_b) self.accept("n", self.key_n) self.controller = controller base.setFrameRateMeter(True) #self.txt = OnscreenText( "Nothing", style = 1, fg = ( 1, 1, 1, 1 ), shadow = ( .9, .9, .9, .5 ), pos = ( -1.0, 0.9 ), scale = .07 ) # task to be called every frame self.step = 0 self.last_time = time.time() self.text_refresh_band = 10 self.text_refresh_count = self.text_refresh_band self._set_title("Keplermatic") self.init_gui() def init_gui(self): x = -0.9 y = 0.7 inc_y = -0.1 cb = CallBack("Logging", self.display_categories, self) self.add_gui_checkbox("Logging", False, x, y, cb.callback) y += inc_y cb = CallBack("Update", self.display_categories,self) self.add_gui_checkbox("Update", True, x, y, cb.callback) y += inc_y y += inc_y keys = self.display_categories.keys() keys.sort() for k in keys: if k in ["axis1","axis2"]: cb = CallBack(k, self.display_categories,self) category_name = k enabled = self.display_categories[category_name] self.add_gui_checkbox(category_name, enabled, x, y, cb.callback) y += inc_y y += inc_y y += inc_y for k in keys: if k not in ["axis1","axis2"]: cb = CallBack(k, self.display_categories,self) category_name = k enabled = self.display_categories[category_name] self.add_gui_checkbox(category_name, enabled, x, y, cb.callback) y += inc_y def _set_title(self, title): from pandac.PandaModules import ConfigVariableString mygameserver = ConfigVariableString("window-title","Panda") mygameserver.setValue(title) def loop(self, task): #self.last_time = time.time() delta_time = task.time - self.last_time # avoid division by 0 if delta_time < 0.0001: delta_time = 0.0001 self.last_time = task.time self.step += 1 txt = "" self._refresh_text(txt) self.controller.loop(self.step, task.time, delta_time) if self.logging: data = self.controller.get_display_data() self.log.snapshot(get_data_logger(), self.step, task.time, data, ('self')) return Task.cont def _refresh_text(self, txt): if not self.enable_screen_updates: return self.text_refresh_count -=1 if self.text_refresh_count <0: self.text_refresh_count = self.text_refresh_band data = self.controller.get_display_data() st = str(self.last_time) data['Time'] = (st, "sim", 0) data['step'] = (self.step, "sim", 0) self.txt.clearText() self.txt.setAlign(TextNode.ALeft) keys = data.keys() keys.sort() txt += "logging: %s\n" % self.logging #print keys show_axis1 = self.display_categories['axis1'] show_axis2 = self.display_categories['axis2'] for name in keys: if name == 'self': continue display_data = data[name] #print display_data value, category, axis = display_data if category not in self.display_categories.keys(): category = "other" show_category = self.display_categories[category] show_it = show_category if not show_it: #print " %s hidden (category %s hidden)" % (name, category) pass if axis == 1: if show_axis1 == False: #print " %s hidden (axis 1)" % name show_it = False if axis == 2: if show_axis2 == False: #print " %s hidden (axis 2)" % name show_it = False if show_it: #print "**** name %s, cat %s [%s], axis %s, value %s show1 %s, show2 %s" %(name, category, show_it, axis, value, show_axis1, show_axis2) value_str = "%s" % value if type(value) == type(0.): # float value_str = "%.10f" % value txt += "%s: %s\n" % (name, value_str) else: pass #print "XXXX name %s, cat %s [%s], axis %s, value %s show1 %s, show2 %s" %(name, category, show_it, axis, value, show_axis1, show_axis2) self.txt.appendText(txt) def add_gui_checkbox(self, text, value, x, y, callback): b = DirectCheckButton(text = text ,scale=.05, pos=(x,0,y), command=callback) b["indicatorValue"] = value return b def quit(self): self.controller.stop() if len(self.log.data) >0: self.log.dump(get_data_logger()) sys.exit() def log_start_stop(self): if self.logging: # stopping self.controller.stop() self.log.dump(get_data_logger()) self.log.data = [] self.logging = not self.logging print "Logging %s" % self.logging def key_p(self): self.enable_screen_updates = not self.enable_screen_updates print "enable_screen_updates=", self.enable_screen_updates def key_right(self): self.controller.key_right() def key_left(self): self.controller.key_left() def key_l(self): self.controller.key_l() def key_s(self): self.controller.key_s() def key_a(self): self.controller.key_a() def key_f(self): self.controller.key_f() def key_g(self): self.controller.key_g() def key_d(self): self.controller.key_d() def key_up(self): self.controller.key_up() def key_down(self): self.controller.key_down() def key_q(self): self.controller.key_q() def key_w(self): self.controller.key_w() def key_z(self): self.controller.key_z() def key_x(self): self.controller.key_x() def key_c(self): self.controller.key_c() def key_v(self): self.controller.key_v() def key_b(self): self.controller.key_b() def key_n(self): self.controller.key_n()
class HLevel(): def __init__(self, showbase, physicsDebug=True): """ :type self.Base: direct.showbase.ShowBase.ShowBase :type showbase: direct.showbase.ShowBase.ShowBase :type physicsDebug: bool """ print "Creating level" self.Base = showbase self.debugDrawing = physicsDebug self.pause = False self.bulletSubstep = 0.008 self.activeLog = False def loadAssets(self): print "Loading Assets" def renderAssets(self): print "Rendering assets" def setCamera(self): print "Setting camera" def setLights(self): print "Setting lights" def destroy(self): print "Destroying level" def loadEgg(self, egg): """ :type egg: str :rtype : panda3d.core.NodePath """ return self.Base.loader.loadModel(egg) def renderModel(self, model): """ :type model: str """ model.reparentTo(self.Base.render) def renderEgg(self, egg): """ :type egg: str :return pada3d.core.NodePath """ m = self.loadEgg(egg) self.renderModel(m) return m def setPhysics(self): print "Setting physics" self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -10)) self.Base.taskMgr.add(self.physicsUpdate, "physicsUpdate", priority=0) if self.debugDrawing: print "Debug drawing" self.debug = BulletDebugNode("debug") self.debug.showWireframe(True) self.debug.showBoundingBoxes(False) self.debug.showNormals(True) self.debugNP = self.Base.render.attachNewNode(self.debug) self.debugNP.show() self.world.setDebugNode(self.debug) def physicsUpdate(self, task): if not self.pause: dt = globalClock.getDt() self.world.doPhysics(dt, 2, self.bulletSubstep) # #0.009-0.008 # print "Physics step" return task.cont def cameraShake(self, amplitud=0.01, frecuencia=5): """ :type amplitud: float :type frecuencia: float """ self.Base.camera.setZ( self.Base.camera, sin(globalClock.getRealTime() * frecuencia) * amplitud) def eggToStatic(self, egg, parent, margin=0.01, name="static"): """ :type egg: str :type parent: panda3d.core.NodePath :type margin: float :type name: str :return: tuple(pada3d.bullet.BulletRigidBodyNode,panda3d.core.NodePath) """ m = self.Base.loader.loadModel(egg) sTuple = modelToShape(m) sTuple[0].setMargin(margin) static = BulletRigidBodyNode(name) # H static.addShape(sTuple[0], sTuple[1]) np = parent.attachNewNode(egg) self.world.attachRigidBody(static) return static, np def togglePause(self): """ """ if self.pause: self.pause = False else: self.pause = True print "Toggle pause", self.pause def activateLog(self): self.activeLog = True self.logText = OnscreenText("NO LOG", scale=0.07, fg=(1, 0, 0, 0.8), bg=(0, 0, 1, 0.2), frame=(0, 1, 0, 0.2), pos=(-1.05, .9), mayChange=True, align=0) self.__logTextLenght = 0 self.__logAbsoluteLenght = 0 self.__logText = "" self.logText.reparentTo(self.Base.aspect2d) def log(self, *args): if self.activeLog is False: return None s = str(self.__logAbsoluteLenght) + ":" for a in args: s += str(a) + " " if self.__logTextLenght < 10: self.logText.appendText("\n" + s) else: self.__logTextLenght = 0 self.logText.clearText() self.logText.setText(s) self.__logTextLenght += 1 self.__logAbsoluteLenght += 1 self.__logText.join(s) def loadFont(self, string): return self.Base.loader.loadFont(string) def drawLine(self, fromP, toP, thickness=2, color=(1, 0, 0, 1), autoClear=True): if autoClear: try: self.debugLineNP.removeNode() except: pass self.debugLine = LineSegs("DebugLine") self.debugLine.reset() self.debugLine.setThickness(thickness) self.debugLine.setColor(color) self.debugLine.moveTo(fromP) self.debugLine.drawTo(toP) self.debugLineNode = self.debugLine.create() self.debugLineNP = NodePath(self.debugLineNode) self.debugLineNP.reparentTo(self.Base.render) return self.debugLineNP
class MyApp(ShowBase): def __init__(self, fStartDirect=True): #ConfigVariableBool("fullscreen",0).setValue(1) ShowBase.__init__(self) self.loadInitialCamPos()#initialize camera positioning self.assocs=dict() self.loadBooleans() self.loadLists() self.shuffleCards() self.loadValues() #creates a random sequence of cards we will memorize self.setInputs() #set up keyboard and mouse inputs self.setUpCollision() #sets up collision detection self.setUpScene() #sets up geometry in the 3D Enviroments self.loadSFX() self.light=self.setUpPointLight() taskMgr.add(self.setUpChest, 'setUpChest') #sets up rotating graphic of chest def loadValues(self): self.counter,self.lightCounter,self.fade,self.numFireflies=0,0,0,15 self.numCards=13 self.numCardsCopy=copy.copy(self.numCards) self.shuffledCardFacesCopy=copy.copy(self.shuffledCardFaces) def loadLists(self): self.cardsPos,self.imageList,self.visitedItems=[],[],[] self.buttonList,self.lastCoord,self.fireFlyList=[],[],[] self.previousCard,self.nextCard=[],[] def loadBooleans(self): self.toggleChest=False self.fadeToggle=False self.togglePreviousCard=False self.toggleNextCard=False self.toggleBar=True self.titleText=None self.userLocation=None def loadInitialCamPos(self): #we disable our mouse because we be using a different method #that will set up our mouse controls base.disableMouse() self.camPosx,self.camPosz=15,28 self.camera.setH(90) self.camera.setP(-25) self.heading=0 base.camera.setPos(self.camPosx,0,self.camPosz) def loadSFX(self): self.soundSteps = loader.loadMusic("footsteps.wav") #circus in the Sky is a piece written by Uzman Riaz (credit) #self.circusInTheSky=loader.loadMusic("circusInTheSky.wav") def setUpCollision(self): #pusher and queue are handlers from when a collision occurs self.cTrav = CollisionTraverser() self.queue = CollisionHandlerQueue() self.pusher = CollisionHandlerPusher() #set up scene geometrys self.setUpCollisionRay() self.setUpCollisionNode() def setUpPointLight(self): taskMgr.doMethodLater(.1, self.createTitleText, 'textFadeInOut') #we create multiple point lights to make it appear as if there are #'firefly' entities within the chest for n in xrange(self.numFireflies): self.generateLights("%fFirefly"%n) #sets up a soft ambient light so that our 3D enviroment appears #more realistic self.alight = AmbientLight('ambientLight') self.alight.setColor(VBase4(.6, .6, .6, 1)) alnp = render.attachNewNode(self.alight) render.setLight(alnp) self.treasureChest.setLight(alnp) def createTitleText(self,task): #task allows up to fade text in and out self.updateFade() if self.titleText!=None: self.titleText.remove() self.titleText=OnscreenText(text="[Click on the chest to begin]", style=Plain,pos=(0,0),fg=(1,1,1,self.fade)) if self.toggleChest==True: self.titleText.remove() return task.done return task.again def generateLights(self,name): #generate pointlights and reparenting them to the chest name=PointLight("Light") name=render.attachNewNode(name) name.setPos(0,0,22) name.hide() self.modelLight = loader.loadModel("misc/Pointlight.egg.pz") self.modelLight.reparentTo(name) self.treasureChest.setLight(name) self.fireFlyList.append(name) def setUpChest(self,task): if self.toggleChest==True: #chest rotates backwards if clicked on self.speed=-1.5 else: self.speed=.5 #chest rotates forward slowly self.lightCounter+=1 angle,radius= radians(self.heading),1.2 x,y,z =(cos(angle)*radius,sin(angle)*radius,sin(angle)*radius) self.heading+=self.speed self.heading%=360 self.treasureChest.setH(self.heading) if self.lightCounter%7==0: for n in xrange(self.numFireflies): self.generateFireFlies(x,y,n) if abs(self.treasureChest.getH()-360)<2 and self.toggleChest==True: #if chest is activated and the chest if facing the camera taskMgr.add(self.moveChest, 'moveChest') return task.done else: return Task.cont def moveChest(self,task): #units are calculated so that camera and chest move simultaneously #to create smooth transition between frames self.alight.setColor(VBase4(.8, .8, .8, 1)) self.shiftChestUnits,self.intervals=.1,52.0 x,y,z=self.treasureChest.getPos() newx=x+self.shiftChestUnits self.treasureChest.setPos(newx,y,z) self.moveCamera() if int(x)==self.camPosx-10: #if we get within a range of acceptable values # we set up our homepage self.homePage() return task.done else: return task.cont def moveCamera(self): self.originalZ,self.targetZ=28.0,22.0 self.shiftCameraZ=(self.originalZ-self.targetZ)/self.intervals self.pitchChange=25.0/self.intervals newPitch=self.camera.getP()+self.pitchChange newHeight=self.camera.getPos()[2]-self.shiftCameraZ camerax,cameray=self.camera.getPos()[0],self.camera.getPos()[1] self.camera.setPos(camerax,cameray,newHeight) self.camera.setP(newPitch) def generateFireFlies(self,x,y,n): zLowerLimit=21.0 zHigherLimit=22.0 light=self.fireFlyList[n] self.xFirefly=random.uniform(-x,x) self.yFirefly=random.uniform(-y,y) self.zFirefly=random.uniform(zLowerLimit,zHigherLimit) light.setPos(self.xFirefly,self.yFirefly,self.zFirefly) def setUpFog(self): self.fogDensity=.03 myFog = Fog("fog") myFog.setColor(1,1,1) myFog.setExpDensity(self.fogDensity) render.setFog(myFog) def displayHelpPanel(self): self.dummyNode1=self.createDummyNode("self.dummyNode1") self.dummyNode2=self.createDummyNode("self.dummyNode2") self.dummyNode3=self.createDummyNode("self.dummyNode3") self.floorPlan=OnscreenImage( image="floorplan.png", scale=(.4,.25,.55), pos=(.7,0,.3)) self.floorPlan.setTransparency(TransparencyAttrib.MAlpha) self.floorPlan.reparentTo(self.dummyNode1) self.displayToggleBar() self.displayAdjacencies() taskMgr.doMethodLater(.1, self.createSubTitle, 'textFadeInOut') def createSubTitle(self,task): self.previousTitlePos=(-1.205,.89) self.nextTitlePos=(-1.195,-.43) try: self.titlePrevious.destroy() self.titlePrevious=OnscreenText( text="[Previous]",pos=self.previousTitlePos, scale=.045,fg=(1,1,1,self.fade)) except: self.titlePrevious=OnscreenText( text="[Previous]",pos=self.previousTitlePos, scale=.045,fg=(1,1,1,self.fade)) try : self.titleNext.destroy() self.titleNext=OnscreenText( text="[Next]",pos=self.nextTitlePos,scale=.045,fg=(1,1,1,self.fade)) except: self.titleNext=OnscreenText( text="[Next]",pos=self.nextTitlePos, scale=.045,fg=(1,1,1,self.fade)) return task.again def createDummyNode(self,name): name=render.attachNewNode("2d") name.reparentTo(aspect2d) return name def displayToggleBar(self): self.toggleBarImage=DirectButton( image = "hidebar.png",scale=(.07,0.1,.55),pos=(1.17,0,.3), relief=None,command=lambda: self.switchDisplays( self.toggleBar,self.dummyNode1,self.toggleBarImage, "hidebar.png","showbar.png", (.07,0.1,.55),(1.17,0,.3))) self.togglePreviousBar() self.toggleNextBar() def togglePreviousBar(self): self.previousBarPos=(-1.2,0,.57) self.togglePreviousBarImage=(DirectButton( image = "hidebarshort.png", scale=(.07,0.1,.195),pos=self.previousBarPos,relief=None, command= lambda: self.switchDisplays( self.togglePreviousCard, self.dummyNode2,self.togglePreviousBarImage, "hidebarshort.png","showbarshort.png", (.07,0.1,.195),self.previousBarPos))) def toggleNextBar(self): self.nextBarPos=(-1.2,0,-.7) self.toggleNextBarImage=(DirectButton( image = "hidebarshort.png", scale=(.07,0.1,.195),pos=self.nextBarPos,relief=None, command= lambda: self.switchDisplays( self.toggleNextCard,self.dummyNode3,self.toggleNextBarImage, "hidebarshort.png","showbarshort.png", (.07,0.1,.195),self.nextBarPos))) def switchPreviousCardDisplay(self): self.toggleBarPrevious=not(self.toggleBarPrevious) def displayAdjacencies(self): if self.previousCard: self.displayPreviousCard() if self.nextCard: self.displayNextCard() def displayPreviousCard(self): self.previousCardPos=(-1,0,.58) self.previousCardTextPos=(-.9,.57) prevCard=self.previousCard.split(".")[0] self.previousCard=OnscreenImage( image=self.previousCard,pos=self.previousCardPos, scale=(0.07,0.82,0.12)) self.previousCard.reparentTo(self.dummyNode2) try: self.assocPrevText.destroy() self.assocPrevText=OnscreenText( text="(%s)"%self.inputs[prevCard], pos=self.previousCardTextPos, scale=.06,fg=(1,1,1,1),align=TextNode.ALeft) self.assocPrevText.reparentTo(self.dummyNode2) except: self.assocPrevText=OnscreenText( text="(%s)"%self.inputs[prevCard], pos=self.previousCardTextPos, scale=.06,fg=(1,1,1,1),align=TextNode.ALeft) self.assocPrevText.reparentTo(self.dummyNode2) def displayNextCard(self): self.nextCardPos=(-1,0,-.685) self.nextCardTextPos=(-.9,-.69) nextCard=self.nextCard.split(".")[0] self.nextCard=OnscreenImage( image=self.nextCard,pos=self.nextCardPos,scale=(0.07,0.82,0.12)) self.nextCard.reparentTo(self.dummyNode3) try: self.assocNextText.destroy() self.assocNextText=OnscreenText( text="(%s)"%self.inputs[nextCard], pos=self.nextCardTextPos, scale=.06,fg=(1,1,1,1),align=TextNode.ALeft) self.assocNextText.reparentTo(self.dummyNode3) except: self.assocNextText=OnscreenText( text="(%s)"%self.inputs[nextCard], pos=self.nextCardTextPos,scale=.06, fg=(1,1,1,1),align=TextNode.ALeft) self.assocNextText.reparentTo(self.dummyNode3) def switchDisplays(self,toggleBar,dummyNode,imageNode,hideImage, showImage,scale,pos): toggleBar=not(toggleBar) if toggleBar==True: dummyNode.show() imageNode.destroy() imageNode=(DirectButton(image = hideImage,scale=scale,pos=pos, relief=None, command=lambda: self.switchDisplays( toggleBar,dummyNode, imageNode,hideImage, showImage,scale,pos))) else: dummyNode.hide() imageNode.destroy() imageNode=(DirectButton(image = showImage,scale=scale,pos=pos, relief=None, command= lambda: self.switchDisplays( toggleBar,dummyNode, imageNode,hideImage, showImage,scale,pos))) def shuffleCards(self): self.shuffledCardNames=[] self.shuffledCardFaces=copy.copy(cardFaces) random.shuffle(self.shuffledCardFaces) for face in self.shuffledCardFaces: self.shuffledCardNames.append(face.split(".")[0]) def setUpCollisionRay(self): #Make a collision node for ours selection ray #Repurposed from Panda3D Documentation self.selectionNode = CollisionNode('mouseRay') self.selectionNP = camera.attachNewNode(self.selectionNode) self.selectionNode.setFromCollideMask( GeomNode.getDefaultCollideMask()) self.selectionNode.setFromCollideMask(1) self.selectionNode.setIntoCollideMask(0) self.selectionRay = CollisionRay() #Make our ray self.selectionNode.addSolid(self.selectionRay) #Add it to the collision node #Register the ray as something that can cause collisions self.cTrav.addCollider(self.selectionNP,self.queue) def setUpCollisionNode(self): #add a collision node to our camera self.fromObject = base.camera.attachNewNode( CollisionNode('colNode')) self.fromObject.setPos(0,0,3) self.fromObject.node().addSolid(CollisionSphere(0, 0, 0, .5)) self.fromObject.node().setIntoCollideMask(0) self.cTrav.addCollider(self.fromObject,self.pusher) self.pusher.addCollider( self.fromObject, base.camera, base.drive.node()) def setInputs(self): self.accept("mouse1",self.mouse1Tasks) self.accept('escape', sys.exit) def playFootSteps(self): self.soundSteps.play() def mouse1Tasks(self): self.mouseTask() def setUpScene(self): #self.setUpControls() self.setUpBackground() #set up the items where we can store information self.setUpItems() def mouseTask(self): self.scale=53 self.loadItemList() if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.selectionRay.setFromLens( base.camNode, mpos.getX(), mpos.getY()) #self.cTrav.showCollisions(render) if self.queue.getNumEntries() > 0: self.mouseEntry() def mouseEntry(self): #if we've clicked on something self.queue.sortEntries() #we get closest item pickedObj = self.queue.getEntry(0).getIntoNodePath().getTag("items") #check if what we clicked is what we want (has proper tag) if len(pickedObj)>0 and (pickedObj not in self.visitedItems): self.mouseTaskSupport(pickedObj) if self.queue.getEntry(0).getIntoNodePath().getTag("openChest"): self.toggleChest=True def mouseTaskSupport(self,pickedObj): self.assocs[ self.shuffledCardNames[self.counter]]=self.items[int(pickedObj)] self.counter+=1 self.visitedItems.append(pickedObj) #self.queue.getEntry(0).getIntoNodePath().clearTag("items") #if len(self.visitedItems)==len(self.items): if len(self.visitedItems)==5: self.testMemory() self.drawMiniCards(-self.camera.getPos()[1]/self.scale+.40, self.camera.getPos()[0]/self.scale-.2) self.updateDisplayCards() self.displayAdjacencies() def loadItemList(self): self.items=["painting","post","tv","bed","carpet","table","tree", "shelf","loveSeat1","loveSeat2","longSofa", "dinnerTable","dinnerChair1","dinnerChair2"] def testMemory(self): self.nextButton=DirectButton(image = 'arrow.png', scale=.15,pos=(0.8,0,-0.6), relief=None, command=self.recallMemory) self.nextButton.setTransparency(TransparencyAttrib.MAlpha) def displayPriorityArrow(self): self.arrow=OnscreenImage(image="arrow2.png", scale=(.05,.1,.05),pos=(-.51,0,-.6), color=(1,0,0,0)) self.arrow.setTransparency(TransparencyAttrib.MAlpha) taskMgr.doMethodLater(.1, self.fadeArrow, 'arrowFadeInOut') def displayUserLocation(self,task,scale=(.05,1,.05)): self.updateFade() if self.userLocation!=None: self.userLocation.destroy(),self.userAngle.destroy() x=-self.camera.getPos()[1]/self.scale+.40 y=self.camera.getPos()[0]/self.scale-.2 self.userLocation=OnscreenImage( image="dot.png",pos=(x,0,y),scale=scale, color=(1,1,1,self.fade)) self.userAngle=OnscreenImage( image="rotating.png",pos=(x,0,y),scale=scale, color=(1,1,1,self.fade)) self.userAngle.setR(-self.camera.getHpr()[0]) self.userLocation.setTransparency(TransparencyAttrib.MAlpha) self.userAngle.setTransparency(TransparencyAttrib.MAlpha) self.userLocation.reparentTo(self.dummyNode1) self.userAngle.reparentTo(self.dummyNode1) return Task.again def updateFade(self): if self.fadeToggle==True: self.fade+=.05 if self.fade>1: self.fadeToggle=False elif self.fadeToggle==False: self.fade-=.05 if self.fade<0: self.fadeToggle=True def drawMiniCards(self,x,y): self.lastCoord+=([[x,0,y]]) self._draw_line_segs(self.dummyNode1,self.lastCoord) for i in xrange(len(self.lastCoord)): self.miniCards=OnscreenImage( image=self.shuffledCardFaces[i], pos=(self.lastCoord[i][0],0,self.lastCoord[i][2]), scale=(0.03,0.82,0.050)) self.miniCards.reparentTo(self.dummyNode1) def _draw_line_segs(self, parent, points, thickness=1.5): segs = LineSegs() segs.setThickness(thickness) segs.setColor( Vec4(1,0,0,.35) ) if points: segs.moveTo(points[0][0], points[0][1], points[0][2]) for p in points[1:]: segs.drawTo(p[0], p[1], p[2]) lines = NodePath(segs.create()) lines.reparentTo(parent) def recallMemory(self): self.checkList=[] self.checkListFaces=[] self.startCard=0 self.endCard=13 self.cardSet=0 self.bk=OnscreenImage(image="bk.png",scale=(2,1,1)) self.recallCards(self.startCard,self.endCard, self.cardSet,0) self.scaleCards=(0.1,0.1,0.13) scaleCards2=(0.07,0.05,0.10) self.recallMemoryPrompt=OnscreenText( text="List the cards in the sequence as you recall", pos=(0,.45),scale=.045,fg=(0,0,0,.75)) def recallCards(self,startCard,endCard,cardSet,createEntries=1): for i in xrange(startCard,endCard): x=2*(i+1)/(self.numCards+1.0)-1-cardSet*1.75 self.cardsPos.append(x) self.createButtons(i,x) if createEntries==1: self.createEntries(x, cardSet) for image in self.buttonList: image.setTransparency(TransparencyAttrib.MAlpha) def createButtons(self,i,x): self.buttonList.append(DirectButton( image = cardFaces[i],scale=(0.06,0.1,0.095),pos=(x,0,.3), relief=None, command=lambda: self.createCheckButtons(i))) def createCheckButtons(self,i): self.correctCount=0 self.checkList.append(i) self.checkListFaces.append(cardFaces[i]) for i in xrange(len(self.checkList)): x=2*(i+1)/(self.numCards+1.0)-1 self.cards=OnscreenImage(image=self.checkListFaces[i], pos=(x,0,-.2),scale=(0.06,0.1,0.095)) if len(self.checkList)==13: correct=self.testResults() self.results=OnscreenText( text="You recalled %d out of %d correctly"%( correct,self.numCards),pos=(0,-0.85),scale=.1) def testResults(self): for i in xrange(len(self.shuffledCardFaces)): if self.shuffledCardFaces[i]==self.checkListFaces[i]: self.correctCount+=1 return self.correctCount def updateDisplayCards(self): self.numCardsCopy-=1 self.previousCard=self.shuffledCardFacesCopy.pop(0) if len(self.shuffledCardFacesCopy)!=0: self.nextCard=self.shuffledCardFacesCopy[0] else: self.nextCard=False for image in self.imageList: image.destroy() self.displayCards() def displayCards(self): for i in xrange(self.numCardsCopy): x=2*(i+1)/(self.numCards+1.0)-.65 self.cardsPos.append(x) self.imageList.append(OnscreenImage( image="%s"%(self.shuffledCardFacesCopy[i]), pos=(x,0,-.8),scale=(0.05,0.05,0.08))) #we use middle numbers as coordinates def fadeArrow(self,task): self.arrow.setColor(1,0,0,self.fade) return task.cont def setUpBackground(self): self.scale=10 #load grass and set position, scale, and texture self.walls=loader.loadModel("Walls") self.walls.setPos(0,0,0) self.walls.setScale(self.scale,self.scale,self.scale) walltex1 = loader.loadTexture('walltex1.png') self.walls.setTexture(walltex1) #render our object self.walls.reparentTo(render) self.loadColGeomsSet1() self.loadColGeomsSet2() self.setUpBackgroundSupport() def setUpBackgroundSupport(self): for geom in self.colGeoms: self.createCollisionGeom(*geom) cFloorNode=CollisionNode('floorCollision') floorQuad=CollisionPolygon(Point3(5, 0, 0), Point3(-1.5,0,0), Point3(-1.5, -4, 0),Point3(5, -4, 0)) cFloorNode.addSolid(floorQuad) def loadColGeomsSet1(self): self.colGeoms=[ (11,(2.4,-1.80,1),(2.4,-1.80,0),(.55,-1.80,0), (.55,-1.80,1)),#Interior 2b (firsthalf), (1,(5,-.05,0),(5,-.05,1),(-1.5,-.05,1), (-1.5,-.05,0)),#West Wall (2,(-1.5,0,0),(-1.5,0,1),(-1.5,-4,1), (-1.5,-4,0)),#South Edge (5,(0.52,0,0),(0.52,0,1),(0.52,-1.2,1), (0.52,-1.2,0)), #South Wall_1_Interior (3,(0.38,0,1),(0.38,0,0),(0.38,-1.2,0), (0.38,-1.2,1)), #South Wall_1_Exterior (4,(0.38,-1.7,1),(0.38,-1.7,0),(0.38,-4,0),(0.38,-4,1)), #South Wall_2_Exterior (6,(0.52,-1.7,0),(0.52,-1.7,1),(0.52,-4,1),(0.52,-4,0)), #South Wall_2 Interior (7,(1.8,0,1),(1.8,0,0),(1.8,-1.45,0),(1.8,-1.45,1)), #Interior 1 (TV) (8,(1.9,0,0),(1.9,0,1),(1.9,-1.45,1),(1.9,-1.45,0)), #Interior 1b (TV) (9,(2.4,-1.95,0),(2.4,-1.95,1),(.55,-1.95,1), (.55,-1.95,0)), #Interior 2 (firsthalf) (10,(3.95,-1.95,0),(3.95,-1.95,1), (2.7,-1.95,1),(2.7,-1.95,0))] #Interior 2 (secondhalf) def loadColGeomsSet2(self): self.colGeoms+=[ (12,(3.95,-1.80,1),(3.95,-1.80,0), (2.7,-1.80,0), (2.7,-1.80,1)), #Interior 2b (secondhalf) (13,(2.95,-1.9,0),(2.95,-1.9,1),(2.95,-2.1,1), (2.95,-2.1,0)),#North Wall 1 Exterior (firsthalf)E (14,(2.95,-2.48,0),(2.95,-2.48,1),(2.95,-4,1), (2.95,-4,0)),#North Wall 1 Exterior (secondhalf)E (15,(2.7,-1.9,1),(2.7,-1.9,0),(2.7,-2.1,0), (2.7,-2.1,1)), #North Wall 1b Interior (firsthalf) E (16,(2.7,-2.48,1),(2.7,-2.48,0),(2.7,-4,0), (2.7,-4,1)), #North Wall 1b Interior (secondhalf) E (17,(3.82,0,1),(3.82,0,0),(3.82,-.35,0), Point3(3.82,-.35,1)),#North Wall 2 Interior (firsthalf) W (18,(3.82,-1.1,1),(3.82,-1.1,0),(3.82,-1.9,0), Point3(3.82,-1.9,1)),#North Wall 2 Interior (secondhalf) W (19,(4,0,0),(4,0,1),(4,-.35,1), Point3(4,-.35,0)),#North Wall 2 Exterior (firsthalf) W (20,(4,-1.1,0),(4,-1.1,1),(4,-1.9,1), Point3(4,-1.9,0))#North Wall 2 Exterior (secondhalf) W ] def createCollisionGeom(self,n,firstPts,secondPts,thirdPts,fourthPts): collisionNode="wallCollision%d"%n collisionNodeName="cWallNode%d"%n collisionNodeName=CollisionNode(collisionNode) quadName="wallQuad%d"%n quadName=CollisionPolygon(Point3(firstPts),Point3(secondPts), Point3(thirdPts),Point3(fourthPts)) collisionNodeName.addSolid(quadName) self.wallC=self.walls.attachNewNode(collisionNodeName) self.roof=self.loadItems("Roof","rooftex.png",scaleX=6,scaleY=6) self.walls2=self.loadItems("Walls2","walltex2.png") self.grass=self.loadItems("grass",'8CYNDAC0.png') self.floor=self.loadItems("floor","floor.png") self.exterior=self.loadItems("exterior",'brick.png') def setUpItems(self): self.itemList=[] self.scale=10 self.tv=self.loadItems("tv",'tv.png') self.carpet=self.loadItems("carpet","carpet.png") self.white=self.loadItems("white","walltex2.png",8,4) self.painting=self.loadItems("painting","kosbie.png") self.wood=self.loadItems("wood","wood.png",8,4) self.tree=self.loadItems("GroomedTree",None,1,1,.9,(52,-5,0)) self.shelf=self.loadItems("shelf","darkwood.png") self.couches=self.loadItems("couch","leather.png",5,5) self.dining=self.loadItems("chairs","wood.png") self.treasureChest=self.loadItems( "treasurechest","woodpanel.png",1,1,None,(0,0,20)) self.sky=self.loadItems("sky","sky.png",1,1) self.selectionItems = render.attachNewNode("selectionRoot") self.setUpCollisionGeom() def setUpCollisionGeom(self): self.paintingNode=self.loadCollisionPolygon( "painting",self.painting,(3.35,-.07,.45),(3.35,-.07,.8), (2.9,-.07,.8),(2.9,-.07,.45)) self.postNode=self.loadCollisionTube( "post",self.wood,.25,-2,0,.25,-2,.55,.03) self.tvNode=self.loadCollisionPolygon( "tv",self.tv,(1.75,-.35,.78),(1.75,-.35,.5),(1.75,-1.1,.5), (1.75,-1.1,.78)) self.bedNode=self.loadCollisionPolygon( "bed",self.white,(1,-2.7,.17),(.5,-2.7,.17),(.5,-1.9,.17), (1,-1.9,.17)) self.carpetNode=self.loadCollisionPolygon( "carpet",self.carpet,(1.95,-3.15,.05),(2.4,-3.15,.05), (2.4,-2.55,.05),(1.95,-2.55,.05)) self.tableNode=self.loadCollisionPolygon( "table",self.wood,(1,-3.5,.26),(1.45,-3.5,.26), (1.45,-3.1,.26),(1,-3.1,.26)) self.supportSetUpCollisionGeom() def supportSetUpCollisionGeom(self): self.treeNode=self.loadCollisionTube( "tree",self.tree,0,0,0,0,0,7,2) self.shelfNode=self.loadCollisionPolygon( "shelf",self.shelf,(.6,-0.05,.78),(.6,-0.05,0), (.6,-.43,0),(.6,-.43,.78)) self.couchNode1=self.loadCollisionTube( "couch1",self.couches,1.05,-.96,0,1.05,-.96,.2,.2) self.couchNode2=self.loadCollisionTube( "couch2",self.couches,1.45,-.96,0,1.45,-.96,.2,.2) self.couchNode3=self.loadCollisionTube( "couch3",self.couches,1.00,-.16,.1,1.5,-.16,.1,.2) self.dinnerTable=self.loadCollisionPolygon( "dinnerTable",self.dining,(3.6,-.89,.26),(3.6,-.61,.26), (3.1,-.61,.26),(3.1,-.89,.26)) self.dinnerChairNode1=self.loadCollisionTube( "dinnerChair1",self.dining,2.9,-.75,0,2.9,-.75,.2,.1) self.dinnerChairNode2=self.loadCollisionTube( "dinnerChair1",self.dining,3.7,-.75,0,3.7,-.75,.2,.1) self.chestNode=self.loadCollisionTube( "chest",self.treasureChest,.02,.02,.25,.07,.07,.25,.25) self.chestNode.setTag( "openChest","1") self.itemList+=(self.paintingNode,self.postNode,self.tvNode, self.bedNode,self.carpetNode,self.tableNode, self.treeNode,self.shelfNode,self.couchNode1, self.couchNode2,self.couchNode3,self.dinnerTable, self.dinnerChairNode1,self.dinnerChairNode2) self.setTag(self.itemList,"items") def setTag(self): self.itemList+=(self.paintingNode,self.postNode,self.tvNode, self.bedNode,self.carpetNode,self.tableNode, self.treeNode,self.shelfNode, self.couchNode1,self.couchNode2,self.couchNode3, self.dinnerTable,self.dinnerChairNode1, self.dinnerChairNode2) self.setTag(self.itemList,"items") def setTag(self,node,tagKey): for i in xrange(len(node)): node[i].setTag(tagKey,str(i)) def loadItems(self,modelName,texture=None,scaleX=1,scaleY=1, scale=None,pos=(0,0,0)): if scale==None: scale=self.scale modelName=loader.loadModel(modelName) modelName.setPos(pos) modelName.setScale(scale,scale,scale) ts=TextureStage("ts") if texture!=None: modelTex=loader.loadTexture(texture) modelName.setTexture(ts,modelTex) modelName.setTexScale(ts,scaleX,scaleY) modelName.reparentTo(render) return modelName def loadCollisionPolygon(self,modelName,attachGeom,firstPts, secondPts,thirdPts,fourthPts): modelName=CollisionNode(modelName) quadName=CollisionPolygon(Point3(firstPts),Point3(secondPts), Point3(thirdPts),Point3(fourthPts)) modelName.addSolid(quadName) modelName=attachGeom.attachNewNode(modelName) return modelName def loadCollisionTube(self,modelName,attachGeom,x0,y0,z0,x1,y1,z1, radius): modelName=CollisionNode(modelName) cylinder=CollisionTube(x0,y0,z0,x1,y1,z1,radius) modelName.addSolid(cylinder) modelName=attachGeom.attachNewNode(modelName) return modelName def homePage(self): self.introduction=False #self.setUphomePageSFX() self.introButton=DirectButton( image=("introduction.png"),scale=.5,pos=(-0.8,0,-0.65), relief=None,command=self.startIntro) self.introButton.setTransparency(TransparencyAttrib.MAlpha) self.startButton=DirectButton( image=("beginJourney.png"),scale=.5,pos=(+0.8,0,-0.65), relief=None, command=self.startJourney) self.startButton.setTransparency(TransparencyAttrib.MAlpha) self.cylinder=self.loadItems( "cylinder","wood.png",1,1,2,(9,-1.3,20.8)) self.hexagon=self.loadItems( "hexagon","wood.png",1,1,2.5,(9,1.4,20.8)) taskMgr.add(self.rotateMenuItems, 'rotateMenuItems') #def setUphomePageSFX(self): #self.volume=0 #self.circusInTheSky.setVolume(0) #self.circusInTheSky.setLoop(1) #self.circusInTheSky.play() #taskMgr.doMethodLater(.5, self.playCircusInTheSky, # 'Fade in Music', extraArgs = [self]) #def playCircusInTheSky(self,task): #self.volume+=.00125 #self.circusInTheSky.setVolume(self.volume) #return Task.cont def rotateMenuItems(self,task): self.speed=1.5 radius=.5 angle = radians(self.heading) x = cos(angle) * radius y = sin(angle) * radius z = sin(angle) * radius self.heading+=self.speed self.heading%=360 self.cylinder.setH(self.heading) self.hexagon.setH(self.heading) if self.introduction==True: self.cylinder.remove() self.hexagon.remove() return task.done return Task.cont def startJourney(self): #self.circusInTheSky.stop() self.introButton.destroy() self.startButton.destroy() self.initSetUpAssoc() #self.setUp3DEnvironmentIntro() ###########change here def setUp3DEnvironmentIntro(self): self.camera.setP(25) self.Enviro3DDummy=self.createDummyNode("3DEnviroDummy") self.textBlocks,self.color,self.keyBrightenComplete=[],0.01,False self.displayCards() self.displayHelpPanel() taskMgr.doMethodLater(.05,self.displayUserLocation, 'Track User', extraArgs = [self]) self.setUpDirectionalLight() self.displayPriorityArrow() self.accept("arrow_down",self.playFootSteps) self.accept("arrow_up",self.playFootSteps) self.enviroTextBlocks() self.Enviro3DSupportText() def enviroTextBlocks(self): self.enviroTextBlock1=( "1. Here is the priority queue for the shuffled cards") self.enviroTextBlock2=( "2. Toggle displays to show/hide windows") self.enviroTextBlock3=( "3. See your location in the plan") self.textBlocks+=(self.enviroTextBlock1,self.enviroTextBlock2, self.enviroTextBlock3) self.textPos=[(0,-.6),(-.6,.6),(.7,-.4)] def Enviro3DSupportText(self): for i in xrange(len(self.textBlocks)): self.titleText=OnscreenText(text=self.textBlocks[i], pos=self.textPos[i],scale=.058,fg=(1,1,1,1)) self.titleText.reparentTo(self.Enviro3DDummy) taskMgr.doMethodLater(.1, self.init3DActiveEnviro,'3DEnviroEntry') taskMgr.doMethodLater(.15,self.brightenKey,"brightenKey") def init3DActiveEnviro(self,task): self.keyButton=DirectButton( image = 'key.png',scale=(.5,.2,.15),color=(0,0,0,0),pos=(-.5,0,0), relief=None, command=self.setUp3DEnvironmentActive) self.keyButton.setTransparency(TransparencyAttrib.MAlpha) self.keyButton.reparentTo(self.Enviro3DDummy) self.keyButton['state'] = DGG.DISABLED return task.done def brightenKey(self,task): if self.keyBrightenComplete==False: self.brightenSpeed=0.025 if self.color<1: self.color+=self.brightenSpeed self.keyButton.setColor(0,0,0,self.color) return task.again else: self.entryText=OnscreenText(text="[Click the key to begin]", pos=(-.7,.13),scale=.058,fg=(1,1,1,1)) self.entryText.reparentTo(self.Enviro3DDummy) self.keyButton['state'] = DGG.NORMAL task.done else: task.done def setUp3DEnvironmentActive(self): base.useDrive() self.keyBrightenComplete=True self.Enviro3DDummy.removeNode() def setUpDirectionalLight(self): dlight = DirectionalLight('dlight') dlight.setColor(VBase4(0.8, 0.8, 0.5, 1)) dlnp = render.attachNewNode(dlight) dlnp.setHpr(0, -60, 0) render.setLight(dlnp) render.setShaderAuto() def startIntro(self): self.introduction=True self.introButton.destroy() self.startButton.destroy() self.setUpHelp() def setUpHelp(self): self.titleText=OnscreenText(text="Introduction", pos=(-0.85,0.85),scale=.1) self.text = TextNode('helpText') self.textBlocks() self.text.setText(self.textBlock1) textNodePath = aspect2d.attachNewNode(self.text) textNodePath.setScale(0.07) textNodePath.setPos(-1,0,0) self.text.setWordwrap(30.0) self.nextButton=DirectButton( image = 'arrow.png',scale=.15,pos=(0.8,0,-0.6),relief=None, command=self.nextPage ) self.nextButton.setTransparency(TransparencyAttrib.MAlpha) def textBlocks(self): self.textBlock1=("This project tests the effectiveness" +" of along established 'Method of loci', which is a" +" mnemonic device used for memory enhancement which uses" +" visualization to organize and recall information." +" We will be using this technique to memory a set of 13" +" cards (one suit)") self.textBlock2=( "STEP 1 \n\n We create rooms which are connected " + "and unique. These are provided for you." +"\n\n STEP 2 \n\n Associate each card with visual " +"objects (eg. 2 ---> Swan)" +"\n\n STEP 3 \n\n We 'place' the cards at specific " +"locations in sequence so relationship between " +"the location and item are made." +"\n\n STEP 4 \n\n Test the associations we've made") def nextPage(self): textNodePath = aspect2d.attachNewNode(self.text) textNodePath.setPos(-1,0,.5) self.nextButton.destroy() self.text.setText(self.textBlock2) self.nextButton=DirectButton( image = 'arrow.png',scale=.15,pos=(0.8,0,-0.6),relief=None, command=(self.clear)) self.nextButton.setTransparency(TransparencyAttrib.MAlpha) def clear(self): self.text.clearText() self.titleText.clearText() self.nextButton.destroy() self.homePage() def initSetUpAssoc(self): self.bk=OnscreenImage(image="bk.png",scale=(2,1,1)) self.inputs=dict() self.cardsPositions=[] self.imageListFaces,self.textObjs,self.entries=[],[],[] self.numCardsPage1=7 self.startCard=0 self.endCard=7 self.cardSet=0 self.callCards(self.startCard,self.endCard, self.cardSet) self.goAhead=[] self.button1=loader.loadMusic("button1.wav") self.assocTextBlocks() taskMgr.doMethodLater(.1, lambda task: self.createAssocHelperText( task,self.assocTextBlock1),'assocHelperText') def assocTextBlocks(self): self.assocTextBlock1=( "[Enter a word you strongly associated with each card]" +"\n Helpful Hint: Use less abstract and more descriptive words") self.assocTextBlock2=( "[That's great! Finish up the rest!]") def createAssocHelperText(self,task,text): self.updateFade() try: self.assocText.destroy() self.assocText=OnscreenText( text=text, pos=(0,-.2),scale=.05,fg=(0,0,0,self.fade)) except: self.assocText=OnscreenText( text=text, pos=(0,-.2),scale=.05,fg=(0,0,0,self.fade)) return task.again def callCards(self,startCard,endCard,cardSet,createEntries=1, scaleCards=(0.1,0.1,0.13)): for i in xrange(startCard,endCard): x=2*(i+1)/(self.numCardsPage1+1.0)-1-cardSet*1.75 self.cardsPositions.append(x) self.imageListFaces.append( OnscreenImage(image="%s"%(cardFaces[i]), pos=(x,0,.3),scale=scaleCards)) self.textObjs.append(OnscreenText(text=str(i),pos=(x,0))) #we use middle numbers as coordinates self.cardName=cardNames[i] if createEntries==1: self.createEntries(x, cardSet) def createEntries(self,x, cardSet): self.entries.append( DirectEntry(text = "" ,scale=.02,pos=(x-0.1,0.1,0.1), command=(lambda textEntered: self.storeAssoc (textEntered, x, cardSet)), numLines = 2)) def clearPage(self): for image in self.imageListFaces: image.destroy() for textObj in self.textObjs: textObj.destroy() for entry in self.entries: entry.destroy() for image in self.goAhead: image.destroy() self.assocText.destroy() self.clearBK() def clearBK(self): self.bk.destroy() def storeAssoc(self,textEntered, x, cardSet): index=int((x+cardSet*1.75+.75)/0.25) self.inputs[cardNames[index]]=textEntered self.greenDot=OnscreenImage( image="greenDot.png",pos=(x,0,.55),scale=(.25,1,.25)) self.greenDot.setTransparency(TransparencyAttrib.MAlpha) self.goAhead.append(self.greenDot) self.button1.play() if len(self.inputs)>6 and cardSet==0: taskMgr.remove('assocHelperText') taskMgr.doMethodLater(.1, lambda task: self.createAssocHelperText( task,self.assocTextBlock2),'assocHelperText') self.startCard=7 self.endCard=13 self.clearBK() self.cardSet=1 self.bk=OnscreenImage(image="bk.png",scale=(2,1,1)) self.callCards(self.startCard,self.endCard, self.cardSet) if len(self.inputs)>12 and cardSet==1: taskMgr.remove('assocHelperText') self.clearPage() self.setUp3DEnvironmentIntro() def startGame(self): self.bk.destroy()
class Begin(ShowBase): def __init__(self): global pointball_value global title_screen global loading_screen # Basics ShowBase.__init__(self) #Setup the window base.disableMouse() render.setAntialias(AntialiasAttrib.MAuto) self.set_windowsettings() base.camLens.setFar(asteroid_spawn_distance * 100) base.camLens.setNear(2000) self.setBackgroundColor(colors.get("black")) # Create the directional and ambient lights, and apply them to the world. ambientLight = AmbientLight("ambientLight") ambientLight.setColor((0.8, 0.8, 0.8, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(LVector3(0, 45, -45)) directionalLight.setColor((1, 1, 1, 1)) directionalLight.setShadowCaster(True) render.setLight(render.attachNewNode(directionalLight)) render.setLight(render.attachNewNode(ambientLight)) # Create a black fog and apply it to the world. self.fog = Fog('distanceFog') self.fog.setColor(0, 0, 0) self.fog.setExpDensity(fog_quality) render.setFog(self.fog) # Initialize Collisions base.cTrav = CollisionTraverser() base.cTrav.setRespectPrevTransform(True) self.collHandEvent = CollisionHandlerEvent() self.collHandEvent.addInPattern("%fn-into-%in") # Add colision sphere to player for losing state cNode = CollisionNode("player") cNode.addSolid(CollisionSphere(0, 0, 0, 3)) self.player_np = base.camera.attachNewNode(cNode) base.cTrav.addCollider(self.player_np, self.collHandEvent) # Setup initial score self.title = OnscreenText(text="Score: {0}".format(score), parent=base.a2dTopLeft, scale=.07, align=TextNode.ALeft, pos=(0.1, -0.1), fg=(1, 1, 1, 1), shadow=(0, 0, 0, 0.5), font=thunderstrike) # Add Occluder Culling - I will need to figure this out later # occluder_model = self.loader.loadModel("./Models/cone_10vert.egg") # render.setOccluder(occluder_model) Begin.keyMap = { "forward": False, "strafe-left": False, "backward": False, "strafe-right": False, "strafe-up": False, "strafe-down": False, "roll-left": False, "roll-right": False } #True if coresponding key is currently held down. #Basic camera movement on the xyz coordinate plane self.accept("escape", sys.exit) self.accept( "w", self.setKey, ["forward", True] ) # Pressing the key down sets the state to true. Tasks will function as if pressing key each frame. self.accept( "w-up", self.setKey, ["forward", False] ) # Releasing the key changes the key state in begin.keyMap to False to tasks will stop looping. self.accept( "a", self.setKey, ["strafe-left", True] ) # Both previous comments apply to the following 'accept self.setKey' block of code. self.accept("a-up", self.setKey, ["strafe-left", False]) self.accept("s", self.setKey, ["backward", True]) self.accept("s-up", self.setKey, ["backward", False]) self.accept("d", self.setKey, ["strafe-right", True]) self.accept("d-up", self.setKey, ["strafe-right", False]) self.accept("space", self.setKey, ["strafe-up", True]) self.accept("space-up", self.setKey, ["strafe-up", False]) self.accept("control", self.setKey, ["strafe-down", True]) self.accept("control-up", self.setKey, ["strafe-down", False]) self.accept("shift", self.setKey, ["strafe-down", True]) self.accept("shift-up", self.setKey, ["strafe-down", False]) self.accept("q", self.setKey, ["roll-left", True]) self.accept("q-up", self.setKey, ["roll-left", False]) self.accept("e", self.setKey, ["roll-right", True]) self.accept("e-up", self.setKey, ["roll-right", False]) self.accept('mouse1', self.shoot) # Shoots the projectile self.accept('f11', self.fullscreenToggle) self.accept('f12', self.framesToggle) # Development keys self.accept('0', self.stop_moving) # Stop moving self.accept('1', self.angle1) self.accept('2', self.angle2) self.accept('3', self.angle3) self.accept('4', self.angle4) self.accept('5', self.angle5) self.accept('6', self.angle6) # Create the loading bar self.loading = DirectFrame(frameSize=(-10, 10, -10, 10), frameColor=(0, 0, 0, 1)) self.loading_bar = DirectWaitBar( text="Generating Asteroids . . .", text_font=thunderstrike, text_fg=(0, 0, 0, 1), text_shadow=(1, 1, 1, 1), #text_pos=(0.001,0.001, -1), value=50, range=asteroid_max + (2 * int(asteroid_max * 0.05)), barColor=(1, 1, 1, 1), frameColor=(0, 0, 0, 0), parent=self.loading) loading_screen = self.loading loading_screen.loading_bar = self.loading_bar # Create the main menu self.quality_name = "Low" self.quality_num = 1 self.quality_applied = 1 self.menu = DirectFrame(frameSize=(10, -10, 10, -10), frameColor=(0, 0, 0, 1)) self.menu_title = DirectFrame( frameSize=(base.a2dLeft, base.a2dRight, 0.55, 0.8), frameTexture=loader.loadTexture("./Fonts/title.png"), parent=self.menu) title_asteroid = Asteroid("small") self.menu_asteroid = DirectFrame(geom=title_asteroid.np, geom_scale=(0.000008, 0.000008, 0.000008), pos=(1.13, 0, 0.56), frameColor=(0, 0, 0, 1), enableEdit=1, parent=self.menu_title) title_screen = self.menu title_screen.menu_asteroid = self.menu_asteroid title_screen.start_btn = self.createButton("Start", self.start_game, 0.2) title_screen.how_to_btn = self.createButton("How to Play", self.how_to_play, 0) title_screen.exit_btn = self.createButton("Quit", sys.exit, -0.2) title_screen.res_apply_btn = self.createButton("Apply", self.apply_res_button, -0.4, 1, (-2, 2.3, -0.6, 1)) title_screen.res_apply_btn.hide() title_screen.resolution_btn = self.createButton( f"Resolution ({resolution[0]} x {resolution[1]})", self.resolution, -0.4) title_screen.fullscreen_btn = self.createButton( "Toggle Fullscreen", self.fullscreenToggle, -0.6) title_screen.quality_btn = self.createButton( f"Qualilty ({self.quality_name})", self.quality, -0.8) title_screen.qual_apply_btn = self.createButton( "Apply", self.apply_qual_button, -0.8, 1, (-2, 2.3, -0.6, 1)) title_screen.qual_apply_btn.hide() taskMgr.add(Begin.menu, "Menu") title_screen.hide() # Setup game tasks and create the 3d asteroids. taskMgr.add(Begin.createAsteroids, "Generate asteroids") def createAsteroids(self): global asteroid_max global asteroid_total global loading_screen global title_screen global base if len(asteroid_total) < asteroid_max: asteroid = Asteroid() asteroid_total.insert(0, asteroid) base.cTrav.addCollider(asteroid.c_np, base.collHandEvent) asteroid.add_togame() loading_screen.loading_bar["value"] += 1 return Task.cont # Extra asteroids to be instantly available when asteroids break if len(extra_smallasteroids) < int(asteroid_max * 0.05): extra_smallasteroids.insert(0, Asteroid("small")) extra_mediumasteroids.insert(0, Asteroid("medium")) loading_screen.loading_bar["value"] += 1 return Task.cont if len(extra_mediumasteroids) < int(asteroid_max * 0.05): extra_mediumasteroids.insert(0, Asteroid("medium")) loading_screen.loading_bar["value"] += 1 return Task.cont print("did not return") loading_screen.hide() title_screen.show() taskMgr.remove("Generate asteroids") def start_game(self): global pointball_value global cursor_hidden global is_living self.accept("player-into-asteroid", self.end_game) self.accept("player-into-pointball", self.score) self.accept(f"missle-into-asteroid", self.shot_asteroid) # Set mouse and display settings self.lastMouseX, self.lastMouseY = 0, 0 cursor_hidden = True self.set_windowsettings() self.startTasks() for asteroid in asteroid_total: asteroid.asteroid_lerp.resume() # Hide the main Menu if not (is_living): #taskMgr.add(self.score, "Score") self.accept('mouse1', self.shoot) base.camera.setPos(0, 0, 0) taskMgr.remove("Death Spin") title_screen.start_btn["text"] = ("Resume", "Resume", " Resume!", "Resume") base.setBackgroundColor(0, 0, 0, 1) self.fog.setColor(0, 0, 0) is_living = True title_screen.hide() # Change what the escape key does self.accept("escape", self.pause) pointball_value = int(time.time()) def pause(self): global is_living global score global cursor_hidden global spaceship_speed_x global spaceship_speed_y global spaceship_speed_z pause_pointball_value = pointball_value for asteroid in asteroid_total: asteroid.asteroid_lerp.pause() # Show + relase the mouse title_screen.show() cursor_hidden = False self.set_windowsettings() taskMgr.remove("Rotate player in hpr") self.acceptOnce("escape", sys.exit) # Change start button text relative to living state + remove death text if died if is_living: title_screen.start_btn["text"] = ("Resume", "Resume", " Resume!", "Resume") else: aspect2d.find("**/-TextNode").removeNode() title_screen.start_btn["text"] = ("Retry", "Retry", " Retry!", "Retry") spaceship_speed_x = 0 spaceship_speed_y = 0 spaceship_speed_z = 0 base.camera.setPos(0, 0, 0) while len(asteroid_total) > asteroid_max: del asteroid_total[0] for asteroid in asteroid_total: asteroid.asteroid_lerp.finish() asteroid.add_togame() score = 0 self.title = OnscreenText(text="Score: {0}".format(score), parent=base.a2dTopLeft, scale=.07, align=TextNode.ALeft, pos=(0.1, -0.1), fg=(1, 1, 1, 1), shadow=(0, 0, 0, 0.5), font=thunderstrike) def quality(self): qual_dict = { # asteroid_number is chosen by 300 was found to be a good number when testing on a low spec machine. The larger ones keep the same density of asteroids as volume increases 1: { "quality": "Low", "asteroid_detail": 36, "fog_quality": 0.000001, "asteroid_spawn_distance": 3000000, "asteroid_number": 300 }, 2: { "quality": "Medium", "asteroid_detail": 30, "fog_quality": 0.0000008, "asteroid_spawn_distance": 4000000, "asteroid_number": 711 }, 3: { "quality": "High", "asteroid_detail": 20, "fog_quality": 0.0000006, "asteroid_spawn_distance": 5000000, "asteroid_number": 1389 }, } self.quality_num = self.quality_num + 1 if self.quality_num != 3 else 1 self.game_quality = qual_dict[self.quality_num] self.quality_name = self.game_quality["quality"] text = f"Quality ({self.quality_name})" title_screen.quality_btn["text"] = (text, text, f" {text}!", text) if self.quality_num != self.quality_applied: title_screen.qual_apply_btn.show() else: title_screen.qual_apply_btn.hide() def apply_qual_button(self): global asteroid_detail global fog_quality global asteroid_future_distance global asteroid_test_distance global asteroid_max global asteroid_total global extra_smallasteroids global extra_mediumasteroids asteroid_detail = self.game_quality["asteroid_detail"] fog_quality = self.game_quality["fog_quality"] asteroid_spawn_distance = self.game_quality["asteroid_spawn_distance"] asteroid_test_distance = asteroid_spawn_distance * (29.0 / 30.0) asteroid_max = self.game_quality["asteroid_number"] self.fog.setExpDensity(fog_quality) self.quality_applied = self.quality_num title_screen.qual_apply_btn.hide() asteroid_total = [] extra_mediumasteroids = [] extra_smallasteroids = [] title_screen.hide() loading_screen.loading_bar["value"] = 0 loading_screen.loading_bar["range"] = asteroid_max + ( 2 * int(asteroid_max * 0.05)) loading_screen.show() taskMgr.add(Begin.createAsteroids, "Generate asteroids") def resolution(self): global resolution res_list = [ # 4:3 (800, 600), (1024, 768), (1920, 1440), (4096, 3071), # 5:4 (1280, 1024), # 16:9 (1280, 720), (1366, 768), (1600, 900), (1920, 1080), (2560, 1440), (3840, 2160), (4096, 2304), #16:10 (1440, 900), (1680, 1050), (2304, 1440), (4096, 2560), # 21:9 (2160, 1080), (3440, 1440) ] index = res_list.index(resolution) resolution = res_list[index + 1] if index < len(res_list) - 1 else res_list[0] if base.getSize() == resolution: title_screen.res_apply_btn.hide() else: title_screen.res_apply_btn.show() text = f"Resolution ({resolution[0]} x {resolution[1]})" title_screen.resolution_btn["text"] = (text, text, f" {text}!", text) def apply_res_button(self): title_screen.res_apply_btn.hide() self.set_windowsettings() def how_to_play(self): webbrowser.open( 'https://github.com/13r0ck/3d-Space-Rocks-Simulator-2020') def createButton(self, text, command, verticalPos, horisontalPos=0, frame_size=(-8, 8, -0.6, 1)): btn = DirectButton(text=(text, text, f" {text}!", text), text_fg=(1, 1, 1, 1), pad=(0.7, 0.3), frameSize=frame_size, frameTexture="./Images/Button_Frame.png", relief=1, text_font=thunderstrike, text_scale=0.9, scale=0.1, command=command, pos=(horisontalPos, 0, verticalPos), textMayChange=1) btn.reparentTo(self.menu) return btn def startTasks(self): #The tasks below are the functions run every frame so the game will work taskMgr.add(Begin.test_distance, "Test Distance") taskMgr.add(self.mouseTask, "Rotate player in hpr") taskMgr.add(Begin.spaceship_movement, "Move the Player in xyz") taskMgr.add(Begin.remove_old_missles, "Remove old missles") taskMgr.add(Begin.pointballManager, "Pointballs Manager") def menu(self): h, p, r = title_screen.menu_asteroid["geom_hpr"] dt = globalClock.getDt() title_screen.menu_asteroid["geom_hpr"] = LVecBase3f(h + 45 * dt, 0, 0) return Task.cont ##### // Key Press Functions \\ ##### def spaceship_movement(self): global spaceship_speed_x global spaceship_speed_y global spaceship_speed_z global max_player_speed dt = globalClock.getDt() # Move the player on the global axis. This is how momentum is not interupted cam_pos_init = base.camera.getPos() base.camera.setPos( cam_pos_init[0] + spaceship_speed_x * dt, # Spaceship X change per frame cam_pos_init[1] + spaceship_speed_y * dt, # Spaceship Y change per frame cam_pos_init[2] + spaceship_speed_z * dt) # " Z " " " # Ff a key is pressed, then we will need to do other calulations this frame. if Begin.keyMap["forward"] or Begin.keyMap["backward"] or Begin.keyMap[ "strafe-left"] or Begin.keyMap["strafe-right"] or Begin.keyMap[ "strafe-up"] or Begin.keyMap["strafe-down"]: local_x, local_y, local_z = 0, 0, 0 cam_pos1 = base.camera.getPos() # Add aribitraty movement on the local axis relative to the key pressed. if Begin.keyMap["forward"]: local_x += 3000 * dt if Begin.keyMap["backward"]: local_x -= 3000 * dt if Begin.keyMap["strafe-right"]: local_y += 3000 * dt if Begin.keyMap["strafe-left"]: local_y -= 3000 * dt if Begin.keyMap["strafe-up"]: local_z += 3000 * dt if Begin.keyMap["strafe-down"]: local_z -= 3000 * dt base.camera.setPos(base.camera, local_y, local_x, local_z) cam_pos2 = base.camera.getPos() #Calculate the global velocity change from the local change # Note: dv_xyz delta velocity xyz dv_xyz = [] dv_xyz = [(cam_pos2[i] - cam_pos1[i]) / dt for i in range(0, 3)] # Calcualte the magnitude to limit player speed mag = math.sqrt((spaceship_speed_x)**2 + (spaceship_speed_y)**2 + (spaceship_speed_z)**2) if mag < max_player_speed: spaceship_speed_x += dv_xyz[0] spaceship_speed_y += dv_xyz[1] spaceship_speed_z += dv_xyz[2] else: possible_x, possible_y, possible_z = spaceship_speed_x, spaceship_speed_y, spaceship_speed_z possible_x += dv_xyz[0] possible_y += dv_xyz[1] possible_z += dv_xyz[2] possible_mag = math.sqrt((possible_x)**2 + (possible_y)**2 + (possible_z)**2) if possible_mag < mag: spaceship_speed_x += dv_xyz[0] spaceship_speed_y += dv_xyz[1] spaceship_speed_z += dv_xyz[2] # Separate from the top movement. Allow for camera rotation if Begin.keyMap["roll-left"]: camera_r = base.camera.getR() base.camera.setR(camera_r - 1) if Begin.keyMap["roll-right"]: camera_r = base.camera.getR() base.camera.setR((camera_r + 1)) return Task.cont def shoot(self): missle = Missle() base.cTrav.addCollider(missle.c_np, self.collHandEvent) def do_null(self): # Redefine the accept key to this to ignore key pass ##### // Tasks \\ ##### def score(self, collision_entry): global score global thunderstrike pointball = collision_entry.getIntoNodePath().parent score += int(pointball.getTag("value")) render.clearLight(pointball.find("**/plight")) pointball.removeNode() self.title.clearText() self.title = OnscreenText(text="Score: {0}".format(score), parent=base.a2dTopLeft, scale=.07, align=TextNode.ALeft, pos=(0.1, -0.1), fg=(1, 1, 1, 1), shadow=(0, 0, 0, 0.5), font=thunderstrike) return Task.cont # Test the distance of all asteroids. If the asteroid is too far away turn it around. def test_distance(self): global asteroid_max global asteroid_test_distance for asteroid in asteroid_total: if asteroid.ttl > 0: asteroid.ttl -= globalClock.getDt() else: asteroid_xyz = asteroid.np.getPos() camera_xyz = base.camera.getPos() distance = math.sqrt( (asteroid_xyz[0] - camera_xyz[0])**2 + (asteroid_xyz[1] - camera_xyz[1])**2 + (asteroid_xyz[2] - camera_xyz[2])**2) # Distance formula if distance > asteroid_test_distance: start_point = asteroid.get_sphere_points( asteroid_spawn_distance, base.camera) asteroid.asteroid_lerp.finish() asteroid.asteroid_path( start_point) #move to sphere relative to camera asteroid.ttl = 1 #asteroid.c_np.show() return Task.cont def mouseTask(self, task): global test_max_min dt = globalClock.getDt() # h_max : h_min , p_max : p_min mw = self.mouseWatcherNode if mw.hasMouse(): # get the window manager's idea of the mouse position x, y = mw.getMouseX(), mw.getMouseY() if self.lastMouseX is not None: dx, dy = x - self.lastMouseX, y - self.lastMouseY else: # no data to compare with yet dx, dy = 0, 0 self.lastMouseX, self.lastMouseY = x, y else: x, y, dx, dy = 0, 0, 0, 0 self.win.movePointer(0, int(self.win.getProperties().getXSize() / 2), int(self.win.getProperties().getYSize() / 2)) self.lastMouseX, self.lastMouseY = 0, 0 # scale position and delta to pixels for user w, h = self.win.getSize() # rotate camera by delta base.camera.setH(base.camera, dx * -800 * dt) base.camera.setP(base.camera, dy * 800 * dt) return Task.cont def remove_old_missles(self): global missle_total dt = globalClock.getDt() # delta t per frame for missle in missle_total: if missle.ttl <= 0: render.clearLight(missle.plnp) missle.core.removeNode() else: missle.ttl -= dt return Task.cont def pointballManager(self): global pointball_total dt = globalClock.getDt() # delta t per frame for pointball in pointball_total: # Animate the size scale_xyz = pointball.one.getScale() time = pointball.ttl_max - pointball.ttl dampened_cos = pointball.max_size * math.exp( 0.36 * -time) * math.cos(0.5 * math.pi * time) dampened_sin = pointball.max_size * math.exp( 0.36 * -time) * math.sin(0.5 * math.pi * time) pointball.one.setScale(dampened_cos, dampened_cos, dampened_cos) pointball.two.setScale(dampened_sin, dampened_sin, dampened_sin) # Move towards player if in range try: if pointball.center.getDistance( base.camera) < pointball.attraction_distance: cam_2_ball = pointball.center.getPos(base.camera) total = cam_2_ball[0] + cam_2_ball[1] + cam_2_ball[2] percent_xyz = [cam_2_ball[i] / total for i in range(0, 3)] pointball.center.setPos( base.camera, cam_2_ball[0] - 20000 * percent_xyz[0], cam_2_ball[1] - 20000 * percent_xyz[1], cam_2_ball[2] - 20000 * percent_xyz[2]) except: pass # Remove Old PointBalls if pointball.ttl <= 0: render.clearLight(pointball.plnp) pointball.center.removeNode() else: pointball.ttl -= dt #for index in range(0,len(pointball_total)- 1): # if pointball_total[index].ttl <= 0: # del pointball_total[index] return Task.cont def death_task(self): camera_hpr = base.camera.getHpr() dt = globalClock.getDt() h_speed = float(base.camera.getTag("h_speed")) p_speed = float(base.camera.getTag("p_speed")) r_speed = float(base.camera.getTag("r_speed")) base.camera.setHpr(camera_hpr[0] + h_speed * dt, camera_hpr[1] + p_speed * dt, camera_hpr[2] + r_speed * dt) base.camera.setX(base.camera.getX() + 4000 * dt) return Task.cont ##### // Colision Functions \\ ##### def shot_asteroid(self, collision_entry): global score_list global pointball_total global pointball_value #Remove the missle missle = collision_entry.getFromNodePath() try: render.clearLight(missle.parent.find("**/plight")) except: pass missle.removeNode() # Gather large asteroid info so still accesable after deleted # Note: na is short for "new_asteroid", has is "hit_asteroid_size" hit_asteroid = collision_entry.getIntoNodePath() hap = hit_asteroid.parent.getPos() has = hit_asteroid.parent.getTag("size") # Remove asteroid from list for index in range(0, len(asteroid_total) - 1): if asteroid_total[index].name == hit_asteroid.name: del asteroid_total[index] break # Delete before smaller asteoids are created to allow for asteroid-into-asteroid collisions hit_asteroid.parent.removeNode() # If small asteroid, just delete, if not create two of smaller size if not (has == "small"): # Generate 2 asteroids at oposite poistions (shimmy) within the larger asteoid, and oposite directions for index in range(0, 2): na = extra_smallasteroids.pop( ) if has == "medium" else extra_mediumasteroids.pop() # First asteroid can be random pos & direction if index == 0: shimmy = [ na.radius * random.randrange(-1, 2, 2), na.radius * random.randrange(-1, 2, 2), na.radius * random.randrange(-1, 2, 2) ] spawn_point = [ hap[0] + shimmy[0], hap[1] + shimmy[1], hap[2] + shimmy[2] ] future_location = False # Second asteroid should be oposite pos & direction of asteroid 1 else: spawn_point = [ hap[0] + shimmy[0] * -1, hap[1] + shimmy[1] * -1, hap[2] + shimmy[2] * -1 ] future_location = LPoint3(future_location[0] * -1, future_location[1] * -1, future_location[2] * -1) # Add asteroid to the game. This code is the same for both asteroids pl3_spawn = LPoint3(spawn_point[0], spawn_point[1], spawn_point[2]) na.add_togame(pl3_spawn, future_location) na.np.setTag("Created", "True") future_location = na.future_location base.cTrav.addCollider(na.c_np, self.collHandEvent) asteroid_total.append(na) # Create more asteroid for the ones we just deleted for i in range(0, 2): if na.size == "small": extra_smallasteroids.insert(0, Asteroid("small")) else: extra_mediumasteroids.insert(0, Asteroid("medium")) else: # Create the point ball current_time = int(time.time()) new_pointball_value = max(100 - (current_time - pointball_value), 20) pointball = PointBall(hap, new_pointball_value) pointball_total.append(pointball) pointball_value = current_time base.cTrav.addCollider(pointball.c_np, self.collHandEvent) # Add a new asteroid to the scene to asteroid = Asteroid() asteroid_total.insert(0, asteroid) base.cTrav.addCollider(asteroid.c_np, self.collHandEvent) asteroid.add_togame( asteroid.get_sphere_points(asteroid_spawn_distance, base.camera)) def end_game(self, collision_entry): global is_living global fog_quality is_living = False asteroid = collision_entry.getIntoNodePath() # Make the world red self.fog.setColor(0.5, 0, 0) self.fog.setExpDensity(fog_quality) self.setBackgroundColor(0.5, 0, 0, 1) # Set random spin upon death. This is called in the death_task base.camera.setTag("h_speed", str(random.randrange(0, 10))) base.camera.setTag("p_speed", str(random.randrange(0, 10))) base.camera.setTag("r_speed", str(random.uniform(0, 5))) # Stop unused tasks in death taskMgr.remove("Rotate player in hpr") taskMgr.remove("Score") taskMgr.remove("Move the Player in xyz") self.accept('mouse1', self.do_null) # Move player and look so player gets to see their killer base.camera.setX(base.camera.getX() + int(asteroid.parent.getTag("radius")) * 2) base.camera.lookAt(asteroid) # Start the death spiral + death text taskMgr.add(Begin.death_task, "Death Spin") self.death_text = OnscreenText( text="Your Spaceship has Crashed !\nPress [Escape]", font=thunderstrike, parent=base.aspect2d, scale=0.1, align=TextNode.ACenter, pos=(0, 0), fg=(1, 1, 1, 1), shadow=(0, 0, 0, 0.5)) self.death_text.reparentTo(aspect2d) ##### // Developement Functions \\ ##### def stop_moving(self): global spaceship_speed_x global spaceship_speed_y global spaceship_speed_z spaceship_speed_x = 0 spaceship_speed_y = 0 spaceship_speed_z = 0 print(f"camera hpr {base.camera.getHpr()}") print(f"camera pos {base.camera.getPos()}") def angle1(self): print("0,0,0") base.camera.setHpr(0, 0, 0) def angle2(self): print("90,0,0") base.camera.setHpr(90, 0, 0) def angle3(self): print("180,0,0") base.camera.setHpr(180, 0, 0) def angle4(self): print("270,0,0") base.camera.setHpr(270, 0, 0) def angle5(self): print("0,-90,0") base.camera.setHpr(0, 90, 0) def angle6(self): print("0,90,0") print(base.camera.getHpr()) base.camera.setHpr(0, -90, 0) ##### // Misc Functions \\ ##### def setKey(self, key, value): self.keyMap[key] = value def fullscreenToggle(self): global fullscreen global Frames if (not (fullscreen)): fullscreen = True self.set_windowsettings() else: fullscreen = False self.set_windowsettings() def set_windowsettings(self, reset_window=False): global fullscreen global cursor_hidden wp = WindowProperties() wp.setCursorHidden(cursor_hidden) base.setFrameRateMeter(Frames) wp.setFullscreen(fullscreen) wp.setSize(resolution) self.win.requestProperties(wp) if cursor_hidden: wp.setMouseMode(WindowProperties.M_relative) else: wp.setMouseMode(0) if reset_window: base.openMainWindow() base.graphicsEngine.openWindows() def framesToggle(self): global Frames if (Frames): base.setFrameRateMeter(False) Frames = False else: base.setFrameRateMeter(True) Frames = True def translate(self, value, leftMin, leftMax, rightMin, rightMax): # Scale value from input range to output range leftSpan = leftMax - leftMin rightSpan = rightMax - rightMin valueScaled = float(value - leftMin) / float(leftSpan) return rightMin + (valueScaled * rightSpan)