Output of creating a new variable of two properties over one another? - javascript

I've been trying to make a very simple and basic game to improve my JavaScript skills. However, I've been having a problem with trying to have a 'ratio' that displays the health of a objects. Here's a similar code because the original code is too long:
function Person(health) {
this.initialHealth = health;
this.lostHealth = health;
}
var bob = new Person(100);
var enemy = new Person(100);
var bobAttack = function() {
enemy.lostHealth = enemy.lostHealth - 50;
};
var enemyHealth = enemy.lostHealth + '/' + enemy.initialHealth;
bobAttack();
console.log(enemyHealth);
The output is:100/100 while I want it to be for example 50/100.

You probably expect 'lazy' evaluation, but you get the value of the expression immediately. That is, the expression var enemyHealth = enemy.lostHealth + '/' + enemy.initialHealth is fully evaluated before the enemy.lostHealth is changed, i.e. before the function bobAttack() is called. If you want delayed evaluation then you could use:
var enemyHealth = function() {
return enemy.lostHealth + '/' + enemy.initialHealth;
}
bobAttack();
console.log(enemyHealth());

Related

How to make this function do this in an interval

I'm trying to get the first function, to run repeatedly. Like it does in the second function. Where should I take a look?
(function printLetterByLetter() {
var i = 0;
var destination = "comment";
var RandomComment = [
"Did you choose that outfit?"
, "I like trains."];
var message = RandomComment[Math.floor(Math.random() * RandomComment.length)];
var typewriter = function () {
document.getElementById(destination).innerHTML += message.charAt(i);
i++;
if (i > message.length) {
clearInterval(typespeed);
}
}
var speed = 60;
var typespeed = setInterval(typewriter, speed)
}());
(function printLetterByLetter() {
var destination = "comment";
var frequency = 1000;
var RandomComment = [
"Did you choose that outfit?"
, "I like trains."];
var RandomCommentTimer = setInterval(function () {
var message = RandomComment[Math.floor(Math.random() * RandomComment.length)];
}, frequency)
}());
So what i'm trying to do is to make one function/module that types out a random comment at a set speed(first function). And after a set time the comment will disappear and a new comment will be typed out(second function). And like the second function this will go on.
So far I haven't made it work myself so I thought: let's see if anyone can help me on stackoverflow.
If anyone can give a tip on where to take a look, that is also most welcome.
You could set and alter the function parameters outside of the function then access them inside. Caveat is that you can't put var in front when setting them. Not putting var in front makes it accessible outside of the current scope.
destination = "comment";
frequency = 6000;
(function printLetterByLetter() {
//now you have access to destination and frequency as they are defined before the function is called
var RandomComment = [
"Did you choose that outfit?"
, "I like trains."];
var RandomCommentTimer = setInterval(function () {
var message = RandomComment[Math.floor(Math.random() * RandomComment.length)];
document.getElementById(destination).innerHTML = message;
}, frequency)
}());

Can't get value inside for loop

window.onload = function(){
for(var b=0;b<2;b++){
var imgc = new Image();
imgc.src = '../images/' + b + '.jpg';
imgc.height = 200;
divv.appendChild(imgc);
alert(document.getElementsByTagName('img')[b].width);
}
}
The image's size wont alert when the alert is inside the for loop. When I move the alert to onclick, it shows up. I hope you can help me.
This question might be answered a hundred of times before.
You have to wait before the image is actually loaded.
After that you can alert the width of the image.
Therefore you have to use the onload-function of the image
window.onload = function(){
for(b=0;b<2;b++){
var imgc = new Image();
// note the selfinvoking function which is immediately called with b as a parameter.
// inside the function b is now a local variable and will not change even if the outer b does
// you ofc can name the local b as you want
imgc.onload = (function(b){
return function(){
alert(document.getElementsByTagName('img')[b].width)
}
})(b)
imgc.src = '../images/' + b + '.jpg';
imgc.height = 200;
divv.appendChild(imgc);
}
}
Even easier you just can get the width from the object you just created - so not neccessary to get the data from the dom:
window.onload = function(){
for(b=0;b<2;b++){
var imgc = new Image();
// note the selfinvling function which is immediately called with b as a parameter.
// inside the function b is now a local variable and will not change even if the outer b does
// you ofc can name the local b as you want
imgc.onload = (function(img){
return function(){
alert(img.width)
}
})(imgc)
imgc.src = '../images/' + b + '.jpg';
imgc.height = 200;
divv.appendChild(imgc);
}
}
Now im gonna assume that you want your images to load after a certain time interval because the function will load the last image immediately if you dont put an interval as it will be fast. if you dont want the 2 second interval just change the '2000' to '0' in the code...hope it helps:
var imgc = new Image();
var b=0;
window.onload = function(){
var s=setInterval(imgloader,2000);
}
function imgloader()
{
imgc.src = '../images/' + b + '.jpg';
imgc.height = 200;
div.appendChild(imgc);
alert(
document.getElementsByTagName('img')[b].width);
b++;
if(b==2){
clearInterval(s);
}
}

Change properties of a class from time to time

