function is not working properly - javascript

I have a problem with my functions for when a enemy shoots a laser. I have done so much debugging on this, i just cannot figure out why it is not working.
When i have my code like this it will shoot to the top of my playArea but not to the bottom (boundary is spelt wrong because i done it from the beginning)
for (var i = 0; i < enemylasers.length; i++){
if(parseInt(enemylasers[i][0].style.top) > playArea.topBoundry){
enemylasers[i][1] -= laserSpeed;
enemylasers[i][0].style.top = enemylasers[i][1] + 'px';
}else{
playArea.removeChild(enemylasers[i][0]);
enemylasers.splice(i,1);
}
}
When i change some of the code around to what i think might be right, it isnt and just does not make the lasers shoot anywhere. here is what i changed it to.
for (var i = 0; i < enemylasers.length; i++){
if(parseInt(enemylasers[i][0].style.top) > playArea.bottomBoundry){
enemylasers[i][1] += laserSpeed;
enemylasers[i][0].style.top = enemylasers[i][1] + 'px';
}else{
playArea.removeChild(enemylasers[i][0]);
enemylasers.splice(i,1);
}
}
This is what creates my enemies laser
function createenemylaser(){
if(enemylasers.length < enemymaxlasers){
var laserpush = Math.floor(Math.random()*enemies.length);
var laser = enemylaser();
laser.classList.add('enemylaser');
laser.style.top = enemies[laserpush][1] + 'px';
laser.style.left = parseInt(enemies[laserpush][0].offsetLeft) +'px';
playArea.appendChild(laser);
enemylasers.push([laser, enemies[laserpush][1]]);
}
}
setInterval(createenemylaser, 2000);
And this is my enemies lasers array
enemylasers=[],
enemylaserspeed = 5,
enemymaxlasers= 8,
And this is what creates the div for my enemy laser
function enemylaser(){
return document.createElement('div');
}
I hope someone can help, i am not that experienced in javascript but i know quiet abit.

Since #Chips_100 suggested I should post my solution from the comments section here, here it is:
You needed to change parseInt(enemylasers[i][0].style.top) > playArea.bottomBoundry to parseInt(enemylasers[i][0].style.top) < playArea.bottomBoundry as you have reversed the direction your lasers are travelling in.

Related

I'm stuck in a project about snow animation in javascript

