JavaScript 核心觀念(53)- 繼承與原型鍊 - 繼承與原型鍊(章節作業)

前言

接下來這章節是關於練習的部分。

章節作業

對於某些觀念較不清楚時,透過大量的練習與分享或者教學等,其實都可以加強自己對於某些觀念。

因此該章節的題目有以下

1
2
3
4
5
條件:

必須使用 Object.create
結構必須正確
每個原型需有獨立的方法

那麼在此我就以仙境傳說這款線上遊戲為舉例(有夠老人)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
function getRandom(x){
return Math.floor(Math.random()*x);
};

// 基礎角色
function base(race = '人類', myName='尚未取名'){
this.race = String(race); // 種族
this.myName = String(myName); // 名稱
}

// 角色能力
function Character(atk = 10, hp = 100, sp = 50, job = '初心者') {
base.call(this, '人類', 'Ray');
this.atk = Number(atk); // 基礎攻擊力
this.hp = Number(hp); // 血量
this.sp = Number(sp); // 魔力
this.job = String(job); // 職業
}

// 初始人物都會具備有基本技能
Character.prototype.NV_BASIC = function (lv) {
console.log('可以使用基本介面之相關技能。');
switch (lv) {
case 1:
console.log('Lv 1 使用交易功能。可以和其他人物交換道具。交換時,用鼠表右鍵點擊想進行交換的人物。');
break;
case 2:
console.log('Lv 2 使用表情符號。可用 Alt + 0 ~ 9 及 Ctrl + 1 、 - 、 = 、 \ 鍵表示感情。可按 Alt + L 鍵能使用更多的表情符號。');
break;
case 3:
console.log('Lv 3 可在原地坐下使恢復速度增加。可按 Insert 鍵或使用 / 坐下的指令。');
break;
case 4:
console.log('Lv 4 可以開設聊天室。可按 Alt + C 鍵。');
break;
case 5:
console.log('Lv 5 可以加入其它玩家的隊伍中。');
break;
case 6:
console.log('Lv 6 使用卡普拉職員倉庫保管道具。');
break;
case 7:
console.log('Lv 7 可以組隊。使用 / ORGANIZE "組隊名稱"的指令。可按 Alt + Z 鍵調整隊伍選項。');
break;
case 8:
console.log('lv8 無');
break;
case 9:
console.log('Lv 9 可以轉職成第一職業。');
break;
default:
console.log('尚未獲取該技能');
break;
}
}

// 初始人物都具備的能力移動與攻擊
Character.prototype.Move = function() {
console.log('你移動了!');
}

Character.prototype.attack = function() {
console.log('你攻擊傷害造成了' + getRandom(this.atk) + '傷害!');
}

const Novice = new Character(100, 1000, 100);

Novice.NV_BASIC(9);
Novice.attack();
Novice.Move();

透過自己比較熟悉的觀念與遊戲化的方式在練習上是可以比較有感覺的唷

初心者(我有稍微重新調整程式碼,因此此圖為範例)

那麼接下來通常我們遊戲玩到最後一定會轉職,因此一定會繼承原本的初心者技能並轉職到特定職業,那麼這邊就以我最愛的神工匠為舉例繼續撰寫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
function getRandom(x){
return Math.floor(Math.random()*x);
};

// 基礎角色
function base(race = '人類', myName='尚未取名'){
this.race = String(race); // 種族
this.myName = String(myName); // 名稱
}

// 角色能力
function Character(atk = 10, hp = 100, sp = 50, job = '初心者') {
base.call(this, '人類', 'Ray');
this.atk = Number(atk); // 基礎攻擊力
this.hp = Number(hp); // 血量
this.sp = Number(sp); // 魔力
this.job = String(job); // 職業
}

