I'm attempting to create a Choose Your Own Adventure type of game, and I'm currently trying to write a 'battle' script. What I've got so far is:
var name = "Anon";
var health = 100;
var youAttack = [name + " hits the " + opp + " with his sword", name + " uses magic!", name + " is too scared to fight!"];
var youBattle = function() {
var youBattle = youAttack[Math.floor(Math.random() * 3)];
return youBattle;
};
var opp = "Orc";
var oppHealth = 100;
var oppAttack = ["The " + opp + " hits you with his hammer!", "The " + opp + " does nothing!", "The " + opp + " back hands you!"];
var oppBattle = function() {
var oppBattle = oppAttack[Math.floor(Math.random() * 3)];
return oppBattle;
};
oppBattle();
youBattle();
I've done it like this so the opponent and player names can easily be changed.
What I'm struggling to figure out is how I can add / remove health from both the opponent and the player depending what attack is used. Obviously no health would be removed if the opp / player does nothing.
Is there a way I can do this without a bunch of messy if / else statements?
I was hoping for something easy like name + " hits the " + opp + " with his sword" + health = health - 10; but obviously that didn't work.
Thanks in advance!
http://jsbin.com/qerud/3/edit
Hope this isn't too much code:
var Attack = function(hero,opp,damageReceived,damageGiven,message){
this.message = message;
this.damageGiven = damageGiven;
this.damageReceived = damageReceived;
this.opp = opp;
this.hero = hero;
this.attack = function(opp){
this.hero.health -= damageReceived;
this.opp.health -= damageGiven;
return this.message;
};
};
var Character = function(name,health){
this.name = name;
this.health = health;
};
hero = new Character('Anon',100);
orc = new Character('Orc',150);
attack1 = new Attack(hero,orc,5,0,"The " + orc.name + " back hands you!");
attack2 = new Attack(hero,orc,0,0,hero.name + " is too scared to fight!");
attack3 = new Attack(hero,orc,15,0,"The " + orc.name + " hits you with his hammer!");
attack4 = new Attack(hero,orc,0,25,hero.name + " uses magic!");
attacks = [attack1,attack2,attack3,attack4];
while(hero.health > 0 && orc.health > 0){
console.log(attacks[Math.floor(Math.random() * 4)].attack());
console.log('Hero Health: '+ hero.health);
console.log('Orc Health: '+ orc.health);
}
if(hero.health > 0 ){
console.log(hero.name + ' won');
} else {
console.log('The ' + orc.name + ' won');
}
I can tell you first hand that trying to write this type of code uses a lot of if/else and more statements, regardless of what language you're using. You can use an array to hold the values of your attack patterns:
var attackName = ["Punch", "Sword", "Magic"]
var attackDamage = [3, 5, 4]
function youAttack(ATK, PHit) {
if(playerHit) {
playerDamage = ATK + PHit;
oppHealth = oppHealth - playerDamage;
return oppHeath;
} else {
alert("You missed!");
}
}
But, without seeing exactly what you're doing I cannot say how you should do your attacks and damages. I can only assume. You will need a system of evaluating attacks, misses, etc. that does use IF/ELSE Statements at least somewhere.
Related
first and foremost i'm new to javascript and coding. second, i'm coding a book store project with javascript with an alert message that shows each customer's total factor. but the alert message shows the code of my function "printFactor" insted of the string that is made by this function. this is my code:
function Book(name, writer, date, price)
{
this.name = name;
this.writer = writer;
this.date = date;
this.price = price;
}
function Customer(name, gender, turn)
{
this.name = name;
this.gender = gender;
this.turn = turn;
this.numberOfBooks = 0;
this.totalSum = 0;
this.bookList = [new Book("-", "-", "-", 0)];
//Functions.
this.addBook = function (newBook) {
this.numberOfBooks++;
this.bookList.push(newBook);
};
this.printFactor = function () {
var message = "";
if (this.numberOfBooks === 0) {
message = "No Books Has Been Added to Book List!";
return (message);
}
else {
message = this.name + " " + this.gender + " Number of Books: " + this.numberOfBooks + " Customer's Turn: " + this.turn + "\nBooks:\n";
var i;
var newMessage;
for (i = bookList.length - 1; i > 0; i--) {
newMessage = bookList[i].name + " " + bookList[i].writer + " " + bookList[i].date + " " + bookList[i].price.toString() +"\n" ;
message += newMessage;
this.totalSum += bookList[i].price;
this.bookList.pop();
}
newMessage = "Total Sum: " + this.totalSum;
message += newMessage;
return (message);
}
};
}
var book = new Book("Faramarz Bio", "Faramarz Falsafi Nejad", "1377/04/29", 13000);
var faramarz = new Customer("faramarz", "Male", 3);
faramarz.addBook(book);
faramarz.addBook(book);
faramarz.addBook(book);
faramarz.addBook(book);
var m = faramarz.printFactor;
window.alert(m);
You need to invoke the function:
var m = faramarz.printFactor();
As is your variable m contains a reference to the function, but you need to call it to get the result.
var m = faramarz.printFactor();
window.alert(m);
You simply don't call your function, this should work.
var m = faramarz.printFactor()
Beside you reference an unexisting variable 'booklist', that should be "this.booklist"
for (i = this.bookList.length - 1; i > 0; i--) {
newMessage = this.bookList[i].name + " " + this.bookList[i].writer + " " + this.bookList[i].date + " " + this.bookList[i].price.toString() +"\n" ;
You need to actually call the function by adding () to the end, like this:
var m = faramarz.printFactor()
I am new to Javascript and have figured how to make the first line log to the console, however, how can I continue the loop and display the results as the balance gets lower until the balance is zero? I appreciate any help with this. Thanks in advance.
function displayPayment() {
var year = 0;
var balance = 1500;
var interest = 0.015;
var minimum = 0.02;
var payNum = 0;
if (balance > 0) {
var newPayNum = payNum + 1;
var newYear = year + 1;
var interestPaid = balance * interest;
var newBalance = interestPaid + balance;
var minPay = newBalance * minimum;
var balanceOwe = newBalance - minPay;
return (" " + newYear + " " + balanceOwe + " " + newPayNum + "
" + interestPaid);
}
}
console.log(" Year " + " Balance " + " PaymentNum " + " InterestPaid \n");
console.log(displayPayment());
You can use either the do while loop or just a while loop. However your balance does not change during the process, so the loop will never exit.
So i've recently ran into issues with trying to move specific pieces of a <p> </p> called result. as such i thought hey! wouldn't be easier to break each part inside of result down into another <p>!? well it works lol however trying to grab that inner <p> that in this cause we'll call vault is being difficult. I've tried several methods but cant seem to grab it's value from outside in a document.getElementByID....here's the code below for the html.
document.getElementById("result").innerHTML = Monster + "<p id='vault'> || HP: " + HP + "</p> || Defense: " + Def + " || Attack: " + ATK + " || Can it Dodge/Block: " + DB + " || Can it retaliate: " + RET + " || Initative: " + INT + " || Exp: " + MEXP + " <input type='submit' class='new' onclick='Combat(" + loop + ")' value='FIGHT!'></input>" + "<br><br>" + A;
}
then the script that eventually calls it
function Combat(id){
document.getElementById("vault").innerHTML = id;
document.getElementById("C").value = id
}
So what i'm trying is change id "C" to ID"VAULT" inside of id ("result").
any ideas on why i can't grab vault?
What you want would be easier with Object-oriented JavaScript.
Usually when coding JavaScript you want to be as independent of the DOM (HTML) as possible.
Consider the following example:
/**
* Monster
*/
var Monster = (function() {
function Monster(HP, DEF, ATK, DB, RET, INT, MEXP) {
if (HP === void 0) {
HP = 100;
}
if (DEF === void 0) {
DEF = 10;
}
if (ATK === void 0) {
ATK = 100;
}
if (DB === void 0) {
DB = 10;
}
if (RET === void 0) {
RET = true;
}
if (INT === void 0) {
INT = 100;
}
if (MEXP === void 0) {
MEXP = 100;
}
this.HP = HP;
this.DEF = DEF;
this.ATK = ATK;
this.DB = DB;
this.RET = RET;
this.INT = INT;
this.MEXP = MEXP;
}
/**
* getHTML
*/
Monster.prototype.getHTML = function() {
return "HP: " + this.HP + " || Defense: " + this.DEF + " || Attack: " + this.ATK + " || Can it Dodge/Block: " + this.DB + " || Can it retaliate: " + this.RET + " || Initative: " + this.INT + " || Exp: " + this.MEXP;
};
/**
* attacked
*/
Monster.prototype.attacked = function(damage) {
if (damage === void 0) {
damage = 0;
}
//check defences
if (damage > this.DEF + this.DB) {
//take damage
this.HP -= (damage - this.DEF + this.DB);
}
if (this.HP < 0) {
//Return true if it slew the monster
return true;
} else {
//Return false if the monster survived
return false;
}
};
return Monster;
}());
/**
* Area
*/
var Area = (function() {
function Area(name) {
if (name === void 0) {
name = "Vault";
}
this.name = name;
this.monsters = [];
}
/**
* addMonster
*/
Area.prototype.addMonster = function(monster) {
this.monsters.push(monster);
return this;
};
/**
* attackVault
*/
Area.prototype.assault = function(damage) {
if (damage === void 0) {
damage = 0;
}
//If no monster
if (this.monsters.length < 1) {
alert("You have cleared this vault");
return true;
} else {
//If monsters exists, attack the first
var monsterKilled = this.monsters[0].attacked(damage);
//If the monster was killed
if (monsterKilled) {
//remove monster
this.monsters.splice(0, 1);
//Alert the player
alert("Well done hero!\nOnly " + (this.monsters.length) + " remaining!");
}
}
//Return maybe monsters left?
return this.monsters.length < 1;
};
return Area;
}());
////GRAP HTML ELEMENT
var output = document.getElementById("current-monster");
////RUNNING YOUR GAME
//Build and populate world
var vault = new Area();
vault
.addMonster(new Monster())
.addMonster(new Monster());
//INTERACTION
alert("Start");
//Hit the vault till it is empty
while (vault.assault(45) != true) {
output.innerHTML = vault.monsters[0].getHTML();
alert("Attack!");
}
output.innerHTML = "Victory!";
<h1 id="title">Monster Game!</h1>
<h2 id="current-monster"></h2>
See how i can easily access the data though JavaScript?
When coding a JavaScript game, it makes sense to keep important data and structures in your JavaScript.
Ok so i added the bit - ADyson suggested...
document.getElementById("result").innerHTML = Monster + "<p id='vault(" + loop + ")'> || HP: " + HP + "</p>" + " || Defense: " + Def + " || Attack: " + ATK + " || Can it Dodge/Block: " + DB + " || Can it retaliate: " + RET + " || Initative: " + INT + " || Exp: " + MEXP + " <input type='submit' class='new' onclick='Combat(" + loop + ")' value='FIGHT!'></input>" + "<br><br>" + A;
}
}
}
function Chest(id){
window.open('LootGen.html', '_blank');
}
function Combat(id){
var id = document.getElementById("vault" + id).innerHTML;
document.getElementById("C").value = id;
submit();
}
However now when i run it on the " ).innerHTML;" i'm getting a
MonsterGen.html:426 Uncaught TypeError: Cannot read property
'innerHTML' of nullCombat # MonsterGen.html:426onclick #
MonsterGen.html:1
Ok I found out exactly was was going wrong; it was the naming convention in the <P>.
Originally it was id='vault(" + loop + ")'... this would make it vault(1) etc.... however the getElement was getting it by this call ("vault" + id) so it would call vault1....thus two separate id's entirely....that's why it was returning null.
So I removed the () in the equation and now everything is working beautifully.
I am new to JS and have created this original problem from CodeAcademy which works. Now I wanted to put my flock of sheep into an object and access it using my sheepCounter function. I am new to accessing key/values from an object and am stuck on what I am doing wrong. Thanks in advance!
Original Code
var sheepCounter = function (numSheep, monthNumber, monthsToPrint) {
for (monthNumber = monthNumber; monthNumber <= monthsToPrint; monthNumber++) {
numSheep *= 4;
console.log("There will be " + numSheep + " sheep after " + monthNumber + " month(s)!");
}
return numSheep;
}
New Code:
var flock = {
sheep: 4,
month: 1,
totalMonths: 12
};
var sheepCounter = function (counter) {
for (counter[month] = counter[month]; counter[month] <= counter[totalMonths]; counter[month]++) {
numSheep *= 4;
console.log("There will be " + counter[sheep] + " sheep after " + counter[month] + " month(s)!");
}
return counter[sheep];
}
Found the error in your solution:
var sheepCounter = function (counter) {
for (counter['month'] = counter['month']; counter['month'] <= counter['totalMonths']; counter['month']++) {
counter['sheep'] *= 4;
console.log("There will be " + counter['sheep'] + " sheep after " + counter['month'] + " month(s)!");
}
return counter['sheep'];
}
You can access your Flock Object like so,
alert(flock.sheep); //4
If you have an array in an object, like
names: ['joe','tom','bob'];
You would access that like so,
alert(flock.names[0]); // joe
alert(flock.names[2]); // bob
So, I have this simple 2d train sim, and I already made a pretty nice SAT realisation, that works without errors (at least I have not stumbled upon any):
function calcCollision(self){
var dist = self.distanceCheck();
var possible = [], collision = [];
var myBox, otherBox, myMin, myMax, otherMin, otherMax, myBoxRecalc = [], otherBoxRecalc = [];
for (var i=0;i<trainCount;i++){
if (dist[i]!="SELF"&&dist[i]<=(dTrain+10)){
possible.push(i);
}
}
if (possible.length!==0){
myBox = self.box();
self.hit = false;
for (i=0;i<possible.length;i++){
otherBox = window["train_"+possible[i]].box();
//для self координат
for (var j=0;j<4;j++){
myBoxRecalc[j] = XYtoBoxCoordinates(self,myBox[j][0],myBox[j][1]);
otherBoxRecalc[j] = XYtoBoxCoordinates(self,otherBox[j][0],otherBox[j][1]);
}
//для self координат, проекция на X
myMin = myBoxRecalc[0][0];
myMax = myBoxRecalc[0][0];
otherMin = otherBoxRecalc[0][0];
otherMax = otherBoxRecalc[0][0];
for (j=0;j<4;j++){
if (myBoxRecalc[j][0]<myMin) myMin=myBoxRecalc[j][0];
if (myBoxRecalc[j][0]>myMax) myMax=myBoxRecalc[j][0];
if (otherBoxRecalc[j][0]<otherMin) otherMin=otherBoxRecalc[j][0];
if (otherBoxRecalc[j][0]>otherMax) otherMax=otherBoxRecalc[j][0];
}
//console.log(myMin + " " + myMax + " " + otherMin + " " + otherMax);
if (otherMax<myMin||otherMin>myMax) break;
//для self координат, проекция на Y
myMin = myBoxRecalc[0][1];
myMax = myBoxRecalc[0][1];
otherMin = otherBoxRecalc[0][1];
otherMax = otherBoxRecalc[0][1];
for (j=0;j<4;j++){
if (myBoxRecalc[j][1]<myMin) myMin=myBoxRecalc[j][1];
if (myBoxRecalc[j][1]>myMax) myMax=myBoxRecalc[j][1];
if (otherBoxRecalc[j][1]<otherMin) otherMin=otherBoxRecalc[j][1];
if (otherBoxRecalc[j][1]>otherMax) otherMax=otherBoxRecalc[j][1];
}
//console.log(myMin + " " + myMax + " " + otherMin + " " + otherMax);
if (otherMax<myMin||otherMin>myMax) break;
//для other координат
for (j=0;j<4;j++){
myBoxRecalc[j] = XYtoBoxCoordinates(window["train_"+possible[i]],myBox[j][0],myBox[j][1]);
otherBoxRecalc[j] = XYtoBoxCoordinates(window["train_"+possible[i]],otherBox[j][0],otherBox[j][1]);
}
//для other координат, проекция на X
myMin = myBoxRecalc[0][0];
myMax = myBoxRecalc[0][0];
otherMin = otherBoxRecalc[0][0];
otherMax = otherBoxRecalc[0][0];
for (j=0;j<4;j++){
if (myBoxRecalc[j][0]<myMin) myMin=myBoxRecalc[j][0];
if (myBoxRecalc[j][0]>myMax) myMax=myBoxRecalc[j][0];
if (otherBoxRecalc[j][0]<otherMin) otherMin=otherBoxRecalc[j][0];
if (otherBoxRecalc[j][0]>otherMax) otherMax=otherBoxRecalc[j][0];
}
//console.log(myMin + " " + myMax + " " + otherMin + " " + otherMax);
if (otherMax<myMin||otherMin>myMax) break;
//для other координат, проекция на Y
myMin = myBoxRecalc[0][1];
myMax = myBoxRecalc[0][1];
otherMin = otherBoxRecalc[0][1];
otherMax = otherBoxRecalc[0][1];
for (j=0;j<4;j++){
if (myBoxRecalc[j][1]<myMin) myMin=myBoxRecalc[j][1];
if (myBoxRecalc[j][1]>myMax) myMax=myBoxRecalc[j][1];
if (otherBoxRecalc[j][1]<otherMin) otherMin=otherBoxRecalc[j][1];
if (otherBoxRecalc[j][1]>otherMax) otherMax=otherBoxRecalc[j][1];
}
//console.log(myMin + " " + myMax + " " + otherMin + " " + otherMax);
if (otherMax<myMin||otherMin>myMax) break;
collision.push(possible[i]);
}
} else return false;
if (collision.length!==0){
self.hit = true;
return collision;
} else return false;
}
It detects possible collision objects for self and returns their ID's if there is a collision. As I already said, it works just fine. The problem appears after that, when i'm trying to create a reaction on the collision. I've been struggling over the algorithm for almost a week, and that's the best solution that I came up with:
function moveCollided(){
for (var i = 0; i < trainCount; i++) {
var banged = calcCollision(window["train_"+i]);
//console.log(banged);
if (window["train_"+i].hit){
window["train_"+i].speed -= (window["train_"+i].speed/3);
for (var j = 0; j < banged.length; j++) {
window["train_"+banged[j]].speed += calcSpeedIncrement(window["train_"+i],window["train_"+banged[j]]);
}
}
}
setTimeout(moveCollided, 15);
}
This function decreases the speed of the train, and adds some speed (calcSpeedIncrement(self,other)) to the train it crashed into. I'm getting a nice collision effect in the straight tracks, but if you keep pushing forward one train slides over the other. And another problem with the same "sliding over" is the collision when one of the trains is standing on the turn.
Does anyone have any ideas on how to solve these problems?
I would simple not try to re-invent the wheel and go for an existing solution. Have you looked at the very popular 2D-physics engine Box2D? Here is a nice implementation of it in JavaScript.