在pygame爬梯子

时间:2016-06-08 01:47:04

标签: python pygame sprite

我对pygame和python整体比较陌生,我目前正在开展一个学校项目。我试图这样做,以便当我的马里奥精灵与梯子精灵重叠时,他可以向上移动,当他没有重叠时,随后就无法向上移动。这是我的代码:

import pygame
import sys
from pygame.locals import*
from Mario import Mario
from Ladder import Ladder

pygame.init()
game_over = False
dispwidth = 600
dispheight = 800
cellsize = 10
white = (255, 255, 255)
black = (0, 0, 0)
bg = white
mario = Mario([0, 800])
ladder = Ladder([600, 800])
mario2 = Mario.image
ladder2 = Ladder.image
mario_rect = mario2.get_rect()
ladder_rect = ladder2.get_rect()


'''def detectcollisions(x1, y1, w1, h1, x2, y2, w2, h2):

    if x2 + w2 >= x1 >= x2 and y2 + h2 >= y1 >= y2:
        return True

    elif x2 + w2 >= x1 + w1 >= x2 and y2 + h2 >= y1 >= y2:
        return True

    elif x2 + w2 >= x1 >= x2 and y2 + h2 >= y1 + h1 >= y2:
        return True

    elif x2 + w2 >= x1 + w1 >= x2 and y2 + h2 >= y1 + h1 >= y2:
        return True

    else:
        return False
    '''    


class Ladder(pygame.sprite.Sprite):
    image = None

    def __init__(self, location):
        pygame.sprite.Sprite.__init__(self)

        if Ladder.image is None:

            Ladder.image = pygame.image.load('Wood-ladder.png')
        self.image = Ladder.image

        self.rect = self.image.get_rect()
        self.rect.bottomright = location

        self.x = 499
        self.y = 420

    def draw(self, surface):
        surface.blit(self.image, (self.x, self.y))


class Mario(pygame.sprite.Sprite):
    image = None

    def __init__(self, location):
        pygame.sprite.Sprite.__init__(self)

        if Mario.image is None:

            Mario.image = pygame.image.load('mario3.png')
        self.image = Mario.image

        self.rect = self.image.get_rect()
        self.rect.bottomleft = location

        self.x = 0
        self.y = 736

    def handle_keys(self):

        keys_pressed = pygame.key.get_pressed()

        if keys_pressed[K_LEFT]:
            self.x -= 5

        if keys_pressed[K_RIGHT]:
            self.x += 5

        while self.collide_rect(ladder):
            if keys_pressed[K_UP]:
                self.y -= 5

    def draw(self, surface):

        surface.blit(self.image, (self.x, self.y))


def main():
    FPS = 30
    while not game_over:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

        keys_pressed = pygame.key.get_pressed()

        if keys_pressed[K_LEFT]:
            mario.x -= 1

        if keys_pressed[K_RIGHT]:
            mario.x += 1

        if mario_rect.colliderect(ladder_rect):
            if keys_pressed[K_UP]:
                mario.y -= 5

        mario.handle_keys()
        screen.fill(bg)
        ladder.draw(screen)
        mario.draw(screen)
        pygame.display.update()
        fpstime.tick(FPS)

while True:
    global fpstime
    global screen

    fpstime = pygame.time.Clock()
    screen = pygame.display.set_mode((dispwidth, dispheight))
    pygame.display.set_caption('Donkey Kong')
    main()

1 个答案:

答案 0 :(得分:1)

你使用pygame.Rect.colliderect走在正确的轨道上(你也可以使用pygame.sprite.collide_rect(mario, ladder))但是它无法工作,因为你没有移动用于碰撞检测的精灵的部分。您只需更改xy属性(blit位置),但这不会影响rects。

在主循环或精灵中处理事件,如果同时执行这两项操作,则会因为处理事件两次而以更快的速度移动。

您可以将精灵放在pygame.sprite.Group一个sprite组中,当您调用sprite_group.update()sprite_group.draw(screen)时,该精灵组将更新并blit所有包含的精灵。

我重组了你的程序,向你展示我是如何做到的。精灵组是一个OrderedUpdates组,因为马里奥应该总是出现在梯子​​上。梯子还有一个问题,当马里奥超过梯子的顶部时,他再也无法向下移动,但我会让你弄清楚。 ;)

import sys
import pygame
from pygame.locals import *


class Ladder(pygame.sprite.Sprite):
    image = pygame.Surface((60, 300))
    image.fill(pygame.Color('blue'))

    def __init__(self, location):
        pygame.sprite.Sprite.__init__(self)
        self.rect = self.image.get_rect(bottomleft=location)


class Mario(pygame.sprite.Sprite):
    image = pygame.Surface((30, 50))
    image.fill(pygame.Color('red'))

    def __init__(self, location):
        pygame.sprite.Sprite.__init__(self)
        self.rect = self.image.get_rect(bottomleft=location)


class Game:

    def __init__(self):
        self.fps = 30
        self.dispwidth = 600
        self.dispheight = 800
        self.screen = pygame.display.set_mode((self.dispwidth, self.dispheight))
        pygame.display.set_caption('Donkey Kong')
        self.fpstime = pygame.time.Clock()
        self.white = (255, 255, 255)
        self.black = (0, 0, 0)
        self.mario = Mario([0, 600])
        self.ladder = Ladder([400, 600])
        self.all_sprites = pygame.sprite.OrderedUpdates(self.ladder, self.mario)
        self.game_over = False

    def run(self):
        while not self.game_over:
            self.handle_events()
            self.run_logic()
            self.draw()
            self.fpstime.tick(self.fps)

    def run_logic(self):
        self.all_sprites.update()

    def handle_events(self):
        for event in pygame.event.get():
            if event.type == QUIT:
                self.game_over = True
        keys_pressed = pygame.key.get_pressed()
        if keys_pressed[K_LEFT]:
            self.mario.rect.x -= 6
        if keys_pressed[K_RIGHT]:
            self.mario.rect.x += 6
        if keys_pressed[K_UP]:
            if pygame.sprite.collide_rect(self.mario, self.ladder):
                self.mario.rect.y -= 6
        if keys_pressed[K_DOWN]:
            if pygame.sprite.collide_rect(self.mario, self.ladder):
                self.mario.rect.y += 6

    def draw(self):
        self.screen.fill(self.white)
        self.all_sprites.draw(self.screen)
        pygame.display.update()


if __name__ == '__main__':
    pygame.init()
    Game().run()
    pygame.quit()
    sys.exit()