I have to create a script that simulates the animation of snow in javascript (I would prefer without using canvas if possible). I'm stuck at this point and I don't know where the mistake is. when I run the program google chrome crashes and the console does not give me errors, I think the error is due to a loop or some incorrect statements, I am attaching the code hoping for your help!
var direction=true; //true=right false =left
var active=true; //if true run the cycle,false stops the cycle
function startSnow() {
var _snowflakes = new Array(30);
var wid=50; //distance from a snowflake to another
var counterX; //var for editing the x position
var counterY; //var for editing the y position
for (var i=0; i< 30; i++) //cycle that initializes snowflakes
{
_snowflakes[i] = document.createElement("img");
_snowflakes[i].setAttribute("src","snowflake.png"); // setting the image
_snowflakes[i].setAttribute("class", "snowflake"); //setting the css style
_snowflakes[i].style.visibility ="inherit"; //when the function is running snowflakes have to be visible, when it finishes they have to be invisible
_snowflakes[i].style.right = (wid*i)+"px"; //set the distance from the left margin
_snowflakes[i].style.top = "30px"; // set the distance from the top
document.getElementById("background").appendChild(_snowflakes[i]);
}
while(active)
{
move();
}
function move() //function that moves the snowflake
{
for(;;)
{
if(counterY>=600) //when the snowflake reaches 600px from the top the function has to stop and hide snowflakes
{
for(var i=0;i<30;i++)
_snowflakes[i].style.visibility = "hidden";
active=false;
break;
}
else
{
if ((counterY%50)==0)
{
direction=!direction //every 50 Y pixels the snoflake change direction
}
counterY++;
for(var i=0;i<30;i++)
{
_snowflakes[i].style.top = counterY+"px"; //Y movement
if (direction==true)
{
_snowflakes[i].style.right = (_snowflakes[i].offsetLeft+counterX) + "px"; //x right movement
counterX++;
}
else
{
_snowflakes[i].style.right = (_snowflakes[i].offsetLeft+counterX) + "px"; //x left movement
counterX--;
}
}
}
}
}
}
Indeed, your code gets into an infinite loop because your variable counterY is not initialised and so it has the value undefined. Adding one to undefined gives NaN, and so you never get to that break statement.
But more importantly, you need a different approach, because even if you fix this, you'll never see an animation happening. For actually seeing the animation, you need to give the browser time to update the display. So a while and for(;;) loop are out of the question.
Instead call move once, and inside that function, in the else block, call requestAnimationFrame(move). This will give the browser time to repaint before move is called a gain. Remove the for(;;) loop, and remove the break.
There is also a logical error in how you move horizontally. As you read the current offsetLeft it makes no sense to increment counterX as that will lead to increasing (relative) jumps to the right (or left). Instead you should just add (or subtract) 1 to offsetLeft -- you can do away with counterX. Also, don't assign that to style.right, but to style.left.
So everything put together (cf. comments where there is a change):
var direction=true;
var active=true;
function startSnow() {
var _snowflakes = new Array(30);
var wid=50;
// var counterX = 0; -- not used.
var counterY = 0; // Need to initialise!
for (var i=0; i< 30; i++) {
_snowflakes[i] = document.createElement("img");
_snowflakes[i].setAttribute("src", "snowflake.png");
_snowflakes[i].setAttribute("alt", "❄"); // added for when image not found
_snowflakes[i].setAttribute("class", "snowflake");
_snowflakes[i].style.visibility = "inherit";
_snowflakes[i].style.left = (wid*i)+"px"; // assign to style.left
_snowflakes[i].style.top = "30px";
document.getElementById("background").appendChild(_snowflakes[i]);
}
// No while loop. Just call move
move();
function move() {
//No for (;;) loop
if (counterY>=600) {
for (var i=0;i<30;i++) {
_snowflakes[i].style.visibility = "hidden"; // you forgot the underscore
}
active=false;
// No break -- function will just return
} else {
if ((counterY%50)==0) {
direction=!direction
}
counterY++;
for (var i=0;i<30;i++) {
_snowflakes[i].style.top = counterY+"px";
if (direction==true) {
// assign to style.left,
_snowflakes[i].style.left = (_snowflakes[i].offsetLeft+1) + "px"; // add 1
} else {
_snowflakes[i].style.left = (_snowflakes[i].offsetLeft-1) + "px"; // sub 1
}
}
requestAnimationFrame(move); // schedule next run of this function
}
}
}
startSnow(); // Need to start it!
#background { width: 800px; height: 800px }
.snowflake { position: absolute; font-size: 40px }
<div id="background">
</div>

adding image to different div upon change/removal of another div

