CraftyJS: I can't destroy an entity with .onHit - javascript

I am having a problem with craftyJS. I made a ship that shoots lasers, but I want the lasers to destroy an entity when it collides with it. I already tried to do this, but it don't work. Here is my code:
Crafty.init(1340,650, document.getElementById('game'));
Crafty.defineScene("gameStart", function() {
function newAlien(){
var random = Math.floor(Math.random() * 4) + 1;
switch(random){
case 1:
var alien = Crafty.e("2D, DOM, Image, Collision")
.image("alien1.png");
alien.x = ship.x;
alien.y = 20
break;
case 2:
var alien = Crafty.e("2D, DOM, Image, Collision")
.image("alien2.png");
alien.x = ship.x;
alien.y = 20;
break;
case 3:
var alien = Crafty.e("2D, DOM, Image, Collision")
.image("alien3.png");
alien.x = ship.x;
alien.y = 20;
break;
case 4:
var alien = Crafty.e("2D, DOM, Image, Collision")
.image("alien4.png");
alien.x = ship.x;
alien.y = 20;
break;
}
}
function newLaser(){
var laser = Crafty.e("2D, DOM, Image, Collision")
.image("laser.png")
.collision()
.onHit("alien", function(){
laser.destroy();
alien.destroy();
});
laser.y = 510;
laser.x = ship.x + 40;
var moveLaser = setInterval(function(){
if(laser.y < 1){
clearInterval(moveLaser);
laser.destroy();
} else {
laser.y = laser.y - 4;
}
}, 1);
}
function checkBorder(){
if(ship.x < 0 || ship.x > 1250){
Crafty.enterScene("gameStart");
}
}
function goLeft(){
var goLeftCount = 65;
var goLeftInterval = setInterval(function(){
if(goLeftCount === 0){
clearInterval(goLeftInterval);
checkBorder();
} else {
ship.x = ship.x - 1;
goLeftCount -= 1;
}
}, 1);
}
function goRight(){
var goRightCount = 65;
var goRightInterval = setInterval(function(){
if(goRightCount === 0){
clearInterval(goRightInterval);
checkBorder();
} else {
ship.x = ship.x + 1;
goRightCount -= 1;
}
}, 1);
}
var ship = Crafty.e("2D, DOM, Image, Bind")
.image("ship.png")
.bind('KeyDown', function(e) {
if(e.key == Crafty.keys['LEFT_ARROW']) {
goLeft();
} else if (e.key == Crafty.keys['RIGHT_ARROW']) {
goRight();
} else if(e.key == Crafty.keys['SPACE']) {
newLaser();
}
});
ship.y = 520;
ship.x = 600;
newAlien();
});
Crafty.enterScene("gameStart");
Can anyone please tell me what are the problems with my code?

One problem: when you try to destroy the alien, the alien variable isn't actually in scope. (You've declared it in a different function.) So there's no way alien.destroy(); will work.
Second problem: the function you pass to .onHit("alien", callback) will only be run when the laser hits an entity with the "alien" component. It has no idea what variable name you assigned the entity. However, the callback function will be passed information about what entities it's colliding with, and you can use that to resolve the collision.

Related

Increase and decrease SVG shape - JS

