【问题标题】:Python-Pygame sprite bounces when gravity is used使用重力时 Python-Pygame 精灵反弹
【发布时间】:2013-10-03 17:57:17
【问题描述】:

我正在制作一个 8 位风格的平台游戏。由于伪重力,玩家下落并获得速度,但他会落入地面几个像素。在没有重力的情况下,他会降落在地面上,但不会下降,但下降速度是恒定的。在地面上时,您可以上升,但当您松手时,他会下降。他不会下来,所以现在这不是问题。任何帮助将不胜感激。

播放器类/文件。

import pygame,sys
from pygame.locals import *
class Player:
    x=0
    y=0
    offset = 5
    L=False
    R=False
    U=False
    D=False
    image = None
    gravity = .25
    velocity = offset
    objectDict = None #this si the list of the current objects so that collision can be check with every
    #object.. get updated every loop to keep a accurate check of locations
    rect = None
    grav = True    #TODO use this to check if we are paying attention to the gravity
    def __init__(self,x,y):
        self.x = x
        self.y = y
        self.image = pygame.image.load('Resources/Pics/player.png')



    def draw(self,DISPLAY):
        #print('draw will go here')
        imgRect = self.image.get_rect()
        imgRect.midleft = (self.x,self.y)
        self.rect = imgRect
        DISPLAY.blit(self.image, imgRect)
        #and now im here

    def checkCollide(self,otherRect):
        return self.rect.colliderect(otherRect)

    def checkCollideAll(self):
        if(self.objectDict != None):
            # print(len(self.objectDict))
        #     for x in range(1,len(self.objectDict)):
        #         newb = self.checkCollide(self.objectDict[x].getRect())
        #         print(self.objectDict[x].getRect())
        #     if(newb):
        #         return True
        # return False
            collideNum = self.rect.collidelist(self.objectDict)
            if(collideNum == -1):
                return False
            else:
                return True

    def willCollideBelow(self):
        if(self.objectDict):
            checkRect = (self.x,(self.y),self.image.get_size())
            collideNum = self.rect.collidelist(self.objectDict)
            if collideNum == -1:
                return False
            else:
                return True


    def objUpdate(self,dict):
        self.objectDict = dict

    def getRect(self):
        return self.rect

    def update(self):
        # while(self.checkCollideAll()):
        #     print('while happened')
        #     self.y -= self.offset
        #     imgRect = self.image.get_rect()
        #     imgRect.midleft = (self.x,self.y)
        #     self.rect = imgRect
        # print(self.willCollideBelow())
        if not self.willCollideBelow():
            self.D = True
            # print('will fall')
        else:
            self.D = False

        if self.U == True:
            self.y -= self.offset

        if self.D == True:
                self.y += self.velocity
                if not self.velocity >= 9.8:
                    self.velocity += self.gravity
        else:
            self.velocity = self.offset
        if self.L == True:
                self.x -= self.offset

        if self.R == True:
                self.x += self.offset

【问题讨论】:

  • 你的意思是说你的角色正在坠落,以至于他与地面相交?如果是这种情况,那是因为在某个时间步长中,他跌落的距离比他在地面上的距离要大,而且看起来您没有任何代码来解决该交叉点。

标签: python-3.x pygame sprite gravity


【解决方案1】:

您没有提供运行示例,并且您的代码难以阅读(pascal 大小写,很多不必要的括号),但这是我的猜测:

willCollideBelow 函数中,检查是否击中了播放器下方的对象:

def willCollideBelow(self):
        if(self.objectDict):
            checkRect = (self.x,(self.y),self.image.get_size())
            collideNum = self.rect.collidelist(self.objectDict)
            if collideNum == -1:
                return False
            else:
                return True

不只是返回TrueFalse,而是返回你实际碰撞的对象(或对象的索引):

def will_collide_below(self):
        if(self.objectDict):
            # using 'collidelistall' would be better, but that's another topic
            return self.rect.collidelist(self.objectDict)

现在您知道玩家与哪个物体发生碰撞,您可以调整玩家的垂直位置:

ground_i = self.will_collide_below()
if ground_i:
    ground = self.objectDict[ground_i]
    self.velocity = 0
    self.rect.bottom = ground.top # or self.y = ground.top

你会明白的。


还有一些注意事项:

您使用不同的变量来存储玩家的位置(我看到xyrectimgRect)。如果您只使用单个 Rect 来存储位置,这将使您的代码更简单:

class Player:
    ...
    def __init__(self,x,y):
        self.image = pygame.image.load('Resources/Pics/player.png')
        self.rect = self.image.get_rect(midleft=(x,y))

    def draw(self, display):
        display.blit(self.image, self.rect)

    def update(self):
        ...
        if self.L: # no need to check == True
            self.rect.move_ip(-self.offset)

        if self.R: # simply use move_ip to alter the position
            self.rect.move_ip(self.offset)

您还使用了一些真正应该使用实例变量的类变量,例如 rectLRUD

【讨论】:

  • 谢谢你,这更有意义。此外,驼峰式和括号是因为我们在 VB 和 Java 方面有经验,这在迁移到 Python 时彻底破坏了所有逻辑格式。
猜你喜欢
  • 1970-01-01
  • 2023-03-02
  • 1970-01-01
  • 2014-02-21
  • 1970-01-01
  • 2021-05-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多