Reset values Issue - javascript

Building a dice game and you get 3 rolls. Once you finish your turn i'm trying to have a "reset" button that will reset the values back to the original spot so the "next person" can play. The values reset as I expected but when I "roll" none of the functions are taking place and i'm pretty new in js so i'm not sure what the problem is.
var playerScore = document.getElementById('firstPlayerScore');
var rollButton = document.getElementById('roll_button');
var dice1 = new dice(1);
var dice2 = new dice(2);
var dice3 = new dice(3);
var dice4 = new dice(4);
var dice5 = new dice(5);
var diceArray = [dice1, dice2, dice3, dice4, dice5];
var cargo = 0;
var numOfRolls = 0;
var cargoButton = document.getElementById('cargo');
var canHaveCargo = false;
function restart(){
dice1 = new dice(1);
dice2 = new dice(2);
dice3 = new dice(3);
dice4 = new dice(4);
dice5 = new dice(5);
diceArray = [dice1, dice2, dice3, dice4, dice5];
cargo = 0;
numOfRolls = 0;
canHaveCargo = false;
addGlow();
updateDiceImageUrl();
document.getElementById("dice1").classList.remove('glowing');
document.getElementById("dice2").classList.remove('glowing');
document.getElementById("dice3").classList.remove('glowing');
document.getElementById("dice4").classList.remove('glowing');
document.getElementById("dice5").classList.remove('glowing');
}
//dice object
function dice(id){
this.id = id;
this.currentRoll = 1;
this.previousRoll = 1;
this.isSelected = false;
this.diceImageUrl = "img/dice/dice1.png";
this.roll = function(){
this.previousRoll = this.currentRoll;
this.currentRoll = getRandomRoll(1, 6);
}
}
//returns an array of all dice that are not currently selected so they can be rolled.
function getRollableDiceList(){
var tempDiceList = [];
for(var i = 0; i < diceArray.length; i++){
if(!diceArray[i].isSelected){
tempDiceList.push(diceArray[i]);
}
}
return tempDiceList;
}
// gets a random number between min and max (including min and max)
function getRandomRoll(min,max){
return Math.floor(Math.random() * (max-min + 1) + min);
}
// calls the roll function on each dice
function rollDice(rollableDiceList){
for(var i = 0; i < rollableDiceList.length; i++){
rollableDiceList[i].roll();
}
}
// updates each dice with the new url for the image that corresponds to what their current roll is
function updateDiceImageUrl(){
for(var i = 0; i < diceArray.length; i++){
var currentDice = diceArray[i];
currentDice.diceImageUrl = "http://boomersplayground.com/img/dice/dice" + currentDice.currentRoll + ".png";
//update div image with img that cooresponds to their current roll
updateDiceDivImage(currentDice);
}
}
//Displays the image that matches the roll on each dice
function updateDiceDivImage(currentDice) {
document.getElementById("dice"+currentDice.id).style.backgroundImage = "url('" + currentDice.diceImageUrl +"')";
}
// returns an array of all
function getNonSelectedDice(){
var tempArray = [];
for(var i = 0; i < diceArray.length; i++){
if(!diceArray[i].isSelected){
tempArray.push(diceArray[i]);
}
tempArray.sort(function(a, b){
return b.currentRoll - a.currentRoll;
});
}
return tempArray;
}
function getSelectedDice(){
var selectedDice = [];
for(var i = 0; i < diceArray.length; i++){
if(diceArray[i].isSelected){
selectedDice.push(diceArray[i]);
}
}
return selectedDice;
}
//boolean variables
var shipExist = false;
var captExist = false;
var crewExist = false;
//checks each dice for ship captain and crew. Auto select the first 6, 5 , 4.
function checkForShipCaptCrew(){
//array of dice that are not marked selected
var nonSelectedDice = getNonSelectedDice();
for(var i = 0; i < nonSelectedDice.length; i++){
//temp variable that represents the current dice in the list
currentDice = nonSelectedDice[i];
if (!shipExist) {
if (currentDice.currentRoll == 6) {
shipExist = true;
currentDice.isSelected = true;
}
}
if (shipExist && !captExist) {
if (currentDice.currentRoll == 5) {
captExist = true;
currentDice.isSelected = true;
}
}
if (shipExist && captExist && !crewExist) {
if (currentDice.currentRoll == 4) {
crewExist = true;
currentDice.isSelected = true;
canHaveCargo = true;
}
}
}
}
function addGlow(){
var selectedDice = getSelectedDice();
for (var i = 0; i < selectedDice.length; i++){
var addGlowDice = selectedDice[i];
var element = document.getElementById('dice' + addGlowDice.id);
element.className = element.className + " glowing";
}
}
function getCargo(){
var cargo = 0;
var moreDice = getNonSelectedDice();
if (canHaveCargo){
for(var i=0; i < moreDice.length; i++){
cargo += moreDice[i].currentRoll;
playerScore.innerHTML = 'You have got ' + cargo + ' in ' + numOfRolls + ' rolls!';
}
} else {
alert("You don't have Ship Captain and the Crew yet!");
}
}
rollButton.addEventListener('click', function(){
//generate rollable dice list
if (numOfRolls < 3) {
var rollableDiceList = getRollableDiceList();
//roll each dice
rollDice(rollableDiceList);
//update dice images
updateDiceImageUrl();
getNonSelectedDice();
// //auto select first 6, 5, 4 (in that order)
checkForShipCaptCrew();
addGlow();
// //adds a red glow to each dice that is selected
numOfRolls++;
}
});
cargoButton.addEventListener('click', getCargo);
var startButton = document.getElementById('restart');
startButton.addEventListener('click', restart);
http://boomer1204.github.io/shipCaptainCrew/
Here is a link to the live game since it's the only way I can describe the problem since I don't know what's not working. If you roll the dice a couple times the dice will get a blue border and be "saved" according to the rules. Now after you hit th restart button that doesn't happen anymore.
Thanks for the help in advance guys