I would like you to help me for a thing here, for a function to increase and then decrease SVG shape when it hits limit.
It should go from 3 to 6 and then 6 to 3 and so on... but instead it goes from 3 to 6 and then 6 to minus infinite. And I don't understand why.
Here is my code :
var size = 3;
var sizeManager = 1;
function increaseAnimation(el){
var elem = document.getElementById(el);
elem.style.transform = "scale("+size+")";
timer = setTimeout('increaseAnimation(\''+el+'\',3000)');
size=size+0.005*sizeManager;
if(size >= 6){
sizeManager=sizeManager*-1;
}
if (size <= 3){
sizeManager=sizeManager*+1;
}
}
Your weird setTimeout implementation, with bound was broken.
There's also the issue that your sizeManager is not properly reflecting:
function increaseAnimation(id, interval) {
var size = 1;
var velocity = 0.05;
var elem = document.getElementById(id);
function iterate() {
elem.style.transform = "scale(" + size + ")";
size += velocity;
if (size > 2 || size < 1) {
velocity *= -1; // velocity reflected
}
}
var timer = setInterval(iterate, interval);
return function stop() {
clearInterval(timer)
}
}
I also added a stop function which you can call at a later point.
var stopper = increaseAnimation("content", 16);
setTimeout(stopper, 5000);
The error is with the line sizeManager=sizeManager*+1; Multiplying a number by one doesn't change it. You basically want to toggle sizeManager between -1 and +1, and you can do so by multiplying by -1, regardless of whether it is currently negative or positive.
I've tested this code and it seems to work:
var size = 3;
var sizeManager = 1;
function increaseAnimation(el) {
var elem = document.getElementById(el);
elem.style.transform = "scale(" + size + ")";
timer = setTimeout("increaseAnimation('" + el + "', 3000)");
size += 0.005 * sizeManager;
if (size >= 6 || size <= 3) {
sizeManager *= -1;
}
}
Full HTML for a POC demo at: https://pastebin.com/GW0Ncr9A
Holler, if you have questions.
function Scaler(elementId, minScale, maxScale, deltaScale, direction, deltaMsecs) {
var scale = (1 == direction)?minScale:maxScale;
var timer = null;
function incrementScale() {
var s = scale + deltaScale*direction;
if (s < minScale || s > maxScale) direction *= -1;
return scale += deltaScale*direction;
};
function doScale(s) {
document.getElementById(elementId).style.transform = 'scale(' + s + ')';
};
this.getDeltaMsecs = function() {return deltaMsecs;};
this.setTimer = function(t) {timer = t;};
this.run = function() {doScale(incrementScale());};
this.stop = function() {
clearInterval(timer);
this.setTimer(null);
};
};
var scaler = new Scaler('avatar', 3, 6, .05, 1, 50);
function toggleScaler(ref) {
if ('run scaler' == ref.value) {
ref.value = 'stop scaler';
scaler.setTimer(setInterval('scaler.run()', scaler.getDeltaMsecs()));
}
else {
scaler.stop();
ref.value = 'run scaler';
}
};

Adding a image to an element

I'm making a element that is randomly appearing on the screen using javascript. What would I do in order to add an image using javascript to the randomly generated element?
function addEnemy() {
var interval = 0.1;
if (iterations > 1500) {
interval = 5;
} else if (iterations > 1000) {
interval = 3;
} else if (iterations > 500) {
interval = 1;
}
if (getRandom(50) == 0) {
var elementName = "enemy" + getRandom(10000000);
var enemy = createSprite(elementName, getRandom(450), -40, 45, 45);
var enemiesDiv = document.getElementById("enemiesDiv");
var element = document.createElement("div");
element.id = enemy.element;
element.className = "enemy";
enemiesDiv.appendChild(element);
enemies[enemies.length] = enemy;
element.enemy.innerHTML
}
}
You can create a new img element, give it the source to your image, then append that img element to your element you created. (I would suggest using a more descriptive variable name than just "element")
The relevant code could look like this:
var myImage = document.createElement('img');
myImage.src = 'my_image.jpg';
element.appendChild(myImage);
A little bit too broad, but I think you could consider using the background property of your created div. Something like this:
function addEnemy() {
var interval = 0.1;
if (iterations > 1500) {
interval = 5;
} else if (iterations > 1000) {
interval = 3;
} else if (iterations > 500) {
interval = 1;
}
if (getRandom(50) == 0) {
var elementName = "enemy" + getRandom(10000000);
var enemy = createSprite(elementName, getRandom(450), -40, 45, 45);
var enemiesDiv = document.getElementById("enemiesDiv");
var element = document.createElement("div");
element.id = enemy.element;
element.className = "enemy";
// Here
element.style.backgroundImage = "url('img_enemy.png')";
enemiesDiv.appendChild(element);
enemies[enemies.length] = enemy;
element.enemy.innerHTML
}
}

Objects being generated, but not being drawn in the correct position

