예제 #1
0
class Game:
    def __init__(self):
        SDL_Init(SDL_INIT_EVERYTHING)

        self.player = None
        self.bat = None
        self.map = None

    def __del__(self):
        SDL_Quit()

    def run(self):
        graphics = Graphics(units.tileToPixel(SCREEN_WIDTH),
                            units.tileToPixel(SCREEN_HEIGHT))
        input = Input()
        event = SDL_Event()

        self.player = Player(graphics,
                             units.tileToGame(SCREEN_WIDTH // 2),
                             units.tileToGame(SCREEN_HEIGHT // 2))
        self.bat = FirstCaveBat(graphics,
                                units.tileToGame(7),
                                units.tileToGame(SCREEN_HEIGHT // 2 + 1))
        self.map = Map.createTestMap(graphics)

        running = True
        lastUpdateTime = SDL_GetTicks() # units.MS
        while running:
            startTime = SDL_GetTicks() # units.MS
            input.beginNewFrame()
            while SDL_PollEvent(ctypes.byref(event)):
                if event.type == SDL_KEYDOWN:
                    input.keyDownEvent(event)
                elif event.type == SDL_KEYUP:
                    input.keyUpEvent(event)

            if input.wasKeyPressed(SDLK_ESCAPE):
                running = False

            # Player horizontal movement
            if input.isKeyHeld(SDLK_LEFT) and input.isKeyHeld(SDLK_RIGHT):
                self.player.stopMoving()
            elif input.isKeyHeld(SDLK_LEFT):
                self.player.startMovingLeft()
            elif input.isKeyHeld(SDLK_RIGHT):
                self.player.startMovingRight()
            else:
                self.player.stopMoving()

            # Player look
            if input.isKeyHeld(SDLK_UP) and input.isKeyHeld(SDLK_DOWN):
                self.player.lookHorizontal()
            elif input.isKeyHeld(SDLK_UP):
                self.player.lookUp()
            elif input.isKeyHeld(SDLK_DOWN):
                self.player.lookDown()
            else:
                self.player.lookHorizontal()

            # Player jump
            if input.wasKeyPressed(SDLK_z):
                self.player.startJump()
            elif input.wasKeyReleased(SDLK_z):
                self.player.stopJump()

            currentTime = SDL_GetTicks() # units.MS
            elapsedTime = currentTime - lastUpdateTime # units.MS
            self.update(min(elapsedTime, MAX_FRAME_TIME))
            lastUpdateTime = currentTime

            self.draw(graphics)

            # This loop lasts 1/60th of a second, or 1000/60th ms
            msPerFrame = 1000 // FPS # units.MS
            elapsedTime = SDL_GetTicks() - startTime # units.MS
            if elapsedTime < msPerFrame:
                SDL_Delay(msPerFrame - elapsedTime)

    def update(self, elapsedTime):
        self.player.update(elapsedTime, self.map)
        self.bat.update(elapsedTime, self.player.centerX())

        if self.bat.damageRect().collidesWith(self.player.damageRect()):
            self.player.takeDamage()

    def draw(self, graphics):
        graphics.clear()
        self.map.drawBackground(graphics)
        self.bat.draw(graphics)
        self.player.draw(graphics)
        self.map.draw(graphics)
        self.player.drawHud(graphics)
        graphics.flip()
예제 #2
0
class World(DirectObject):

    def __init__(self):
        
        self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0, "charge":0, "fall":0}
        base.win.setClearColor(Vec4(0,0,0,1))

        # Post the instructions

        self.title = addTitle("")
        
        self.environ = loader.loadModel("../resources/level/test/world")      
        self.environ.reparentTo(render)
        self.environ.setPos(0,0,-1000)
        
        
        # Create the main character, Ralph
        #self.ralph = addPlayer(0,0,0)
        ralphStartPos = self.environ.find("**/start_point").getPos()
        self.ralph = Player("p1")
        self.ralph.setColor("stony_red")
        self.ralph.reparentTo(render)
        
        self.lvlContainer = LevelContainer("../resources/level/test.ppm")
        self.lvlContainer.render(self.environ,loader)
        
        #audio3d = Audio3DManager.Audio3DManager(base.sfxManagerList[0], camera)
        #mySound = audio3d.loadSfx('mario03.wav')
        #audio3d.attachSoundToObject(mySound, self.ralph)

        # Create a floater object.  We use the "floater" as a temporary
        # variable in a variety of calculations.
        
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)

        # Accept the control keys for movement and rotation

        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.accept("c", self.setKey, ["charge",1])
        self.accept("c-up", self.setKey, ["charge",0])
        self.accept("x", self.setKey, ["fall",1])
        self.accept("x-up", self.setKey, ["fall",0])

        taskMgr.add(self.move,"moveTask")

        # Set up the camera
        
        base.disableMouse()
        base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,2)
        
        # We will detect the height of the terrain by creating a collision
        # ray and casting it downward toward the terrain.  One ray will
        # start above ralph's head, and the other will start above the camera.
        # A ray may hit the terrain, or it may hit a rock or a tree.  If it
        # hits the terrain, we can detect the height.  If it hits anything
        # else, we rule that the move is illegal.

        self.cTrav = CollisionTraverser()

        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0,0,1000)
        self.ralphGroundRay.setDirection(0,0,-1)
        self.ralphGroundCol = CollisionNode('ralphRay')
        self.ralphGroundCol.addSolid(self.ralphGroundRay)
        self.ralphGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.ralphGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol)
        self.ralphGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler)

        self.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0,0,1000)
        self.camGroundRay.setDirection(0,0,-1)
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)
        
        mySound = base.loader.loadSfx("audio/t2.mp3")
        mySound.setVolume(0.5)
        mySound.play()

        # Uncomment this line to see the collision rays
        #self.ralphGroundColNp.show()
        #self.camGroundColNp.show()
       
        # Uncomment this line to show a visual representation of the 
        # collisions occuring
        #self.cTrav.showCollisions(render)
        
        # Create some lighting
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor(Vec4(.3, .3, .3, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection(Vec3(-5, -5, -5))
        directionalLight.setColor(Vec4(1, 1, 1, 1))
        directionalLight.setSpecularColor(Vec4(1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))
    
    #Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value
    

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):

        # If the camera-left key is pressed, move camera left.
        # If the camera-right key is pressed, move camera right.

        base.camera.lookAt(self.ralph)
        if (self.keyMap["cam-left"]!=0):
            base.camera.setX(base.camera, -20 * globalClock.getDt())
        if (self.keyMap["cam-right"]!=0):
            base.camera.setX(base.camera, +20 * globalClock.getDt())

        # save ralph's initial position so that we can restore it,
        # in case he falls off the map or runs into something.

        startpos = self.ralph.getPos()

        # If a move-key is pressed, move ralph in the specified direction.
        if (self.keyMap["charge"]!=0):
            self.ralph.charge()
        if (self.keyMap["charge"]==0):
            self.ralph.stopCharge()
            
             # If a move-key is pressed, move ralph in the specified direction.
        if (self.keyMap["fall"]==1):
            self.ralph.fall()


        if (self.keyMap["left"]!=0):
            self.ralph.rotateLeft()
        if (self.keyMap["right"]!=0):
            self.ralph.rotateRight()
        if (self.keyMap["forward"]!=0):
            self.ralph.moveForward()
        if(self.keyMap["left"]==0 and self.keyMap["right"]==0 and self.keyMap["forward"]==0):
            self.ralph.stopMoving()

        # 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

        # Now check for collisions.

        self.cTrav.traverse(render)

        # Adjust ralph's Z coordinate.  If ralph's ray hit terrain,
        # update his Z. If it hit anything else, or didn't hit anything, put
        # him back where he was last frame.

        entries = []
        for i in range(self.ralphGroundHandler.getNumEntries()):
            entry = self.ralphGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.ralph.setZ(entries[0].getSurfacePoint(render).getZ())
        else:
            self.ralph.setPos(startpos)

        # Keep the camera at one foot above the terrain,
        # or two feet above ralph, whichever is greater.
        
        entries = []
        for i in range(self.camGroundHandler.getNumEntries()):
            entry = self.camGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0)
        if (base.camera.getZ() < self.ralph.getZ() + 2.0):
            base.camera.setZ(self.ralph.getZ() + 2.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.
        
        self.floater.setPos(self.ralph.getPos())
        self.floater.setZ(self.ralph.getZ() + 2.0)
        base.camera.lookAt(self.floater)

        return task.cont
        
        
    def addPlayer(self,x,y,z):
        player = Actor("character/pushy.x",
                                 {"falling":"character/new/pushy_charge.x",
                                  "run":"character/new/pushy_run.x",
                                  "standup":"character/pushy_standup.x",
                                  "walk":"character/pushy.x"})
        player.reparentTo(render)
        player.setScale(.2)
        player.setPos(x,y,z)
        # 0.05 fall
        #run 0.1
        player.setPlayRate(0.5, "falling")
        player.setPlayRate(0.1, "run")
        player.state = 0
        audio3d = Audio3DManager.Audio3DManager(base.sfxManagerList[0], camera)
        mySound = audio3d.loadSfx('mario03.wav')
        audio3d.attachSoundToObject(mySound, self.ralph)