微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Pygame 精灵碰撞无法正常工作,精灵只是有时碰撞而不是在正确的区域

如何解决Pygame 精灵碰撞无法正常工作,精灵只是有时碰撞而不是在正确的区域

我正在尝试在 pygame 中制作一个简单的 paltformer。我正在研究包括存储在 pygame 组中的平台的碰撞。但是,当我测试碰撞时,角色精灵只会在它位于平台内部而不是顶部时感觉到它发生了碰撞。精灵进入平台的程度也各不相同。我不确定出了什么问题。我在主游戏类中创建了一个碰撞检测方法来检测碰撞的位置。这是带有碰撞方法 _check_plat_player_collision

的完整主类
import sys

import pygame

from settings import Settings
from char import Char
from platform import Platform
from pygame.locals import *


class Main:
    """overall class to manage game assets and behavior"""

    def __init__(self):
        """initialise game and create new game resources"""
        pygame.init()
        self.settings = Settings()
        self.clock = pygame.time.Clock()

        self.screen = pygame.display.set_mode((self.settings.screen_width,self.settings.screen_height))
        pygame.display.set_caption("Platformer")

        self.char = Char(self)

        self.platforms = pygame.sprite.Group()
        ground = Platform(0,760,1200,40,'images/ground.png')
        self.platforms.add(ground)
        platform1 = Platform(500,600,200,50,'images/grass_plat.png')
        self.platforms.add(platform1)



    def run_game(self):
        """start main game loop"""
        while True:
            #Watch for keyboard and mouse events

            self._check_events()
            self.char.update()
            self._check_plat_player_collision()
            self._update_screen()

            self.clock.tick(30)     

    def _check_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

    def _check_keydown_events(self,event):
        if event.key == pygame.K_d:
            self.char.moving_right = True
        elif event.key == pygame.K_a:
            self.char.moving_left = True
        elif event.key == pygame.K_q: #when q is pressed the game exits
            sys.exit()

        if not (self.char.is_jump):
            if event.key == pygame.K_SPACE and self.settings.touching:
                self.char.is_jump = True


    def _check_keyup_events(self,event):
        if event.key == pygame.K_d:
            self.char.moving_right = False
            self.settings.current_direction=1
        elif event.key == pygame.K_a:
            self.char.moving_left = False
            self.settings.current_direction=2

    def _draw_levels(self):
        if self.settings.level == 1:
            #draw platforms
            self.platforms.draw(self.screen)

    def _check_plat_player_collision(self):
        if pygame.sprite.spritecollideany(self.char,self.platforms):
            self.settings.touching = True

        if not pygame.sprite.spritecollideany(self.char,self.platforms):
            self.settings.touching = False#

        for plat in self.platforms:
            if self.char.rect.colliderect(plat):
                print(abs(plat.rect.top-self.char.rect.bottom))
                if abs(plat.rect.top-self.char.rect.bottom) < self.settings.collision_tolerance:
                    self.settings.gravity = 0
                    self.settings.veLocity = 0

                if abs(plat.rect.bottom-self.char.rect.top) < self.settings.collision_tolerance:
                    
                    self.settings.gravity = 1
                    self.settings.veLocity = 0
                    self.is_jump=False
                if abs(plat.rect.left-self.char.rect.right) < self.settings.collision_tolerance:
                    self.char.moving_right = False
                if abs(plat.rect.right-self.char.rect.left) < self.settings.collision_tolerance:
                    self.char.moving_left = False

    def _update_screen(self):
        #reraw the screen for each pass through the loop
        self.screen.fill(self.settings.bg_color)
        self.char.blitme()
        self._draw_levels()


        #make most recently drawn screen visible
        pygame.display.flip()

if __name__ == '__main__':
    #make a game instance and run the game
    pf = Main()
    pf.run_game()

方法检查平台组中平台的循环,并检查是否有任何边缘接触,如果是,则对角色精灵施加约束。

作为参考,字符类中更新方法的相关部分是这样的。

if self.settings.touching:
    self.currenty=self.y
if not self.settings.touching:
    self.settings.gravity=1
if self.is_jump:
    self.settings.veLocity = -20
if self.y-self.currenty<0:
    self.is_jump=False

self.settings.veLocity+=self.settings.gravity
self.y+=self.settings.veLocity


#update rect object from self.x
self.rect.x = self.x
self.rect.y = self.y

我还尝试将碰撞检测放在字符类中,以查看是否可以更准确地更新位置,但出现错误。我遇到的错误是在尝试使用 self.platforms = pf_game.platforms 将平台组导入字符类时,但这带来了错误 AttributeError: 'Main' object has no attribute 'platforms'

我希望这就够了,我不想把所有的代码都贴在这里。如果您需要进一步查看,这里是我 GitHub 上代码链接。谢谢!

https://github.com/ValorToMe/Practice_Platformer

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。