2013-02-04 64 views
0

截至目前,我有一个玩家类,每个更新方法都有重力无效,现在我所有的重力方法都是检查玩家是否碰撞与地面,如果它没有碰撞,那么玩家yVel + = 1,但永远不会超过13(每帧不会超过13个像素),但问题是如果我的玩家正好在地面之上并落下(13 )像素到地面,他卡在地面的中间,不能跳回去。有什么办法可以解决这个问题吗?或者我需要完全重写我的球员课程中的所有内容吗?试图通过使用colllision检测来防止玩家类落入地面类pygame

所有的
import pygame 
import time # lint:ok 
from pygame.locals import * 

char = 'ball.png' 
char_jump = 'ball_jump.png' 

ball = pygame.image.load(char) 
ballJump = pygame.image.load(char_jump) 


class Player(pygame.sprite.Sprite): 
    def __init__(self, screen, image, xPos, yPos, xVel, yVel, checkGroup): 
     pygame.sprite.Sprite.__init__(self) 
     self.xPos = xPos 
     self.yPos = yPos 
     self.xVel = xVel 
     self.yVel = yVel 
     self.image = image 
     self.screen = screen 
     self.rect = self.image.get_rect() 
     self.isInAir = True 
     self.checkGroup = checkGroup 

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

    def update(self): 
     self.gravity() 
     self.xPos += self.xVel # updates x and y based on velocities 
     self.yPos += self.yVel # updates rect 
     self.rect.topleft = (self.xPos, self.yPos) # updates sprite rectangle 

     if self.xPos > 440: # keeps player from going to far right and left 
      self.xPos = 440 
     if self.xPos < -3: # ######### 
      self.xPos = -3 

    def gravity(self): 
     if self.checkCollision(self.checkGroup) is True: 
      self.yVel = 0 
     elif self.checkCollision(self.checkGroup) is False: 
      self.yVel = 50 

    def jump(self): 
     if self.isInAir is False: 
      print('jump') 
      self.yVel -= 20 
      self.image = ballJump 

    def moveRight(self): 
     self.xVel = 3 

    def moveLeft(self): 
     self.xVel = -3 

    def stopLeft(self): 
     self.xVel = 0 
     self.image = ball 

    def stopRight(self): 
     self.xVel = 0 
     self.image = ball 

    def stopJump(self): 
     self.image = ball 
     if self.yVel < 0: # if player is still jumping up 
      self.yVel = 1 # make y Velocity positive (fall down) 

    def checkCollision(self, group): 
     if pygame.sprite.spritecollideany(self, group): 
      return True 
     elif not pygame.sprite.spritecollideany(self, group): 
      return False 

回答

1

首先,你的碰撞检查是多余的:

def checkCollision(self, group): 
    if pygame.sprite.spritecollideany(self, group): 
     return True 
    elif not pygame.sprite.spritecollideany(self, group): 
     return False 

电话spritecollideany如果两次没有冲突。你可以只使用:

def checkCollision(self, group): 
    return pygame.sprite.spritecollideany(self, group) 

同为

def gravity(self): 
    if self.checkCollision(self.checkGroup) is True: 
     self.yVel = 0 
    elif self.checkCollision(self.checkGroup) is False: 
     self.yVel = 50 

它可以改写为

def gravity(self): 
    self.yVel = 0 if self.checkCollision(self.checkGroup) else 50 

我们您的问题:

你检查你的球员是否与某物发生碰撞,如果是,你就停止移动。这会导致你描述的问题,因为你不会检查你移动的每个像素的碰撞,而只是针对每个第n个像素,其中n是你的移动速度。常用的方法是使用称为CCD(连续碰撞检测)的东西,但这不在该答案的范围内。

一种更简单的方法如下:用于x轴的碰撞

首先检查,那么对于y轴的碰撞。如果您注册了碰撞,请检测导致碰撞的物体。然后改变玩家在该物体上的位置。你可以找到一个完整的例子here

def collide(self, xvel, yvel, platforms): 
     for p in platforms: 
      if sprite.collide_rect(self, p): 
       ... 
       if xvel > 0: self.rect.right = p.rect.left 
       if xvel < 0: self.rect.left = p.rect.right 
       if yvel > 0: 
        self.rect.bottom = p.rect.top # <- relevant line 
        ... 
        self.yvel = 0 
       if yvel < 0: self.rect.top = p.rect.bottom 

如果你有一个简单的游戏,大多数时候这是一个足够好的方法。