8

我对整个面向对象范式很陌生。

我正在尝试在某个游戏中为角色建模,你有不同的级别、职业和大量的设备选择等等。

我的最终目标是创建某种“梳妆台”,玩家可以在其中打开网站,试穿一些装备,看看它如何影响他们的参数,花费多少等等。

我已经对主要部分进行了编程(这里),但这是我第一次使用 html、css 和 javascript 工作,目前只是一团糟。这次我想好好开始 :)


假设我有一个我们将要模拟的角色的对象:

var Lord = function(){

    this.Level =       1;
    this.Gender =      'Male';
    this.Faction =     'Knight';

    this.Attack =      0;
    this.Defense =     1;
    this.SpellPower =  0;
    this.Knowledge =   0;
    this.Luck =        0;
    this.Morale =      1;
    this.Initiative =  0;

    this.addParameter = function(Parameter, amount){
        this[Parameter] += amount;
    };
    this.changeLevelTo = function(Level){
        this.Level = Level;
    };
    this.changeGenderTo = function(Gender){
        this.Gender = Gender;
    };
    this.changeFactionTo = function(Faction){
        this.Faction = Faction;
        //adjust default stats based on new faction
    };
};

我的问题是:骑士一开始有 1 防御和 1 士气,不同的派系会给你不同的属性提升。这些值不能重新分配。玩家还可以获得一些统计点数,用于在升级时用于不同的参数,这些可以重新分配。

此外,玩家可能会装备一些可以提升属性的装备,这些装备也不能重新分配(只能通过取消装备)。

我之前所做的是,我创建了一大堆数组,它们的索引对应于每个参数,每个数组代表来自不同派系的默认属性提升,来自设备的总属性提升,以及玩家分配的属性手动。然后,我对每个索引求和,以给我一个最终的参数数组来显示。然后玩家只能重新分配第三个数组中的点,而不能重新分配任何其他数组。

我应该如何使用面向对象的编程来实现这一点?

我已经阅读了一些基本概念(封装、继承、多态性),但它们相当抽象,当我开始研究它时,我真的不知道该怎么做:s

-

-


回应


这个网站很难用:o

好的,我会尝试看看我能从 qternion 的回答中得到什么:

var Faction = function(atk, def, sp, kn, luk, mor, ini){
    this.Attack =      atk;
    this.Defense =     def;
    this.SpellPower =  sp;
    this.Knowledge =   kn;
    this.Luck =        luk;
    this.Morale =      mor;
    this.Initiative =  ini;
}

var Knight = new Faction(0,1,0,0,0,1,0);
var Wizard = new Faction(0,0,0,1,0,1,0);

然后在主的对象上,我会

    //this.Faction = 'Knight'
    this.Faction = Knight

    this.Defense = function(){
        return this.Faction.Defense + this.someOtherClass.Defense;
    }

我将寻求使用http://javascript.crockford.com/prototypal.html使用原型改进上述内容

感谢大家的所有贡献:)

4

3 回答 3

2

只需将 Lord 更改为函数(即var Lord = function() { /* current code */ })并将其属性设置为this.Level = 1;. 然后从现在开始,您可以new Lord()像大多数面向对象的编程语言一样创建任意数量的领主。

实践中的一个例子......

var Lord = function() {

    this.Level=1;
    this.Gender='Male';
    this.Faction='Knight';

    /* ... */

    this.addParameter=function(Parameter, amount){
        this[Parameter] += amount;
    };

    /* ... */
};
var a=new Lord();
var b=new Lord();
于 2013-07-22T15:21:57.883 回答
2

如果你愿意,你可以保留你的数组。面向对象编程最重要的是封装,它归结为提供一种与 Character 对象交互的方法,而无需了解任何有关低级实现的信息。您想要处理对象,而不是数组或哈希表(即使在这一切之下,这就是对象的实际构建方式!)您想要的是编写如下所示的代码:

var link = Knight();
link.equip(new MasterSword());
alert(link.getAttackPoints());

嗯,@qternion 有点击败我。所以我把这个答案变成了维基!让我们在这一点上释放 SO 的智慧。

于 2013-07-22T15:14:47.103 回答
2

你可以让你的统计值是方法而不是成员变量。这样,您可以在调用期间计算给定的统计数据,例如 knight.defense()。反过来,你的角色类中的方法 defence() 可以从派系类中调用 defence(),从设备组类中调用 defence() 等。这样做的好处是你可以在任何时候添加额外的属性修饰符,例如,如果你决定你想要一个额外的系统或其他东西。

然后,每个派系类都可以为其修饰符覆盖其 defence() 函数。

我不会称这是最面向对象的方式,但这就是我作为 Javascript 程序员自己的方式。

附录:冥王星的答案也是你如何获得可重用的“类”(而不是单个对象)。如前所述,我还将 Faction 设为一个类,而不仅仅是一个字符串(您可以使用 instanceof 进行类型检查):

var Faction = function (){
    this.prototype.defense = function () { return this.Defense; };
    this.prototype.initStats = function () { this.Defense = 0;};
    this.initStats(this);
};

var Knight = new Faction ();
Knight.prototype.initStats = function () { this.Defense = 1;};

例如。

于 2013-07-22T15:12:20.923 回答