Python Forum
[PyGame] How would I make my position variable more accurate?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] How would I make my position variable more accurate?
#1
Currently, I have a variable that is supposed to exit the program once the player reaches a certain point, but my collision detection system is "fake" in the sense that the player can still move a bit after the collision. This causes my position variable to be off. Does anyone know how to add my correction variable to my position variables?


import pygame

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 255, 255)
 
DISPLAY_WIDTH = 800
DISPLAY_HEIGHT = 600
gameDisplay = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))

def textObjects(text, font):
    textSurface = font.render(text, True, BLACK)
    return textSurface, textSurface.get_rect()
def messageDisplay(text):
    largeText = pygame.font.Font('freesansbold.ttf', 115)
    textSurf, textRect = textObjects(text, largeText)
    textRect.center = ((DISPLAY_WIDTH/2), (DISPLAY_HEIGHT/2))
    gameDisplay.blit(textSurf, textRect)

    
class Player(pygame.sprite.Sprite):
 
    def __init__(self):
 

        super().__init__()
 

        width = 100
        height = 150
        self.image = pygame.Surface([width, height])
        self.image.fill(RED)
 

        self.rect = self.image.get_rect()
 

        self.xVel = 0
        self.yVel = 0
 

        self.level = None
 
    def update(self):
        self.calc_grav()
 

        self.level.bgX += self.xVel
 
 

        correction = 0
        block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
        for block in block_hit_list:
            if self.xVel < 0:
                self.friction()
                correction = self.rect.right - block.rect.left
            elif self.xVel > 0:
                self.friction()
                correction = self.rect.left - block.rect.right

        if correction != 0:
            for block in self.level.platform_list:
                block.rect.x += correction

 
        self.rect.y += self.yVel
 

        block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
        for block in block_hit_list:
            if self.yVel > 0:
                self.rect.bottom = block.rect.top
            if self.yVel < 0:
                self.rect.top = block.rect.bottom
 

            self.yVel = 0
 
            if isinstance(block, MovingPlatform):
                self.level.bgX += block.xVel
 
    def calc_grav(self):
        
        if self.yVel == 0:
            self.yVel = 1
        else:
            self.yVel +=0.3
 
        if self.rect.y >= DISPLAY_HEIGHT - self.rect.height and self.yVel >= 0:
            self.yVel = 0
            self.rect.y = DISPLAY_HEIGHT - self.rect.height
        
 
    def jump(self):
        self.rect.y += 2
        platform_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
        self.rect.y -= 2
 

        if len(platform_hit_list) > 0 or self.rect.bottom >= DISPLAY_HEIGHT:
            self.yVel = -10
 
    def moveLeft(self):

        self.xVel = 10
 
    def moveRight(self):

        self.xVel = -10
 
    def friction(self):

        self.xVel = 0
 
 
class Platform(pygame.sprite.Sprite):
 
    def __init__(self, width, height):
        super().__init__()
 
        self.image = pygame.Surface([width, height])
        self.image.fill(GREEN)
 
        self.rect = self.image.get_rect()
 
 
class MovingPlatform(Platform):

    xVel = 0
    yVel = 0
 
    boundary_top = 0
    boundary_bottom = 0
    boundary_left = 0
    boundary_right = 0
 
    player = None
 
    level = None
 
    def update(self):
        self.rect.x += self.xVel
        correction = 0
        hit = pygame.sprite.collide_rect(self, self.player)
        if hit:
            if self.xVel < 0:
                self.player.friction()
                correction = self.player.rect.right - self.rect.left
            elif self.xVel > 0:
                self.player.friction()
                correction = self.player.rect.left - self.rect.right

        if correction != 0:
            for block in self.level.platform_list:
                block.rect.x += correction
            
 
        self.rect.y += self.yVel
 

        hit = pygame.sprite.collide_rect(self, self.player)
        if hit:
            if self.yVel < 0:
                self.player.rect.bottom = self.rect.top
            else:
                self.player.rect.top = self.rect.bottom
 
        if self.rect.bottom > self.boundary_bottom or self.rect.top < self.boundary_top:
            self.yVel *= -1
        cur_pos = self.rect.x
        if cur_pos < self.boundary_left or cur_pos > self.boundary_right:#<-- [b]HERE IS WHERE I NEED TO ADD[/b]
            self.xVel *= -1
 
 
