所以我已经在一个项目上工作了一段时间,我真的很想在游戏中加入动画瓷砖。我用 pygame 创建了一个 2d 像素艺术风格的游戏,我使用名为 Tiled 的编辑器来创建地图。Tiled 会生成一个 .tmx 文件以及一个用于渲染地图的 .tsx 文件。我已经让地图渲染没有任何问题。问题来自渲染动画图块。他们只是没有动画。我了解动画的基本原理。我只需要获取动画的第一张图像,等待帧之间的持续时间,然后渲染下一帧。但我只是不知道如何让它工作。pytmx 以及它如何从 Tiled 文件中读取动画的文档很少。
这是 .tmx 文件:
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.2" tiledversion="1.3.4" orientation="orthogonal" renderorder="right-down" width="32" height="32" tilewidth="96" tileheight="96" infinite="0" nextlayerid="5" nextobjectid="5">
<tileset firstgid="1" source="Bigger-Textures(96x96).tsx"/>
<layer id="1" name="Tile Layer 1" width="32" height="32">
<data encoding="csv">
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,4,6,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,13,15,1,1,1,1,1,1,12,12,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,13,15,1,1,1,1,1,1,11,12,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,13,25,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,22,23,23,23,23,23,23,23,9,7,23,23,23,23,23,23,24,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,13,15,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,13,15,1,1,1,1,12,3,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,12,12,1,4,5,5,27,25,5,5,6,1,1,12,12,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,11,12,1,13,7,8,9,7,8,9,15,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,12,1,1,13,16,17,18,16,11,18,15,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,13,25,26,27,25,26,27,15,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,13,7,23,23,23,23,23,24,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,13,15,1,1,1,1,1,10,12,12,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,13,15,1,1,1,1,1,12,1,12,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,13,25,5,5,5,5,5,5,5,5,5,6,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,22,23,23,23,23,23,23,23,23,23,23,24,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
</data>
</layer>
<objectgroup id="4" name="Obstacles">
<object id="1" name="wall" x="0" y="-96" width="3168" height="96"/>
<object id="2" name="wall" x="3072" y="0" width="96" height="3168"/>
<object id="3" name="wall" x="-96" y="3072" width="3168" height="96"/>
<object id="4" name="wall" x="-96" y="-96" width="96" height="3168"/>
</objectgroup>
</map>
这是 .tsx 文件:
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.2" tiledversion="1.3.4" name="Bigger-Textures (96x96)" tilewidth="96" tileheight="96" tilecount="81" columns="9">
<image source="../gfx/tiles/tilesheets/Textures-sprite-sheet-4X.png" width="864" height="864"/>
<tile id="1">
<animation>
<frame tileid="1" duration="500"/>
<frame tileid="2" duration="500"/>
</animation>
</tile>
<tile id="2">
<animation>
<frame tileid="2" duration="500"/>
<frame tileid="1" duration="500"/>
</animation>
</tile>
<tile id="9">
<animation>
<frame tileid="9" duration="500"/>
<frame tileid="10" duration="500"/>
</animation>
</tile>
<tile id="10">
<animation>
<frame tileid="10" duration="500"/>
<frame tileid="9" duration="500"/>
</animation>
</tile>
</tileset>
这就是我目前渲染瓷砖的方式:
def render(self):
self.ti = self.handler.currentMap.get_tile_image_by_gid
xStart = max(0, self.handler.camera.xOffset / self.handler.currentMap.tilewidth)
xEnd = min(self.handler.currentMap.width, (self.handler.camera.xOffset + self.handler.displayWidth) / self.handler.currentMap.tilewidth + 1)
yStart = max(0, self.handler.camera.yOffset / self.handler.currentMap.tileheight)
yEnd = min(self.handler.currentMap.height, (self.handler.camera.yOffset + self.handler.displayHeight) / self.handler.currentMap.tileheight + 1)
for i in range(len(self.handler.currentMap.layers) - 1):
for x in range(int(xStart), int(xEnd)):
for y in range(int(yStart), int(yEnd)):
tile = self.handler.currentMap.get_tile_image(x, y, i)
if (tile):
self.display.blit(tile, (x * self.handler.currentMap.tilewidth - self.handler.camera.xOffset,
y * self.handler.currentMap.tileheight - self.handler.camera.yOffset))
这是它在 Pytmx github 上所说的:
# just iterate over animated tiles and demo them
# tmx_map is a TiledMap object
# tile_properties is a dictionary of all tile properties
# iterate over the tile properties
for gid, props in tmx_map.tile_properties.items():
# iterate over the frames of the animation
# if there is no animation, this list will be empty
for animation_frame in props['frames']:
# do something with the gid and duration of the frame
# this may change in the future, as it is a little awkward now
image = tmx_map.get_tile_image_by_gid(gid)
duration = animation_frame.duration
...
任何帮助是极大的赞赏!这是GitHub上的项目,如果它有任何用途:D