Search code examples
pythonpygameruntime-error2d-gamestiled

Solve pygame binascii.Error: Incorrect padding?


I'm making a game for my final project in class. I'm quite new to pygame and this whole game development thing. I used this video as my guide.

I used Tiled to make a tile map for my game but when I tried to run it with pygame, I got this:

Traceback (most recent call last):
File "C:\Users\Rose\Desktop\mp2 shits\shit.py", line 114, in <module>
Game().main(screen)
File "C:\Users\Rose\Desktop\mp2 shits\shit.py", line 58, in main
self.tilemap = tmx.load('tileMap.tmx', screen.get_size())
File "C:\Users\Rose\Desktop\mp2 shits\tmx.py", line 835, in load
return TileMap.load(filename, viewport)
File "C:\Users\Rose\Desktop\mp2 shits\tmx.py", line 714, in load
layer = Layer.fromxml(tag, tilemap)
File "C:\Users\Rose\Desktop\mp2 shits\tmx.py", line 255, in fromxml
data = data.decode('base64').decode('zlib')
File "C:\Python27\lib\encodings\base64_codec.py", line 42, in base64_decode
output = base64.decodestring(input)
File "C:\Python27\lib\base64.py", line 325, in decodestring
return binascii.a2b_base64(s)
binascii.Error: Incorrect padding
[Finished in 5.0s]

Here is my code:

import pygame
import tmx

class Player(pygame.sprite.Sprite):
def __init__(self, location, *groups):
    super(Player, self).__init__(*groups)
    self.image = pygame.image.load('red.gif').convert()
    self.rect = pygame.rect.Rect(location, self.image.get_size())
    self.resting = False 
    self.dy = 0 

def update(self, dt, game):
    last = self.rect.copy()

    key = pygame.key.get_pressed()
    if key[pygame.K_LEFT]:
        self.rect.x -= 150 * dt
    if key[pygame.K_RIGHT]:
        self.rect.x += 150 * dt

    if self.resting and key[pygame.K_SPACE]:
        self.dy = -500
    self.dy = min(400, self.dy + 40)

    self.rect.y += self.dy * dt

    new = self.rect
    self.resting = False
    for cell in game.tilemap.layers['triggers'].collide(new, 'blockers'):
        if last.right <= cell.left and new.right > cell.left:
            new.right = cell.left
        if last.left >= cell.right and new.left < cell.right:
            new.left = cell.right
        if last.bottom <= cell.top and new.bottom > cell.top:
            self.resting = True
            new.bottom = cell.top
            self.dy = 0
        if last.top >= cell.bottom and new.top < cell.bottom:
            new.top = cell.bottom
            self.dy = 0

    game.tilemap.set_focus(new.x, new.y)

class Game(object):
def main(self, screen):
    clock = pygame.time.Clock()

    background = pygame.image.load('bg.png')

    self.tilemap = tmx.load('tileMap.tmx', screen.get_size())

    self.sprites = tmx.SpriteLayer()
    start_cell = self.tilemap.layers['triggers'].find('player')[0]
    self.player = Player((start_cell.px, start_cell.py), self.sprites)
    self.tilemap.layers.append(self.sprites)

    fps = 30
    running = True
    while running:
        dt = clock.tick(fps)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                running = False

        self.tilemap.update(dt/1000., self)
        pygame.display.set_caption("Little Red")
        screen.blit(background, (0,0))
        self.tilemap.draw(screen)
        pygame.display.flip()

if __name__ == '__main__':
    pygame.init()
    width = 1024
    height = 480
    screen = pygame.display.set_mode((width, height))
    Game().main(screen)

Thanks in advance to those who would be kind enough to help!

EDIT: This is what my map looks like... tmx file


Solution

  • It looks like tmx.py unconditionally tries to base64-decode and zlib-decode the data, without checking what format the data is actually in. Recent versions of Tiled default to CSV formatted data, so make sure to change the tile layer data format to base64+zlib in the Map Properties in Tiled.

    When creating a new map you only need to set this up once, since Tiled will remember your preference.