[JavaScript][2D游戏必看]碰撞检测

大家好,我们都知道,在一些游戏中,玩家和地图间的碰撞效果是必不可少的,但是有时自己做出的效果不尽人意,要不就是产生许多空气墙,要不就是直接穿墙。那么今天就为大家介绍如何用JavaScript完美实现碰撞检测。

开始之前我们定义一个示例:

map = [
[1,1,1,1,1,1,1,1],
[1,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,1],
[1,0,0,1,1,0,0,1],
[1,0,0,1,1,0,0,1],
[1,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1],
];//地图数据
solidBlock = [1];//储存实体方块的id
player = {
   
    top:1,
    left:2,
    speed:0.1
};//储存玩家位置信息,速度

首先,我们要知道,一个玩家可以站在1个方块,2个方块甚至4个方块上(玩家体型和单个方块差不多时),
我们就需要判定所处的4个方块是否有实体方块,

并且,在以上示例中,玩家的坐标可能会出现有小数的情况,

如果我们用 map[player.top][player.left] 读取是不行的,
我们就需要两个函数: Math.floor(num.) 向下取整和 Math.ceil(num.) 向上取整

例如,当玩家处于四个方块之间时,可以用以下代码获取:

map[Math.floor(player.top)][Math.floor(player.left)]//左上角方块的ID(或者说是编号)
map[Math.ceil(player.top)][Math.floor(player.left)]//左下角方块的ID(或者说是编号)
map[Math.floor(player.top)][Math.ceil(player.left)]//右上角方块的ID(或者说是编号)
map[Math.ceil(player.top)][Math.ceil(player.left)]//右下角方块的ID(或者说是编号)

数组.indexOf(项) 表示在数组中搜索这个项,
如果有则返回项的位置,没有则返回-1

solidBlock.indexOf(方块Id) == -1 表示判断这个方块是否为非实体方块,

由此我们可以做出第一个碰撞判断:

move = (direction/*方向*/)=>{
   
    if (player.speed <= 1) {
   //速度不超过一格时
        if (direction == "up") {
   //向屏幕上方移动时
            if (solidBlock.indexOf(map[Math.floor(player.top - player.speed)][Math.ceil(player.left)]) == -1) {
   
                if (solidBlock.indexOf(map[Math.floor(player.top - player.speed)][Math.floor(player.left)]) == -1) {
   
                    //假设移动前的位置刚好没有实体方块,那么移动后只需判断移动的方向轴即可(比如向上走时判定左上角和右上角)
                    player.top -= player.speed;
                }
            }
            else if (solidBlock.indexOf(map[Math.floor(player.top)][Math.ceil(player.left)]) == -1) {
   
                if (solidBlock.indexOf(map[Math.floor(player.top)][Math.floor(player.left)]) == -1) {
   
                    //如果原速度已经无法行走,但是可以通过 Math.floor() 和 Math.ceil() 将玩家贴在墙壁边时则进行校准
                    //如果缺少这部分校准,则会在实体方块边上留间隙无法填满,下同
                    player.top = Math.floor(player.top);
                }
            }//校准
        }
        else if (direction == "down") {
   //向屏幕下方移动时
            if (solidBlock.indexOf(map[Math.ceil(player.top + player.speed)][Math.ceil(player.left)]) == -1) {
   
                if (solidBlock.indexOf(map[Math.ceil(player.top + player.speed)][Math.floor(player.left)]) == -1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值