Just add this to your restart()
function restart(){
...
shipExist = false;
capExist = false;
crewExist = false;
...
}

It's hard to replicate without a fiddle, but it seems that you are adding and removing the 'glowing' class using separate processes. Have you tried adding the glowing class the same way you are removing it?
element.classList.add("glowing")
See an example within a fiddle: https://jsfiddle.net/5tstf2f8/

Related

Why does collision function won't remove an enemy?

I am trying to remove enemies when they get hit by a bullet, but as i can see this doesn't work.
I am writing this in codehs worksheet (javascript bootcamp).
var char;
var bullet;
var enemy;
var life = 5;
var enemyTimer = Randomizer.nextInt(0,50);
var enemies = [];
function start(){
makeChar();
keyDownMethod(movements);
makeBullet();
setTimer(shootBullet, 30);
addEnemy();
setTimer(makeEnemy, 5);
checkCollision();
}
function makeChar(){
char = new Circle(10);
char.setColor(Color.red);
char.setPosition(getWidth()/2, 430);
add(char);
}
function movements(e){
if (e.keyCode == Keyboard.RIGHT){
char.move(10,0);
}
if (e.keyCode == Keyboard.LEFT){
char.move(-10,0);
}
}
function makeBullet(){
bullet = new Rectangle(5,10);
bullet.setPosition(char.getX(), char.getY());
bullet.setColor(Color.green);
add(bullet);
}
function shootBullet(){
bullet.move(0,-10);
if (bullet.getY() < 0){
bullet.setPosition(char.getX(), char.getY());
}
}
function makeEnemy(){
for (var i = 0; i < enemies.length; i ++){
var b = enemies[i];
b.move(0,5)
b.move(Randomizer.nextInt(-3,3),0);
}
}
function addEnemy(){
setTimer(en,800);
}
function en(){
enemy = new Rectangle(50,50);
var x = Randomizer.nextInt(10, 350);
var y = enemy.getY();
y += 10;
enemy.setPosition(x,y);
add(enemy);
enemies.push(enemy);
}
function intersects(a,b){
return (a.getX() < b.getX() + b.getHeight() && a.getX() + a.getWidth() >b.getX() && a.getY() < b.getY() + b.getHeight() && a.getY() + a.getHeight() > b.getY());
}
function checkCollision(){
for(var i =0; i < enemies.length; i++){
var en = enemies[i];
if (intersects(bullet, en)){
println("hi");
remove(en);
i--;
remove(bullet);
}
}
}
With print I tried to see if it did read collision but it did not even print it.
I want it to remove enemies when it gets hit by a bullet,
Can somebody help?