I have a game which involves a dog chasing cats; upon the dog touching the cat div, the class changes so that a "dead" cat appears and is then removed. I would also like to have a smaller version of the dead cat image show up in a div in the upper right corner as a sort of score keeper.
So essentially every time a cat is killed a small image pops up in the score div.
The problem is if I have the prepend for the small image placed where it is now, it continues to add the image indefinitely as opposed to only one for each dead cat. I'm guessing it's because it's within this if statement for the collision detection but I can't figure out a way around it.
I've tried making it a function, moving it outside of the getCollision function, tried to attach a trigger...nothing I've done seems to work to solve what I assume to be a relatively simple problem.
If anyone can help or point me in the right direction I'd greatly appreciate it! Below is the code:
"use strict";
$(document).ready(function() {
console.log("linked");
var $dog = $('.dog'); //global variables
var body = $('body');
var $cat = $('.cat');
function newCat() { //creates a div w/ class cat, appends to body
var cat = $('<div class="cat"></div>');
body.append(cat);
setInterval(function() { //moves cats randomly
cat.css("top", Math.random() * window.innerHeight);
cat.css("left", Math.random() * window.innerWidth);
}, 1500)
}
for(var i=0; i<10; i++) { //create multiple cats
newCat();
}
function getCollision(cat) { //collision detection for elements
$(cat).each(function(index, cat) { //loops through each cat div
var $dogH = $dog.outerHeight(true);
var $dogW = $dog.outerWidth(true);
var $dogX = $dog.position();
var $dogY = $dog.position();
var $catH = parseInt($(cat).css('height').replace('px', ''))
var $catW = parseInt($(cat).css('width').replace('px', ''))
var $catX = parseInt($(cat).css('left').replace('px', ''))
var $catY = parseInt($(cat).css('top').replace('px', ''))
if ($dogX.left < $catX + $catW &&
$dogY.top < $catY + $catH &&
$catX < $dogX.left + $dogW &&
$catY < $dogY.top + $dogW) {
$(cat).addClass('dead');
$('.score').prepend('<img src="images/cat_dead_sm.png" />');
setTimeout(function() {
$('.dead').remove(); //removes dead cat
}, 2500);
console.log('boom');
};
});
};
$(document).mousemove(function(event) { //moves dog div to follow cursor
$('.dog').css({
'top': event.pageY,
'bottom': event.pageX,
'left': event.pageX,
'right': event.pageY
});
$cat = $('.cat')
getCollision($cat); //calls getcollision to check distance
})();
// function keepScore() {
// $('.score').prepend('<img src="images/cat_dead_sm.png" />');
// }
// };
});
I think the problem is that a dead cat can still die - another iteration of the collision detection can occur before the setTImeout that removes the dead cat is triggered. You could check if the current cat is already dead before prepending the score image.
We just need to check if it's already dead to avoid this:
if ($dogX.left < $catX + $catW &&
$dogY.top < $catY + $catH &&
$catX < $dogX.left + $dogW &&
$catY < $dogY.top + $dogW &&
!$(cat).hasClass('dead')
) {
$(cat).addClass('dead');
$('.score').prepend('<img src="images/cat_dead_sm.png" />');
setTimeout(function () {
$('.dead').remove(); //removes dead cat
}, 2500);
console.log('boom');
}
Or even better - you could avoid collision detection on dead cats entirely:
$cat = $('.cat:not(.dead)');
getCollision($cat);

Issues with rotating jqueryUI modal

