Python游戏问题

时间:2014-12-09 19:53:24

标签: python

我正在为我的CS课程开发2D python游戏项目,我遇到了一个问题,我不知道问题是什么:

这个项目是我成绩的很大一部分,直到现在我还有A + 这个项目非常令人沮丧

好吧所以到目前为止我已经完成了所有工作,除了某些原因我的protaganist()卡在游戏画面的左上角!

另外,我需要有关如何创建跳转动作的想法

如果有人能提供帮助,我将非常感激!

我正在导入我的老师从他的图书网站上提供的游戏引擎,但是我添加的时间太长了,但我会尝试在底部添加一些

这是我的所有代码:

            import gameEngine
            import pygame
            import math

            pygame.init()

            screen = pygame.display.set_mode((640, 480))


            pygame.mixer.init()

            sndAtk = pygame.mixer.Sound("OOT_AdultLink_Attack1.wav")
            #goal is to create a game
            #must have menu to start game
            #menu should have a start and quit button.. start runs gaming operations and quit exits program
            #sprites for character and enemies and bullets maybe, use one large image and simply move visibiliy
            #this saves memory as 1 image is loaded instead of many
            """
            class game(gameEngine.scene):
                def __init__(self, scene):
                    self.background()

                    self.sprites["spawn.gif", "badguys.gif"]
            """
            """
            protaganist is our hero sprite
            should run left and right, jump left and right
            and attack left and right...
            I might add in the bow and jump attack
            """

            class scrollinggrass(gameEngine.SuperSprite):
                def __init__(self, scene):
                    gameEngine.SuperSprite.__init__(self, scene)
                    self.setImage("gamebackground.jpg")
                    self.rect.centerx = 20
                    self.rect.centery = 500
                    self.rect = self.image.get_rect()
                    self.dx = 10
                    self.dy = 0
                    self.checkKeys()

                def checkKeys(self):


                    keys = pygame.key.get_pressed()
                    if keys[pygame.K_RIGHT]:
                        print("working")
                        self.forward(3)
                        run.play()

                    if keys[pygame.K_LEFT]:
                        self.forward(-3)


            class hearts(gameEngine.SuperSprite):
                def __init__(self, scene):
                    gameEngine.SuperSprite.__init__(self, scene)

                    self.setImage("heart.png")
                    self.setTransparentColor = self.imageMaster.get_at((1,1))
                    self.imageMaster.set_colorkey(self.setTransparentColor)

                    self.setPosition((550 , 30))

            class badguy(gameEngine.SuperSprite):
                def __init__(self, scene):
                    gameEngine.SuperSprite.__init__(self, scene)
                    self.setImage("badguy1.png")
                    self.rect = self.imageMaster.get_rect()
                    self.health = 2
                    self.DEAD = 1
                    self.state = 0



            class protaganist(gameEngine.SuperSprite):
                def __init__(self, scene):
                    gameEngine.SuperSprite.__init__(self, scene)

                    self.imageList = []
                    self.rect = self.imageMaster.get_rect()
                    self.STANDING = 0
                    self.RUNNING = 1
                    self.ATTACKING = 2
                    self.JUMPING = 3
                    self.DEAD = 10
                    self.imageFrame = 0
                    self.state = self.STANDING
                    self.hearts = 1
                    self.heartPts = self.hearts * 3
                    self.stats()


                    self.loadImages()
                #    self.image = self.imageList[0]
                    self.checkKeys()

                def stats(self):
            #sets it up so each heart is essentially 3 hit points
                    if self.heartPts >= 3:
                        self.hearts = 1
                    elif self.heartPts >= 6:
                        self.hearts = 2
                    elif self.heartPts == 9:
                        self.hearts = 3
                    elif self.heartPts > 9:
                        self.heartPts = 9
            # changes state to dead if hp == 0
                    if self.heartPts == 0:
                        self.state = DEAD


                def loadImages(self):

                    self.setPosition((320 , 380))

                    self.setImage("heroSTANDING.gif")
                    self.setTransparentColor = self.imageMaster.get_at((1,1))
                    self.imageMaster.set_colorkey(self.setTransparentColor)



                def checkKeys(self):


                    keys = pygame.key.get_pressed()
                    if keys[pygame.K_RIGHT]:
                        self.state = runRight
                        self.frame += 1
                        if self.frame >= len(self.imageList):
                            self.frame = 1
                        self.image = self.imageList[self.frame]
                      #  self.image = self.image.get_rect()
                       # self.rect.center = (320, 240)
                    if keys[pygame.K_LEFT]:
                        self.state = 1

                    while keys[pygame.K_g]:
                        self.state = Attacking
                        sndAtk.play()
                    if self.state == self.DEAD:
                        self.image = self.deadImgList[0]
                        self.frame += 1
                        self.image = self.deadImgList[self.frame]
                        #self.image = self.image.get_rect()
                        #self.rect.center = (320, 240)


            class game(gameEngine.Scene):
                def __init__ (self):
                    gameEngine.Scene.__init__(self)



                    pygame.display.set_caption("Link's Mediocre Adventure")

                    background = pygame.Surface(screen.get_size())
                    background.fill((0, 0, 0))
                    screen.blit(background, (0, 0))

                    pro = protaganist(self)
                    baddy = badguy(self)
                    baddy1 = badguy(self)
                    heart = hearts(self)
                    grass = scrollinggrass(self)


                    goodlySprites = self.makeSpriteGroup((grass, pro, heart))
                    baddySprites = self.makeSpriteGroup((baddy, baddy1))

                   # self.addSpriteGroup(goodlySprites)
                    self.addGroup((baddySprites))


                    clock = pygame.time.Clock()
                    keepGoing = True
                    while keepGoing:
                        clock.tick(30)
                        for event in pygame.event.get():
                            if event.type == pygame.QUIT:
                                keepGoing = False



                        if pro.state == pro.ATTACKING:
                            if pro.collidesGroup(baddySprites):
                                baddy.health -= 1
                                baddy1.health -= 1
                                if baddy.health == 0:
                                    baddy.reset()
                                elif baddy1.health == 0:
                                    baddy.reset()
                        elif pro.state != pro.ATTACKING:
                            if pro.collideGroup(baddySprites):
                                pro.heartPts -= 1

                        goodlySprites.update()
                        baddySprites.update()

                        goodlySprites.draw(screen)
                        baddySprites.draw(screen)

                        pygame.display.flip()



            def main():

                game.start()

            if __name__ == "__main__":
                game()