class Level(object):
 
    def __init__(self, player):
        self.platform_list = pygame.sprite.Group()
        self.enemy_list = pygame.sprite.Group()
        self.player = player
         
        self.background = None
     

        self.bgX = 0
        self.level_limit = -1000 #<-- [b]HERE IS WHERE I NEED TO ADD[/b]
 
    def update(self):
        self.platform_list.update()
        self.enemy_list.update()
 
    def draw(self, screen):
 
        screen.fill(BLUE)
 

        self.platform_list.draw(screen)
        self.enemy_list.draw(screen)

        for platform in self.platform_list:
            platform.rect.x += self.player.xVel
 
        for enemy in self.enemy_list:
            enemy.rect.x += self.player.xVel
 
class Level_01(Level):
 
    def __init__(self, player):
 

        Level.__init__(self, player)
 
        self.level_limit = -1500 #<-- [b]HERE IS WHERE I NEED TO ADD[/b]
 

        level = [[210, 70, 500, 500],
                 [210, 70, 800, 400],
                 [210, 70, 1000, 500],
                 [210, 70, 1120, 280],
                 ]
 

        for platform in level:
            block = Platform(platform[0], platform[1])
            block.rect.x = platform[2]
            block.rect.y = platform[3]
            block.player = self.player
            self.platform_list.add(block)
 

        block = MovingPlatform(100, 40)
        block.rect.x = 1350
        block.rect.y = 280
        block.boundary_left = 1350
        block.boundary_right = 1600
        block.xVel = -1
        block.player = self.player
        block.level = self
        self.platform_list.add(block)
 
 
class Level_02(Level):
 
    def __init__(self, player):
 
        Level.__init__(self, player)
 
        self.level_limit = -1500#<-- [b]HERE IS WHERE I NEED TO ADD[/b]
 

        level = [[210, 70, 500, 550],
                 [210, 70, 800, 400],
                 [210, 70, 1000, 500],
                 [210, 70, 1120, 280],
                 ]
 

        for platform in level:
            block = Platform(platform[0], platform[1])
            block.rect.x = platform[2]
            block.rect.y = platform[3]
            block.player = self.player
            self.platform_list.add(block)
 
        block = MovingPlatform(70, 70)
        block.rect.x = 1500
        block.rect.y = 300
        block.boundary_top = 100
        block.boundary_bottom = 550
        block.yVel = -1
        block.player = self.player
        block.level = self
        self.platform_list.add(block)
 
 
def main():
    pygame.init()
 

    size = [DISPLAY_WIDTH, DISPLAY_HEIGHT]
    screen = pygame.display.set_mode(size)
 
    pygame.display.set_caption("Platformer with moving platforms")
 
    player = Player()
 
    level_list = []
    level_list.append(Level_01(player))
    level_list.append(Level_02(player))
 
    current_level_no = 0
    current_level = level_list[current_level_no]
 
    active_sprite_list = pygame.sprite.Group()
    player.level = current_level
 
    player.rect.x = 350
    player.rect.y = DISPLAY_HEIGHT - player.rect.height
    active_sprite_list.add(player)
 

    done = False
 

    clock = pygame.time.Clock()
 
    # -------- Main Program Loop -----------
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
 
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    player.moveLeft()
                if event.key == pygame.K_RIGHT:
                    player.moveRight()
                if event.key == pygame.K_UP:
                    player.jump()
 
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT and player.xVel > 0:
                    player.friction()
                if event.key == pygame.K_RIGHT and player.xVel < 0:
                    player.friction()
 
        active_sprite_list.update()
 
        current_level.update()
 

        current_position = current_level.bgX 
        if current_position < current_level.level_limit:#<-- [b]HERE IS WHERE I NEED TO ADD[/b]
            if current_level_no < len(level_list)-1:
                player.rect.x = 350
                current_level_no += 1
                current_level = level_list[current_level_no]
                player.level = current_level
            else:

                done = True
 

        current_level.draw(screen)
        active_sprite_list.draw(screen)
 

        clock.tick(60)
 

        pygame.display.flip()
 
    pygame.quit()
 
if __name__ == "__main__":
    main()
I've added "here is where I need to add" to where I need to add it
Reply


Messages In This Thread
How would I make my position variable more accurate? - by HelpMEE - Dec-30-2019, 02:52 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  [split] Accurate Clicks Per Second Hamti 5 4,056 Sep-06-2022, 07:14 AM
Last Post: zackwang
  [split] Accurate Clicks Per Second kathyalex 4 3,216 Feb-16-2021, 04:27 PM
Last Post: SheeppOSU
  Accurate Clicks Per Second JudyLarose 8 9,498 Feb-10-2021, 03:00 AM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020