What is the process of combining two class elements?

In my JavaScript class practice, I'm working on creating two users, each equipped with a weapon. My goal is to have a function within the class that allows the players to attack each other and decrease their health based on the damage of their respective weapons. I've split my work into three different files, but I'm struggling to combine my User class with my Gun class to assign a weapon to each user. Here's what I envision:

let John = new User("John", "Sniper");
let Michael = new User("Michael", "Shotgun");

John.attack("Michael");

My plan is to add more functions to my classes for some fun, but first, I need to solve the challenge of incorporating a weapon into the User class.

I've attempted several methods, but nothing seems to work...

main.js

import Gun from '/js/gun.js';
import User from '/js/user.js';

let players = [new User("Mic", "sniper"), new User("AI", "rifle")];

players[0].shootAt(players[1]);
players[1].shootAt(players[0]);

user.js

export default class User{
    constructor(userName, gun){
        this.name = userName;
        this.health = 50;
        console.log(this.name + ' was created with ' + this.health + ' health');
    }

    shootAt(target){
        target.health -= gun.damage;
    }
}

gun.js



export default class Gun{
    constructor(){
        this.sniper = {
            damage: 150,
            magazine: 7,
            fireRate: 1.5   
        };
        this.rifle = {
            damage: 25,
            magazine: 30,
            fireRate: 0.05
        };
    }

}

The current implementation is not functioning as desired:

let players = [new User("Mic", "sniper"), new User("AI", "rifle")];

players[0].shootAt(players[1]);
players[1].shootAt(players[0]);

But this is the outcome I hope to achieve... Any assistance would be greatly appreciated!

Answer №1

The reason for the issue you are experiencing is due to not creating a new Gun object with defined properties, but instead passing a string to your User class where the properties are not accessible from the gun class.

To address this in the Gun class, it is important to ensure that items are accessible and to specify the type of gun. One way to do this is by adding a gunType property to the Gun class and also storing the user's gun in a property within the User class.

In the provided code snippet below, I have included basic getters for the Gun properties that utilize the gunType to fetch the data pertaining to the current gun type. It is essential to note that this method may encounter issues if an unsupported type is used, so one might consider expanding this area or creating gun types through extending the Gun class as recommended by Mr. Poliwhril. Additionally, new Gun objects are instantiated and passed to the User class while being stored in the gun property for future reference.

class User{
    constructor(userName, Gun){
        this.name = userName;
        this.health = 50;
        this.gun = Gun;
        console.log(this.name + ' was created with ' + this.health + ' health');
    }

    shootAt(target){
        target.health -= this.gun.damage; // Deducts target's health based on gun damage
    }
}

class Gun{
    constructor( gunType ){
        this.sniper = {
            damage : 150,
            magazine : 7,
            fireRate : 1.5   
        }
        this.rifle = {
            damage : 25,
            magazine : 30,
            fireRate : .05
        }
        
        this.gunType = gunType;
    }

    get damage() {
        return this[ this.gunType ].damage;
    }
    get magazine() {
        return this[ this.gunType ].magazine;
    }
    get fireRate() {
        return this[ this.gunType ].fireRate;
    }

}


players = [ new User("Mic", new Gun( "sniper") ), new User("AI", new Gun( "rifle" ) ) ]; // Creating users with specified guns

Answer №2

To commence, it is essential to establish the definition of a gun and then proceed with crafting various types. Once the functionalities of a gun are clear and the process of creating them is understood, they can be allocated to a user.

For instance, consider a battle simulation involving two players.

An additional aspect that could be incorporated is factoring in reloading time for each type of gun.

