Python Pygame碰撞Rect常量碰撞?

Python Pygame碰撞Rect常量碰撞?,python,pygame,sprite,collision-detection,Python,Pygame,Sprite,Collision Detection,谢谢21点,这是你的建议代码。玩家图像只保留在左上角(0,0)。图像在runner数组中循环,但按left或right不会使播放器精灵在背景图像的边缘移动,也不会移动背景图像和块 import pygame, math from math import * backimage = pygame.image.load("C:/Users/Jed/Desktop/Drawings/DSC_0001_cropped.jpg") cameraX_offset = 0 cameraY_offset =

谢谢21点,这是你的建议代码。玩家图像只保留在左上角(0,0)。图像在runner数组中循环,但按left或right不会使播放器精灵在背景图像的边缘移动,也不会移动背景图像和块

import pygame, math
from math import *


backimage = pygame.image.load("C:/Users/Jed/Desktop/Drawings/DSC_0001_cropped.jpg")
cameraX_offset = 0
cameraY_offset = 0
screen = pygame.display.set_mode([700,700])

pygame.init()
pygame.key.set_repeat(20, 20)

#Runner instances#
runner = []
#lots of images from disk add to array
currentRunner = 17
#end of runners!#



freespeed = 5   #speed character moves at edges of background
jumping = False
jumpingLeft = True
jumpVariable = 0
initialY = None

class Player(pygame.sprite.Sprite):
    def __init__(self):
        self.image = runner[int(floor(currentRunner))]
        self.rect = self.image.get_rect()
        self.rect.topleft = (350, 500)

    def see_on_block(self):
        new_rect = self.rect.move(0, 2)
        if not any(new_rect.colliderect(b.rect) for b in blocks):
                self.rect= new_rect

    def movement (self):
        global cameraX_offset, currentRunner, jumping, jumpingLeft, jumpVariable, initialY
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:                  #moving character left
                    if cameraX_offset <= 0 and self.rect.left > 20:     
                        self.rect.left -= freespeed
                    elif 350 < self.rect.left <= 800:
                        self.rect.left -= freespeed
                    elif cameraX_offset > 0:
                        cameraX_offset -=1
                    if currentRunner >= 7:
                        currentRunner = 0
                    else:
                        currentRunner += 0.3

                if event.key == pygame.K_RIGHT:                 #moving character right
                    if cameraX_offset >= 250 and self.rect.left < 635:
                        self.rect.left += freespeed
                    elif -10 <= self.rect.left < 350:
                        self.rect.left += freespeed
                    elif cameraX_offset < 250:
                        cameraX_offset += 1
                    if currentRunner < 8 or



currentRunner >= 15:
                        currentRunner = 8
                    else:
                        currentRunner += 0.3

                if event.key == pygame.K_SPACE:
                    jumping = True
                    initialY = self.rect.top

                elif event.type == pygame.KEYUP:
                    if 0 <= currentRunner <= 7:
                        currentRunner = 16
                    elif 8 <= currentRunner <= 15:
                        currentRunner = 17

        if jumping == True:
            if 0 <= currentRunner <= 7 or currentRunner == 16 or 18 <= currentRunner <= 21: #sees whether character is facing left or right when jump initiated
                jumpingLeft = True
            else:
                jumpingLeft = False
            jumpVariable += (radians(5))

            if radians(90) <= jumpVariable < radians(270):
                self.rect.top = initialY - 100*sin(jumpVariable - radians(90))  #moves character in Y according to sin
                if jumpingLeft == True:
                    if cameraX_offset <= 0 and self.rect.left > 20:         #moves character in X if facing left
                        self.rect.left -= jumpVariable
                    elif 350 < self.rect.left <= 800:
                        self.rect.left -= jumpVariable
                    elif cameraX_offset > 0:
                        cameraX_offset -= 2
                elif jumpingLeft == False:
                    if cameraX_offset >= 250 and self.rect.left < 635:      #moves character in X if facing right
                        self.rect.left += jumpVariable
                    elif -10 <= self.rect.left < 350:
                        self.rect.left += jumpVariable
                    elif cameraX_offset < 250:
                        cameraX_offset += 2

            if jumpVariable >= radians(270):                        #changes character's sprite when jumping according to variable
                jumping = False
                jumpVariable = 0
            if  0 < jumpVariable < radians(45):
                if jumpingLeft == True:
                    currentRunner = 18
                else:
                    currentRunner = 22
            elif radians(45) <= jumpVariable < radians(70):
                if jumpingLeft == True:
                    currentRunner = 19
                else:
                    currentRunner = 23
            elif radians(70) <= jumpVariable < radians (105):
                if jumpingLeft == True:
                    currentRunner = 20
                else:
                    currentRunner = 24
            elif radians(105) <= jumpVariable < radians (225):
                if jumpingLeft == True:
                    currentRunner = 21
                else:
                    currentRunner = 25
            elif radians(225) <= jumpVariable <= radians(260):
                if jumpingLeft == True:
                    currentRunner = 18
                else:
                    currentRunner = 22
            elif radians(260) < jumpVariable < radians(270):
                if jumpingLeft == True:
                    currentRunner = 16
                else:
                    currentRunner = 17

        if jumping == False:
            jumpVariable = 0

        self.image = runner[int(floor(currentRunner))]
        self.rect = self.image.get_rect()
        screen.blit(self.image, (self.rect.left, self.rect.top))


