Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript-OOP_Javascript_Oop - Fatal编程技术网

Javascript-OOP

Javascript-OOP,javascript,oop,Javascript,Oop,好的,我为一个JS游戏写了一些代码。代码本身可以工作,但不是正确的OOP形式。在“敌人”类中,我需要引用“玩家”类中的变量和方法。查看引用变量的“碰撞”方法。请注意,我专门从脚本末尾名为“Player”的新实例“Player”中获取数据。对于OOP,我应该如何在这两个类之间共享信息 谢谢 var Player=function(){ 这个.x=15; 这个y=15; }; Player.prototype.reset=函数(){ this.x=200;//重置为此 this.y=320;//重

好的,我为一个JS游戏写了一些代码。代码本身可以工作,但不是正确的OOP形式。在“敌人”类中,我需要引用“玩家”类中的变量和方法。查看引用变量的“碰撞”方法。请注意,我专门从脚本末尾名为“Player”的新实例“Player”中获取数据。对于OOP,我应该如何在这两个类之间共享信息

谢谢

var Player=function(){
这个.x=15;
这个y=15;
};
Player.prototype.reset=函数(){
this.x=200;//重置为此
this.y=320;//重置为此
};
var=function(){
这个.x=25;
这个y=30;
};
defey.prototype.collision=函数(){

如果javascript函数中的(player.x>=this.x-35&player.x=this.y-30&player.y,则可以使用
参数

您的问题的解决方案可能是将
Player
的实例传递给方法
collision

正如@lvaro Touzón所提到的,一个好的做法是在代码中使用继承,因为
敌人
玩家
现在基本相同


此外,您还可以阅读有关ES6类的内容,这些类使编程更加容易,但是它们仍然依赖于原型继承,这使得它们只是语法上的糖分。如果您想使用OOP,那么这可能会对您有所帮助

添加辅助扩展函数

function extend(current, base) {
    for (var key in base) {
        if (base.hasOwnProperty(key)) {
            current[key] = base[key];
        }
    }
    current.prototype = Object.create(base.prototype);
};
按照@alvaro Touzón的建议创建类
Avatar

var Avatar = (function () {
    function Avatar (x, y) {
        this.x = x;
        this.y = y;
    }
    Avatar.prototype.reset = function() {
      return this;
    };

    Avatar.prototype.collision = function(object) {
      if (object.x >= this.x - 35 & object.x <= this.x + 35) { // check column
        if (object.y >= this.y - 30 & object.y <= this.y + 30) { // check row
          object.reset(); // calls object method "reset"
        }
      }
    };

    return Avatar;
}());
创建
游戏

var Game = (function () {

    Game.prototype.player = new Player(15, 15);
    Game.prototype.enemys = [
        new Enemy(25, 30),
        new Enemy(10, 30),
    ];

    function Game () {
        // setup
    }

    Game.prototype.start = function() {
      for (var i = 0; i < array.length; i++){
          var enemy = this.enemys[i];
          this.player.collision(enemy);
      }
      return this;
    };


    return Game;
}());
它的工作原理


你有一组对象-敌人和对象-玩家,他们都有能力计算彼此之间的碰撞,因为共同的祖先。每次你调用游戏的开始都会计算碰撞。我会在
游戏中添加
setInterval
。开始计算碰撞,但这会使游戏复杂化代码。

我不能说你想如何运行你的游戏,但总的来说,为了共享数据,我一直相信创建单例类并在不同的对象中使用它。这样我们也可以更好地处理错误。在js中,没有单例类可以这么说。但你可以始终创建简单的js模块,如下所示:

var abc = (function(){
 var abc = "someval"; //private variable
 var setAbc = function() {
  //some logic
 }
 var getAbc = function() {
  //some logic
 }
 var publicMethod = function {
  //some logic
 }

 return {
  setAbc: setAbc,
  getAbc: getAbc,
  publicMethod: publicMethod
 }
})();

变异/重置玩家与敌人无关。重置到哪个位置与玩家无关。
这些事情应该由游戏在主游戏循环中完成,而
碰撞
-方法应该只确定这个元素是否击中了传递的元素

//manages the bounding-Box / Collisions, 
//also pretty much everything related to (basic) rendering, like Assets/Image or DOM-Node, ... but since you've not included that in your code, I can't adapt it.

class Element{
    constructor(config){
        let {x, y, width, height, hitBoxOffsetX, hitBoxOffsetY} = config || {};
        this.x = +x || 0;
        this.y = +y || 0;
        this._hitBoxOffsetX = +hitBoxOffsetX || 0;
        this._hitBoxOffsetY = +hitBoxOffsetY || 0;
        this.width = +width || 0;
        this.height = +height || 0;
    }

    //bounding box
    get left(){     return this.x + this._hitBoxOffsetX }
    get right(){    return this.left + this.width       }
    get top(){      return this.y + this._hitBoxOffsetY }
    get bottom(){   return this.top - this.height       }

    collision(other){
        return this.right > other.left && this.left < other.right &&
            this.top > other.bottom && this.bottom < other.top;
    }
}

//everything that can somehow be hit, extends Element
class Player extends Element {
    constructor(){
        super({
            hitBoxOffsetX: -35, //hitBox starts 35px to the left of this.x
            hitBoxOffsetY: -30, //hitBox starts 30px to the top of this.y
            width: 70,          //width of the hitBox
            height: 60          //height of the hitBox
        });
    }
}

class Enemy extends Element {
    constructor(){
        //since I have no idea about the dimensions of these Entities
        super(); 
    }
}

//and walls, for example
class Wall extends Element {
    constructor(x, y, width, height){
        super({
            x, y,
            width: +width || 20, 
            height: +height || 20
        });
    }
}

如果你在javascript中使用OOP,一个想法是从玩家那里扩展敌人,或者用一个基数代替两个基数,比如阿凡达,或者任何我想传递的名字都是“玩家”,而不是“玩家”到碰撞方法?不,你应该传递玩家的实例,在你的例子中是
Player
,这通常是正确的。我使用一个游戏引擎来构建游戏,它使用HTML5画布和JS。引擎只寻找更新游戏的新功能,这在本文中没有特别提到。引擎寻找“player.prototype.update”和“敌方.prototype.update”,它会根据这两个功能不断更新游戏。
var abc = (function(){
 var abc = "someval"; //private variable
 var setAbc = function() {
  //some logic
 }
 var getAbc = function() {
  //some logic
 }
 var publicMethod = function {
  //some logic
 }

 return {
  setAbc: setAbc,
  getAbc: getAbc,
  publicMethod: publicMethod
 }
})();
//manages the bounding-Box / Collisions, 
//also pretty much everything related to (basic) rendering, like Assets/Image or DOM-Node, ... but since you've not included that in your code, I can't adapt it.

class Element{
    constructor(config){
        let {x, y, width, height, hitBoxOffsetX, hitBoxOffsetY} = config || {};
        this.x = +x || 0;
        this.y = +y || 0;
        this._hitBoxOffsetX = +hitBoxOffsetX || 0;
        this._hitBoxOffsetY = +hitBoxOffsetY || 0;
        this.width = +width || 0;
        this.height = +height || 0;
    }

    //bounding box
    get left(){     return this.x + this._hitBoxOffsetX }
    get right(){    return this.left + this.width       }
    get top(){      return this.y + this._hitBoxOffsetY }
    get bottom(){   return this.top - this.height       }

    collision(other){
        return this.right > other.left && this.left < other.right &&
            this.top > other.bottom && this.bottom < other.top;
    }
}

//everything that can somehow be hit, extends Element
class Player extends Element {
    constructor(){
        super({
            hitBoxOffsetX: -35, //hitBox starts 35px to the left of this.x
            hitBoxOffsetY: -30, //hitBox starts 30px to the top of this.y
            width: 70,          //width of the hitBox
            height: 60          //height of the hitBox
        });
    }
}

class Enemy extends Element {
    constructor(){
        //since I have no idea about the dimensions of these Entities
        super(); 
    }
}

//and walls, for example
class Wall extends Element {
    constructor(x, y, width, height){
        super({
            x, y,
            width: +width || 20, 
            height: +height || 20
        });
    }
}
update(){
    requestAnimationFrame(update);
    //move everything

    //collision-checks

    //if your player has some sort of weapon, maybe you want to first check 
    //wether it has "killed" some enemies,
    //before checking wether an enemy has hit your player.

    var hitEnemy = enemies.find(enemy => enemy.collision(player));
    //btw. Bullets would also be "enemies"
    if(hitEnemy){
        //and you probably don't want to 
        player.x = currentLevel.playerResetPosition.x;
        player.y = currentLevel.playerResetPosition.y;
        //destroy hitEnemy
        //maybe mark the player as blinking/non-hitable for a few seconds?
    }

    //render everything
}