Trying to change team javascript baseball program

I am using the code.org javascript library. I'm trying to have it so it changes team based on the two selected once 3 outs are reached. I tried to declare team1 and team2 and setting them equal to the check box that is selected but that doesnt work correctly.
The team name doesn't change on the label like it does when you first select a team. I'm not quite sure how to do it but the main goal is to get the team name to change when the current team gets 3 outs. There is a label that is being used in the player selection function that displays the 1st team selected.
var outs = 0;
var team1 = "";
var team2 = "";
var strikes = 0;
var balls = 0;
var fouls = 0;
var inning = 0;
var hit = 0;
var currentPlayer = team1, team2;
//Player Selection
onEvent("btnStart","click", function() {
var chkBoxs = ["Yankees", "Boston", "Astros"];
var selected = [];
for (var index = 0; selected.length < 2 && index < chkBoxs.length; index++) {
if (getChecked(chkBoxs[index])) { selected.push(index); }
}
setScreen("game");
if (selected.length == 2) {
console.log("The Teams are: " + chkBoxs[selected[0]] + " and " + chkBoxs[selected[1]]);
}
if (chkBoxs[selected[0]]) {
setText("lblTeamGame",chkBoxs[selected[0]]);
team1 = chkBoxs[selected[0]];
team2 = chkBoxs[selected[1]];
} else {
setText("lblTeamGame",chkBoxs[selected[1]]);
}
});
//Pitching Rules
function Count() {
if (balls == 4)
{
console.log("Walk");
setText("lblBallCount", 0);
setText("lblStrikeCount", 0);
balls = 0;
strikes = 0;
}
if (strikes == 3)
{
console.log("Strike Out");
outs++;
setText("lblStrikeCount", 0);
setText("lblOutCount", outs);
setText("lblBallCount", 0);
strikes = 0;
balls = 0;
}
if (outs == 3)
{
inning++;
setText("lblInningCount", inning);
switchPlayer();
}
if(hit)
{
setText("lblStrikeCount", 0);
setText("lblBallCount", 0);
strikes = 0;
balls = 0;
}
}
//Switch Teams
function switchPlayer() {
if(currentPlayer == team1) {
currentPlayer = team2;
showElement("player2_highlight");
hideElement("player1_highlight");
} else {
showElement("player1_highlight");
hideElement("player2_highlight");
currentPlayer = 1;
}
console.log("current player is: " + currentPlayer);
}
This could be your problem:
function switchPlayer(){
if(currentPlayer==team1){
currentPlayer=team2;
showElement("player2_highlight");
hideElement("player1_highlight");
} else {
showElement("player1_highlight");
hideElement("player2_highlight");
currentPlayer=team1; // Specify team1 instead of just 1
}
console.log("current player is: "+currentPlayer);
}
Also, after switching teams, you need to reset the number of outs.
if(outs==3)
{
inning++;
setText("lblInningCount",inning);
switchPlayer();
outs=0;
}

Returning cell value based on Radio selection

The goal I am trying to achieve is to retrieve a cell value based on a form radio selection and update a text area.
Process: User opens dialog box. They select a field office. Onclick runs the function check. After check runs google.script.run.withSuccessHandler(addSignatureLine).getSignatureLine(cellElement); is supposed to run and update the textarea with the Id 'AdditionalMessage' with the signature line retrieved from .getSignatureLine.
Here are two functions of the html code:
<script>
function addSignatureLine(signatureLine){
document.getElementById('AdditionalMessage').value = '\n\n'signatureLine;
};
function updateSignatureLine() {
var cellElement = document.getElementById('ET');
console.log('cellElement: ' + cellElement);
google.script.run.withSuccessHandler(addSignatureLine)
.getSignatureLine(cellElement);
};
function check() {
var ele = document.getElementsByName('fieldOfficeET');
var flag = 0;
for (var i = 0; i < ele.length; i++) {
if (ele[i].checked)
flag = 1;
}
if (flag == 1)
document.getElementById('Submit').disabled = false;
};
</script>
Here is the getSignatureLine.gs script
function getSignatureLine(cellObject) {
var ss = SpreadsheetApp.openById('googleSheetId');
var sheet = ss.getSheetByName('AMS Contact Information');
var firstRow = 2;
var lastRow = 10;
var dataRange = sheet.getRange(firstRow, 1, lastRow, 11);
var dataValues = dataRange.getValues();
for (var key in cellObject) { //Loop through all the data in the form
Logger.log('key: ' + key);
Logger.log('value: ' + cellObject[key]);
}
//Determines the row the Field Office is in
for (var rr = 0; rr < dataValues.length; rr++) {
if (dataValues[rr][0] == cellObject.fieldOfficeET) {
var r = rr + 2
break;
}
}
var signatureLine = sheet.getRange(r, 11).getValue();
Logger.log("signatureLine: " + signatureLine)
return signatureLine;
}
There is a problem with this line:
document.getElementById('AdditionalMessage').value = '\n\n'signatureLine;
I would try:
document.getElementById('AdditionalMessage').value = '\n\n' + signatureLine;
Add a plus sign to concatenate the text.