I have two functions. In the first one I increase a variable by adding 100 to it and I put a setInterval so the funcion repeats itself after some time. The other function is a class, a contrusctor to create an object. I want this.x_origen to get increased by adding aumento to it after some time and repeat it. However what I'm getting here is that the first function increases aument and then it finishes and then the second function starts. How can I solve this?
var aument = 0;
function aumento(){
aument = aument + 100;
return aument;
}
setInterval(function () {aumento()}, 1000/50);
function create_class_brick (x_origen_in, y_origen_in, x_final_in, y_final_in, mi_estado, mi_velocidad, mi_id){
this.x_origen = x_origen_in + aumento();
this.y_origen = y_origen_in;
this.x_final = x_final_in + aumento();
this.y_final = y_final_in;
this.estado = mi_estado;
this.velocidad = mi_velocidad;
this.id_elemento = mi_id;
this.DESPLAZAR_LADRILLO = desplazar_ladrillo;
this.F0 = f0;
this.F2 = f2;
this.crear_ladrillo = crear_ladrillo;
this.obtener_x_origen_ladrillo = obtener_x_origen_ladrillo;
this.obtener_y_origen_ladrillo = obtener_y_origen_ladrillo;
this.obtener_x_final_ladrillo = obtener_x_final_ladrillo;
this.obtener_y_final_ladrillo = obtener_y_final_ladrillo;
}
An example on how to wait for the initial call:
function brick (x_origen_in){
this.x_origen = x_origen_in;
}
function aumento(brick){
console.log(brick.x_origen);
brick.x_origen += 100;
setTimeout(aumento.bind(this, brick), 500);
}
var brick = new brick(100);
aumento(brick);
http://jsfiddle.net/x6c08u39/
You can use Object.defineProperty to dynamically generate the value whenever it is accessed.
First, lets simplify the auto-incrementing of aument:
var aument = 0;
function aumento(){
aument += 100;
}
// The first argument for setInterval is the function to execute
// No need to figure out the interval value at runtime as there are no dynamic values
setInterval(aumento, 20); // 1000/50 === 20
Now lets make an object that will have a the correct value:
function create_class_brick (x_origen_in, y_origen_in, x_final_in, y_final_in, mi_estado, mi_velocidad, mi_id){
Object.defineProperty(this, 'x_origen', {
get: function () { return x_origen_in + aument; }
});
// Other stuff
// ...
}
A quick test:
> aument
34100
> var obj = new create_class_brick(23);
undefined
> obj.x_origen
161523
> obj.x_origen
167223
> obj.x_origen
172423

objects in an array alerted randomly

I have built this code using javascript that makes a few objects called monster. I then put those monsters in an array and finally am trying to call one of thous monsters to the console randomly. Unfortunately it displays in my console log as undefined. Any advice on how to get a random monster in the console log every time I refresh the page?
function Monster(type, level, mAttack, mAgility, mHP) {
this.type = type;
this.level = level;
this.mAttack = mAttack;
this.mAgility = mAgility;
this.mHP = mHP;
}
Monster.prototype.logInfo = function() {
console.log("I am a : ", this.type);
console.log("I am level : ", this.level);
console.log("I have the attack of : ", this.mAttack);
console.log("I have the agility : ", this.mAgility);
console.log("I have the health : ", this.mHP);
}
var troll = new Monster("troll", 1, 10, 10, 10);
var skeleton = new Monster("skeleton", 1, 10, 10, 10);
var slime = new Monster("slime", 1, 10, 10);
var boar = new Monster("boat", 1, 10, 10);
var monsterList = new Array();
monsterList[0] = troll;
monsterList[1] = skeleton;
monsterList[3] = slime;
monsterList[4] = boar;
var summonRandomMonster = function (){
monsterSummoner = monsterList[Math.floor(Math.random() * monsterList.length)];
}
console.log(monsterSummoner);
You create a function but never call it. Therefor monsterSummoner is never set.
// THIS IS NEVER CALLED
var summonRandomMonster = function (){
monsterSummoner = monsterList[Math.floor(Math.random() * monsterList.length)];
}
console.log(monsterSummoner);
Try this instead. Notice that now that the function is called the value is set.
var monsterSummoner;
var summonRandomMonster = function (){
monsterSummoner = monsterList[Math.floor(Math.random() * monsterList.length)];
}
summonRandomMonster();
console.log(monsterSummoner);
You're close... Change your last four lines as follows -
var monsterList = [troll,skeleton,slime,boar];
var summonRandomMonster = function (){
monsterSummoner = monsterList[Math.floor(Math.random() * monsterList.length)];
console.log(monsterSummoner);
}
for (var i = 0; i < 100; i++) {
summonRandomMonster();
}
There are atleast two problems in this code. The variable "monsterSummoner" is not defined, and the function "summonRandomMonster" is not called.

Reversal of the value of variable upon callback

How can I achieve this? Firstly the code...
function flutter() {
var random = Math.floor(Math.random()*5);
var $obj = $('.bird');
$obj.animate({ top :'-=' + random + 'px' }, 20, flutter);
}
</script>
In the code above, when the callback is executed, I want to reverse the value of random. My goal is thus to move the Class bird up and down and try to see if it create fluttering effect.
You can use some closure like this:
$obj.animate({ top :'-=' + random + 'px' }, 20, function(){
flutter(random*-1);
});
And this is the full code:
function flutter(offset) {
var random = ( isNaN(offset) ) ? Math.floor(Math.random()*5) : (offset) ;
var $obj = $('.bird');
$obj.animate({ top :'-=' + random + 'px' }, 20, function(){
flutter(random*-1);
});
}
And first call will be simple: flutter();
I just tweaked flutter above to make it more efficient and convenient.
function flutter(distance, target) {
// you can call flutter without argument. And no repetitive element finding is needed
var random = distance || Math.floor(Math.random()*5);
var $obj = target || $('.bird');
$obj.animate({ top :'-=' + random + 'px' }, 20, function(){
flutter(-random, $obj);
});
}

Categories

Resources