I am trying to build a modal that rotates to a particular element, $(.linkmoddet), based on a clicked element in the navbar $('.selectcircle') using the .switchClass function in jQueryUI.
However, I am having issues with the actual math involved, often causing:
only one or two elements to rotate at a time.
multiple elements gaining classes but not losing them.
occasionally losing all the classes involved, defaulting the element in question to a standard size and position in CSS.
Code
Edit: This has now been fixed.
http://codepen.io/yeasayer/pen/ZWxYZG
var selectcircle = $('.selectcircle');
var linkmoddet = $('.linkmoddet');
selectcircle.click(function(){
var circleindex = $(this).index()-1;
var centerindex;
console.log(circleindex);
selectcircle.each(function (index){
if (circleindex == index)
{
console.log($(this));
}
});
linkmoddet.each(function (index){
if ($(this).hasClass('moddetcenter'))
{
centerindex = $(this).index();
console.log("the center is index #"+centerindex);
}
var rotation = centerindex - circleindex;
//This is where I start having issues.
var i = $(this).index() + rotation;
var j;
if (i <= -1)
{
j = i + moddetids.length-1;
$(this).switchClass(classes[i+$(this).index()],classes[j]);
}
if (i >= moddetids.length)
{
j = i - moddetids.length;
$(this).switchClass(classes[i-$(this).index()],classes[j]);
}
else
{
if (rotation < 0)
{
j = i-1;
}
else
{
j = i+1;
}
$(this).switchClass(classes[i], classes[j]);
}
});
});
Does anyone have an idea on how to achieve the desired results, possibly in a simpler manner than described above?
Alright, it turns out that I figured it out by doing the following:
linkmoddet.each(function (index){
var classnum;
var newrot;
if ($(this).hasClass('moddetcenter'))
{
classnum = 2;
if (rotation < 0)
{
rotation += classes.length;
}
if (classnum + rotation >= classes.length)
{
newrot = classnum + rotation - classes.length;
$(this).switchClass(classes[classnum],classes[newrot]);
}
else if (rotation != 0)
{
$(this).switchClass(classes[classnum],classes[classnum+rotation]);
}
}
/* This is repeated for all the classes available in the classes array.
* ie: 0 being the first class, 1 being the second, etc. It's not an
* elegant solution, but it works for my current needs at the moment
* while I put it in a function in the future. */
Thanks!

Touch Events not registering for HTML5 Canvas Authoring using Flash CC

I have been having some issues when it comes to authoring HTML 5 Canvas in Flash CC, mostly as a result of the lack of information on writing JavaScript inside Flash.
I have been converting an existing drag and drop .fla into HTML 5 with the hope of making it iOS and Android compatible. It is already functioning with mouse, but I have hit a brick wall on trying to add touch support.
The only way I have been able to even register the touch events is by listening to the entire window, which isn't very useful when I have multiple pieces that I want to move around.
This is what I have so far, all this code is located on the first frame of the main Scene Timeline, and the scene is composed of 5 pieces and 5 targets for those pieces, as well as a pop up task completed box and a reset button.
this.stop();
MainStage = this;//Declare
//*********************
//Actual Drag and Dropping
// Initialize:
var numPieces = 5;//<---------------Place number of pieces HERE---------------
var homePosX = [];
var homePosY = [];
var correctAns = 0;
var isClickableAry = [];
var whoAmI = [];//Declared "Globally" so that I can identify which piece is being grabbed later
for (var i = 0; i < numPieces; i++)
{
var pieceName = "p" + (i + 1);
var piece = this[pieceName];
//This sets the starting position for each piece
homePosX[i+1] = piece.x;//(i+1) is so that Piece names line up with Target names and MC names
homePosY[i+1] = piece.y;
whoAmI[i] = piece;
isClickableAry[i] = 1;//Makes it so each pieces is set as clickable
if( piece ){
piece.name = pieceName;
piece.on("mousedown" || "touchstart", function(evt)
{
evt.preventDefault();
//Debug
console.log(checkPiece(this));
//Rather than adding and removing event listeners, just check to see if piece is clickable
if(isClickableAry[checkPiece(this)] == 1){
this.parent.addChild(this);// Bump to top
this.offset = {x:this.x - evt.stageX, y:this.y - evt.stageY};
//Debug
console.log(piece + "PICKED UP, X " + piece.x + ", Y " + piece.y + " is Clickable? ");
//Set Home Coordinates (Where it was picked up)
homeX = this.x;
homeY = this.y;
}
});
piece.on("touchmove",function(evt)
{
console.log("touch moved! " + touchobj);
evt.preventDefault();
});
piece.on("pressmove", function(evt)
{
if(isClickableAry[checkPiece(this)] == 1){
this.x = evt.stageX + this.offset.x;
this.y = evt.stageY + this.offset.y;
//Mouse Cursor change
document.body.style.cursor='move';
}
});
piece.on("pressup" || "touchend" || "touchcancel", function(evt)
{
var target = this.parent["t"+this.name.substr(1)];
//Reset Cursor
document.body.style.cursor='auto';
if( target && hitTestInRange( target, 60) && isClickableAry[checkPiece(this)] == 1 ){
this.x = target.x;
this.y = target.y;
//If it is correct add one
correctAns++;
//Make that button Unclickable
isClickableAry[checkPiece(this)] = 0;
if(correctAns >= numPieces){
//If they have answered correctly equal to the the number of pieces
MainStage.complete_mc.parent.addChild(MainStage.complete_mc);//Bump to top
MainStage.complete_mc.gotoAndStop(1);
//reset answer counter and make drag pieces and buttons unclickable
correctAns = 0;
//Debug
console.log(correctAns + "CORRECT!";)
}
}else{
//Return to home Coordinates (Where it was on intialization)
if(isClickableAry[checkPiece(this)] == 1){
this.x = homePosX[checkPiece(this)+1];
this.y = homePosY[checkPiece(this)+1];
}
}
});
piece.on("mouseover", function(evt)
{
if(isClickableAry[checkPiece(this)] == 1){
//Makes cursor a pointer finger
document.body.style.cursor='pointer';
}
});
piece.on('mouseout',function(evt)
{
//sets cursor back to normal
document.body.style.cursor='auto';
});
}
}
function hitTestInRange( target, range )
{
if( target.x > stage.mouseX - range &&
target.x < stage.mouseX + range &&
target.y > stage.mouseY - range &&
target.y < stage.mouseY + range )
{
return true;
}
return false;
}
//Check which piece it is
function checkPiece(checkName)
{
for (var i = 0; i < numPieces; i++)
{
if (checkName == whoAmI[i]){
return i;
}
}
}
//Reset Functionality
this.complete_mc.reset_btn.addEventListener("click", resetPos.bind(this));
function resetPos(){
for (var i = 0; i < numPieces; i++)
{
var pieceName = "p" + (i + 1);
var piece = this[pieceName];
correctAns = 0;
//Makes Pieces Grabable again
isClickableAry[i] = 1;
//This returns each piece to their Original Starting Positions
piece.x = homePosX[i+1];
piece.y = homePosY[i+1];
}
}
//Controlling the Pop Up Window, window pops up when user answers everything correctly
this.complete_mc.exitComplete_btn.addEventListener("click", closePopUp.bind(this));
this.complete_mc.exitComplete_btn_alt. addEventListener("click", closePopUp.bind(this));
function closePopUp(){
MainStage.complete_mc.gotoAndStop(0);
}
In my own troubleshooting with other problems that have come up generally the issue has to do with scope of either functions or variables, since when flash exports the files it generates its own .js file and turns all of your movie clips into code and separates the code that you have written by whichever frame you wrote it on.
Any help at all would be appreciated.
EDIT: After a bit more research I think the problem might have something to do with touch events only being able to target separate elements? So it isn't able to grab objects inside the canvas element just the canvas element itself?
Turns out that adding touch support is incredibly easy. All I was missing was one line of code
createjs.Touch.enable(stage);
this makes all the touch events respond as mouse events. and fixed all my issues.

Intel XDK: document.location.href leads to the wrong page

Hello Stack Overflow Community, I've been searching and trying out different things and nothing seems to work. In my Intel XDK project, when I try using location.location.href = "#EndGame" or other forms of it, the page does change but it changes to a different page than the one I asked it to, in my case it changed to the "mainpage". It happened properly when I used a button but not with JavaScript. I checked my code and I don't think there's anything in there that should cause a problem. So is this a bug? If it is one, can you suggest for me a way around it?
I'm not very advanced in JavaScript and HTML5 so this might seem like a bad question.
This is the button:
<a class="button widget uib_w_3 d-margins PictWid" data-uib="app_framework/button" data-ver="1" id="Start" style=" margin:0px auto;display:block" onclick="GameLoading()" href="#GamePlay" data-transition="fade">Start</a>
This is the js code:
function GameOver()
{
window.clearInterval(Timer);
window.clearInterval(Timer2);
w4=0
for (i = 0; i < level; i++)
{
CenterX[w4] = -100;
CenterY[w4] = -100;
w4+=1;
}
ShowGold();
Draw1();
level=0;
m=0;
k=0;
k2=0;
x3= 0+24.72;
y3 = hei2 - 24.72;
vx=0;
vy=0;
x2 = wid2/2;
y2 = hei2/2;
x = wid2/2;
y = hei2/2;
setTimeout(function(){document.location.href = "#EndGame"},500);
EndGamePage();
}
function EndGamePage()
{
wid2 = screen.width;
hei2 = screen.height;
wid = screen.width - 20;
hei = screen.height - 20;
if (wid < hei)
{
//alert("Testing2!")
document.getElementById("Title2").style.width = wid + "px";
document.getElementById("Start2").style.width = wid + "px";
document.getElementById("Title2").style.marginTop = hei2*0.15 + "px";
} else
{
// alert("Testing3!")
document.getElementById("Title2").style.width = hei + "px";
document.getElementById("Start2").style.width = hei + "px";
document.getElementById("Title2").style.marginTop = wid2*0.15 + "px";
}
}
You cant make a link handle both href and a function to trigger on click , so the proper solution is to add this line to your function GameLoading() , or call a new function from within that function:
window.location+="/#EndGame"
Not sure if this gonna work with intel XDK or not , but worth trying.
Try This
location.hash = "#EndGame";
After 6 months worth of experience, I found out that the best way, for me, is to use what's called a "show" function/method. Here it is:
function show(shown, hidden, hidden2, hidden3, hidden4) {
document.getElementById(shown).style.display = 'block';
document.getElementById(hidden).style.display = 'none';
document.getElementById(hidden2).style.display = 'none';
document.getElementById(hidden3).style.display = 'none';
document.getElementById(hidden4).style.display = 'none';
return false;
}
What it does is it just shows or hide specified div if you give it their ids. So in a button, you could have:
<a onclick="show('pagetwo', 'pagezero', 'pagethree', 'pageone', 'pagefour');" id='Start' class="ui-btn">Start</a>

Categories

Resources