class Block(pygame.sprite.Sprite):
    def __init__(self, blockX, blockY, block_width, block_height):
        self.blockX = blockX
        self.blockY = blockY
        self.block_width = block_width
        self.block_height = block_height

    def draw_block(self):
        self.rect = pygame.draw.rect(screen,[160, 160, 160], (self.blockX - 2*cameraX_offset, self.blockY - cameraY_offset, self.block_width, self.block_height))


##create object instances##
blocks = []
floorBlock = Block (0, 680, 1200, 20)
blocks.append(floorBlock)
leftWall = Block (0 , 0, 20, 700)
blocks.append(leftWall)
rightWall = Block (1180 , 0, 20, 700)
blocks.append(rightWall)
block1 = Block (450, 600, 100, 20)
blocks.append(block1)
player = Player()


##main loop##
running = True    
while running:

    pygame.time.Clock().tick(100)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.blit(backimage, (0-cameraX_offset, 0-cameraY_offset))

    for b in blocks:
        b.draw_block()


    player.movement()
    player.see_on_block()
    pygame.display.flip()

pygame.quit()
导入pygame、数学
从数学导入*
backimage=pygame.image.load(“C:/Users/Jed/Desktop/draws/DSC\u 0001\u croped.jpg”)
cameraX_偏移量=0
cameraY_偏移量=0
screen=pygame.display.set_模式([700700])
pygame.init()
pygame.key.set_重复(20,20)
#跑步者实例#
跑步者=[]
#从磁盘添加到阵列的大量映像
currentRunner=17
#跑步者的终点#
freespeed=5#速度角色在背景边缘移动
跳跃=错误
跳转左=真
jumpVariable=0
初始值=无
职业玩家(pygame.sprite.sprite):
定义初始化(自):
self.image=runner[int(floor(currentRunner))]
self.rect=self.image.get_rect()
self.rect.topleft=(350500)
def见_块上的_(自):
new_rect=self.rect.move(0,2)
如果没有任何(块中b的新矩形碰撞矩形(b.rect)):
self.rect=new\u rect
def移动(自):
全局摄影机X_偏移,currentRunner,跳跃,跳跃左,跳跃变量,初始值
对于pygame.event.get()中的事件:
如果event.type==pygame.KEYDOWN:
如果event.key==pygame.K_LEFT:#向左移动角色
如果cameraX_偏移量为20:
self.rect.left-=自由速度
elif 350=7:
currentRunner=0
其他:
currentRunner+=0.3
如果event.key==pygame.K_RIGHT:#向右移动角色
如果cameraX_偏移量>=250且self.rect.left<635:
self.rect.left+=自由速度
elif-10=15:
currentRunner=8
其他:
currentRunner+=0.3
如果event.key==pygame.K_空间:
跳跃=正确
initialY=self.rect.top
elif event.type==pygame.KEYUP:

如果0那么代码中为播放器设置矩形的部分才是关键。最初将流道的矩形设置为与图像的矩形相同,结果是(0,0,宽度,高度)

由于流道正在四处移动,因此必须考虑其位置,并在see_on_块中修改矩形的位置(rect的前两个值)


我建议您使用self.rect中的前两个值作为位置,而不是self.X和self.Y,并根据需要修改代码。

去掉
X
Y
属性,使用
rect
属性存储精灵的位置和大小。这就是它的用途
Rect
对象有一系列方法和属性来移动它们,并获取点和边的坐标和位置

因此,
Player
类的前两个方法可能如下所示:

class Player(pygame.sprite.Sprite):
    def __init__(self):
        self.image = runner[int(floor(currentRunner))]
        self.rect = self.image.get_rect()
        self.rect.topleft = (350, 500)

    def see_on_block(self):
        self.rect.y += 2
        for b in blocks:
            if self.rect.colliderect(b.rect):
                self.rect.y -= 2
                break
最后一种方法可以表达得更紧凑一些,不需要减法:

    def see_on_block(self):
        new_rect = self.rect.move(0, 2)
        if not any(new_rect.colliderect(b.rect) for b in blocks):
            self.rect = new_rect

如果您使用Pygame的精灵组而不是列表,您可以通过调用来替换
If
条件。

非常感谢,您的解决方案非常有效!然而,self.rect[0,1,2,3]指的是什么?一个rect有四个不同的值可以使用:rect[0]指的是矩形的x位置,rect[1]指的是矩形的y位置,rect[2]指的是宽度,rect[3]指的是矩形的高度。最好只使用rect的属性,而不是调用rect[1]您应该调用rect.y等。有关属性和方法,请参阅。该行可以写成
tempRect=self.rect.move(self.X,self.y)
。您好,BlackJack,谢谢您的帮助。我曾尝试使用您的建议,但当我运行该程序时,runner sprite卡在画布上的位置(0,0),并且尽管在跑步和跳跃时按下键使sprite图像在动画实例中循环,但sprite在背景图像边缘时不会向左或向右移动,背景图像也不会移动。我已经编辑了原始帖子,以包含更新的代码。谢谢在
Player.movement()
的下一行中,您将使用始终位于(0,0)的图像
rect
实例覆盖
self.rect
。对于blitting,您可以顺便使用
Rect
实例本身。不需要从中提取x和y。
    def see_on_block(self):
        new_rect = self.rect.move(0, 2)
        if not any(new_rect.colliderect(b.rect) for b in blocks):
            self.rect = new_rect