Ok, so I have a game where I have some tree objects that need to be drawn in one side or another. The problem is, even though the condition is working and the trees are being drawn, they're not following the SIDES_RATE condition, specially on Side 2, they're going to the opposite direction while in Side 1 they're almost moving straight, instead of diagonal.
This is my Tree Class:
function Tree1(side, pos_x) {
this.speed = TREE_SPEED;
this.side = side;
this.height = 107;
this.width = 49.3;
this.pos_x = pos_x;
this.pos_y = 10;
this.tree1_image = tree_images[this.side];
}
This is my Tree controller
setInterval(generateTree, TREE_SPEED * 1000);
function generateTree() {
a = (Math.round(Math.random()));
if (a == 0){
tree1_array.push(new Tree1(Math.round(Math.random()),200));
} else {
tree2_array.push(new Tree2(Math.round(Math.random()),600));
}
}
function moveTree(tree){
tree.height += ZOOM_RATE;
tree.width += ZOOM_RATE;
if (tree.side == 0){
tree.pos_x -= SIDES_RATE;
} else if (tree.side == 1) {
tree.pos_x += SIDES_RATE;
}
tree.pos_y += TREE_SPEED;
}
function treeController(){
for (i = 0; i < tree1_array.length; i++){
if (tree1_array[i].pos_y > 900){
tree1_array.splice(i,1);
} else {
moveTree(tree1_array[i]);
}
}
}
This is where I draw them:
Game.draw = function() {
for (i = 0; i < tree1_array.length; i++) {
this.context.drawImage(tree1_array[i].tree1_image,
tree1_array[i].pos_x - tree1_array[i].width/2,
tree1_array[i].pos_y - tree1_array[i].height/2,
tree1_array[i].width,
tree1_array[i].height);
}
}
I don't know what's happening for it to happen. Anything helps.

program flow animating in javascript

Hello I am having errors with my code:
https://jsfiddle.net/wzhm2whj/
<script>
//Initial Global variables
var mainloop_frame_time = 34;
var top = 0;
var rootMenu = document.getElementById('menu');
var rootMenuDivs = rootMenu.getElementsByTagName('div')[0];
var rootListDivs = rootMenuDivs.getElementsByTagName('ul')[0];
var childDivs = rootListDivs.getElementsByTagName('div');
var childDiv = childDivs[0];
var childDiv_counter = 0;
var child_change_flag = true;
var child_index_increment = 0;
var child_index_amount = childDivs.length;
//var child_animation_keyframe = 0;
var frame = 0;
var childDiv_tmp1_position = 0;
//finding the web browsers viewport size.
var elem = (document.compatMode === "CSS1Compat") ? document.documentElement : document.body;
var client_height = elem.clientHeight;
var process_array = new Array();
//Initial styling
for (var i = 0; i < childDivs.length; i++) {
var childDiv = childDivs[0];
childDiv.style.backgroundColor = "antiquewhite";
}
var childDiv = childDivs[0];
//rotate function variables
var rotate_div;
var rotate_passed_deg;
var rotate_deg_stop;
var rotate_results;
var rotate_current_deg = 0;
var speed_modifier = 1;
var tmp1_speed = 0;
//case flags
case2_flag = -1;
case3_flag = -1;
//This may not be needed >>> If not, put all code in mainloop.
var processes_logic = function() {
switch (frame) {
case 0:
process_array.push(menu_child0);
break;
//this case is when the previous case is 80% done
case 28:
rootMenu.style.transformOrigin = "top left";
process_array.push(menu_slant);
break;
case 35:
//Added the ability for paramaters, all push paramaters here are: function, menu_index, position, speed, tmp as flag for switching to next menu,
//process_index used to give the process index as refrence to delete..
window.alert(process_array.length);
process_array.push(new Array(menu_div_slide_out, child_index_amount - 1, 0, 0, 0, process_array.length-1));
break;
}
}
var initiate_all_processes = function() {
for (var i = 0; i < process_array.length; i++) {
//Added the ability for paramaters, considerer removing as its not used atm, or revising.
if (process_array[i] != undefined && process_array[i] != null && process_array[i] != "") {
if (process_array[i].length < 6) {
process_array[i]();
} else {
process_array[i][0](process_array[i][5]);
}
}
}
}
function menu_div_slide_out(process_index) {
/*process_array[process_index][
0 = function,
1 = current menu item (index length working backwards)
2 = position,
3 = speed,
4 = tmp,
5 = refrence to this process in array] */
//for debuging purposes to see if a ChildDiv is not devined, what process index is being pointed to.
//window.alert('Process index ' + process_index);
//!!!!!!!! You are probably mixing up how you are setting process index! try +1
process_array[process_index][2] += 3.5 + (process_array[process_index][3] * 1.7);
process_array[process_index][3] += (speed_modifier * .3);
childDivs[process_array[process_index][1]].style.left = process_array[process_index][2] + 'px';
if (process_array[process_index][2] > 100 && process_array[process_index][4] && process_array[process_index][1] > 0) {
// window.alert('CCC');
process_array[process_index][4] = true;
//Add another process at ever 100pxs
process_array.push(new Array(menu_div_slide_out, process_array[process_index][1] - 1, 0, 0, false, process_array.length-1));
//debugger;
} else
if (process_array[process_index][2] >= (900 - (process_array[process_index][2] / 20))) {
childDivs[process_array[process_index][1]].remove();
//process_array.splice(process_array[process_index][5], 1);
}
}
function menu_slant() {
rotate_return = rotate(rootMenu, .1 + (tmp1_speed), 27);
tmp1_speed += (speed_modifier * .5);
if (rotate_return === true) {
/////////////This can be unremoved because there is more animation, perhaps. or can be done in another key frame.
tmp1_speed = 0;
rotate_current_deg = 0;
remove_process(menu_slant);
} else {
if (rotate_return / 27 * 100 >= 60 && case3_flag < 0) {
case2_flag = frame;
}
}
}
var menu_child0 = function() {
childDiv_tmp1_position += 3 + (tmp1_speed * 1.7);
childDiv.style.top = childDiv_tmp1_position + 'px';
rotate(childDiv, .2 + (tmp1_speed), 170);
tmp1_speed += (speed_modifier * .7);
if (childDiv_tmp1_position / client_height * 100 >= 80 && case2_flag < 0) {
case2_flag = frame;
}
if (childDiv_tmp1_position >= client_height) {
childDiv.style.visibility = 'hidden';
tmp1_speed = 0;
childDiv_tmp1_position = 0;
rotate_current_deg = 0;
//may be bloated >>
remove_process(menu_child0);
}
}
function remove_process(index) {
var index_tmp = process_array.indexOf(index);
if (index_tmp >= 0) {
process_array.splice(index_tmp, 1);
}
}
function rotate(rotate_div, rotate_passed_deg, rotate_passed_deg_stop) {
rotate_current_deg += rotate_passed_deg;
rotate_deg = rotate_current_deg < rotate_passed_deg_stop ? rotate_current_deg : rotate_passed_deg_stop;
rotate_div.style.webkitTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.mozTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.msTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.oTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.transform = 'rotate(' + rotate_deg + 'deg)';
if (rotate_current_deg >= rotate_passed_deg_stop) {
return true;
} else {
return rotate_current_deg;
}
}
//main loop for the animation
var mainloop = function() {
processes_logic();
initiate_all_processes();
frame++;
}
var loop_interval = setInterval(mainloop, mainloop_frame_time);
</script>
I am trying to animate my website falling apart but I am having a hard time articulation this into code. I thought of running the animation in a loop, creating events at specific frames and reusing some codes as functions. I have a rotate function which works to rotate several things.
THE PROBLEM:
The problem I am having is sliding my menu items one at a time to the right. I want one to slide a bit and the next to start sliding after. I wrote a function to slide an item and then in that function it adds another process to an array for the next menu item to be called and run the same function (with passed interval of who is calling). I do not know how many menu items there will be, thats why I am trying to make it dynamic.
I can get it so that the first mwnu item falls, the menu falls by rotating it (some times if there is an error in the code then it wont rotate, but when there are no errors it works better).
The issue is sliding each menu item.
my website is here: http://clearlove.ca/89-404-error
Can any one help me with why this isnt working, and if there is a better way to do what I am trying to do?

