Storing prompt as object value - javascript

I am making a game that battles a monster when you click the button and the equation for damage is based on the player and monsters stats. I had help getting the object for the monster to work in the equation but I don't know how to get the Player object working properly because it isn't being stored as a select option.
Here is the post I made earlier, it will be easier to understand my code if you look at the answer here firstOther Post
Here is my current fiddle
I need to be able to prompt the user for their username but still use their stats in the equation.
function Player(username, lvl, exp, gold, hp, atk, def, spd) {
var self = this;
this.username = username;
this.lvl = lvl;
this.exp = exp;
this.gold = gold;
this.hp = hp;
this.atk = atk;
this.def = def;
this.spd = spd;
this.implement = function() {
var h1 = document.getElementById('user');
h1.innerText = this.username;
h1.addClass('playerName');
$(h1).data('player', self)
}
this.implement();
}
var newPlayer = new Player(prompt("What is your username?"), 1, 0, 0, 10, 2, 2, 2);
playerEl = $('.playerName');
player = playerEl.data('player');

You have an error in adding the class playerName, h1 is a dom element reference which does not have the addClass method.
Since you have jQuery, you can use
this.implement = function() {
$('#user').text(this.username).addClass('playerName').data('player', this)
}

Related

Difficulty getting functions to work in my Javascript class

Clearly, a new developer! Thank you for replying in advance, I know the answer must be really simple but I have been stuck for an hour.
This exercise asks to create a class and then asks to change some of the dynamic values using class methods/functions. I am not able to get my values to change when I call the function.
Here are the directions for the exercise, followed by my code, sorry that my work looks so rudimentary!
These are the directions:
// Create a new class called SuperHero
// - Your class should have the following DYNAMIC values
// - name
// - superpower
// - age
// - Your class should have the following STATIC values
// - archNemesis, assigned to "The Syntax Error"
// - powerLevel = 100
// - energyLevel = 50
//Where I start having issues is here:
// - Create the following class methods
// - sayName, should print the hero's name to the console
// - maximizeEnergy, should update the energyLevel to 1000
// - gainPower, should take an argument of a number and INCREASE the powerLevel //by that number
class SuperHero {
constructor(name, superpower, age,){
this.name = name;
this.superpower = superpower;
this.age = age;
this.archNemesis = "The Syntax Error";
this.powerLevel = 100;
this.energyLevel = 50;
}
var power = 20;
sayName() {
console.log(this.name);
}
maximizeEnergy() {
this.energyLevel = 1000;
}
gainPower(power) {
this.powerLevel = this.powerLevel + power;
}
};
var superHero1 = new SuperHero("Batman", "strength", 40);
Thanks again! :)
Well, you code is 80% correct. Only issues I see is the this.energyLevel(1000); and sayName() method. They are not really required.
this.energyLevel is a property and not a function, so calling it like this.energyLevel(1000); is wrong. You should be setting this value as this.energyLevel = 1000;
sayName() is not really doing anything useful. You are already setting/initializing the name in the constructor.
Here is a simple example of a class and how to use it's methods for changing it's property values. Check the output in your browser console.
class SuperHero {
constructor(name, superpower, age, archNemesis, powerLevel, energyLevel) {
this.name = name;
this.superpower = superpower;
this.age = age;
this.archNemesis = "The Syntax Error";
this.powerLevel = 100;
this.energyLevel = 50;
}
maximizeEnergy() {
this.energyLevel = 1000;
}
gainPower(gainPower = 20) {
this.powerLevel += gainPower;
}
}
var superHero1 = new SuperHero("Batman", "strength", 40, "The Joker", 100, 50);
var superHero2 = new SuperHero("Wonder Woman", "agility", "Cheetah", 1000, 1000);
console.log('name', superHero1.name);
console.log('superpower',superHero1.superpower);
console.log('archNemesis',superHero1.archNemesis);
console.log('energyLevel',superHero1.energyLevel);
superHero1.gainPower(100);
console.log('powerLevel',superHero1.powerLevel);
console.log('-------------------------------------');
console.log('name', superHero2.name);
console.log('superpower',superHero2.superpower);
console.log('archNemesis',superHero2.archNemesis);
console.log('energyLevel',superHero2.energyLevel);
superHero2.gainPower(200);
console.log('powerLevel',superHero2.powerLevel);
you probably want to do things more like this:
sayName() {
console.log(this.name);
}
maximizeEnergy() {
this.energyLevel = 1000;
}
gainPower(power) {
this.powerLevel = this.powerLevel + power;
}
They are all pretty self explanatory.

