2016-06-08 1 views
1

Я относительно новичок в pygame и python в целом, и сейчас я работаю над школьным проектом. Я пытаюсь сделать так, что, когда мой спрайт Марио перекрывается с эскизом лестницы, он может двигаться вверх, а когда он не перекрывается, впоследствии не может двигаться вверх. Вот мой код:Лестница подъема в pygame

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() 
+0

Каковы ваши ошибки или что не работает? –

ответ

1

Вы были на правильном пути с pygame.Rect.colliderect (вы также можете использовать pygame.sprite.collide_rect(mario, ladder)), но он не может работать, потому что вы не двигаетесь прямоугольниками спрайтов, которые используются для обнаружения столкновений , Вы изменяете только атрибуты x и y (blit position), но это не влияет на прямоугольники.


Обрабатывать события в главном цикле или в спрайта, если вы делаете и вы будете двигаться с увеличенной скоростью, потому что вы обрабатывать событие дважды.

Вы можете поместить спрайты в группу спрайтов, которые будут обновлять и заливать все содержащиеся спрайты, когда вы вызываете sprite_group.update() и sprite_group.draw(screen).

Я изменил вашу программу, чтобы показать вам, как я это сделаю. Группа спрайтов - группа 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() 
+0

Спасибо за помощь! Просто быстрый вопрос, где именно находится группа спрайтов? –

+0

Я использовал группу [OrderedUpdates] (http://www.pygame.org/docs/ref/sprite.html#pygame.sprite.OrderedUpdates) в качестве группы спрайтов. Это атрибут 'self.all_sprites' класса' Game'. OrderedUpdates - это специальная группа спрайтов, которая поддерживает порядок добавленных спрайтов. С обычной «pygame.sprite.Group» Марио мог случайно появиться за или перед лестницей. – skrx