def set_controls(self): """Configure common game controls. Configure major keys, collisions system and controls to manipulate characters. """ base.accept("f1", self._show_keys) # noqa: F821 base.accept("escape", base.main_menu.show) # noqa: F821 base.accept("r", self._show_char_relations) # noqa: F821 base.accept("m", base.world.rails_scheme.show) # noqa: F821 base.accept("j", base.journal.show) # noqa: F821 # configure mouse collisions col_node = CollisionNode("mouse_ray") col_node.setIntoCollideMask(NO_MASK) col_node.setFromCollideMask(MOUSE_MASK) self._mouse_ray = CollisionRay() col_node.addSolid(self._mouse_ray) # set common collisions handler handler = CollisionHandlerEvent() handler.addInPattern("%fn-into") handler.addAgainPattern("%fn-again") handler.addOutPattern("%fn-out") self.traverser = CollisionTraverser("traverser") self.traverser.addCollider( base.cam.attachNewNode(col_node), handler # noqa: F821 ) self.set_mouse_events() taskMgr.doMethodLater(0.03, self._collide_mouse, "collide_mouse") # noqa: F821 taskMgr.doMethodLater(0.04, self._traverse, name="main_traverse") # noqa: F821
class CollisionBase(ShowBase): def __init__(self): self.cTrav = CollisionTraverser() self.mchandler = CollisionHandlerEvent() self.mchandler.addInPattern('into-%in') self.mchandler.addAgainPattern('%fn-again-%in') self.mchandler.addOutPattern('out-%in')
class CogdoFlyingCollisions(GravityWalker): wantFloorSphere = 0 def __init__(self): GravityWalker.__init__(self, gravity=0.0) def initializeCollisions(self, collisionTraverser, avatarNodePath, avatarRadius=1.4, floorOffset=1.0, reach=1.0): self.cHeadSphereNodePath = None self.cFloorEventSphereNodePath = None self.setupHeadSphere(avatarNodePath) self.setupFloorEventSphere(avatarNodePath, ToontownGlobals.FloorEventBitmask, avatarRadius) GravityWalker.initializeCollisions(self, collisionTraverser, avatarNodePath, avatarRadius, floorOffset, reach) return def setupWallSphere(self, bitmask, avatarRadius): self.avatarRadius = avatarRadius cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius) cSphereNode = CollisionNode('Flyer.cWallSphereNode') cSphereNode.addSolid(cSphere) cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) if config.GetBool('want-fluid-pusher', 0): self.pusher = CollisionHandlerFluidPusher() else: self.pusher = CollisionHandlerPusher() self.pusher.addCollider(cSphereNodePath, self.avatarNodePath) self.cWallSphereNodePath = cSphereNodePath def setupEventSphere(self, bitmask, avatarRadius): self.avatarRadius = avatarRadius cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius * 1.04) cSphere.setTangible(0) cSphereNode = CollisionNode('Flyer.cEventSphereNode') cSphereNode.addSolid(cSphere) cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.event = CollisionHandlerEvent() self.event.addInPattern('enter%in') self.event.addOutPattern('exit%in') self.cEventSphereNodePath = cSphereNodePath def setupRay(self, bitmask, floorOffset, reach): cRay = CollisionRay(0.0, 0.0, 3.0, 0.0, 0.0, -1.0) cRayNode = CollisionNode('Flyer.cRayNode') cRayNode.addSolid(cRay) self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode) cRayNode.setFromCollideMask(bitmask) cRayNode.setIntoCollideMask(BitMask32.allOff()) self.lifter = CollisionHandlerGravity() self.lifter.setLegacyMode(self._legacyLifter) self.lifter.setGravity(self.getGravity(0)) self.lifter.addInPattern('%fn-enter-%in') self.lifter.addAgainPattern('%fn-again-%in') self.lifter.addOutPattern('%fn-exit-%in') self.lifter.setOffset(floorOffset) self.lifter.setReach(reach) self.lifter.addCollider(self.cRayNodePath, self.avatarNodePath) def setupHeadSphere(self, avatarNodePath): collSphere = CollisionSphere(0, 0, 0, 1) collSphere.setTangible(1) collNode = CollisionNode('Flyer.cHeadCollSphere') collNode.setFromCollideMask(ToontownGlobals.CeilingBitmask) collNode.setIntoCollideMask(BitMask32.allOff()) collNode.addSolid(collSphere) self.cHeadSphereNodePath = avatarNodePath.attachNewNode(collNode) self.cHeadSphereNodePath.setZ(base.localAvatar.getHeight() + 1.0) self.headCollisionEvent = CollisionHandlerEvent() self.headCollisionEvent.addInPattern('%fn-enter-%in') self.headCollisionEvent.addOutPattern('%fn-exit-%in') base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent) def setupFloorEventSphere(self, avatarNodePath, bitmask, avatarRadius): cSphere = CollisionSphere(0.0, 0.0, 0.0, 0.75) cSphereNode = CollisionNode('Flyer.cFloorEventSphere') cSphereNode.addSolid(cSphere) cSphereNodePath = avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.floorCollisionEvent = CollisionHandlerEvent() self.floorCollisionEvent.addInPattern('%fn-enter-%in') self.floorCollisionEvent.addAgainPattern('%fn-again-%in') self.floorCollisionEvent.addOutPattern('%fn-exit-%in') base.cTrav.addCollider(cSphereNodePath, self.floorCollisionEvent) self.cFloorEventSphereNodePath = cSphereNodePath def deleteCollisions(self): GravityWalker.deleteCollisions(self) if self.cHeadSphereNodePath != None: base.cTrav.removeCollider(self.cHeadSphereNodePath) self.cHeadSphereNodePath.detachNode() self.cHeadSphereNodePath = None self.headCollisionsEvent = None if self.cFloorEventSphereNodePath != None: base.cTrav.removeCollider(self.cFloorEventSphereNodePath) self.cFloorEventSphereNodePath.detachNode() self.cFloorEventSphereNodePath = None self.floorCollisionEvent = None self.cRayNodePath.detachNode() del self.cRayNodePath self.cEventSphereNodePath.detachNode() del self.cEventSphereNodePath return def setCollisionsActive(self, active=1): if self.collisionsActive != active: if self.cHeadSphereNodePath != None: base.cTrav.removeCollider(self.cHeadSphereNodePath) if active: base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent) if self.cFloorEventSphereNodePath != None: base.cTrav.removeCollider(self.cFloorEventSphereNodePath) if active: base.cTrav.addCollider(self.cFloorEventSphereNodePath, self.floorCollisionEvent) GravityWalker.setCollisionsActive(self, active) return def enableAvatarControls(self): pass def disableAvatarControls(self): pass def handleAvatarControls(self, task): pass
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 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 CogdoFlyingCollisions(GravityWalker): wantFloorSphere = 0 def __init__(self): GravityWalker.__init__(self, gravity=0.0) def initializeCollisions(self, collisionTraverser, avatarNodePath, avatarRadius = 1.4, floorOffset = 1.0, reach = 1.0): self.cHeadSphereNodePath = None self.cFloorEventSphereNodePath = None self.setupHeadSphere(avatarNodePath) self.setupFloorEventSphere(avatarNodePath, ToontownGlobals.FloorEventBitmask, avatarRadius) GravityWalker.initializeCollisions(self, collisionTraverser, avatarNodePath, avatarRadius, floorOffset, reach) return def setupWallSphere(self, bitmask, avatarRadius): self.avatarRadius = avatarRadius cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius) cSphereNode = CollisionNode('Flyer.cWallSphereNode') cSphereNode.addSolid(cSphere) cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) if config.GetBool('want-fluid-pusher', 0): self.pusher = CollisionHandlerFluidPusher() else: self.pusher = CollisionHandlerPusher() self.pusher.addCollider(cSphereNodePath, self.avatarNodePath) self.cWallSphereNodePath = cSphereNodePath def setupEventSphere(self, bitmask, avatarRadius): self.avatarRadius = avatarRadius cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius * 1.04) cSphere.setTangible(0) cSphereNode = CollisionNode('Flyer.cEventSphereNode') cSphereNode.addSolid(cSphere) cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.event = CollisionHandlerEvent() self.event.addInPattern('enter%in') self.event.addOutPattern('exit%in') self.cEventSphereNodePath = cSphereNodePath def setupRay(self, bitmask, floorOffset, reach): cRay = CollisionRay(0.0, 0.0, 3.0, 0.0, 0.0, -1.0) cRayNode = CollisionNode('Flyer.cRayNode') cRayNode.addSolid(cRay) self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode) cRayNode.setFromCollideMask(bitmask) cRayNode.setIntoCollideMask(BitMask32.allOff()) self.lifter = CollisionHandlerGravity() self.lifter.setLegacyMode(self._legacyLifter) self.lifter.setGravity(self.getGravity(0)) self.lifter.addInPattern('%fn-enter-%in') self.lifter.addAgainPattern('%fn-again-%in') self.lifter.addOutPattern('%fn-exit-%in') self.lifter.setOffset(floorOffset) self.lifter.setReach(reach) self.lifter.addCollider(self.cRayNodePath, self.avatarNodePath) def setupHeadSphere(self, avatarNodePath): collSphere = CollisionSphere(0, 0, 0, 1) collSphere.setTangible(1) collNode = CollisionNode('Flyer.cHeadCollSphere') collNode.setFromCollideMask(ToontownGlobals.CeilingBitmask) collNode.setIntoCollideMask(BitMask32.allOff()) collNode.addSolid(collSphere) self.cHeadSphereNodePath = avatarNodePath.attachNewNode(collNode) self.cHeadSphereNodePath.setZ(base.localAvatar.getHeight() + 1.0) self.headCollisionEvent = CollisionHandlerEvent() self.headCollisionEvent.addInPattern('%fn-enter-%in') self.headCollisionEvent.addOutPattern('%fn-exit-%in') base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent) def setupFloorEventSphere(self, avatarNodePath, bitmask, avatarRadius): cSphere = CollisionSphere(0.0, 0.0, 0.0, 0.75) cSphereNode = CollisionNode('Flyer.cFloorEventSphere') cSphereNode.addSolid(cSphere) cSphereNodePath = avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.floorCollisionEvent = CollisionHandlerEvent() self.floorCollisionEvent.addInPattern('%fn-enter-%in') self.floorCollisionEvent.addAgainPattern('%fn-again-%in') self.floorCollisionEvent.addOutPattern('%fn-exit-%in') base.cTrav.addCollider(cSphereNodePath, self.floorCollisionEvent) self.cFloorEventSphereNodePath = cSphereNodePath def deleteCollisions(self): GravityWalker.deleteCollisions(self) if self.cHeadSphereNodePath != None: base.cTrav.removeCollider(self.cHeadSphereNodePath) self.cHeadSphereNodePath.detachNode() self.cHeadSphereNodePath = None self.headCollisionsEvent = None if self.cFloorEventSphereNodePath != None: base.cTrav.removeCollider(self.cFloorEventSphereNodePath) self.cFloorEventSphereNodePath.detachNode() self.cFloorEventSphereNodePath = None self.floorCollisionEvent = None self.cRayNodePath.detachNode() del self.cRayNodePath self.cEventSphereNodePath.detachNode() del self.cEventSphereNodePath return def setCollisionsActive(self, active = 1): if self.collisionsActive != active: if self.cHeadSphereNodePath != None: base.cTrav.removeCollider(self.cHeadSphereNodePath) if active: base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent) if self.cFloorEventSphereNodePath != None: base.cTrav.removeCollider(self.cFloorEventSphereNodePath) if active: base.cTrav.addCollider(self.cFloorEventSphereNodePath, self.floorCollisionEvent) GravityWalker.setCollisionsActive(self, active) return def enableAvatarControls(self): pass def disableAvatarControls(self): pass def handleAvatarControls(self, task): pass
def __init__(self): global collide ShowBase.__init__(self) self.traverser = CollisionTraverser('traverser1') base.cTrav = self.traverser #traverser.addCollider(cnode1, handler) entry = 1 imageObject = OnscreenImage(image = '/Users/devanshi/Downloads/sky.png', pos = (0, 0, 0), scale = 2) imageObject.setTransparency(TransparencyAttrib.MAlpha) base.cam.node().getDisplayRegion(0).setSort(20) self.forest=NodePath(PandaNode("Forest Root")) self.forest.reparentTo(render) loader.loadModel("models/background").reparentTo(self.forest) loader.loadModel("models/foliage01").reparentTo(self.forest) loader.loadModel("models/foliage02").reparentTo(self.forest) loader.loadModel("models/foliage03").reparentTo(self.forest) loader.loadModel("models/foliage04").reparentTo(self.forest) loader.loadModel("models/foliage05").reparentTo(self.forest) loader.loadModel("models/foliage06").reparentTo(self.forest) loader.loadModel("models/foliage07").reparentTo(self.forest) loader.loadModel("models/foliage08").reparentTo(self.forest) loader.loadModel("models/foliage09").reparentTo(self.forest) self.forest1=NodePath(PandaNode("Forest Root")) self.forest1.reparentTo(render) loader.loadModel("models/foliage01").reparentTo(self.forest1) loader.loadModel("models/foliage02").reparentTo(self.forest1) loader.loadModel("models/foliage03").reparentTo(self.forest1) loader.loadModel("models/foliage04").reparentTo(self.forest1) loader.loadModel("models/foliage05").reparentTo(self.forest1) loader.loadModel("models/foliage06").reparentTo(self.forest1) loader.loadModel("models/foliage07").reparentTo(self.forest1) loader.loadModel("models/foliage08").reparentTo(self.forest1) loader.loadModel("models/foliage09").reparentTo(self.forest1) self.forest.hide(BitMask32.bit(1)) self.forest.setScale(2.5, 2.5, 2.5) self.forest.setPos(0, 0, -2) self.forest1.hide(BitMask32.bit(1)) self.forest1.setScale(1.5, 1.5, 1.5) self.forest1.setPos(-1,-1, 0) self.forest2=NodePath(PandaNode("Forest Root")) self.forest2.reparentTo(render) loader.loadModel("models/foliage01").reparentTo(self.forest2) loader.loadModel("models/foliage02").reparentTo(self.forest2) loader.loadModel("models/foliage03").reparentTo(self.forest2) loader.loadModel("models/foliage04").reparentTo(self.forest2) loader.loadModel("models/foliage05").reparentTo(self.forest2) loader.loadModel("models/foliage06").reparentTo(self.forest2) loader.loadModel("models/foliage07").reparentTo(self.forest2) loader.loadModel("models/foliage08").reparentTo(self.forest2) loader.loadModel("models/foliage09").reparentTo(self.forest2) self.forest2.hide(BitMask32.bit(1)) self.forest1.setScale(1.5, 1.5, 1.5) self.forest1.setPos(1,1, 0) self.stall = self.loader.loadModel("models/patch/cornfield") self.stall.reparentTo(self.render) self.stall.setScale(0.5) self.stall.setPos(40,0,1) self.stall.setHpr(0,0,0) self.tex1=self.loader.loadTexture("models/water.png") self.stall.setTexture(self.tex1,1) self.flock = Actor("models/goose/goosemodelonly", {"gfly":"models/goose/gooseanimationonly" }) self.flock.setScale(0.05, 0.05, 0.05) self.flock.setPos(0,-30,13) self.flock.reparentTo(self.render) self.flock.loop("gfly") self.tex2=self.loader.loadTexture("models/orange.jpg") self.flock.setTexture(self.tex2,1) self.camera.setPos(0,0,0) self.camera.setHpr(90,0,0) # Create the four lerp intervals needed for the panda to # walk back and forth. pandaPosInterval1 = self.flock.posInterval(13, Point3(-5, -30, 13), startPos=Point3(5, -30, 13)) pandaPosInterval2 = self.flock.posInterval(13, Point3(5, -30, 13), startPos=Point3(-5, -30, 13)) pandaHprInterval1 = self.flock.hprInterval(3, Point3(0, 0, 0), startHpr=Point3(180, 0, 0)) pandaHprInterval2 = self.flock.hprInterval(3, Point3(180, 0, 0), startHpr=Point3(0, 0, 0)) # Create and play the sequence that coordinates the intervals. self.pandaPace = Sequence(pandaPosInterval1, pandaHprInterval1, pandaPosInterval2, pandaHprInterval2, name="pandaPace") self.pandaPace.loop() # Disable the camera trackball controls. #self.disableMouse() # Load the environment model. self.environ = self.loader.loadModel("models/environment1") # Reparent the model to render. self.environ.reparentTo(self.render) # Apply scale and position transforms on the model. self.environ.setScale(0.25, 0.25, 0.25) self.environ.setPos(-8, 42, 0) self.boy = Actor("models/trex/trex", {"run":"models/trex/trex-run", "eat":"models/trex/trex-eat"}) self.boy.reparentTo(self.render) self.boy.setPos(0,0,0) self.boy.setScale(0.5) self.isMoving = False self.myAnimControl = self.boy.getAnimControl('run') base.camera.setPos(self.boy.getX(),self.boy.getY()+10,20) self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(render) self.cBoy = self.boy.attachNewNode(CollisionNode('cBoyNode')) self.cBoy.node().addSolid(CollisionSphere(0, 0, 3, 8.5)) #self.cBoy.show() #self.cPond = self.stall.attachNewNode(CollisionNode('cPond')) #self.cPond.node().addSolid(CollisionSphere(40, 0, 1, 70)) #self.cPond.show() # Add the spinCameraTask procedure to the task manager. #self.taskMgr.add(self.spinCameraTask,"asdsad") self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0} cs1 = CollisionSphere(0, 0, 0, 2) self.cnodePath1 = render.attachNewNode(CollisionNode('cnode1')) self.cnodePath1.node().addSolid(cs1) #self.cnodePath1.setCollideMask(BitMask32(0x10)) #self.cnodePath1.show() self.taskMgr.add(self.moveSphere1, "sfasdasf") cs2 = CollisionSphere(0, 0, 0, 1) self.cnodePath2 = render.attachNewNode(CollisionNode('cnode2')) self.cnodePath2.node().addSolid(cs2) #self.cnodePath2.reparentTo(self.render) #self.cnodePath2.node().setFromCollideMask(BitMask32.bit(0)) #self.cnodePath2.node().setIntoCollideMask(BitMask32.allOff()) #self.cnodePath2.show() self.taskMgr.add(self.moveSphere2, "sfasd") handler = CollisionHandlerEvent() handler.addInPattern('cnode1-into-cnode2') handler.addAgainPattern('cnode1-again-cnode2') handler.addOutPattern('cs1-out-cs2') self.accept('cnode1-into-cnode2', self.collide) #self.accept('cs1-out-cs2', self.collide) #self.accept('cnode1-again-cnode2', self.collide) self.traverser.addCollider(self.cnodePath1, handler) # Load and transform the panda actor. self.pandaActor = Actor("models/panda-model", {"walk": "models/panda-walk4"}) self.pandaActor.setScale(0.005, 0.005, 0.005) self.pandaActor.reparentTo(self.render) # Loop its animation. self.pandaActor.loop("walk") self.taskMgr.add(self.movePanda, "Sasdas") self.pandaActor2 = Actor("models/panda-model",{"walk": "models/panda-walk4"}) self.pandaActor2.setScale(0.003, 0.003, 0.003) self.pandaActor2.reparentTo(self.render) # Loop its animation. self.pandaActor2.loop("walk") self.taskMgr.add(self.movePanda2, "Sak") self.camera.setPos(0,0,0) self.camera.setHpr(90,0,0) self.cTrav1=CollisionTraverser() self.collisionHandler1 = CollisionHandlerQueue() self.cTrav1.addCollider(self.cBoy, self.collisionHandler1) self.taskMgr.add(self.boyMoveTask, "BoyMoveTask") #self.accept("v",self.switchView) self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left",1]) self.accept("arrow_right", self.setKey, ["right",1]) self.accept("arrow_up", self.setKey, ["forward",1]) #self.accept("a", self.setKey, ["cam-left",1]) #self.accept("s", self.setKey, ["cam-right",1]) self.accept("arrow_left-up", self.setKey, ["left",0]) self.accept("arrow_right-up", self.setKey, ["right",0]) self.accept("arrow_up-up", self.setKey, ["forward",0]) #self.accept("a-up", self.setKey, ["cam-left",0]) #self.accept("s-up", self.setKey, ["cam-right",0]) self.cTrav2=CollisionTraverser() self.collisionHandler2 = CollisionHandlerQueue()
mpos = base.mouseWatcherNode.getMouse() # this function will set our ray to shoot from the actual camera lenses off the 3d scene, passing by the mouse pointer position, making magically hit what is pointed by it in the 3d space pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) return task.cont #** Now the tricky part: we have here a particular kind of pattern that react firing a task event when a collider, tagged as 'rays', whatever the value is stored into, hit an object tagged as 'balls', no matter what value is stored into its tag. The resulting event strings sent to the panda3D event manager will be the result of the FROM collider (ray) and the tag value owned by the INTO object being hit (a ball), provided that was settled with a tag key 'balls'. # That said, these two lines will catch all the events for either smiles and frowneys because we both tagged 'em as 'balls', for all IN events... collisionHandler.addInPattern("%(rays)ft-into-%(balls)it") # ...and here for the OUT events collisionHandler.addOutPattern("%(rays)ft-out-%(balls)it") #** To complicate things a little, this time we'll going to use the addAgainPattern method, that will raise an event while the mouse ponter is keeping over a ball of any group. Note that the 'ray_again_all' chunk will be used by the CollisionHandlerEvent to fire the event. See the related accept below. collisionHandler.addAgainPattern("ray_again_all%(" "rays" ")fh%(" "balls" ")ih") """ Note that we could have been done the same using this form as well: collisionHandler.addAgainPattern("%(rays)ft-again-%(balls)it") but then we should have used 2 accepts like this: DO.accept('ray1-again-smileys', collideAgainBalls) DO.accept('ray1-again-frowney', collideAgainBalls) instead of just one as we did below, and this don't hurt very much in this snippet cos' we got just 2 groups, but could be complicated if we need to use a lot more groups. Another big thing to note is that we could have been done all of this using the masking technique (see step4.py). """
class MyApp(ShowBase): def center_mouse(self): self.win.movePointer(0,self.win.getXSize()/2,self.win.getYSize()/2) def __init__(self): #Game variables self.health = 100 self.panda_kill_count = 0 self.level = 0 #Implementation variables #self.color = [Vec4((204.0/255), (255.0/255), (204/255), 0.1),Vec4((0/255), (255.0/255), (255.0/255), 0.1),Vec4((255.0/255), (51.0/255), (255.0/255), 0.1),Vec4((153.0/255), (255.0/255), (153.0/255), 0.1),Vec4((255.0/255), (178.0/255), (102.0/255), 0.1),Vec4((229.0/255), (204.0/255), (255.0/255), 0.1)] self.color = [Vec4(0.4,0.4,0.4,0.1)] self.mirror=False self.paused=False self.displayed=False self.game_started=False self.randomthings_ = randomthings.RandomThings(self) self.shifted_cam=False self.is_firstP=False self.old_anim2 = None self.old_anim=None self.timeout=False (self.r,self.f,self.b,self.l)=(0,0,0,0) self.inside_level=False self.move_anim_queue=[] self.anim_queue=[] self.prev_time=0.0 self.bullets = [] self.rightspeed=0 self.forwardspeed=0 ShowBase.__init__(self) self.makeDefaultPipe() bb=self.pipe.getDisplayHeight() aa=self.pipe.getDisplayWidth() self.openDefaultWindow(size=(aa, bb)) import layer2d self.layer2d = layer2d self.layer2d.update_info('Loading...') self.keyreader= ReadKeys(self,layer2d) #Sounds self.gunshot = self.loader.loadSfx("sounds/gunshot_se.ogg") self.gunshot.setLoop(False) self.music = self.loader.loadSfx("sounds/music.ogg") self.music.setLoop(True) self.zombie_die = self.loader.loadSfx('sounds/zombie_die.ogg') self.zombie_die.setLoop(False) self.kicked = self.loader.loadSfx('sounds/kicked.ogg') self.kicked.setLoop(False) self.hurt_sound = self.loader.loadSfx('sounds/hurt.ogg') self.hurt_sound.setLoop(False) self.dead_sound = self.loader.loadSfx('sounds/dead.ogg') self.dead_sound.setLoop(False) self.intro_sound = self.loader.loadSfx('sounds/intro.ogg') self.intro_sound.setLoop(False) self.intro_sound.play() self.enableParticles() self.center_mouse() #self.disableMouse() self.prev_pos = None if base.mouseWatcherNode.hasMouse(): x=base.mouseWatcherNode.getMouseX() y=base.mouseWatcherNode.getMouseY() self.prev_pos = (x,y) #Hide cursor props = WindowProperties() props.setCursorHidden(True) self.win.requestProperties(props) self.environ = self.loader.loadModel('models/ourworld') self.environ.setPos(0,0,0) self.environ.reparentTo(self.render) self.pandaActor = Actor("models/hero_anim", {'kick':'models/hero_anim-kick','unready_to_shoot':'models/hero_anim-unready_to_shoot','jump':'models/hero_anim-jump',"shooting":"models/hero_anim-shooting","ready_to_shoot":"models/hero_anim-ready_to_shoot","ready_to_walk":"models/hero_anim-ready_to_run","ready_to_run":"models/hero_anim-ready_to_run","walk4":"models/hero_anim-walk1", "breathe": "models/hero_anim-breathe", "run": "models/hero_anim-walk"}) self.pandaActor.setPlayRate(3,'ready_to_shoot') self.pandaActor.setPlayRate(-1.0,"ready_to_walk") self.pandaActor.setPlayRate(1.5,'run') self.pandaActor.setPlayRate(1.5,'ready_to_run') self.pandaActor.reparentTo(self.render) self.pandaActor.setPos(self.environ,0,0,100) self.pandaActor.loop("breathe") self.phy = NodePath("PhysicsNode") self.phy.reparentTo(self.render) self.pandaAN = ActorNode("PandaActor") self.pandaActorPhysicsP = self.phy.attachNewNode(self.pandaAN) self.physicsMgr.attachPhysicalNode(self.pandaAN) self.pandaActor.reparentTo(self.pandaActorPhysicsP) #set mass of panda self.pandaAN.getPhysicsObject().setMass(100) #apply gravity self.gravityFN=ForceNode('world-forces') self.gravityFNP=self.environ.attachNewNode(self.gravityFN) self.gravityForce=LinearVectorForce(0,0,-30.81) #gravity acceleration self.gravityFN.addForce(self.gravityForce) self.physicsMgr.addLinearForce(self.gravityForce) #camera stuff self.camera.reparentTo(self.pandaActor) self.camera.lookAt(self.pandaActor) self.taskMgr.add(self.spinCameraTask, "zombieTask_SpinCameraTask") self.taskMgr.doMethodLater(0.01,self.movePandaTask,"zombieTask_movePandaTask") #Collision Handling self.cTrav = CollisionTraverser() self.collisionHandler = CollisionHandlerEvent() #Add collider for terrain self.groundCollider = self.environ.find("**/terrain") #Add walker for panda self.collision_sphere = CollisionSphere(0,0,1,1) self.collNode = CollisionNode('pandaWalker') self.cnodePath = self.pandaActor.attachNewNode(self.collNode) self.cnodePath.node().addSolid(self.collision_sphere) #AddZombieDetector for panda self.zombie_sphere = CollisionSphere(0,0,3,1) self.zomb_detector_node = CollisionNode('zombieDetector') self.zomb_detector_NP = self.pandaActor.attachNewNode(self.zomb_detector_node) self.zomb_detector_NP.node().addSolid(self.zombie_sphere) #self.zomb_detector_NP.show() #Add pusher against gravity self.pusher = PhysicsCollisionHandler() self.pusher.addCollider(self.cnodePath, self.pandaActorPhysicsP) self.pusher.addCollider(self.zomb_detector_NP,self.pandaActorPhysicsP) self.cTrav.addCollider(self.cnodePath,self.pusher) self.cTrav.addCollider(self.zomb_detector_NP,self.pusher) self.pusher.addInPattern('%fn-into-%in') self.pusher.addAgainPattern('%fn-again-%in') #Add collision handler patterns self.collisionHandler.addInPattern('%fn-into-%in') self.collisionHandler.addAgainPattern('%fn-again-%in') self.abientLight = AmbientLight("ambientLight") self.abientLight.setColor(Vec4(0.1, 0.1, 0.1, 1)) self.directionalLight = DirectionalLight("directionalLight") self.directionalLight.setDirection(Vec3(-5, -5, -5)) self.directionalLight.setColor(Vec4((229.0/255), (204.0/255), (255.0/255), 0.7)) self.directionalLight.setSpecularColor(Vec4(0.4, 0.4, 0.4, 0.1)) self.directionalLight.setShadowCaster(True,512,512) self.render.setLight(self.render.attachNewNode(self.abientLight)) self.render.setLight(self.render.attachNewNode(self.directionalLight)) self.render.setShaderAuto() #create zombie land self.zombieland = zombie.Zombies(self) self.taskMgr.doMethodLater(0.01,self.zombieland.moveZombie, "zombieTask_ZombieMover") layer2d.incBar(self.health) self.taskMgr.add(self.game_monitor,"zombieTask_gameMonitor") self.taskMgr.doMethodLater(2.7,self.music_play, "zombieTask_music") #Add random useless things: self.randomthings_.add_random_things() def music_play(self,task): self.music.play() return Task.done #def get_color(self): # return self.color[min(len(self.color)-1,self.level)] #GameMonitor def game_monitor(self,task): if self.paused: return Task.cont #Update Score self.layer2d.update_score(self.panda_kill_count) #Check for health of actor if self.health <= 0: self.dead_sound.play() self.pandaActor.detachNode() print "LOL u ded" self.info = """Game Over.. Score: """ + str(self.panda_kill_count) + """ Press alt+f4 to quit the game. """ self.layer2d.update_info(self.info) self.taskMgr.removeTasksMatching('zombieTask_*') if self.game_started<>True: if not self.displayed: self.display_information() self.pandaActor.setPos(self.pandaActorPhysicsP.getRelativePoint(self.render,Point3(10,10,100))) return Task.cont #Check if user is inside some level. if yes, pass. if self.inside_level or self.timeout: return Task.cont self.inside_level = True #self.health=100 self.timeout=True print ".." #The next lines will be executed only when the user is in between two levels (or at the beginning of the game) #Display information based on game level self.display_information() print "HUEHUEHUEHUE" #Schedule wave of zombies self.taskMgr.doMethodLater(10,self.addWave, "zombieTask_ZombieAdder") return Task.cont def addWave(self,task): ##add a wave of 5 zombies, depending on the level. ##speed of zombie increases with each level ##durability of zombie increases with each level. ##Wave ends when all zombies die. self.directionalLight.setSpecularColor(Vec4(0.4, 0.4, 0.4, 0.1)) self.layer2d.update_info("level"+str(self.level)) self.timeout=False self.zombieland.add(5) return Task.done #information displayer def display_information(self): #display information based on levels. print self.game_started self.displayed=True if self.game_started==False: info = """ Welcome to PandaLand. Once upon a time, there used to be these cute little creatures called Pandas. They were lazy, funny, and adorable. But that is what we humans thought. Pandas are actually an evil alien race that spread from planet to planet, spreading destruction and terror everywhere. They ruled earth several billion years ago. But our super ancestors (Dinosaurs) fought agaisnt them with great valour and selflessness; and managed to save planet Earth from doom. But the pandas went into hiding (and became cute); until few days back! Now they seek to kill all. You, the Joker, are our only hope,since Batman has retired. Go Kill Pandas.For Mother Earth! """ self.layer2d.information['bg'] = (0,0,0,0.8) else: self.layer2d.update_info('') if self.level==0: info=""" Your game will start in a few seconds. This is the first level. Pandas will spawn and follow you. Shoot to kill. Test out your controls while they are still cute and harmless :) Jump: Space Shoot: LeftClick Kick: RightClick Walk: A/W/S/D For more information, press P. """ self.layer2d.information['bg'] = (0,0,0,0.6) elif self.level==1: info=""" Level 0 Completed! Starting Level 1. Pandas have turned evil and stronger. They will try to eat you up. To run: Press Shift + A/S/W/D """ elif self.level==2: info=""" Level 1 Completed! Starting Level 2. Pandas are even stronger now. They will get stronger by each level. Your automatic shooting speed has also improved due to experience gained. """ elif self.level==3: info=""" Level 2 Completed! Starting Level 3. Pandas also move faster by each level. They really want to eat you. But don't worry, you also run faster as the levels proceed. """ else: info = """ Level """ + str(self.level-1) + """ Completed! Starting """ + str(self.level) + """ . Well done! Keep fighting, our fate lies in your hands. """ self.layer2d.update_info(info) #self.create_bullet() def create_bullet(self): self.bullet = self.loader.loadModel('models/gun/bullet') self.gunshot.play() self.bulletAN = ActorNode("BulletNode") self.bulletActorPhysicsP = self.phy.attachNewNode(self.bulletAN) self.physicsMgr.attachPhysicalNode(self.bulletAN) self.bullet.reparentTo(self.bulletActorPhysicsP) self.bulletAN.getPhysicsObject().setMass(1) self.bullet.setPos(self.pandaActor,0,-3,3.5) self.bullet.setScale(0.1,0.1,0.1) self.bullet.setHpr(self.pandaActor,0,90,0) self.bullet.setP(self.camera.getP()+90) self.bullet_sphere = CollisionSphere(0,0,0,0.2) self.bullet_collNode = CollisionNode('bullet') self.bullet_cnodePath = self.bullet.attachNewNode(self.bullet_collNode) self.bullet_cnodePath.node().addSolid(self.bullet_sphere) #self.pusher.addCollider(self.bullet_cnodePath,self.bulletActorPhysicsP) self.cTrav.addCollider(self.bullet_cnodePath,self.collisionHandler) #self.bullet_cnodePath.show() self.bullets += [self.bullet] def bulletKiller(self,task): if self.paused: return Task.cont self.bullets[0].remove_node() self.bullets = self.bullets[1:] return Task.done def bulletThrower(self,task): if self.paused: return Task.cont #make bullet move if self.pandaActor.getCurrentAnim()<>'shooting' and self.pandaActor.getCurrentAnim()<>'ready_to_shoot': self.pandaActor.play('shooting') print "loL" self.create_bullet() self.bulletAN.getPhysicsObject().setVelocity(self.render.getRelativeVector(self.camera,Vec3(0,200,0))) self.taskMgr.doMethodLater(max(0.05,0.1*(5-self.level)),self.bulletThrower, "zombieTask_bulletThrower") self.taskMgr.doMethodLater(0.5,self.bulletKiller, "zombieTask_bulletKiller") self.prev=True if self.old_anim2==None: self.old_anim2='breathe' if self.old_anim2 not in ['run','walk4']: self.old_anim2='breathe' self.anim_queue = [(self.pandaActor,True,'unready_to_shoot'),(self.pandaActor,False,self.old_anim2)] return Task.done def movePandaTask(self,task): if self.paused: return Task.cont tempos = self.pandaActor.getPos() speed = 0.1 if self.run_: speed+=0.3*self.level self.rightspeed = -(self.r-self.l)*speed self.forwardspeed = -(self.f-self.b)*speed if (self.r-self.l)<>0 and (self.f-self.b)<>0: #print self.forwardspeed #print self.rightspeed #sys.exit(0) self.rightspeed *= 0.7 self.forwardspeed *= 0.7 self.pandaActor.setPos(self.pandaActor,self.rightspeed, self.forwardspeed,0) return Task.again def spinCameraTask(self, task): if self.paused: return Task.cont if self.render.getRelativePoint(self.pandaActorPhysicsP,self.pandaActor.getPos())[2] < -10: self.pandaAN.getPhysicsObject().setVelocity(0,0,30) #self.pandaActor.setPos(self.pandaActorPhysicsP.getRelativePoint(self.render,Point3(10,10,100))) self.prev_time=task.time #play queued animations: for x in self.move_anim_queue+self.anim_queue: if x[0].getCurrentAnim()==None: if x[1]: x[0].play(x[2]) else: x[0].loop(x[2]) if x in self.move_anim_queue: self.move_anim_queue.remove(x) elif x in self.anim_queue: self.anim_queue.remove(x) #Do other stuff if self.mouseWatcherNode.hasMouse(): x=base.mouseWatcherNode.getMouseX() y=base.mouseWatcherNode.getMouseY() if self.prev_pos==None: self.prev_pos = (x,y) xx = self.prev_pos[0] - x yy = self.prev_pos[1] + y self.prev_pos = (xx,yy) self.pandaActor.setHpr(self.pandaActor,-20*(pi/2.0)*x,0,0) #self.camera.setHpr(self.pandaActor, 20*(pi/2.0)*x, 20*(pi/2.0)*yy, 0) if self.is_firstP: self.camera.lookAt(self.pandaActor) self.camera.setPos(self.pandaActor,0,0,4) self.camera.setHpr(self.camera,180,0,0) else: self.camera.setPos(self.pandaActor,0,8,5) self.camera.lookAt(self.pandaActor) if self.mirror: self.camera.setY(-self.camera.getY()) self.camera.lookAt(self.pandaActor) self.camera.setHpr(self.camera,0,20*(pi/2.0)*yy,0) self.center_mouse() #zombie collisions return Task.cont #User Actions: def meelee(self): #Make actor stomp here. or something #Load animation self.zombieland.meelee() self.anim_queue += [(self.pandaActor,True,self.pandaActor.getCurrentAnim())] self.pandaActor.play('kick') #pass def ranged_start(self): #put animation here self.old_anim = self.pandaActor.getCurrentAnim() if self.old_anim not in ['shooting','unready_to_shoot','ready_to_shoot'] : self.old_anim2 = self.old_anim if self.old_anim not in ['ready_to_shoot','shooting','unready_to_shoot']: self.pandaActor.play('ready_to_shoot') self.taskMgr.add(self.bulletThrower, "zombieTask_bulletThrower") def ranged_stop(self,task=None): if self.paused: return Task.cont #stop animation here if self.pandaActor.getCurrentAnim()<>'shooting' and task==None: self.pandaActor.play('shooting') self.taskMgr.remove("zombieTask_bulletThrower") self.taskMgr.doMethodLater(0.5,self.ranged_stop,'zombieTask_rangedStop') return Task.done self.taskMgr.remove("zombieTask_bulletThrower") return Task.done