def camera_move(self, task): """ Moves the camera about the quadcopter """ keys_vs_moves = {'k': i, 'h': -i, 'i': j, 'y': -j, 'u': k, 'j': -k } mat = np.array(self.cam.getMat())[0:3, 0:3] move_total = LPoint3f(0, 0, 0) for key, move in keys_vs_moves.items(): pressed_key = self.mouseWatcherNode.is_button_down(KeyboardButton.asciiKey(key)) if pressed_key: move = LPoint3f(move) move_total += move # if any([abs(coordinate) > 0 for coordinate in move_total]): # ROTATE COORDINATE SYSTEM (TO CAMERA) move_total = LPoint3f(*tuple(np.dot(mat.T, np.array(move_total)))) proportionality_constant = 0.05 cam_pos = self.cam.getPos() + move_total * proportionality_constant self.cam.setPos(cam_pos) self.cam.lookAt(self.quad_model) return task.cont
def keystroke(self, key): key = str(KeyboardButton.asciiKey(key)) if key == None: return if key == 'space': key = ' ' if len(key) != 1: return if not application.paused: if hasattr(__main__, 'keystroke'): __main__.keystroke(key) for entity in scene.entities: if entity.enabled == False or entity.ignore or entity.ignore_input: continue if application.paused and entity.ignore_paused == False: continue if hasattr(entity, 'keystroke') and callable(entity.keystroke): entity.keystroke(key) if hasattr(entity, 'scripts'): for script in entity.scripts: if script.enabled and hasattr(script, 'keystroke') and callable( script.keystroke): script.keystroke(key)
def _saveLayout(self): if self.modButtons.isDown(KeyboardButton.control()): self.modButtons.buttonUp(KeyboardButton.control()) self.modButtons.buttonUp(KeyboardButton.asciiKey('s')) filename = asksaveasfilename(filetypes=[('plist files', '*.plist')]) if filename: self.layout.save(filename) AppPreferences.set('last_layout', filename)
def __init__(self, charNr): FSM.__init__(self, "FSM-Player%d"%charNr) charPath = "characters/character%d/" % charNr self.character = Actor( charPath + "char"#, { #"Idle":charPath + "idle", #"walk":charPath + "walk", #"punch_l":charPath + "punch_l", #"punch_r":charPath + "punch_r", #"kick_l":charPath + "kick_l", #"kick_r":charPath + "kick_r", #"defend":charPath + "defend" #} ) self.character.reparentTo(render) self.character.hide() self.walkSpeed = 5.0 # units per second self.leftButton = KeyboardButton.asciiKey('a') self.rightButton = KeyboardButton.asciiKey('d')
def _openLayout(self): if self.modButtons.isDown(KeyboardButton.control()): self.modButtons.buttonUp(KeyboardButton.control()) self.modButtons.buttonUp(KeyboardButton.asciiKey('o')) filename = askopenfilename(filetypes=[('plist files', '*.plist')]) if filename: if self.layout: NodePath(self.layout).detachNode() self.layout = MissionLayout.loadLayout(filename) render.attachNewNode(self.layout) AppPreferences.set('last_layout', filename)
def defineKeys(self): for k in self.keyState.keys(): self.keyState[k] = False if self.isKeyDown(KeyboardButton.up()): self.keyState["WalkFw"] = True if self.isKeyDown(KeyboardButton.down()): self.keyState["WalkBw"] = True if self.isKeyDown(KeyboardButton.left()): self.keyState["RotateL"] = True if self.isKeyDown(KeyboardButton.right()): self.keyState["RotateR"] = True if self.isKeyDown(KeyboardButton.shift()): self.keyState["Run"] = True if self.isKeyDown(KeyboardButton.space()): self.keyState["Jump"] = True if self.isKeyDown(KeyboardButton.asciiKey("d")): self.keyState["Duck"] = True
def cameraControlTask(self, windowSizeX, windowSizeY, task): mw = self.base.mouseWatcherNode curPos = self.camera.getPos() curHpr = self.camera.getHpr() forward = self.camera.getQuat().getForward() right = self.camera.getQuat().getRight() up = self.camera.getQuat().getUp() moveSpeed = .05 rotSpeed = 20 # get initial mouse position, this runs only once on the first frame after the task is added to the taskmanager if self.setAnchor: self.anchorX = mw.getMouseX() self.anchorY = mw.getMouseY() self.setAnchor = False # update rotation if mw.hasMouse(): deltaX = rotSpeed * ((mw.getMouseX() - self.anchorX)) deltaY = rotSpeed * ((mw.getMouseY() - self.anchorY)) self.base.win.movePointer( 0, int((0.5 * self.anchorX + 0.5) * windowSizeX), int((-0.5 * self.anchorY + 0.5) * windowSizeY)) threshold = 0.05 if abs(deltaX) < threshold: deltaX = 0 if abs(deltaY) < threshold: deltaY = 0 self.camera.setHpr(curHpr.getX() - deltaX, curHpr.getY() + deltaY, 0) # update position deltaPos = Vec3(0, 0, 0) if mw.isButtonDown(KeyboardButton.asciiKey(bytes('w', 'utf-8'))): deltaPos += forward if mw.isButtonDown(KeyboardButton.asciiKey(bytes('s', 'utf-8'))): deltaPos -= forward if mw.isButtonDown(KeyboardButton.asciiKey(bytes('d', 'utf-8'))): deltaPos += right if mw.isButtonDown(KeyboardButton.asciiKey(bytes('a', 'utf-8'))): deltaPos -= right if mw.isButtonDown(KeyboardButton.asciiKey(bytes('e', 'utf-8'))): deltaPos += up if mw.isButtonDown(KeyboardButton.asciiKey(bytes('q', 'utf-8'))): deltaPos -= up deltaPos.normalize() deltaPos *= moveSpeed self.camera.setPos(curPos + deltaPos) return task.cont
class InputMapperTecladoMouse(InputMapper): # teclas accion defecto TeclasAccionDefecto = { KeyboardButton.enter(): InputMapper.AccionArrojar, KeyboardButton.space(): InputMapper.AccionAscender, KeyboardButton.tab(): InputMapper.AccionUsar, KeyboardButton.control(): InputMapper.AccionAgachar, KeyboardButton.alt(): InputMapper.AccionAgarrar, KeyboardButton.asciiKey(b"c"): InputMapper.AccionFlotar, KeyboardButton.asciiKey(b"x"): InputMapper.AccionSoltar, KeyboardButton.asciiKey(b"z"): InputMapper.AccionFrenar, KeyboardButton.asciiKey(b"w"): InputMapper.AccionAvanzar, KeyboardButton.asciiKey(b"a"): InputMapper.AccionAvanzar, KeyboardButton.asciiKey(b"s"): InputMapper.AccionAvanzar, KeyboardButton.asciiKey(b"d"): InputMapper.AccionAvanzar, KeyboardButton.asciiKey(b"r"): InputMapper.AccionAvanzar, KeyboardButton.asciiKey(b"f"): InputMapper.AccionAvanzar } # teclas parametro defecto TeclasParamDefecto = { KeyboardButton.asciiKey(b"w"): InputMapper.ParametroAdelante, KeyboardButton.asciiKey(b"a"): InputMapper.ParametroIzquierda, KeyboardButton.asciiKey(b"s"): InputMapper.ParametroAtras, KeyboardButton.asciiKey(b"d"): InputMapper.ParametroDerecha, KeyboardButton.asciiKey(b"r"): InputMapper.ParametroArriba, KeyboardButton.asciiKey(b"f"): InputMapper.ParametroAbajo, KeyboardButton.asciiKey(b"q"): InputMapper.ParametroGirando | InputMapper.ParametroIzquierda, KeyboardButton.asciiKey(b"e"): InputMapper.ParametroGirando | InputMapper.ParametroDerecha, KeyboardButton.shift(): InputMapper.ParametroRapido, KeyboardButton.asciiKey(b"v"): InputMapper.ParametroLento } def __init__(self, base): InputMapper.__init__(self, base) def update(self): # parametros self.parametros = InputMapper.ParametroNulo for tecla, parametro in InputMapperTecladoMouse.TeclasParamDefecto.items( ): if self.isButtonDown(tecla): self.parametros |= parametro # acciones self.accion = InputMapper.AccionNula for tecla, accion in InputMapperTecladoMouse.TeclasAccionDefecto.items( ): if self.isButtonDown(tecla): self.accion = accion break
def __init__(self, charId, charNr, controls): FSM.__init__(self, "FSM-Player{}".format(charNr)) self.charId = charId charPath = "characters/character{}/".format(charNr) self.character = Actor( charPath + "char", { "Idle": charPath + "idle", "Walk": charPath + "walk", "Walk_back": charPath + "walk_back", "Punch_l": charPath + "punch_l", "Punch_r": charPath + "punch_r", "Kick_l": charPath + "kick_l", "Kick_r": charPath + "kick_r", "Defend": charPath + "defend", "Hit": charPath + "hit", "Defeated": charPath + "defeated", }, ) self.character.reparentTo(render) self.character.hide() self.walkSpeed = 2.0 # units per second if controls == "p1": self.character.setH(90) self.leftButton = KeyboardButton.asciiKey("d") self.rightButton = KeyboardButton.asciiKey("f") self.punchLButton = KeyboardButton.asciiKey("q") self.punchRButton = KeyboardButton.asciiKey("w") self.kickLButton = KeyboardButton.asciiKey("a") self.kickRButton = KeyboardButton.asciiKey("s") self.defendButton = KeyboardButton.asciiKey("e") elif controls == "p2": self.character.setH(-90) self.leftButton = KeyboardButton.right() self.rightButton = KeyboardButton.left() self.punchLButton = KeyboardButton.asciiKey("i") self.punchRButton = KeyboardButton.asciiKey("o") self.kickLButton = KeyboardButton.asciiKey("k") self.kickRButton = KeyboardButton.asciiKey("l") self.defendButton = KeyboardButton.asciiKey("p") self.getPos = self.character.getPos self.getX = self.character.getX characterSphere = CollisionSphere(0, 0, 1.0, 0.5) self.collisionNodeName = "character{}Collision".format(charId) characterColNode = CollisionNode(self.collisionNodeName) characterColNode.addSolid(characterSphere) self.characterCollision = self.character.attachNewNode(characterColNode) # Uncomment this line to show collision solids # self.characterCollision.show() base.pusher.addCollider(self.characterCollision, self.character) base.cTrav.addCollider(self.characterCollision, base.pusher) characterHitRay = CollisionSegment(0, -0.5, 1.0, 0, -0.8, 1.0) characterColNode.addSolid(characterHitRay) self.audioStep = base.audio3d.loadSfx("assets/audio/step.ogg") self.audioStep.setLoop(True) base.audio3d.attachSoundToObject(self.audioStep, self.character) self.audioHit = base.audio3d.loadSfx("assets/audio/hit.ogg") self.audioHit.setLoop(False) base.audio3d.attachSoundToObject(self.audioStep, self.character)
def __init__(self, charId, charNr, controls): FSM.__init__(self, "FSM-Player{}".format(charNr)) self.charId = charId charPath = "characters/character{}/".format(charNr) self.character = Actor( charPath + "char", { "Idle": charPath + "idle", "Walk": charPath + "walk", "Walk_back": charPath + "walk_back", "Punch_l": charPath + "punch_l", "Punch_r": charPath + "punch_r", "Kick_l": charPath + "kick_l", "Kick_r": charPath + "kick_r", "Defend": charPath + "defend", "Hit": charPath + "hit", "Defeated": charPath + "defeated" }) self.character.reparentTo(render) self.character.hide() self.walkSpeed = 2.0 # units per second if controls == "p1": self.character.setH(90) self.leftButton = KeyboardButton.asciiKey(b"d") self.rightButton = KeyboardButton.asciiKey(b"f") self.punchLButton = KeyboardButton.asciiKey(b"q") self.punchRButton = KeyboardButton.asciiKey(b"w") self.kickLButton = KeyboardButton.asciiKey(b"a") self.kickRButton = KeyboardButton.asciiKey(b"s") self.defendButton = KeyboardButton.asciiKey(b"e") elif controls == "p2": self.character.setH(-90) self.leftButton = KeyboardButton.right() self.rightButton = KeyboardButton.left() self.punchLButton = KeyboardButton.asciiKey(b"i") self.punchRButton = KeyboardButton.asciiKey(b"o") self.kickLButton = KeyboardButton.asciiKey(b"k") self.kickRButton = KeyboardButton.asciiKey(b"l") self.defendButton = KeyboardButton.asciiKey(b"p") self.getPos = self.character.getPos self.getX = self.character.getX characterSphere = CollisionSphere(0, 0, 1.0, 0.5) self.collisionNodeName = "character{}Collision".format(charId) characterColNode = CollisionNode(self.collisionNodeName) characterColNode.addSolid(characterSphere) self.characterCollision = self.character.attachNewNode( characterColNode) # Uncomment this line to show collision solids #self.characterCollision.show() base.pusher.addCollider(self.characterCollision, self.character) base.cTrav.addCollider(self.characterCollision, base.pusher) characterHitRay = CollisionSegment(0, -0.5, 1.0, 0, -0.8, 1.0) characterColNode.addSolid(characterHitRay) self.audioStep = base.audio3d.loadSfx("assets/audio/step.ogg") self.audioStep.setLoop(True) base.audio3d.attachSoundToObject(self.audioStep, self.character) self.audioHit = base.audio3d.loadSfx("assets/audio/hit.ogg") self.audioHit.setLoop(False) base.audio3d.attachSoundToObject(self.audioStep, self.character)
def quad_move(self, task): position_proportionality_constant = 0.0007 angle_proportionality_constant = 0.2 angle_max = 10 angle_directions = {i: k, j: -j} keys_vs_moves = {'w': i, 's': -i, 'a': j, 'd': -j, 'e': k, 'q': -k} move_total = LPoint3f(0, 0, 0) angle_total = LPoint3f(0, 0, 0) for key, move in keys_vs_moves.items(): pressed_key = self.mouseWatcherNode.is_button_down(KeyboardButton.asciiKey(key)) if pressed_key: move_total += move if key not in ['e', 'q', 'm']: angle_total += LPoint3f(*tuple(sign(move) * np.array( angle_directions[LPoint3f(*tuple(int(abs(c)) for c in move))]) * angle_proportionality_constant)) else: prop_sign = 1 if key == 'e' else -1 for prop in self.prop_models: prop.setHpr(prop.get_hpr() + LPoint3f(10 * prop_sign, 0, 0)) self.movements += key with open(ROOT_DIR + self.simulation_folder + 'movements.txt', 'w') as file: file.write(self.movements) # self.movie(namePrefix=self.simulation_folder, duration=1.0, fps=30, # format='png', sd=4, source=None) if any([abs(coordinate) > 0 for coordinate in angle_total]): # tilt_force_node = ForceNode('tilt-force') # tilt_force = AngularVectorForce(*angle_total) # tilt_force_node.addForce(tilt_force) # # self.actor_node.getPhysical(0).addAngularForce(tilt_force) desired_quad_hpr = list(self.quad_model.getHpr() + angle_total) for index, coordinate in enumerate(desired_quad_hpr): if coordinate: desired_quad_hpr[index] = sign(coordinate) * min(abs(coordinate), 90 + angle_max if index == 0 else angle_max) desired_quad_hpr = LPoint3f(*desired_quad_hpr) self.quad_model.setHpr(desired_quad_hpr) if any([abs(coordinate) > 0 for coordinate in move_total]): movement_force_node = ForceNode('movement-force') movement_force = LinearVectorForce(*(- move_total * position_proportionality_constant)) # movement_force.setMassDependent(1) movement_force_node.addForce(movement_force) self.actor_node.getPhysical(0).addLinearForce(movement_force) # time.sleep(0.1) # thruster.setP(-45) # bend the thruster nozzle out at 45 degrees # desired_quad_pos = self.quad_model.getPos() + move_total * position_proportionality_constant # self.quad_model.setPos(desired_quad_pos) return task.cont
def __init__(self): # # MODEL AND ANIMATION # # The players model file path self.basePath = "character/" self.model = self.basePath + "character" # Paths of the animation files self.anim_idle = self.basePath + "character-Idle" self.anim_walk = self.basePath + "character-Walk" self.anim_plant = self.basePath + "character-Plant" # NOTE: This should always be enabled to smoth the transition within # animations. For example for the accleration of the character # untill it reaches full pace. self.enable_interpolation = True # # AUDIO # self.sfxPath = "sfx/" self.walk_sound = loader.loadSfx(self.sfxPath + "step.ogg") self.walk_sound.setLoop(True) # # CONTROLS # self.key_forward = KeyboardButton.asciiKey('w') self.key_backward = KeyboardButton.asciiKey('s') self.key_left = KeyboardButton.asciiKey('a') self.key_right = KeyboardButton.asciiKey('d') self.key_plant = KeyboardButton.space() self.key_center_camera = KeyboardButton.home() # accleration for the various states self.accleration = 3.5 # the speed of how fast the player deacclerates self.deaccleration = 16.0 # maximum acclerations at the various states self.max_accleration = 8.0 # the speed for how fast the player is generally moving self.speed = 0.7 # # GAME SPECIFIC # # planting possibility self.planting_enabled = False self.carry_seed = False # # CAMERA CONTROL VARIABLES # # Camera basics self.cam_near_clip = 0.5 self.cam_far_clip = 5000 self.cam_fov = 70 # Mouse camera movement # enables the camera control via the mouse self.enable_mouse = True # invert vertical camera movements self.mouse_invert_vertical = False # screen sizes self.win_width_half = base.win.getXSize() / 2 self.win_height_half = base.win.getYSize() / 2 # mouse speed self.mouse_speed_x = 150.0 self.mouse_speed_y = 80.0 # the next two vars will set the min and max distance the cam can have # to the node it is attached to self.max_cam_distance = 5.0 self.min_cam_distance = 2.0 # the initial cam distance self.cam_distance = (self.max_cam_distance - self.min_cam_distance) / 2.0 + self.min_cam_distance # the maximum distance on the Z-Axis to the player self.max_cam_height_distance = 2.0 # the minimum distance on the Z-Axis to the player self.min_cam_height_distance = 0.15 # the average camera height self.cam_height_avg = (self.max_cam_height_distance - self.min_cam_height_distance) / 2.0 + self.min_cam_height_distance # the initial cam height self.cam_height = self.cam_height_avg # the speed of the cameras justification movement towards # the average height self.cam_z_justification_speed = 1 # a floater which hovers over the player and is used as a # look at position for the camera self.cam_floater_pos = Point3F(0, 0, 1.5) # # PHYSICS # # show collision solids self.show_collisions = False # The physical physic_world which will be responsible for collision checks and # physic updates self.physic_world = None # the name of the collision solids that surround the character self.char_collision_name = "CharacterCollisions" # the mass of the character self.player_mass = 25 # the heights of the various player states # normal height self.player_height = 1.186 # the radius of the players collision shape self.player_radius = self.player_height / 4.0 # step height self.stepheight = 0.7
def __init__(self, charId, charNr, controls): # 参数 controls 是一个字符串变量,我们等待 p# 之类的值,其中 # 必须是 1 或 2 ,因为我们只有两个游戏玩家 # 使用字符编号调用 init 函数,因此我们可以将该类用于我们存储在资产中的任何字符模型,而不需要为每个字符编写一个类以的字符ID FSM.__init__(self, "FSM-Player{}".format(charNr)) # 初始化 FSM 类 self.charId = charId charPath = "characters/character{}/".format(charNr) # 使用存储在 charNr 中的字符编号来选择玩家所选字符的文件夹 self.character = Actor( charPath + "char", { "Idle":charPath + "idle", "walk":charPath + "walk", "punch_l":charPath + "punch_l", "punch_r":charPath + "punch_r", "kick_l":charPath + "kick_l", "kick_r":charPath + "kick_r", "Hit":charPath + "hit", "defend":charPath + "defend" }) # 告诉Panda3D引擎加载动画模型,演员是由引擎设置的全局功能。这个函数的第一个参数是我们角色的主要模型,第二个是名称和路径字符串的映射。名称将用于稍后选择应播放哪个动画,另一个字符串确定 .egg 文件的路径,该文件包含属于主模型的动画。请注意,不需要也不应该将.egg 扩展名添加到路径中,因为稍后鸡蛋文件将转换为bam文件格式,我们将在后面的部分中对其进行描述。 # self.character.setH(90) # 将字符围绕其向上指向轴旋转90度,在这种情况下,该轴是Z轴。 # 告诉引擎它应该将字符添加到渲染节点。必须对应该在引擎创建的3D空间中呈现的任何对象执行此操作。 self.character.reparentTo(render) # render 是由引擎设置的全局变量 self.character.hide() # 直接调用 hide 函数,因为我们不希望角色在加载后直接显示。 # 使用一组预定义的运动变量为角色添加键盘交互 self.walkSpeed = 2.0 # units per second if controls == "p1": self.character.setH(90) self.leftButton = KeyboardButton.asciiKey(b"d") self.rightButton = KeyboardButton.asciiKey(b"f") # 使用'D'和'F'键分别让角色左右移动 self.punchLButton = KeyboardButton.asciiKey(b"q") self.punchRButton = KeyboardButton.asciiKey(b"w") self.kickLButton = KeyboardButton.asciiKey(b"a") self.kickRButton = KeyboardButton.asciiKey(b"s") self.defendButton = KeyboardButton.asciiKey(b"e") elif controls == "p2": self.character.setH(-90) self.leftButton = KeyboardButton.right() self.rightButton = KeyboardButton.left() self.punchLButton = KeyboardButton.asciiKey(b"i") self.punchRButton = KeyboardButton.asciiKey(b"o") self.kickLButton = KeyboardButton.asciiKey(b"k") self.kickRButton = KeyboardButton.asciiKey(b"l") self.defendButton = KeyboardButton.asciiKey(b"p")
def move(self, task): # Get the time that elapsed since last frame. We multiply this with # the desired speed in order to find out with which distance to move # in order to achieve that desired speed. dt = globalClock.getDt() # If the camera-left key is pressed, move camera left. # If the camera-right key is pressed, move camera right. if self.isDown(KeyboardButton.asciiKey(b"j")): base.camera.setX(base.camera, -20 * dt) if self.isDown(KeyboardButton.asciiKey(b"k")): base.camera.setX(base.camera, +20 * dt) # If a move-key is pressed, move ralph in the specified direction. if self.isDown(KeyboardButton.asciiKey(b"a")): self.ralph.setH(self.ralph.getH() + 300 * dt) if self.isDown(KeyboardButton.asciiKey(b"d")): self.ralph.setH(self.ralph.getH() - 300 * dt) if self.isDown(KeyboardButton.asciiKey(b"w")): self.ralph.setY(self.ralph, -20 * dt) if self.isDown(KeyboardButton.asciiKey(b"s")): self.ralph.setY(self.ralph, +10 * dt) # update distributed position and rotation #self.ralph.setDistPos(self.ralph.getX(), self.ralph.getY(), self.ralph.getZ()) #self.ralph.setDistHpr(self.ralph.getH(), self.ralph.getP(), self.ralph.getR()) # If ralph is moving, loop the run animation. # If he is standing still, stop the animation. currentAnim = self.ralph.getCurrentAnim() if self.isDown(KeyboardButton.asciiKey(b"w")): if currentAnim != "run": self.ralph.loop("run") elif self.isDown(KeyboardButton.asciiKey(b"s")): # Play the walk animation backwards. if currentAnim != "walk": self.ralph.loop("walk") self.ralph.setPlayRate(-1.0, "walk") elif self.isDown(KeyboardButton.asciiKey(b"a")) or self.isDown(KeyboardButton.asciiKey(b"d")): if currentAnim != "walk": self.ralph.loop("walk") self.ralph.setPlayRate(1.0, "walk") else: if currentAnim is not None: self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. camvec = self.ralph.getPos() - base.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if camdist > 10.0: base.camera.setPos(base.camera.getPos() + camvec * (camdist - 10)) camdist = 10.0 if camdist < 5.0: base.camera.setPos(base.camera.getPos() - camvec * (5 - camdist)) camdist = 5.0 # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. base.camera.lookAt(self.floater) return task.cont
def __init__(self, charId, charNr, controls): FSM.__init__(self, "FSM-Player{}".format(charNr)) self.charId = charId charPath = "characters/character{}/".format(charNr) self.character = Actor( charPath + "char", { "Idle": charPath + "idle", "Walk": charPath + "walk", "Walk_back": charPath + "walk_back", "Punch_l": charPath + "punch_l", "Punch_r": charPath + "punch_r", "Kick_l": charPath + "kick_l", "Kick_r": charPath + "kick_r", "Hit": charPath + "hit", "Defend": charPath + "defend", "Defeated": charPath + "defeated" }) self.character.reparentTo(render) self.character.hide() self.walkSpeed = 2.0 if controls == "p1": self.character.setH(90) self.leftButton = KeyboardButton.asciiKey("d") self.rightButton = KeyboardButton.asciiKey("f") self.punchLButton = KeyboardButton.asciiKey("q") self.punchRButton = KeyboardButton.asciiKey("w") self.kickLButton = KeyboardButton.asciiKey("a") self.kickRButton = KeyboardButton.asciiKey("s") self.defendButton = KeyboardButton.asciiKey("e") elif controls == "p2": self.character.setH(-90) self.leftButton = KeyboardButton.right() self.rightButton = KeyboardButton.left() self.punchLButton = KeyboardButton.asciiKey("i") self.punchRButton = KeyboardButton.asciiKey("o") self.kickLButton = KeyboardButton.asciiKey("k") self.kickRButton = KeyboardButton.asciiKey("l") self.defendButton = KeyboardButton.asciiKey("p") characterSphere = CollisionSphere(0, 0, 1.0, 0.5) self.collisionNodeName = "character{}Collision".format(charId) characterColNode = CollisionNode(self.collisionNodeName) characterColNode.addSolid(characterSphere) self.characterCollision = self.character.attachNewNode( characterColNode) base.pusher.addCollider(self.characterCollision, self.character) base.cTrav.addCollider(self.characterCollision, base.pusher) characterHitRay = CollisionSegment(0, -0.5, 1.0, 0, -0.8, 1.0) characterColNode.addSolid(characterHitRay) self.getPos = self.character.getPos self.getX = self.character.getX