jQuery addClass or other methods doesn't seem to works on an element

(Sorry for my bad english)
I know, this question has been posted so many times, but the threads that I read didn't fix my problem.
I have a grid, with a random black cell drawn for each time I refresh the page. When the time come to "00:01", the cell need to replicate with the neighbors cells, I tried to put a background-color with jQuery, I tried to use attr('id', 'replicant'), I tried addClass... Nothing seem to work :S
Here the code for the draw :
function drawReplicant(replicant, cellTab)
{
for (var i = 0; i < replicant.length; i++) {
if($.inArray(replicant[i], cellTab))
{
var concat = 'row'+replicant[i].x+'col'+replicant[i].y;
$(concat.toString()).addClass("replicant");
}
}
}
And here, the full code :
var lastClicked;
var cellTab = Array();
var replicant = Array();
var neightbors = Array();
var newReplicant = Array();
var randomRow = Math.floor((Math.random() * 10) + 1);
var randomCol = Math.floor((Math.random() * 10) + 1);
var rows = 10;
var cols = 10;
var grid = clickableGrid(rows, cols,randomRow,randomCol,cellTab, function(el,row,col,i){
console.log("You clicked on element:",el);
console.log("You clicked on row:",row);
console.log("You clicked on col:",col);
console.log("You clicked on item #:",i);
$(el).addClass('clicked');
lastClicked = el;
});
document.getElementById("game").appendChild(grid);
function clickableGrid( rows, cols, randomRow, randomCol, cellTab, callback ){
var i=0;
var grid = document.createElement('table');
grid.className = 'grid';
for (var r=0;r<rows;++r){
var tr = grid.appendChild(document.createElement('tr'));
for (var c=0;c<cols;++c){
var cell = tr.appendChild(document.createElement('td'));
$(cell).addClass('row'+r+'col'+c);
if(randomCol == c && randomRow == r)
{
storeCoordinate(r, c, replicant);
$(cell).css('background', '#000000');
}
storeCoordinate(r, c, cellTab);
cell.addEventListener('click',(function(el,r,c,i){
return function(){
callback(el,r,c,i);
}
})(cell,r,c,i),false);
}
}
return grid;
}
function storeCoordinate(xVal, yVal, array)
{
array.push({x: xVal, y: yVal});
}
function replicate(replicant)
{
for (var i = 0; i < replicant.length; i++) {
var supRowX = replicant[i].x-1;
var supRowY = replicant[i].y;
storeCoordinate(supRowX, supRowY, newReplicant);
var subRowX = replicant[i].x+1;
var subRowY = replicant[i].y;
storeCoordinate(subRowX, subRowY, newReplicant);
var supColsX = replicant[i].x;
var supColsY = replicant[i].y-1;
storeCoordinate(supColsX, supColsY, newReplicant);
var subColsX = replicant[i].x;
var subColsY = replicant[i].y+1;
storeCoordinate(subColsX, subColsY, newReplicant);
}
}
function drawReplicant(replicant, cellTab)
{
for (var i = 0; i < replicant.length; i++) {
if($.inArray(replicant[i], cellTab))
{
var concat = 'row'+replicant[i].x+'col'+replicant[i].y;
$(concat.toString()).addClass("replicant");
}
}
}
var w = null; // initialize variable
// function to start the timer
function startTimer()
{
// First check whether Web Workers are supported
if (typeof(Worker)!=="undefined"){
// Check whether Web Worker has been created. If not, create a new Web Worker based on the Javascript file simple-timer.js
if (w==null){
w = new Worker("w.countdown.js");
}
// Update timer div with output from Web Worker
w.onmessage = function (event) {
var bool = false;
document.getElementById("timer").innerHTML = event.data;
if(event.data == "00:01")
{
replicate(replicant);
replicant = newReplicant;
drawReplicant(replicant, cellTab);
}
};
} else {
// Web workers are not supported by your browser
document.getElementById("timer").innerHTML = "Sorry, your browser does not support Web Workers ...";
}
}
// function to stop the timer
function stopTimer()
{
w.terminate();
timerStart = true;
w = null;
}
startTimer();
The replication WORKS, I have my new replicants in my array. But when I loop in this array to draw them, it doesn't seem to work although I'm able to get the cell to draw with :
var concat = 'row'+replicant[i].x+'col'+replicant[i].y;
If my first black cell if at the row4col4 position, this line will return :
row3col4
row5col4
row4col3
row4col5
And then, when the timer will restart, those 5 black cells will replicate with their neighbors, etc.
I use a web worker for the timer, here the code :
var timerStart = true;
function myTimer(d0)
{
// get current time
var d=(new Date()).valueOf();
// calculate time difference between now and initial time
var diff = d-d0;
// calculate number of minutes
var minutes = Math.floor(diff/1000/60);
// calculate number of seconds
var seconds = Math.floor(diff/1000)-minutes*60;
var myVar = null;
// if number of minutes less than 10, add a leading "0"
minutes = minutes.toString();
if (minutes.length == 1){
minutes = "0"+minutes;
}
// if number of seconds less than 10, add a leading "0"
seconds = seconds.toString();
if (seconds.length == 1){
seconds = "0"+seconds;
}
if(seconds >= 20)
{
seconds = "00";
}
// return output to Web Worker
postMessage(minutes+":"+seconds);
}
if (timerStart){
// get current time
var d0=(new Date()).valueOf();
// repeat myTimer(d0) every 100 ms
myVar=setInterval(function(){myTimer(d0)},1000);
// timer should not start anymore since it has been started
timerStart = false;
}
Thanks a lot :-)