Create class with dynamic properties

I create a class for my RPG games, and I would like to ask the user the name of their character, how can I do this ?
Pitch is the base name I created, but I would like pitch to be replaced by the name given by the user
class Personnage {
constructor(nom, sante, force) {
this.nom = nom;
this.sante = sante;
this.force = force;
this.xp = 0;
}
const principal = new Personnage("Pitch", 150, 25);
Thx for your answers ! (sorry for my english aha)
Consider this version to achieve what you are trying.
class Personnage {
var _nom;
var _force;
var _xp;
constructor(nom, sante, force) {
_nom = nom;
_sante = sante;
_force = force;
_xp = 0;
}
const principal = new Personnage(some_user_variable, 150, 25);
Though it is unclear what you are trying to do. Does this help?

Type Error - Referencing Javascript Classes

Firstly a little elaboration of the project I'm working on. I have started building a 'map maker' for a 2d game I am working on. The project is just for fun and has proven so far to be a great way to learn new things.
I recently showed my working map maker code to a friend who suggested it would be much more re-usable if I restructured the project to be more OOR, which I am now attempting.
The problem I have is when I add a 'Guild' instance to my map, the first one works fine, but the second causes a type error that is giving me a headache!
I will post all of the relevant code from the different files below, but the overall structure is as follows:
Map.js = Map class file, container for setting the map overall size and iterating over (and placing) map objects.
MapObject.js = Class file for simple map objects such as walls, contains the position and icon properties.
Guild.js = Class file, extends MapObject.js, this is where my problem seems to be, adds an additional 'MapIcon' and will have other features such as levels and names etc.
map-maker.js = Main file for generating the map-maker page, utilises the above class files to create the map.
Below is the code used to create an instance of 'Guild' on my map:
map-maker.js (creating the map / map object / guild instances)
// Initialise a new instance of map class from Map.js using the user
provided values for #mapX and #mapY.
var currentMap = new Map(XY,40);
// Get the user box volume * map boxsize from Map.js
currentMap.calcDimensions();
// Create a Map Object and push it to the currentMap with its position.
function createMapObject(x,y,floor){
currentMap.objects.push(new MapObject(x,y,floor));
}
// Create a Guild Object (extension of Map Object) and push it to the currentMap with its position.
function createGuildObject(x,y,floor){
currentMap.objects.push(new Guild(x,y,floor));
}
....
case 13: // Enter Key (Submit)
unhighlightTools();
currentMap.drawMap();
if(currentFloor != null){
currentFloor.hasFloor = true;
if(currentFloor.tileName == "Guild"){
createGuildObject(currentFloor.position.x,currentFloor.position.y,currentFloor);
}else {
createMapObject(currentFloor.position.x,currentFloor.position.y,currentFloor);
}
console.log("Map object created at - X:"+currentFloor.position.x+" Y:"+currentFloor.position.y);
}
currentFloor = [];
highlightTools();
break;
}
Guild.js (constructor and assigning map icon)
class Guild extends MapObject {
constructor(x,y,floor) {
super(x,y,floor);
this.levels = [];
}
mapIcon() {
this.mapIcon = new Image();
this.mapIcon.src = "../images/mapSprites/obj-1.png"
return this.mapIcon;
}
}
MapObject.js (position setup and constructor)
class MapObject {
constructor(x,y,floor) {
this.position = {x, y};
this.icon = this.wallFloorIcons(floor);
}
wallFloorIcons(floor) {
this.img = new Image();
this.name = "";
this.name += (floor.wallNorth) ? 'n' : '';
this.name += (floor.wallEast) ? 'e' : '';
this.name += (floor.wallSouth) ? 's' : '';
this.name += (floor.wallWest) ? 'w' : '';
this.name = 'wall-'+this.name+'.png';
if(this.name == 'wall-.png'){
this.img.src = "../images/mapSprites/floor.png";
}else {
this.img.src = "../images/mapSprites/"+this.name;
}
return this.img;
}
getIcon() {
return this.img;
}
}
Map.js (processing the objects at a given location and drawing the canvas)
class Map {
// Map Width / Height and number of boxes. Used to generate map and zoom level.
constructor(wh, boxSize) {
this.size = wh;
this.width = wh[0];
this.height = wh[1];
this.boxSize = boxSize;
this.objects = [];
this.boxes = wh[0];
}
// Calculates the width and height * boxSize for rendering the canvas.
calcDimensions(){
this.realX = Math.floor(this.width * this.boxSize);
this.realY = Math.floor(this.height * this.boxSize);
this.realX = parseInt(this.realX,10);
this.realY = parseInt(this.realY,10);
this.realXY = [
this.realX,
this.realY
];
return this.realXY;
}
// Draws the canvas, grid and adds the objects that belong to the map.
drawMap(){
var self = this;
self.canvas = document.getElementById("canvas");
self.c = self.canvas.getContext("2d");
self.background = new Image();
self.background.src = "../images/mapSprites/oldPaperTexture.jpg";
// Make sure the image is loaded first otherwise nothing will draw.
self.background.onload = function(){
self.c.drawImage(self.background,0,0);
self.fillMap();
}
}
fillMap(){
var self = this;
self.c.lineWidth = 1;
self.c.strokeStyle = 'black';
self.c.fillStyle = "rgba(255, 255, 255, 0.2)";
for (var row = 0; row < self.boxes; row++) {
for (var column = 0; column < self.boxes; column++) {
var x = column * self.boxSize;
var y = row * self.boxSize;
self.c.beginPath();
self.c.rect(x, y, self.boxSize, self.boxSize);
self.c.stroke();
self.c.closePath();
for (var i=0; i<self.objects.length; i++) {
var floor = self.objects[i];
if (floor.position.x == column && floor.position.y == row) {
if (self.objectsAtPosition({x:floor.position.x, y:floor.position.y}) != null) {
var mapObjects = self.objectsAtPosition({x:floor.position.x, y:floor.position.y})
for (var mapObject of mapObjects) {
this.c.drawImage(mapObject.getIcon(), x, y, self.boxSize, self.boxSize);
console.log(mapObject);
if(mapObject instanceof Guild){
console.log(mapObject);
this.c.drawImage(mapObject.mapIcon(), x, y, self.boxSize, self.boxSize);
}
}
}
}
}
}
}
}
deleteObject(pos){
this.objectsAtPosition(pos);
for( var i = 0; i < this.objects.length; i++){
if(this.objects[i] == this.objs){
delete this.objects[i];
this.objects.splice(i,1);
}
}
}
objectsAtPosition(position) {
var objs = [];
for (var o of this.objects) {
if (o.position.x == position.x && o.position.y == position.y) {
objs.push(o);
}
}
return objs;
}
}
When I run the code, this is my error:
Uncaught TypeError: mapObject.mapIcon is not a function
at Map.fillMap (Map.js:70)
at Image.self.background.onload (Map.js:39)
The error comes after I add 1 guild then try to add any other map object. Guild or otherwise.
Sorry if this question is a little vague, I'm still learning (as you can see :p).
Thanks for your time!
Earl Lemongrab
Got a solution from a friend in the end.
The issue was that I was reassigning this.mapIcon = new Image() so it exploded when it was called a second time.
Feel pretty silly for not spotting it.
Thanks for the help everyone.

JavaScript, Trying to get buttons to move on click

/*
var young_link = {
power: 30,
cpower: 20,
hp: 3,
image: "../images/young_link.jpg",
};
var young_zelda = {
power: 30,
cpower: 20,
hp: 3,
}
var impa = {
power: 30,
cpower: 20,
hp: 3,
}
var hey = {
power: 30,
cpower: 20,
hp: 3,
}
//$("#test").html(young_link);
console.log(young_link);*/
$(document).ready(function() {
var hero_image = new Array();
hero_image[0] = new Image();
hero_image[0].src = 'assets/images/link.png';
hero_image[0].id = 'image';
hero_image[1] = new Image();
hero_image[1].src = 'assets/images/bongo.png';
hero_image[1].id = 'image';
hero_image[2] = new Image();
hero_image[2].src = 'assets/images/gandondorf.jpg';
hero_image[2].id = 'image';
hero_image[3] = new Image();
hero_image[3].src = 'assets/images/queen.png';
hero_image[3].id = 'image';
//var test = "<img src= '../images/young_link.jpg'>";
//var young_hero = ["young_link","young_zelda","impa", "malon"];
var young_hero = ["Link", "Bongo Bongo","Gandondorf","Queen Gohma"];
var health = [100, 70, 120, 50];
for (var i = 0; i < young_hero.length; i++) {
var hero_btns = $("<buttons>");
hero_btns.addClass("hero hero_button");
hero_btns.attr({"data-name":young_hero[i],"data-health":health[i],"data-image":hero_image[i]});
hero_btns.text(young_hero[i]);
hero_btns.append(hero_image[i]);
hero_btns.append(health[i]);
$("#buttons").append(hero_btns);
}
$(".hero_button").on("click" , function() {
var battle_ground = $("<div>");
battle_ground.addClass("hero hero_button");
battle_ground.text($(this).data("data-name"));
$("#battle").append(battle_ground);
});
});
The for loop is working and appending the buttons on the screen. But in $(".hero_button").on("click" , function() it is just putting a empty box on the page with a click. So, it is not taking the data that is attached to the button.
Sam answered your question correctly and rightly deserves the accepted answer. But I wanted to give you an insight into how you can do this in a cleaner way, without lots of arrays which must line up. Also without using jQuery at all. Below you can see a more object oriented way to do this.
You can see it in action in this jsFiddle
// Now we have an object which represents a hero. No need to duplicate loads of code.
function Hero(heroData) {
this.name = heroData.name;
this.health = heroData.health;
this.setImage = function() {
this.image = new Image();
this.image.src = heroData.imageSrc;
this.image.id = heroData.imageId;
}
this.createHeroButton = function() {
this.createButtonElement();
this.addButtonToPage();
this.attachButtonEvents();
}
this.createButtonElement = function() {
var heroButton = document.createElement('button');
heroButton.classList.add('hero,hero_button');
heroButton.setAttribute('name', this.name);
heroButton.setAttribute('health', this.health);
heroButton.appendChild(this.image);
this.button = heroButton;
}
this.attachButtonEvents = function() {
this.button.addEventListener('click', this.addButtonToPage.bind(this));
}
this.addButtonToPage = function() {
var container = document.getElementById('container');
container.appendChild(this.button);
}
this.takeDamage = function(damageValue) {
this.health -= damageValue;
this.button.setAttribute('health', this.health);
}
this.setImage();
}
// So here we create a Hero instance, in this case Link, we can use now describe links attributes, image, name, health...
var link = new Hero({
name: 'Link',
health: 100,
imageSrc: 'http://orig12.deviantart.net/8bb7/f/2011/276/4/e/four_swords_link_avatar_by_the_missinglink-d4bq8qn.png',
imageId: 'link-image'
});
var mario = new Hero({
name: 'Mario',
health: 100,
imageSrc: 'http://rs568.pbsrc.com/albums/ss123/stvan000/thumb-super-mario-bros-8bit-Mario.jpg~c200',
imageId: 'mario-image'
});
// Now we can easily make a button and add it to the page
link.createHeroButton();
mario.createHeroButton();
// Lets try decreasing the health on mario
mario.takeDamage(10);
// Because we have an object reference which handles all of our heros state we can decrease his health and update the buttons data without much trouble.
A couple of changes to get the data set and read correctly:
make button tags instead of buttons
use .attr() instead of .data() to get the attributes
See comments inline in the code below.
Also, instead of adding an attribute for the Image object of each item (which will add an attribute like data-image="[Object object]") just add an integer corresponding to the iterator index and use that to reference into the hero_image array when you need to get the corresponding image.
Additionally, you can use Array.forEach() to iterate over the items in the heroes array with a callback function. That way you don't have to worry about updating the iterator variable (i in this case) and indexing into the array. You should take a look at this functional programming guide which has some good exercises.
$(document).ready(function() {
var hero_image = new Array();
hero_image[0] = new Image();
hero_image[0].src = 'assets/images/link.png';
hero_image[0].id = 'image';
hero_image[1] = new Image();
hero_image[1].src = 'assets/images/bongo.png';
hero_image[1].id = 'image';
hero_image[2] = new Image();
hero_image[2].src = 'assets/images/gandondorf.jpg';
hero_image[2].id = 'image';
hero_image[3] = new Image();
hero_image[3].src = 'assets/images/queen.png';
hero_image[3].id = 'image';
var young_heroes = ["Link", "Bongo Bongo", "Gandondorf", "Queen Gohma"];
var health = [100, 70, 120, 50];
young_heroes.forEach(function(young_hero,i) {
var hero_btns = $("<button>");
hero_btns.addClass("hero hero_button");
hero_btns.attr({
"data-name": young_hero,
"data-health": health[i],
//instead of adding an attribute for the image object, just add an index
"data-index": i
});
hero_btns.text(young_hero);
hero_btns.append(hero_image[i]);
hero_btns.append(health[i]);
$("#buttons").append(hero_btns);
});
$(".hero_button").on("click", function() {
var battle_ground = $("<div>");
battle_ground.addClass("hero hero_button");
//use .attr() here instead of .data()
battle_ground.text($(this).attr("data-name"));
/** My additions -
* I am not sure exactly how this should be done
* so adjust accordingly
**/
//additionally, you can add attributes to the new battle_ground item
battle_ground.attr('data-health',$(this).attr("data-health"));
battle_ground.append(hero_image[$(this).attr("data-index")]);
battle_ground.append($(this).attr("data-health"));
/** End my additions **/
$("#battle").append(battle_ground);
});
});
#battle div {
border: 1px solid #555;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="buttons"></div>
Battle ground:
<div id="battle"></div>

Multiple objects aren't getting displayed

I've been messing around with objects in Javascript and I've come across a problem. Basically I'm trying to print certain properties from objects I've created and it's not working properly.
Here's the code:
function Hotel(name, rooms, booked) {
this.name = name;
this.rooms = rooms;
this.booked = booked;
var CanadaHotel = new Hotel("CanadaIn", 50, 10);
var AmericanHotel = new Hotel("AmericanIn", 60, 3);
document.write(CanadaHotel.rooms);
document.write(AmericanHotel.booked);
None of the properties are being displayed and I don't know why.. any help is greatly appreciated.
Thank you
SyntaxError: missing } after function body
Fixed
function Hotel(name, rooms, booked) {
this.name = name;
this.rooms = rooms;
this.booked = booked;
}
var CanadaHotel = new Hotel("CanadaIn", 50, 10);
var AmericanHotel = new Hotel("AmericanIn", 60, 3);
console.log(CanadaHotel.rooms);
console.log(AmericanHotel.booked);

Categories

Resources