class Gun {
  constructor(damage, magazineSize, fireRate, ammo) {
    this.damage = damage;
    this.magazineSize = magazineSize;
    this.fireRate = fireRate;
    this.ammo = ammo;
    this.inMagazine = ammo > magazineSize ? magazineSize : ammo;
  }
  getDamageOverTime(rateInSeconds) {
    let multiplier = this.fireRate * rateInSeconds;
    let estimatedDamageMultiplier = Math.ceil(multiplier);
    let actualDamageMultiplier = 0;
    while (estimatedDamageMultiplier > 0 && this.inMagazine > 0) {
      actualDamageMultiplier++;
      estimatedDamageMultiplier--;
      this.inMagazine--;
    }
    return this.damage * actualDamageMultiplier;
  }
  reload() {
    while (this.inMagazine < this.magazineSize && this.ammo > 0) {
      this.inMagazine++;
      this.ammo--;
    }
  }
  isMagazineEmpty() {
    return this.inMagazine <= 0;
  }
  isOutOfAmmo() {
    return this.ammo <= 0; 
  }
}

class Sniper extends Gun {
  constructor(ammo) {
    super(120, 5, 1.5, ammo);
  }
}

class Shotgun extends Gun {
  constructor(ammo) {
    super(45, 30, 0.5, ammo);
  }
}

class User {
  constructor(userName, gun, health) {
    this.name = userName;
    this.gun = gun;
    this.health = health;
    console.log(`${this.name} was created with ${this.health} health.`);
  }
  shootAt(target, rate) {
    if (this.gun.isMagazineEmpty()) {
      console.log(`${this.name} is out of ammo!`);
      this.gun.reload();
    } else {
      let damage = this.gun.getDamageOverTime(rate);
      target.health -= damage;
      console.log(`${this.name} shot at ${target.name} for ${damage} damage.`);
    }
  }
  isAlive() {
    return this.health > 0;
  }
  toString() {
    return `{ name: ${this.name}, health: ${this.health}, ammo: ${this.gun.inMagazine} }`;
  }
}

const DEBUG = true;
let john = new User("John", new Sniper(10), 200);
let michael = new User("Michael", new Shotgun(90), 1200);
battleSim([john, michael], 1000);