Drawing multiple random canvas images in a loop

I'm trying to draw a grid with random images assigned to each square. I'm having trouble with the draw sequence and potentially closure issues with the Javascript variables. Any help is appreciated.
var tileSize = 30;
var drawCanvasImage = function(ctx,tile,x,y) {
return function() {
ctx.drawImage(tile,x,y);
console.log("x = " + x + "/ y = " + y);
}
}
function textures(ctx) {
var grass = new Image();
var sea = new Image();
var woods = new Image();
for (var i=0; i<=10; i++) {
for (var j=0; j<=20; j++) {
rand = Math.floor(Math.random()*3 + 1);
x = i * tileSize;
y = j * tileSize;
if (rand == 1) {
grass.onload = drawCanvasImage(ctx,grass,x,y);
} else if (rand == 2) {
sea.onload = drawCanvasImage(ctx,sea,x,y);
} else {
woods.onload = drawCanvasImage(ctx,woods,x,y);
}
}
}
grass.src = "textures/grass.png";
sea.src = "textures/sea.png";
woods.src = "textures/woods.png";
}
//function called by the onload event in the html body tag
function draw() {
var ctx = document.getElementById("grid").getContext('2d');
grid(ctx); //a function to draw the background grid - works fine
textures(ctx);
}
The current result is three drawn tiles, all at the position of x = 300 (equivalent to the i loop of 10 * the tileSize of 30) and a random y position.
After following a lead and accounting for (maybe?) closure issues by creating the variable drawCanvasImage, I at least got those three tiles to draw.
----Edit----
Working Code - Revision 2:
function randomArray() {
for (var i=0; i<=(xValue/tileSize); i++) {
terrainArray[i] = [];
for (var j=0; j<=(yValue/tileSize); j++) {
rand = Math.floor(Math.random()*4 + 1);
if (rand == 1) {
terrainArray[i][j] = 3;
} else if (rand == 2) {
terrainArray[i][j] = 2;
} else if (rand == 3) {
terrainArray[i][j] = 1;
} else {
terrainArray[i][j] = 0;
}
}
}
}
var drawTerrain = function(ctx,tile,landUseValue) {
return function() {
for (var i=0; i<=(xValue/tileSize); i++) {
for (var j=0; j<=(yValue/tileSize); j++) {
if (terrainArray[i][j] == landUseValue) {
ctx.drawImage(tile,i*tileSize,j*tileSize);
}
}
}
}
}
function textures(ctx) {
var grass = new Image();
var sea = new Image();
var woods = new Image();
var desert = new Image();
grass.onload = drawTerrain(ctx,grass,3);
sea.onload = drawTerrain(ctx,sea,0);
woods.onload = drawTerrain(ctx,woods,2);
desert.onload = drawTerrain(ctx,desert,1);
grass.src = "textures/grass.png";
sea.src = "textures/sea.png";
woods.src = "textures/woods.png";
desert.src = "textures/desert.png";
}
You're rewriting the onloads of the three images in every iteratiom. So, it will only execute the last-added onload f or every image.
Suggestion: run your drawing method only after the thred are loaded(and them just call drawCanvasImage every iteration without an .onload=)
Even better:store the randoms in an array, have each image independantly walk through the array on load and add copies of only itself wherever applicable .
Improvement to rev 2
function randomArray() {
for (var i=0; i<=(xValue/tileSize); i++) {
terrainArray[i] = [];
for (var j=0; j<=(yValue/tileSize); j++) {
rand = Math.floor(Math.random()*4 + 1);
terrainArray[i][j] = 4-rand;
//OR: replace above two lines with terrainArray[i][j]=Math.floor(Math.random()*4 + 1);. There's no need to have them in exactly reverse order.
}
}
}
var drawTerrain = function(ctx,tile,landUseValue) {
return function() {
for (var i=0; i<=(xValue/tileSize); i++) {
for (var j=0; j<=(yValue/tileSize); j++) {
if (terrainArray[i][j] == landUseValue) {
ctx.drawImage(tile,i*tileSize,j*tileSize);
}
}
}
}
}
function textures(ctx) {
var grass = new Image();
var sea = new Image();
var woods = new Image();
var desert = new Image();
grass.onload = drawTerrain(ctx,grass,3);
sea.onload = drawTerrain(ctx,sea,0);
woods.onload = drawTerrain(ctx,woods,2);
desert.onload = drawTerrain(ctx,desert,1);
grass.src = "textures/grass.png";
sea.src = "textures/sea.png";
woods.src = "textures/woods.png";
desert.src = "textures/desert.png";
}
To make it even more flexible, you could use an array to store the images, and then use length. This way, if you want to add another image, all you have to do is modify the array.
var srcArray=["textures/grass.png","textures/sea.png","textures/woods.png","textures/desert.png"];
var imgArray=[];
var terrainArray=[];
function textures(ctx){
randomArray();
for(var i=0;i<srcArray.length;i++){
imgArray[i]=new Image();
imgArray[i].src=srcArray[i];
imgArray[i].onload=drawTerrain(ctx,i);
}
}
function randomArray() {
for (var i=0; i<=(xValue/tileSize); i++) {
terrainArray[i] = [];
for (var j=0; j<=(yValue/tileSize); j++) {
terrainArray[i][j]=Math.floor(Math.random()*srcArray.length);
}
}
}
var drawTerrain = function(ctx,index) {
return function() {
for (var i=0; i<=(xValue/tileSize); i++) {
for (var j=0; j<=(yValue/tileSize); j++) {
if (terrainArray[i][j] == index) {
ctx.drawImage(imgArray[index],i*tileSize,j*tileSize);
}
}
}
}
}
So now, all you have to do is call terrain(ctx) when you want to load all the images. And, whenever you want to add an image to the list of images, just add it to the array up top. You won't have to dig deeper and modify the random values and whatnot.
It's because every time you do a loop, you assign a new function to [image].onload, overwriting the previous one. That's how you end up with only three images.
This should work:
if (rand == 1) {
grass.addEventlistener('load', drawCanvasImage(ctx,grass,x,y), false);
} else if (rand == 2) {
sea.addEventlistener('load', drawCanvasImage(ctx,sea,x,y), false);
} else {
woods.addEventlistener('load', drawCanvasImage(ctx,woods,x,y), false);
}
Here you just add a new listener for every loop.

Categories

Resources