我对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()
答案 0 :(得分:1)
你使用pygame.Rect.colliderect
走在正确的轨道上(你也可以使用pygame.sprite.collide_rect(mario, ladder)
)但是它无法工作,因为你没有移动用于碰撞检测的精灵的部分。您只需更改x
和y
属性(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()