Doesn't work after writing it inside a class

I'm practicing some Javascript and I'm trying to figure out how to move a div from the left of the screen to the right. I did this in a separate file to test it first and it works, however, if I create a class and put my functions and variables inside it stops working and Firebug doesnt give me back any error. Can anyone help me?
Here's the code I figured out:
function crear_div (){
this.pos_x = 10;
this.pos_y = 10;
this.x_min = 10;
this.x_max = 500;
this.y_min = 10;
this.y_max = 500;
this.incremento = 10;
this.estado = 0;
this.id_elemento = "pelota";
this.f0 = f0;
this.f2 = f2;
}
function f0(){
this.pos_x = this.pos_x + this.incremento;
document.getElementById(this.id_elemento).style.left = this.pos_x + "px";
if (this.pos_x >= this.x_max){
this.estado = 1;
}
}
function f2(){
this.pos_x = this.pos_x - this.incremento;
document.getElementById(id_elemento).style.left = this.pos_x + "px";
if (this.pos_x <= this.x_min){
this.estado = 0;
}
}
function desplazar(){
switch(this.estado){
case 0:
this.f0();
break;
case 1:
this.f2();
break;
}
}
window.setInterval(function () {this.desplazar();}, 250);
You need to create an object of the class, and use it in the interval function:
var the_div = new crear_div();
window.setInterval(function() {
the_div.desplazar();
}, 250);

Categories

Resources