Python-Pygame精灵在使用重力时反弹

时间:2013-10-03 17:57:18

标签: python-3.x pygame sprite gravity

我正在制作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

1 个答案:

答案 0 :(得分:2)

你没有提供一个正在运行的例子,你的代码很难阅读(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