游戏引擎

            class SuperSprite(pygame.sprite.Sprite):
                """ An enhanced Sprite class
                    expects a gameEngine.Scene class as its one parameter
                    Use methods to change image, direction, speed
                    Will automatically travel in direction and speed indicated
                    Automatically rotates to point in indicated direction
                    Five kinds of boundary collision
                """

                def __init__(self, scene):
                    pygame.sprite.Sprite.__init__(self)
                    self.scene = scene
                    self.screen = scene.screen

                    #create constants
                    self.WRAP = 0
                    self.BOUNCE = 1
                    self.STOP = 2
                    self.HIDE = 3
                    self.CONTINUE = 4

                    #create a default text image as a placeholder
                    #This will usually be changed by a setImage call
                    self.font = pygame.font.Font("freesansbold.ttf", 30)
                    self.imageMaster = self.font.render(">sprite>", True, (0, 0,0), (0xFF, 0xFF, 0xFF))
                    self.image = self.imageMaster
                    self.rect = self.image.get_rect()

                    #create properties
                    #most will be changed through method calls
                    self.x = 200
                    self.y = 200
                    self.dx = 0
                    self.dy = 0
                    self.dir = 0
                    self.rotation = 0
                    self.speed = 0
                    self.maxSpeed = 10
                    self.minSpeed = -3
                    self.boundAction = self.WRAP
                    self.pressed = False
                    self.oldCenter = (100, 100)
                    self.states = {}
                    self.currentState = "default"

                def update(self):
                    self.oldCenter = self.rect.center
                    self.checkEvents()
                    self.__rotate()
                    self.__calcVector()
                    self.__calcPosition()
                    self.checkBounds()
                    self.rect.center = (self.x, self.y)

                def checkEvents(self):
                    """ overwrite this method to add your own event code """
                    pass

                def __rotate(self):
                    """ PRIVATE METHOD
                        change visual orientation based on
                        rotation property.
                        automatically called in update.
                        change rotation property directly or with
                        rotateBy(), setAngle() methods
                    """
                    oldCenter = self.rect.center
                    self.oldCenter = oldCenter
                    self.image = pygame.transform.rotate(self.imageMaster, self.rotation)
                    self.rect = self.image.get_rect()
                    self.rect.center = oldCenter

                def __calcVector(self):
                    """ calculates dx and dy based on speed, dir
                        automatically called in update
                    """
                    theta = self.dir / 180.0 * math.pi
                    self.dx = math.cos(theta) * self.speed
                    self.dy = math.sin(theta) * self.speed
                    self.dy *= -1

                def __calcPosition(self):
                    """ calculates the sprites position adding
                        dx and dy to x and y.
                        automatically called in update
                    """
                    self.x += self.dx
                    self.y += self.dy

                def checkBounds(self):
                    """ checks boundary and acts based on
                        self.BoundAction.
                        WRAP: wrap around screen (default)
                        BOUNCE: bounce off screen
                        STOP: stop at edge of screen
                        HIDE: move off stage and wait
                        CONTINUE: keep going at present course and speed

                        automatically called by update
                    """

                    scrWidth = self.screen.get_width()
                    scrHeight = self.screen.get_height()

                    #create variables to simplify checking
                    offRight = offLeft = offTop = offBottom = offScreen = False

                    if self.x > scrWidth:
                        offRight = True
                    if self.x < 0:
                        offLeft = True
                    if self.y > scrHeight:
                        offBottom = True
                    if self.y < 0:
                        offTop = True

                    if offRight or offLeft or offTop or offBottom:
                        offScreen = True

                    if self.boundAction == self.WRAP:
                        if offRight:
                            self.x = 0
                        if offLeft:
                            self.x = scrWidth
                        if offBottom:
                            self.y = 0
                        if offTop:
                            self.y = scrHeight

                    elif self.boundAction == self.BOUNCE:
                        if offLeft or offRight:
                            self.dx *= -1
                        if offTop or offBottom:
                            self.dy *= -1

                        self.updateVector()
                        self.rotation = self.dir

                    elif self.boundAction == self.STOP:
                        if offScreen:
                            self.speed = 0

                    elif self.boundAction == self.HIDE:
                        if offScreen:
                            self.speed = 0
                            self.setPosition((-1000, -1000))

                    elif self.boundAction == self.CONTINUE:
                        pass

                    else:
                        # assume it's continue - keep going forever
                        pass

                def setSpeed(self, speed):
                    """ immediately sets the objects speed to the
                        given value.
                    """
                    self.speed = speed

                def speedUp(self, amount):
                    """ changes speed by the given amount
                        Use a negative value to slow down
                    """
                    self.speed += amount
                    if self.speed < self.minSpeed:
                        self.speed = self.minSpeed
                    if self.speed > self.maxSpeed:
                        self.speed = self.maxSpeed

                def setAngle(self, dir):
                    """ sets both the direction of motion
                        and visual rotation to the given angle
                        If you want to set one or the other,
                        set them directly. Angle measured in degrees
                    """
                    self.dir = dir
                    self.rotation = dir

                def turnBy (self, amt):
                    """ turn by given number of degrees. Changes
                        both motion and visual rotation. Positive is
                        counter-clockwise, negative is clockwise
                    """
                    self.dir += amt
                    if self.dir > 360:
                        self.dir = amt
                    if self.dir < 0:
                        self.dir = 360 - amt
                    self.rotation = self.dir

                def rotateBy(self, amt):
                    """ change visual orientation by given
                        number of degrees. Does not change direction
                        of travel.
                    """
                    self.rotation += amt
                    if self.rotation > 360:
                        self.rotation = amt
                    if self.rotation < 0:
                        self.rotation = 360 - amt

                def setImage (self, image):
                    """ loads the given file name as the master image
                        default setting should be facing east.  Image
                        will be rotated automatically """
                    self.imageMaster = pygame.image.load(image)
                    self.imageMaster = self.imageMaster.convert()

                def setDX(self, dx):
                    """ changes dx value and updates vector """
                    self.dx = dx
                    self.updateVector()

                def addDX(self, amt):
                    """ adds amt to dx, updates vector """
                    self.dx += amt
                    self.updateVector()

                def setDY(self, dy):
                    """ changes dy value and updates vector """
                    self.dy = dy
                    self.updateVector()

                def addDY(self, amt):
                    """ adds amt to dy and updates vector """
                    self.dy += amt
                    self.updateVector()

                def setComponents(self, components):
                    """ expects (dx, dy) for components
                        change speed and angle according to dx, dy values """

                    (self.dx, self.dy) = components
                    self.updateVector()

                def setBoundAction (self, action):
                    """ sets action for boundary.  Values are
                        self.WRAP (wrap around edge - default)
                        self.BOUNCE (bounce off screen changing direction)
                        self.STOP (stop at edge of screen)
                        self.HIDE (move off-stage and stop)
                        self.CONTINUE (move on forever)
                        Any other value allows the sprite to move on forever
                    """
                    self.boundAction = action

                def setPosition (self, position):
                    """ place the sprite directly at the given position
                        expects an (x, y) tuple
                    """
                    (self.x, self.y) = position

                def moveBy (self, vector):
                    """ move the sprite by the (dx, dy) values in vector
                        automatically calls checkBounds. Doesn't change
                        speed or angle settings.
                    """
                    (dx, dy) = vector
                    self.x += dx
                    self.y += dy
                    self.checkBounds()

                def forward(self, amt):
                    """ move amt pixels in the current direction
                        of travel
                    """

                    #calculate dx dy based on current direction
                    radians = self.dir * math.pi / 180
                    dx = amt * math.cos(radians)
                    dy = amt * math.sin(radians) * -1

                    self.x += dx
                    self.y += dy

                def addForce(self, amt, angle):
                    """ apply amt of thrust in angle.
                        change speed and dir accordingly
                        add a force straight down to simulate gravity
                        in rotation direction to simulate spacecraft thrust
                        in dir direction to accelerate forward
                        at an angle for retro-rockets, etc.
                    """

                    #calculate dx dy based on angle
                    radians = angle * math.pi / 180
                    dx = amt * math.cos(radians)
                    dy = amt * math.sin(radians) * -1

                    self.dx += dx
                    self.dy += dy
                    self.updateVector()

                def updateVector(self):
                    #calculate new speed and angle based on dx, dy
                    #call this any time you change dx or dy

                    self.speed = math.sqrt((self.dx * self.dx) + (self.dy * self.dy))

                    dy = self.dy * -1
                    dx = self.dx

                    radians = math.atan2(dy, dx)
                    self.dir = radians / math.pi * 180

                def setSpeedLimits(self, max, min):
                    """ determines maximum and minimum
                        speeds you will allow through
                        speedUp() method.  You can still
                        directly set any speed you want
                        with setSpeed() Default values:
                            max: 10
                            min: -3
                    """
                    self.maxSpeed = max
                    self.minSpeed = min

                def dataTrace(self):
                    """ utility method for debugging
                        print major properties
                        extend to add your own properties
                    """
                    print "x: %d, y: %d, speed: %.2f, dir: %.f, dx: %.2f, dy: %.2f" % \
                          (self.x, self.y, self.speed, self.dir, self.dx, self.dy)

                def mouseDown(self):
                    """ boolean function. Returns True if the mouse is
                        clicked over the sprite, False otherwise
                    """
                    self.pressed = False
                    if pygame.mouse.get_pressed() == (1, 0, 0):
                        if self.rect.collidepoint(pygame.mouse.get_pos()):
                            self.pressed = True
                    return self.pressed

                def clicked(self):
                    """ Boolean function. Returns True only if mouse
                        is pressed and released over sprite
                    """
                    released = False
                    if self.pressed:
                        if pygame.mouse.get_pressed() == (0, 0, 0):
                            if self.rect.collidepoint(pygame.mouse.get_pos()):
                                released = True
                        return released

                def collidesWith(self, target):
                    """ boolean function. Returns True if the sprite
                        is currently colliding with the target sprite,
                        False otherwise
                    """
                    collision = False
                    if self.rect.colliderect(target.rect):
                        collision = True
                    return collision

                def collidesGroup(self, target):
                    """ wrapper for pygame.sprite.collideany
                        simplifies checking sprite - group collisions
                        returns result of collision check (sprite from group
                        that was hit or None)
                    """
                    collision = pygame.sprite.spritecollideany(self, target)
                    return collision

                def distanceTo(self, point):
                    """ returns distance to any point in pixels
                        can be used in circular collision detection
                    """
                    (pointx, pointy) = point
                    dx = self.x - pointx
                    dy = self.y - pointy

                    dist = math.sqrt((dx * dx) + (dy * dy))
                    return dist

                def dirTo(self, point):
                    """ returns direction (in degrees) to
                        a point """

                    (pointx, pointy) = point
                    dx = self.x - pointx
                    dy = self.y - pointy
                    dy *= -1

                    radians = math.atan2(dy, dx)
                    dir = radians * 180 / math.pi
                    dir += 180
                    return dir

                def drawTrace(self, color=(0x00, 0x00, 0x00)):
                    """ traces a line between previous position
                        and current position of object
                    """
                    pygame.draw.line(self.scene.background, color, self.oldCenter,
                                     self.rect.center, 3)
                    self.screen.blit(self.scene.background, (0, 0))

                def addState(self, stateName, stateImageFile):
                    """ Creates a new sprite state with the associated name
                        and image. Useful to build multi-state sprites.
                    """
                    #load the image
                    tempImage = pygame.image.load(stateImageFile)
                    tempImage.convert()
                    self.states[stateName] = tempImage

                def setState(self, stateName):
                    """ attempts to set the sprite to the indicated state
                        (image)
                    """
                    self.imageMaster = self.states[stateName]
                    self.rect = self.imageMaster.get_rect()
                    self.currentState = stateName

                def getState(self):
                    """ returns the current state name
                        (default if no states have been explicitly set)
                    """
                    return self.currentState

1 个答案:

答案 0 :(得分:1)

if pro.state == pro.ATTACKING:
    if pro.collidesWith(baddySprites):
        baddy.health -= 1
        if baddy.health == 0:
            baddy.reset()
elif pro.state != pro.ATTACKING:
    if pro.collidesWith(baddySprites):
        pro.heartPts -= 1

baddySprites是一个精灵组,所以我打赌你必须使用collidesGroup代替collidesWith

if pro.state == pro.ATTACKING:
    if pro.collidesGroup(baddySprites):
        baddy.health -= 1
        if baddy.health == 0:
            baddy.reset()
elif pro.state != pro.ATTACKING:
    if pro.collidesGroup(baddySprites):
        pro.heartPts -= 1

但即使你这样做,看起来你仍然会有问题。也就是说,此代码仅从baddy而非baddy1中扣除健康状况。我假设精灵组支持迭代。如果是这样,你应该对每个敌人独立进行碰撞检测。

for enemy in baddySprites:
    if pro.state == pro.ATTACKING:
        if pro.collidesWith(enemy):
            enemy.health -= 1
            if enemy.health == 0:
                enemy.reset()
    elif pro.state != pro.ATTACKING:
        if pro.collidesWith(enemy):
            pro.heartPts -= 1