// 初始人物都會具備有基本技能
Character.prototype.NV_BASIC = function (lv) {
console.log('可以使用基本介面之相關技能。');
switch (lv) {
case 1:
console.log('Lv 1 使用交易功能。可以和其他人物交換道具。交換時,用鼠表右鍵點擊想進行交換的人物。');
break;
case 2:
console.log('Lv 2 使用表情符號。可用 Alt + 0 ~ 9 及 Ctrl + 1 、 - 、 = 、 \ 鍵表示感情。可按 Alt + L 鍵能使用更多的表情符號。');
break;
case 3:
console.log('Lv 3 可在原地坐下使恢復速度增加。可按 Insert 鍵或使用 / 坐下的指令。');
break;
case 4:
console.log('Lv 4 可以開設聊天室。可按 Alt + C 鍵。');
break;
case 5:
console.log('Lv 5 可以加入其它玩家的隊伍中。');
break;
case 6:
console.log('Lv 6 使用卡普拉職員倉庫保管道具。');
break;
case 7:
console.log('Lv 7 可以組隊。使用 / ORGANIZE "組隊名稱"的指令。可按 Alt + Z 鍵調整隊伍選項。');
break;
case 8:
console.log('lv8 無');
break;
case 9:
console.log('Lv 9 可以轉職成第一職業。');
break;
default:
console.log('尚未獲取該技能');
break;
}
}

// 初始人物都具備的能力移動與攻擊
Character.prototype.Move = function() {
console.log('你移動了!');
}

Character.prototype.attack = function() {
console.log('你攻擊傷害造成了' + getRandom(this.atk) + '傷害!');
}

const Novice = new Character(100, 1000, 100);

Novice.NV_BASIC(9);
Novice.attack();
Novice.Move();

function WhiteSmith(job, CartKg) {
// 由於轉職之後能力值一定會有所變化
Character.call(this, 999, 30000, 900, job); // 轉職時必定傷害與血量等跟職業都會有所變化,因此就必須重新傳入
this.CartKg = CartKg; // 手推車重量
this.Status = false; // 由於手推車攻擊技必須啟用手推車加速才可以攻擊
}

// 接下來神工匠也會繼承於初始角色的能力
WhiteSmith.prototype = Object.create(Character.prototype);
WhiteSmith.prototype.constructor = WhiteSmith;
// 神工匠專屬技能

// 手推車加速
WhiteSmith.prototype.CARTBOOST = function() {
this.Status = true;

console.log(this.myName + '正在使用手推車加速!');

// 五秒後恢復正常
setTimeout(() => {
this.Status = false;
console.log('手推車加速狀態結束!');
}, 5000);
}

// 手推車終結技
WhiteSmith.prototype.CARTTERMINATION = function() {
if(this.Status) {
console.log(this.myName + '對怪物照成了' + this.atk * (this.CartKg / 1000) + '固定傷害');
} else {
console.error('你還沒有使用手推車加速!');
}
}


const RayTwo = new WhiteSmith('神工匠', 8000);

接下來一樣來呼叫相關方法

原型鏈

當然上面的原型鏈只是練習因此拆的可能並不完美,最主要是使用對自己曾經接觸過的東西來增加興趣。

最後這邊要注意一件事情,如果你將 WhiteSmith.prototype = Object.create(Character.prototype); 放在比 WhiteSmith.prototype.CARTTERMINATIONWhiteSmith.prototype.CARTBOOST 還後面的地方,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 手推車加速
WhiteSmith.prototype.CARTBOOST = function() {
this.Status = true;

console.log(this.myName + '正在使用手推車加速!');

// 五秒後恢復正常
setTimeout(() => {
this.Status = false;
console.log('手推車加速狀態結束!');
}, 5000);
}

// 手推車終結技
WhiteSmith.prototype.CARTTERMINATION = function() {
if(this.Status) {
console.log(this.myName + '對怪物照成了' + this.atk * (this.CartKg / 1000) + '固定傷害');
} else {
console.error('你還沒有使用手推車加速!');
}
}

WhiteSmith.prototype = Object.create(Character.prototype);

這樣是會導致 WhiteSmith 的原型被使用 Object.create 過來的 Character 原型方法給蓋掉,因此原型在撰寫時,請多加注意程式碼的順序。

參考文獻

Liker 讚賞

這篇文章如果對你有幫助,你可以花 30 秒登入 LikeCoin 並點擊下方拍手按鈕(最多五下)免費支持與牡蠣鼓勵我。
或者你可以也可以請我「喝一杯咖啡(Donate)」。

Buy Me A Coffee Buy Me A Coffee

Google AD

撰寫一篇文章其實真的很花時間,如果你願意「關閉 Adblock (廣告阻擋器)」來支持我的話,我會非常感謝你 ヽ(・∀・)ノ