You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
5.5 KiB
206 lines
5.5 KiB
class Robot {
|
|
constructor(height, width, posX, posY, color, scene) {
|
|
this.height = height;
|
|
this.width = width;
|
|
this.x = posX;
|
|
this.y = posY;
|
|
this.color = color;
|
|
this.range = WIDTH_MAP / 2;
|
|
this.damage = DAMAGE;
|
|
this.life = new HealthBar(scene, this.width * 2, this.width / 3, this.x, this.y - this.width, LIFE, 0x008000);
|
|
this.shield = new HealthBar(scene, this.width * 2, this.width / 3, this.x, this.y - this.width * 1.5, SHIELD, 0x0000FF);
|
|
|
|
this.canAttack = true;
|
|
this.missile = new Missile(scene, 'bullet', this.width / 5, this.width / 4);
|
|
scene.add.existing(this.missile);
|
|
|
|
this.addScene(scene);
|
|
|
|
this.lNode = [];
|
|
|
|
let condition = new Condition(this, true, false, 0.5, 0);
|
|
condition.addNode(new Move(false));
|
|
this.addNode(condition);
|
|
this.addNode(new Attack());
|
|
this.addNode(new Move(true));
|
|
}
|
|
|
|
addScene(scene) {
|
|
this.scene = scene;
|
|
this.circle = this.scene.add.circle(this.x, this.y, this.width / 2, this.color);
|
|
}
|
|
|
|
setX(x) {
|
|
this.x = x;
|
|
this.circle.setX(this.x);
|
|
this.life.setX(this.x);
|
|
this.shield.setX(this.x);
|
|
}
|
|
|
|
setY(y) {
|
|
this.y = y;
|
|
this.life.setY(this.y - this.width);
|
|
this.shield.setY(this.y - this.width * 1.5);
|
|
this.circle.setY(this.y);
|
|
}
|
|
|
|
setTarget(target) {
|
|
this.target = target;
|
|
this.updateTarget();
|
|
}
|
|
|
|
updateTarget() {
|
|
if (this.verifyTarget())
|
|
this.setTargetPos(this.target.x, this.target.y);
|
|
}
|
|
|
|
setTargetPos(x, y) {
|
|
let diffX = this.target.x - this.x;
|
|
let diffY = this.target.y - this.y;
|
|
let hypot = Math.hypot(diffX, diffY);
|
|
this.velocityX = diffX / hypot * WIDTH_MAP / 1000 * SPEED;
|
|
this.velocityY = diffY / hypot * WIDTH_MAP / 1000 * SPEED;
|
|
}
|
|
|
|
advanceToTarget() {
|
|
if (this.verifyTarget()) {
|
|
if ((this.velocityX >= 0 && this.x >= this.target.x) || (this.velocityX <= 0 && this.x <= this.target.x))
|
|
this.setX(this.target.x);
|
|
else
|
|
this.setX(this.x + this.velocityX);
|
|
|
|
if ((this.velocityY >= 0 && this.y >= this.target.y) || (this.velocityY <= 0 && this.y <= this.target.y))
|
|
this.setY(this.target.y);
|
|
else
|
|
this.setY(this.y + this.velocityY);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
fleeFromTarget() {
|
|
if (this.verifyTarget()) {
|
|
if (this.velocityX >= 0 && this.x - this.width / 2 <= 0)
|
|
this.setX(this.width / 2);
|
|
else if (this.velocityX <= 0 && this.x + this.width / 2 >= WIDTH_MAP)
|
|
this.setX(WIDTH_MAP - this.width / 2);
|
|
else
|
|
this.setX(this.x - this.velocityX);
|
|
|
|
if (this.velocityY >= 0 && this.y - this.width / 2 <= 0)
|
|
this.setY(this.height / 2);
|
|
else if (this.velocityY <= 0 && this.y + this.width / 2 >= WIDTH_MAP)
|
|
this.setY(WIDTH_MAP - this.height / 2);
|
|
else
|
|
this.setY(this.y - this.velocityY);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
attackTarget() {
|
|
if (this.verifyTarget() && this.target.isAlive() && this.isTargetInRange()) {
|
|
if (this.canAttack)
|
|
this.attack(this.target);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
verifyTarget() {
|
|
if (this.haveTarget()) {
|
|
if (!this.target.isAlive()) {
|
|
this.setTarget(null);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
attack(target) {
|
|
this.canAttack = false;
|
|
|
|
this.missile.setPosition(this.x, this.y).setVisible(true);
|
|
|
|
this.missile.setRotation(Math.atan2(this.y - this.target.y, this.x - this.target.x) - 3.14 / 2);
|
|
|
|
this.scene.tweens.add({
|
|
targets: this.missile,
|
|
x: target.x,
|
|
y: target.y,
|
|
ease: 'Linear',
|
|
duration: 200,
|
|
onComplete: () => this.finishAttack(target)
|
|
});
|
|
|
|
this.scene.time.addEvent({delay: Phaser.Math.Between(1000, 3000), callback: this.reload, callbackScope: this});
|
|
}
|
|
|
|
finishAttack(target) {
|
|
if (target.beAttack(this.damage)) {
|
|
this.setTarget(null);
|
|
}
|
|
this.missile.setVisible(false);
|
|
}
|
|
|
|
reload() {
|
|
this.canAttack = true;
|
|
}
|
|
|
|
beAttack(damage) {
|
|
let diff = this.shield.decrease(damage)
|
|
if (diff > 0) {
|
|
console.log("Shield Broken");
|
|
this.life.decrease(diff);
|
|
}
|
|
return this.die();
|
|
}
|
|
|
|
isTargetInRange() {
|
|
if (this.verifyTarget()) {
|
|
return this.calcDistance(this.target) < this.range;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
calcDistance(robot) {
|
|
return Math.hypot(robot.x - this.x, robot.y - this.y);
|
|
}
|
|
|
|
isAlive() {
|
|
return this.life.value > 0;
|
|
}
|
|
|
|
die() {
|
|
if (this.life.value === 0) {
|
|
this.circle.destroy();
|
|
this.shield.destroy();
|
|
this.life.destroy();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
haveTarget() {
|
|
return this.target != null;
|
|
}
|
|
|
|
read() {
|
|
for (let i = 0; i < this.lNode.length; i++) {
|
|
if (this.lNode[i].do(this)) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
addNode(node) {
|
|
this.lNode.push(node);
|
|
}
|
|
|
|
cleanNodes() {
|
|
this.lNode = [];
|
|
}
|
|
}
|