0

今のところ、すべての更新メソッドに対して重力が作用しないプレーヤークラスがあります。現在、重力メソッドが行うのは、プレーヤーが地面に衝突しているかどうかを確認することだけです。衝突していない場合は、プレーヤーの yVel += 1 、しかし13を超えることはありません(フレームごとに13ピクセルを超えることはありません)が、問題は、プレーヤーが地面の真上にあり、地面に(13)ピクセル落下した場合、彼は地面の真ん中で立ち往生し、できないことです飛び出す。これを修正する方法はありますか、それともプレーヤー クラスのすべてを完全に書き直す必要がありますか?

    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
4

1 に答える 1

1

まず第一に、衝突チェックは冗長です:

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

spritecollideany衝突がない場合は 2 回呼び出します。あなたはただ使うことができます:

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 軸の衝突をチェックします。衝突を登録する場合は、衝突の原因となったオブジェクトを検出します。次に、プレーヤーの位置を変更して、そのオブジェクトの上に置きます。ここで完全な例を見つけることができます。

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

単純なゲームの場合、ほとんどの場合、これで十分なアプローチです。

于 2013-02-06T11:07:56.700 に答える