【问题标题】:Rectangle collision in golang (pixel module)golang中的矩形碰撞(像素模块)
【发布时间】:2021-04-15 08:48:28
【问题描述】:

我很难理解我在基于网格的游戏中的碰撞检测代码有什么问题。 我正在尝试检测“平铺”矩形和“玩家”矩形之间的碰撞(交叉点)。

平铺矩形在 x,y 坐标处绘制,但矩形的角(左下角和右上角)为 (x-16, y-16)(x+48, y+48)。

播放器矩形取决于播放器位置,但其角应位于 (player_x-16, player_y-16)(player_x+16, player_y+16)。

我已经尝试使用像素模块中的内置“(r Rect) Intersects(r Rect)”函数,但仅在领带矩形和当前玩家位置之间检测到碰撞(不是 16 像素的偏移量) .

“tiles”二维数组保存我的地图,因此我可以检查玩家所在的瓷砖类型。

我也尝试编写自己的矩形碰撞检测“算法”,因为没有更好的词,结果相同。

我的角色在每次按键后向任何方向移动 4 个像素,我会判断玩家是否超出边界(与墙相撞或在墙内),如果是,则将角色向后移动 4 个像素。

这是使用内置函数的代码的相关部分(我现在有这个):

func (player Player) IsOutOfBounds(tiles [][]*world.Tile) bool {
    x, y, _, _ := NormalizeCoordinates(player.Pos.X, player.Pos.Y)
    //So now no need to loop through every cell since I know which one the player is touching   
    if strings.Contains(tiles[x][y].Type, "wall") || tiles[x][y].Type == "pillar" {
        return true
    }
    return false
}

// I use this function to find the closest multiple of 32 from the player position which is going to be the index of the tile the player is in
func NormalizeCoordinates(player_x, player_y float64) (int, int, int, int) {
    x := int(player_x + 32/2)
    x -= x % 32

    y := int(player_y + 32/2)
    y -= y % 32

    x2 := x + 32

    y2 := y + 32

    return x, y, x2, y2
}

简而言之:

预期行为:检测设置边界之间的冲突(player_x/y -/+ 16 和平铺矩形边界)

当前行为:检测 player_x/y 和图块矩形边界之间的碰撞

这是它现在的样子,红色是我希望它检测到碰撞的地方,绿色是它实际检测到的地方:

编辑:添加图片以更好地说明我的问题并更新了我的问题

【问题讨论】:

  • 什么是xy
  • @NickyLogan x 和 y 坐标,(0,0) 是程序创建的窗口的左下角。 x 加 1 表示右移 1 个像素,y 加 1 表示上移 1 个像素。
  • @NickyLogan 感谢您的链接,我检查了一下,似乎这就是我在第二个代码提取中实现的(授予 && 而不是 ||)。但是,它不会改变行为。
  • 存在重叠时 Check_collision 是否应该返回 true

标签: go collision-detection pixel rectangles


【解决方案1】:

你去吧,希望你理解算法,如果没有,阅读一些关于空间散列的东西。

// IntersectTiles returns all tiles player intersects with, tile offset if a position of bottom left
// corner of a first tile in tile map. No clamping is preformed so you have to check bounds your self.
func IntersectTiles(player, tilesize, tileOffset pixel.Vec, playerSize float64) (coll [][2]int) {
    bounds := pixel.R(player.X-playerSize, player.Y-playerSize, player.X+playerSize, player.Y+playerSize)
    player = player.Sub(tileOffset)

    // Pos finds a tile index based of tile size
    pos := func(pos pixel.Vec) [2]int {
        return [...]int{int(pos.X / tilesize.X), int(pos.Y / tilesize.Y)}
    }

    min := pos(bounds.Min)
    max := pos(bounds.Max)

    for y := min[1]; y < max[1]+1; y++ {
        for x := min[0]; x < max[0]+1; x++ {
            coll = append(coll, [...]int{x, y})
        }
    }

    return
}

【讨论】:

  • 在看到你的答案之前,我用我的工作编辑了我的问题,不过我还是会尝试一下
猜你喜欢
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 2014-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多