【问题标题】:Godot: How to limit player movement to certain tiles only?Godot:如何将玩家的移动限制在某些瓷砖上?
【发布时间】:2019-09-18 19:29:47
【问题描述】:

我正在尝试制作“Stone Age”克隆。 而且我正在尝试想办法将我的玩家移动限制在某些瓷砖上。这意味着玩家只能在某些图块上移动。

到目前为止,我所做的是制作两个 TileMap,一个用于“可步行的地板”,一个用于“不可步行的地板”。我将它们放在不同的碰撞层上,并且我的播放器只与“无法行走的地板”发生碰撞。所以玩家被阻止进入它: 这里(https://i.imgur.com/sPGCS0V.png):可步行的地板是棕色瓷砖,不可步行的地板是写着“FLOOR”的地板。

这种方法是个问题,因为我想在平台上移动我的播放器。 (上面有箭头的图块)但是如果所有背景都无法行走,我的玩家在平台上时会与它发生碰撞,因此他将无法使用平台移动......

有没有更好的方法来做到这一点?

【问题讨论】:

    标签: game-engine godot


    【解决方案1】:

    我在this 指南上找到了解决方案并稍作修改。简而言之,解决办法就是在运动的方向上使用ray-cast,看看有没有碰撞。

    我所做的是创建一个瓦片地图并将所有允许玩家移动的瓦片称为“可行走_[某物]”。在我检测到来自光线投射的碰撞的播放器脚本中,我检查了光线投射与之碰撞的图块的名称。如果名称以“walkable”开头,我允许移动,而在所有其他情况下,我不允许。

    onready var ray = $RayCast2D
    
    var speed = 256 # big number because it's multiplied by delta
    var tile_size = 64 # size in pixels of tiles on the grid
    
    var last_position = Vector2() # last idle position
    var target_position = Vector2() # desired position to move towards
    var movedir = Vector2() # move direction
    
    func _process(delta):
        # MOVEMENT
        if ray.is_colliding():
            var collision = ray.get_collider()
            if collision is TileMap:
                var tile_name = get_tile(collision)     
                if !(tile_name.begins_with("Walkable")):                
                    position = last_position
                    target_position = last_position
                else:
                    position += speed * movedir * delta
    
                    if position.distance_to(last_position) >= tile_size - speed * delta: # if we've moved further than one space
                        position = target_position # snap the player to the intended position
    
    
        else:
            position += speed * movedir * delta
    
            if position.distance_to(last_position) >= tile_size - speed * delta: # if we've moved further than one space
                position = target_position # snap the player to the intended position
    
    

    这是 get_tile() 函数,它获取射线投射碰撞的瓦片的字符串名称。因为光线投射碰撞返回整个瓦片地图,我们需要知道我们与哪个特定瓦片发生碰撞。所以我用玩家的位置+光线投射矢量的方向来找出正确的瓷砖。首先,我添加了一个 tile 大小的宽度和高度的半个 tile,因为玩家位置被认为是玩家节点的左上角。例如,如果玩家是一个大小为 2x2 的正方形,并且他位于 (0,0) 上。这意味着它的左上角在 0,0 上。这意味着 1,1 是正方形的中心。

    func get_tile(tile_map):    
        if tile_map is TileMap:
            var v = Vector2(tile_size / 2 , tile_size /2)
            var tile_pos = tile_map.world_to_map(position + v + ray.cast_to)
            var tile_id = tile_map.get_cellv(tile_pos)
            if (tile_id == -1):
                return "None"
            else:
                return tile_map.tile_set.tile_get_name(tile_id)
    
    

    为了完成,here 是完整播放器脚本的 pastebin。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-19
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多