I'm creating a basic game using Python Arcade and Tiled Map Editor. My problem is, I can't use the Object Layer in arcade in their built-in Physics Engine. I can see, after creating an instance of the tiled map
the layers are separated into Tile Layers
and Object Layers
, but arcade.PhysicsEngineSimple()
doesn't use the object layers. This means I can't have collisions into walls or set a starting position for my player and enemies.
I asked a similar question before: Unable to use Object Layer from a Tiled Map with Python Arcade, which involved creating a Tile Layer
called "Walls" and using "use_spatial_hash": True
, but after using the solution, I realized that this still only uses the Tile Layer
and doesn't work for what I want. The collisions work, but it will be set to the size of the tile (In my case 64X64
) but if I want a collision boundary that is thin and long then it won't work.
If anyone has any experience with handling Object Layers
in Python Arcade, your help will be greatly appreciated.
It is very basic code at the moment, as I'm just learning arcade.
My code can be found here: Basic Dungeon Game
I am using arcade version 3.0.0dev32
There is no built-in functionality to support Object Layers
in Arcade. So you need to write your own. For example you can use following approach:
Object Layer
data from tilemapObject Layer
coordinatesWalls
Sprite listBelow is your updated code:
import arcade
from game_sprites import Player
SCALE = 3
PLAYER_MOVEMENT_SPEED = 7
class Game(arcade.Window):
def __init__(self):
super().__init__()
self.camera = None
self.tile_map = None
map_name = "maps/dungeon.tmx"
layer_options = {'Bricks': {'use_spatial_hash': True}}
self.tile_map = arcade.load_tilemap(map_name, SCALE, layer_options)
player_position = self.tile_map.object_lists["Sprite Positions"][0].properties
# Get object layer
points = self.tile_map.object_lists['Walls'][0].shape
width = abs(points[0][0] - points[1][0])
height = abs(points[0][1] - points[2][1])
center_x = points[0][0] + width/2
center_y = points[0][1] - height/2
wall = arcade.SpriteSolidColor(width, height, center_x, center_y, arcade.color.RED)
self.scene = arcade.Scene.from_tilemap(self.tile_map)
walls = self.scene['Bricks']
walls.append(wall)
self.player = Player(center_x=player_position["X"]*SCALE, center_y=player_position["Y"]*SCALE, scale=1)
self.player_list = arcade.SpriteList()
self.player_list.append(self.player)
self.physics_engine = arcade.PhysicsEngineSimple(self.player, walls=walls)
self.camera_sprites = arcade.camera.Camera2D()
self.left_pressed = False
self.right_pressed = False
self.up_pressed = False
self.down_pressed = False
def on_draw(self):
self.clear()
self.camera_sprites.use()
self.scene.draw()
self.player_list.draw()
def on_update(self, delta_time):
self.physics_engine.update()
self.player.update_animation()
self.player.change_x = 0
self.player.change_y = 0
# self.player.coll
if self.up_pressed and not self.down_pressed:
self.player.change_y = PLAYER_MOVEMENT_SPEED
elif self.down_pressed and not self.up_pressed:
self.player.change_y = -PLAYER_MOVEMENT_SPEED
if self.left_pressed and not self.right_pressed:
self.player.change_x = -PLAYER_MOVEMENT_SPEED
elif self.right_pressed and not self.left_pressed:
self.player.change_x = PLAYER_MOVEMENT_SPEED
self.scroll_to_player()
def on_key_press(self, key, modifiers):
if key == arcade.key.UP:
self.up_pressed = True
elif key == arcade.key.DOWN:
self.down_pressed = True
elif key == arcade.key.LEFT:
self.left_pressed = True
elif key == arcade.key.RIGHT:
self.right_pressed = True
def on_key_release(self, key, modifiers):
if key == arcade.key.UP:
self.up_pressed = False
elif key == arcade.key.DOWN:
self.down_pressed = False
elif key == arcade.key.LEFT:
self.left_pressed = False
elif key == arcade.key.RIGHT:
self.right_pressed = False
def scroll_to_player(self):
position = (self.player.center_x, self.player.center_y)
self.camera_sprites.position = arcade.math.lerp_2d(self.camera_sprites.position, position, 0.1)
Game()
arcade.run()