JavaScript 传说 Rails 社区的朋友 JavaScript 都比较强

mikasayee · 2014年02月12日 · 最后由 chita 回复于 2014年02月13日 · 3097 次阅读

本人是个后端 但公司里就我一个懂点 web 的被拉去要用 cocos2d-html5 做一个客户端的 demo

大量的 Js 让我痛不欲生啊 遇到各种坑爹问题 这次遇到了找了 2 天没找到 网上也找不到靠谱的 js 社区 慕名而来 Ruby 社区问一下

主要就是 get_move_ranges 和 check_move_ranges 两个方法 这是一个战棋类游戏 寻找用户角色可移动范围的算法。大体的思路就是 角色比如在 (x:10, y: 10) 坐标,然后寻找 上、下、左、右 四个坐标点 然后在这 4 个坐标点再依次展开。

这当中我使用变量 this.move_paths 来存储用户每次可移动的路径 比如每个用户可移动 3 步 他最后存储的就是 [{x: 11, y: 10}, {x: 12, y: 10}, {x: 13, y: 10}]

现在遇到比较奇怪的问题是 this.move_paths 在前几次遍历中是正常的 到后面居然都是重复的值 导致有一些路径无法移动

下面是用到的两个函数

// 获得用户移动范围
get_move_ranges: function(distance, player_position) {

    this.check_move_ranges(distance, player_position, 'up');
    this.check_move_ranges(distance, player_position, 'down');
    this.check_move_ranges(distance, player_position, 'left');
    this.check_move_ranges(distance, player_position, 'right');

    return this.move_ranges;
    // tiled信息

    // 是否有障碍物
},

// 递归遍历cover
check_move_ranges: function(distance, position, direction) {
    if ( distance > this.move_step ){
        return
    }

    var pls = jQuery.extend({}, position); // 新建对象 因为javascript传递对象是引用

    if (direction == 'up')
        pls.y += 32;
    else if (direction == 'down')
        pls.y -= 32;
    else if (direction == 'left')
        pls.x -= 32;
    else if (direction == 'right')
        pls.x += 32;

    // 定义数据结构
    var cover = {
        x: pls.x,
        y: pls.y
    };

    // 存储路径坐标
    this.move_paths[distance - 1] = pls;


    if (cover.x == 272 && cover.y == 208) {
        console.log('------------------');
        console.log(this.move_paths);
        console.log('------------------');
    }


    // 检查cover是否已经存在数组中
    if ( !this.is_cover_exist(cover) )
        this.move_ranges.push(cover);

    if (this.move_paths.length == this.move_step) {
        this.all_paths.push(this.move_paths);
        console.log(this.move_paths);   //  !!!!!!注释行!!!!!
    }

    this.get_move_ranges(distance + 1, pls);
},

下面就是见证奇迹的时刻 和 让我彻底晕菜的时刻

我在一个特定的点 x:272 y:208 店打印这个 this.move_paths

if (cover.x == 272 && cover.y == 208) {
     console.log('------------------');
     console.log(this.move_paths);
     console.log('------------------');
}

上面代码有个 !!! 注释行!!!
在我注释的时候 this.move_paths 输出的是正常的 this.move_paths 里有 278, 208 这个对象

但是我把这个 注释行去掉 没有更改任何的代码 这个输出的值变了居然 没有 278,208 这个对象 天呐

我不知道是我逻辑的问题还是 js 语法的问题 所以前来请教各位

1 楼 已删除

#1 楼 @krazy 删了之后还是不对 this.all_paths 里 没有{ x=272, y=208 }的值

#2 楼 @mikasayee 噢 忽略我.. 看错了

move_step 是干嘛的

#4 楼 @chita move_step 是角色可移动的距离 比如可以移动 5 步 move_step 就是 5

#5 楼 @mikasayee 那 distance 又是什么

什么距离?这两个做比较干嘛

#6 楼 @chita distance 使计算当前角色已经走过的距离
初始值是 1 没移动一个距离加 1 当 distance > move_step 的时候就停止移动了

#7 楼 @mikasayee 好吧

你的 move_paths 在哪初始化的 all_paths 里 push 的都是同一个引用吧 你打印 all_paths 试试

里面应该都是一个数组

#8 楼 @chita 对啊 谢谢哥 我这脑子 上面遇到类似问题
那在递归中我应该如何 替代 move_paths 这个变量的功能呢

我想的是加了一个 this.num_path 变量 当 distance > move_step 的时候
move_paths[num_path][distance] = pls
但是这样操作回报一个 move_paths[num_path][distance] undefine 的错误

#9 楼 @mikasayee 你这当然 undefine 了 二维数组需要初始化的

类似于 move_paths[num_path]=[]

然后 move_paths[num_path][distance] = pls 才能不报错

只用一个 move_paths 逻辑上肯定还有问题

我的思路 是 递归路径的时候 需要把前面路径传入函数 distance 没什么必要了

大概就是

get_move_ranges: function(movepath, player_position) {

 this.check_move_ranges(movepath.concat(), player_position, 'up');
        this.check_move_ranges(movepath.concat(), player_position, 'down');
        this.check_move_ranges(movepath.concat(), player_position, 'left');
        this.check_move_ranges(movepath.concat(), player_position, 'right');



}

 check_move_ranges: function(movepath, position, direction) {
var distance =movepath.length
if ( distance > this.move_step ){
            return
        }
}

#10 楼 @chita 非常感谢你 我传路径以后好像还是有引用问题 可能我对 js 理解的不太深入

我在调试的时候发现一个奇怪的事情,但这个事情帮我把问题解决了~.~

if (this.move_paths.length == this.move_step) {
    var mp = [];
    for ( var i = 0; i < this.move_step; i ++ ) {
        mp.push(this.move_paths[i])
    }
    this.all_paths.push(mp);
}

我直接输出 this.move_paths 还是不可以 但是我 this.move_paths[0/1/2] 结果值就正常了 所以我就循环把他的值付给另一个变量 然后在添加到 all_paths 数组里

虽然我还云里雾里 不过好歹把问题解决了 再次感谢 ~。~

#11 楼 @mikasayee

如果只是拷贝 数组的话

var mp = [];
   for ( var i = 0; i < this.move_step; i ++ ) {
       mp.push(this.move_paths[i])
   }
   this.all_paths.push(mp);

这一段可以直接改为

this.all_paths.push(this.move_paths.concat())

问题 解决了 就好

需要 登录 后方可回复, 如果你还没有账号请 注册新账号