function battleSim(players, updateRateMs) {
  let loopId = setInterval(function() {
    if (DEBUG) console.log(players.join('\n'));
    if (players.filter(p => p.isAlive()).length < 2) {
      clearInterval(loopId);
      console.log(`${players.filter(p => p.isAlive())[0].name} is victorious!`);
      return;
    }
    let shootsFirst = Math.round(Math.random());
    let shootsSecond = 1 - shootsFirst;
    if (players[shootsFirst].isAlive()) {
      players[shootsFirst].shootAt(players[shootsSecond], updateRateMs / 1000);
    }
    if (players[shootsSecond].isAlive()) {
      players[shootsSecond].shootAt(players[shootsFirst], updateRateMs / 1000);
    }
  }, updateRateMs);
}
.as-console-wrapper {
  top: 0;
  max-height: 100% !important;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the nuances in semantics between AJAX and post/get requests

I'm currently trying to grasp the concept of 'AJAX.' I know that it is short for Async JavaScript over XML, although JSON can also be used instead of XML. As far as I understand, AJAX allows for updating only parts of a web page without need ...

Create a search feature based on names utilizing Node Express in conjunction with SQL database

After deciding to create an API with a search feature using SQL queries in node express, this is how I structured my code: app.get('/search/:query', (req, res) => { pool.getConnection((err, connection) => { if(err) throw err ...

An unusual outcome occurred while attempting to duplicate the text

After copying the letter A, I noticed that an empty string is being logged to the console instead of the expected A. However, when I paste, the console does successfully log the letter A. document.addEventListener('copy', handler); document ...

jquery method to make entire navigation bar clickable

I have a single menu bar. I recently discovered an interesting way to make the entire menu bar area clickable using jQuery. Design code snippet: <%@ Control Language="C#" AutoEventWireup="true" CodeFile="MenuControl.ascx.cs" Inherits="MenuControl"%> ...

Issue with Chrome Extension in Selenium JavaScript WebDriver Test

I'm currently facing an issue with my Selenium JavaScript Webdriver test. Everything seems to be working fine, no errors are being thrown. The only problem is related to a Chrome Extension that is supposed to change the title of the page and then retr ...

Exploring date comparison in AngularJS

I've encountered an issue while using ng-show in a page that I'm currently designing: <td ng-show="week.EndDate > controller.currentDate"> The week object has a property called EndDate, and the value of currentDate is being set in my c ...

Ways to use string functions in JavaScript to substitute with /

Here is the image path I am working with: var str = "D:\Poc\testProject\DataPush\public\unzip\cust\AccountData\2.jpg" When I included "unzip" in the path, it threw an error as shown in this image, but when ...

The AJAX request is failing to reach the server

I'm currently using AJAX to populate a dropdown, but for some reason the call isn't reaching the server. Upon checking Firebug, I see the following error: POST 0 status 404 not found This is the code I'm working with: function selec ...

Simple HTML generator using Node.js

My preference is to write my HTML in a basic and straightforward manner, without any fancy tools. The only feature I would like to have is the ability to use an include statement to easily add header, navigation, and footer sections to each page. I'v ...

gulp - synchronized gulp.pipe(gulp.dest) execution

Here's my challenge: I have two tasks, where Task B depends on Task A. In Task A, one of the requirements is to loop through an array and then use gulp.dest, but it seems like Task B will be executed before Task A is completed. The main goal of Task ...

Using Backbone to Handle Different Data Formats

I have a unique text file containing date-time data in the format below: 2014-03-14T16:32 2014-03-15T13:04 2014-03-16T06:44 ... I want to use this static file as a read-only data source for my backbone collection. However, the current format is not suita ...

"Learn how to update an existing table row and populate its cells with JSON data retrieved from a successful AJAX request without creating a

Currently, I am utilizing CouchCMS. The platform offers a feature known as repeatable regions which essentially generates tables to showcase recurring content. The defined repeatable region looks like this: <cms:repeatable name="item_detail" ...

Please ensure all three of the last checkboxes are ticked before finalizing submission

Here is the list of checkboxes for my PHP form. I am trying to figure out how to write a script that will only allow the form to be submitted if the last three checkboxes are checked. I have tried looking at similar questions but haven't found the sol ...

Enhance user experience by implementing an autocomplete feature for a text input field

Can you name the process in which a form is automatically filled using database information without needing to refresh the page? One common example of this technique is seen on platforms like Google or Facebook, where they predict friends you may be searc ...

Issue encountered while transforming the data buffer into the video within a Node.js environment

I am attempting to create a buffer from the mp4 video, and then convert that buffer back into the video. The buffer is being generated as follows: const buffer = Buffer.from("Cat.mp4"); console.log(buffer); The output I receive is <Buffer 43 61 74 2e ...

Issue with printing error messages for JavaScript form validation

I have implemented the following code for a form to handle validation and display errors below the fields when they occur: <!DOCTYPE html> <html> <head> <style type="text/css"> .errorcss { background-color: yellow; color:re ...

What is the best approach to retrieve a JSON object from a form exception that has a specific name?

I have a certain form with input fields. My goal is to generate a JSON object from the form, excluding any input whose name is "point". However, my code doesn't seem to be working properly when I use the "not()" function. What am I doing wrong and how ...

Encountering the issue of "Cannot read properties of undefined" while attempting to pass data to a prop

Currently, I am developing a Vue application that heavily relies on charts. The issue lies in the fact that I am fetching data from the database individually for each chart component, resulting in multiple calls and a slower page load time. I am looking to ...

Is there a module loader in Angular.JS or do I have to rely on script tags for loading modules?

While using Angular JS, I have a desire to organize unrelated code in separate modules similar to AMD or CommonJS. However, my Google search for 'Angular.JS make new module' has not yielded any documentation on creating Angular.JS modules. There ...

Utilizing AngularJS to dynamically bind input to a value with a filter and keep it updated

I'm facing an issue with an input element linked to an object property along with a filter. Even though I update the object.field programmatically, the displayed value in the input does not change, although the correct value is reflected in the DOM In ...