在“团队”类中有一个“踢”方法,其实质是分别随机选择一个目标,以造成伤害。如何使每个角色(弓箭手,法师,剑客)首先寻找其类的目的,(即射手“踢”弓箭手,剑客“踢”剑客等),如果它的“isAlive”=“假”英雄试图打一个随机目标?在原型重合的条件下,我得到“TypeError:sameTypeUnit .__ proto__不是函数”错误。
//constructor for creating a unit
function Unit(maxHealth, basicDamage,type) {
this.maxHealth = maxHealth;
this.currentHealth = maxHealth;
this.basicDamage = basicDamage;
this.type = type;
}
/*method for showing the status of life, true if the "health" is greater
than 0 and false if equal to or lower */
Unit.prototype.isAlive = function () {
return this.currentHealth > 0;
};
/* a method that
shows the level of health*/
Unit.prototype.getFormattedHealth = function () {
return this.currentHealth + "/" + this.maxHealth + " HP";
};
/*a method that returns the base damage of the hero and damage to the
weapon (if it is set)*/
Unit.prototype.getDamage = function () {
return this.basicDamage;
};
/* The method of hitting
the hero for the chosen purpose*/
Unit.prototype.kick = function (target) {
if (this.isAlive()) {
target.currentHealth = Math.max(0,
target.currentHealth - this.getDamage());
console.log(this.type + " hit " + this.type);
}
return this;
};
/*method for showing all the characteristics of the hero and changes
with them*/
Unit.prototype.toString = function () {
return "Type - " + this.type + ", is alive - " +
this.isAlive() + ", " + this.getFormattedHealth() +
', hero current damage - ' + this.getDamage() + ' points';
};
/*the constructors of the main types of units which we will use*/
function Archer(maxHealth, basicDamage) {
Unit.apply(this, arguments);
this.type = "archer";
}
function Swordsman(maxHealth, basicDamage) {
Unit.apply(this, arguments);
this.type = "swordsman";
}
function Mage(maxHealth, basicDamage) {
Unit.apply(this, arguments);
this.type = "mage";
}
Archer.prototype = Object.create(Unit.prototype);
Swordsman.prototype = Object.create(Unit.prototype);
Mage.prototype = Object.create(Unit.prototype);
/*We create units of which we will then write to the teams.
Three units per team*/
var archer = new Archer(60, 5);
var swordsman = new Swordsman(100, 10);
var mage = new Mage(40, 15);
var troll = new Archer(70, 5);
var orc = new Swordsman(150, 10);
var druid = new Mage(50, 15);
/*class for creating teams*/
function Team(name) {
this.name = name;
this.members = [];
this.activeMember = 0;
}
/*method for adding a new unit with an arbitrary number of units*/
Team.prototype.addMember = function (...members) {
this.members.push(...members);
}
/*method of life of the team, if all participants have
"currentHealth" <0 then this method = "false"*/
Team.prototype.isAlive = function () {
return this.members.some(n => n.isAlive());
};
/*Damage method similar to that in "Unit" in it the choice
is made - who is attacking whom (the team members take turns
attacking the random participant of the other team)*/
Team.prototype.kick = function(targetTeam) {
var sameTypeUnit = null;
for(var i=0;i<this.members.length;i++) {
sameTypeUnit = this.members[i];
}
if (sameTypeUnit.__proto__(sameTypeUnit) && sameTypeUnit.isAlive()) {
while (sameTypeUnit.isAlive()) {
sameTypeUnit.kick(sameTypeUnit);
}
}else if (!sameTypeUnit.isAlive()) {
var m = targetTeam.members.filter(n => n.isAlive())
target = m[Math.random() * m.length | 0];
if (target && this.isAlive()) {
var active = null;
do {
active = this.members[this.activeMember];
this.activeMember = (this.activeMember + 1)
% this.members.length;
} while (!active.isAlive());
active.kick(target);
}
}
};
/*method to output information about the team*/
Team.prototype.toString = function () {
var res = "Name of team - " + this.name + '\n'
+ "life of a team : " + this.isAlive() + '\n'
+"members :\n";
for (var i=0; i<this.members.length; i++)
res += this.members[i]+"\n";
return res;
};
/*create team 1 and add units to it*/
var team1 = new Team('Alliance');
team1.addMember(archer,swordsman,mage);
/*create team 2 and add units to it*/
var team2 = new Team('Orcs');
team2.addMember(troll,orc,druid);
/*class that organizes a battle between two teams until
"currentHealth" of all units in the team will not be zero*/
function Game(team1, team2) {
this.team1 = team1;
this.team2 = team2;
}
/*the method in which the battle occurs until the
"isAlive" property of all participants of one of the commands
is equal to "false"*/
Game.prototype.battle = function() {
if (!this.team1.isAlive() || !this.team2.isAlive()) {
if (this.team1.isAlive()) {
alert("Team 1 is win");
}
if (this.team2.isAlive()) {
alert("Team 2 is win");
}
console.log(`THE BATTLE IS END :
${this.team1.toString()}
${this.team2.toString()}
${this.team1.name} - ${this.team1.members.length} -
${this.team1.members.map(n => n.currentHealth)}
${this.team2.name} - ${this.team2.members.length} -
${this.team2.members.map(n => n.currentHealth)}
`);
return;
}
team1.kick(team2);
team2.kick(team1);
requestAnimationFrame(this.battle.bind(this));
};
var game = new Game(team1, team2);
game.battle();
答案 0 :(得分:1)
如果我找对你,你只想基于当前的攻击者filter
敌人成员:
Team.prototype.kick = function(targetTeam) {
for(const member of this.members) {
// Filter the enemies based on their type
const enemies = targetTeam.members.filter(m => m.type === member.type);
// If there are no enemies with the same type, take another one:
if(!enemies.length) enemies.push(...targetTeam.members);
// TODO: Shuffle
// Attack enemies as long as there are some...
while(enemies.length && member.isAlive()) {
member.kick( enemies[0] );
if(!enemies[0].isAlive()) enemies.shift();
}
}
}
另一种方法是对敌人进行排序,以使相同类型的敌人排在第一位,然后稍微改变它:
/* Clones and Shuffles the array, but moves enemies with the same type to the front */
function typeFirstShuffle(array, type) {
return [...array].sort((a, b) =>
(a.type === type) - (b.type === type) || // same type first
Math.random() * 2 - 1 // otherwise shuffle
);
}
可以用作
Team.prototype.kick = function(targetTeam) {
for(const member of this.members) {
const enemies = typeFirstShuffle(targetTeam.members, member.type);
// ... Same as above
}
}
答案 1 :(得分:1)
尝试使用ES6的课程和inhgeritance系统。它会让它变得更干净,更容易。但主要问题在于团队踢的逻辑。有太多冗余和不必要的条件。我使用类继承重写了整个事情,但是踢功能的所有逻辑都需要改变
class Unit {
constructor(maxHealth, basicDamage, classType)
{
this.maxHealth = maxHealth;
this.currentHealth = maxHealth;
this.basicDamage = basicDamage;
this.type = classType;
}
isAlive()
{
return this.currentHealth > 0;
}
getFormattedHealth()
{
return this.currentHealth + "/" + this.maxHealth + " HP";
}
getDamage()
{
return this.basicDamage;
}
kick(target)
{
if (this.isAlive()) {
target.currentHealth = Math.max(0,
target.currentHealth - this.getDamage());
console.log(this.type + " hit " + target.type);
}
return this;
}
toString()
{
return "Type - " + this.type + ", is alive - " +
this.isAlive() + ", " + this.getFormattedHealth() +
', hero current damage - ' + this.getDamage() + ' points';
}
}
class Archer extends Unit
{
constructor(maxHealth, basicDamage)
{
super(maxHealth, basicDamage, "archer");
}
}
class Swordsman extends Unit
{
constructor(maxHealth, basicDamage)
{
super(maxHealth, basicDamage, "swordsman");
}
}
class Mage extends Unit
{
constructor(maxHealth, basicDamage)
{
super(maxHealth, basicDamage, "mage");
}
}
/*We create units of which we will then write to the teams.
Three units per team*/
var archer = new Archer(60, 5);
var swordsman = new Swordsman(100, 10);
var mage = new Mage(40, 15);
var troll = new Archer(70, 5);
var orc = new Swordsman(150, 10);
var druid = new Mage(50, 15);
class Team
{
constructor(name)
{
this.name = name;
this.members = [];
this.activeMember = 0;
}
addMember(...memebrsToAdd)
{
memebrsToAdd.forEach(mem => this.members.push(mem));
}
isAlive()
{
return this.members.some(n => n.isAlive());
}
selectRandomTarget(targetTeam)
{
let numberOfMembers = targetTeam.members.length;
let target = null;
while(target == null || !target.isAlive())
{
let randomIndex = Math.floor(Math.random() * numberOfMembers);
target = targetTeam.members[randomIndex];
}
return target;
}
kick(targetTeam) {
console.log(`\nTeam ${this.name} is attacking`);
for(var i=0; i < this.members.length; i++) {
let singleMember = this.members[i];
if(!this.isAlive()) break;
if(!singleMember.isAlive()) continue;
let target = this.selectRandomTarget(targetTeam);
singleMember.kick(target);
}
}
toString() {
var res = "Name of team - " + this.name + '\n'
+ "life of a team : " + this.isAlive() + '\n'
+"members :\n";
for (var i=0; i<this.members.length; i++)
res += this.members[i]+"\n";
return res;
}
}
/*create team 1 and add units to it*/
var team1 = new Team('Alliance');
team1.addMember(archer,swordsman,mage);
/*create team 2 and add units to it*/
var team2 = new Team('Orcs');
team2.addMember(troll,orc,druid);
class Game
{
constructor(team1, team2)
{
this.team1 = team1;
this.team2 = team2;
}
battle()
{
let currentTeam = team1
while(this.team1.isAlive() && this.team2.isAlive())
{
let defendingTeam = currentTeam === team1 ? team2 : team1;
currentTeam.kick(defendingTeam);
currentTeam = currentTeam === team1 ? team2 : team1;
}
this.displayWinningMessage();
}
displayWinningMessage()
{
console.log(`THE BATTLE IS END :
${this.team1.toString()}
${this.team2.toString()}
${this.team1.name} - ${this.team1.members.length} -
${this.team1.members.map(n => n.currentHealth)}
${this.team2.name} - ${this.team2.members.length} -
${this.team2.members.map(n => n.currentHealth)}`
);
}
}
var game = new Game(team1, team2);
game.battle();
&#13;