You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中this绑定异常致x/y失效,玩家移动功能故障求助

问题分析与修复方案

你的核心问题是**this指向错误**,导致移动方法无法访问到玩家的坐标属性,同时还有移动方向的逻辑错误,以下是具体说明和修复方式:

错误原因

  1. this指向混乱:你创建的move是player.Move的实例,它和player实例是完全独立的对象。Move内部的Right/Up等方法里的this指向的是move实例本身,而不是存储坐标的player实例——move实例没有x和y属性,所以会输出undefined,做加减运算后变成NaN。
  2. 移动逻辑错误:Canvas的y轴是向下增长的,你原来的Up方法写的是this.y +=10(实际会向下移动),Down方法写的是this.y -=10(实际会向上移动),方向完全搞反。
  3. Right方法赋值错误:你写的是this.x =10,这是直接把坐标设为10,而不是累加移动距离。

修复方案一:简化结构(推荐)

直接把移动方法挂载到Player实例上,避免多层构造函数带来的this问题:

修改functions.js中的Game构造函数

function Game(){
    this.sprites = []
    this.Player = function(x,y){
        this.x = x
        this.y = y
        // 直接在Player实例上定义移动方法
        this.Right = function(){
            this.x += 10
            console.log(this.x,this.y)
        }
        this.Up = function(){
            this.y -= 10 // Canvas向上移动是y值减小
            console.log(this.x,this.y)
        }
        this.Left = function(){
            this.x -= 10
            console.log(this.x,this.y)
        }
        this.Down = function(){
            this.y += 10 // Canvas向下移动是y值增大
            console.log(this.x,this.y)
        }
    }
}

修改main.js,直接使用player的方法

var draw = new drawCanvas()
var game = new Game()
var player = new game.Player(250,250)

document.addEventListener('keydown',arrows,false);

// 直接调用player的移动方法
function arrows(e){
    switch(e.which){
        case 37: player.Left(); break;
        case 38: player.Up(); break;
        case 39: player.Right(); break;
        case 40: player.Down(); break;
    }
}

function loop(){
    draw.background('#00FF00')
    draw.drawLine(0,0,player.x,player.y)
    requestAnimationFrame(loop)
}
requestAnimationFrame(loop)

修复方案二:保留Move结构

如果想保留Move的独立结构,可以通过闭包保存Player的引用,让Move方法能访问到玩家坐标:

修改functions.js中的Game构造函数

function Game(){
    this.sprites = []
    this.Player = function(x,y){
        this.x = x
        this.y = y
        var self = this; // 保存Player实例的引用
        this.Move = function(){
            // 通过self访问Player的x/y属性
            this.Right = function(){
                self.x += 10
                console.log(self.x,self.y)
            }
            this.Up = function(){
                self.y -= 10
                console.log(self.x,self.y)
            }
            this.Left = function(){
                self.x -= 10
                console.log(self.x,self.y)
            }
            this.Down = function(){
                self.y += 10
                console.log(self.x,self.y)
            }
        }
    }
}

此时main.js可以保留原来的move实例创建逻辑,因为Move内部的方法已经能通过self访问到player的坐标了。


内容的提问来源于stack exchange,提问作者MrMagicMan100

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 22:33:33