JavaScript中this绑定异常致x/y失效,玩家移动功能故障求助
问题分析与修复方案
你的核心问题是**this指向错误**,导致移动方法无法访问到玩家的坐标属性,同时还有移动方向的逻辑错误,以下是具体说明和修复方式:
错误原因
this指向混乱:你创建的move是player.Move的实例,它和player实例是完全独立的对象。Move内部的Right/Up等方法里的this指向的是move实例本身,而不是存储坐标的player实例——move实例没有x和y属性,所以会输出undefined,做加减运算后变成NaN。- 移动逻辑错误:Canvas的y轴是向下增长的,你原来的
Up方法写的是this.y +=10(实际会向下移动),Down方法写的是this.y -=10(实际会向上移动),方向完全搞反。 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
相关产品推荐
相关产品推荐

