Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript: alerting user when all objects are caught in game

I made this small game to prep for my web programming exam but it's not quite working out and I'm fairly stuck.

I basically have an object Star which has a property isCaught that is standard false and turns to true when it collides with another object (witch).

I want my program to always loop through my array of Star objects and check if every element inside the array has been caught (isCaught = true), if so it should alert the user. However, it only returns false (and only 3 times).

I also tried to delete the objects from the array if they weren't caught and reached the end of the screen, but then I would get an indexation problem (that's the commented out part).

I'm probably doing something really stupid really wrong but I can't find it. Here's the code:

function Star(x, y, vy){
    this.x = x;
    this.y = y;
    this.vy = vy;
    this.isCaught = false;

    var starImg = new Image();
    starImg.src = 'images/star.png';

    $(starImg).load(function(){ 
    });

    this.drawStar = function(){
        ctx.drawImage(starImg,this.x,this.y,20,20); 
        //context.beginPath();
    }
}

function Witch(){
    this.x = 10;
    this.y = 300;

    var witchImg = new Image();
    witchImg.src = 'images/witch2.png';

    $(witchImg).load(function(){
    });

    this.drawWitch = function(){
        ctx.drawImage(witchImg,this.x,this.y,50,50);
    }
}


var canvas;
var ctx;

var speed = 33;
var starsAmount = 6;

var stars = [];
var witch = new Witch();

$(function(){  
    canvas = document.getElementById("gameCanvas");
    ctx = canvas.getContext("2d");

    $("body").mousemove(function(arg){
        //witch.y = arg.pageY;
        witch.x = arg.pageX;
    });

    for(var i=0;i<starsAmount;i++){
        stars.push(new Star(Math.floor(Math.random()*canvas.width)+50,10,2));
    }

    Animate();
});

function Animate(){
    ctx.clearRect(0,0,canvas.width,canvas.height);

    var countCaught = 0;

    for (var i = 0; i < stars.length; i++){
        stars[i].y += stars[i].vy;

        stars[i].drawStar();
        witch.drawWitch();
    }

    //collision detection
    for(var i=0; i<stars.length; i++){
        var distanceX = (stars[i].x+10)-(witch.x+25);
        var distanceY = (stars[i].y+10)-(witch.y+25);

        var distance = Math.sqrt((distanceX*distanceX)+(distanceY*distanceY));

        if(distance < 35){
            stars[i].x = Math.floor(Math.random()*canvas.width);
            stars[i].y = -20;
            stars[i].vy += 1;

            stars[i].isCaught = true;
        }

        var allCaught = checkCaught();
        console.log(allCaught);

        if(allCaught == true){
            ("You've lost!");
        }

        //if the stars reach the end of the screen and they are not caught, delete them from the array
        /*
        if((stars[i].y+10) == canvas.height && stars[i].isCaught == false){
            console.log(stars[i].y);
            stars.splice(i,1);
            console.log("say something im giving up on you" + i);
        }
        console.log("array length " + stars.length);
        */
    }

    setTimeout(Animate,speed);
}

function checkCaught(){
    var allCaught = true;

    for(var i=0; i<stars.length; i++){
        if(stars[i].isCaught == false){
            allCaught = false;
        }
        else{
            allCaught = true;
        }
    }
    return allCaught;
}

Thanks in advance!

like image 241
Axelle Avatar asked Feb 16 '26 19:02

Axelle


2 Answers

The ES5 way to write your allCaught function is using Array.prototype.every:

function checkCaught() {
    return stars.every(function(star) {
        return star.isCaught;
    });
}

The ES6 way would be:

var checkCaught = () => stars.every(star => star.isCaught);
like image 136
Alnitak Avatar answered Feb 18 '26 07:02

Alnitak


You could simplify this function like this:

function checkCaught(){
    var allCaught = true;

    for(var i=0; i<stars.length; i++){
        if(stars[i].isCaught == false){
            allCaught = false;
            break;
        }
    }
    return allCaught;
}

It looks ok, but you seem to have an object array, which might not be easily iteratable. Have you tried to iterate with a foreach loop?

for (key in stars) {
    if (stars[key].isCaught === false) {
        allCaught = false;
        break;
    }
}

If you really want some help please add a plunker or https://jsfiddle.net/ or whatever.

I did try to make a fiddle for you... but it seems to work out for me there, so I don't really know, what your problem is... https://jsfiddle.net/zh0ybdho/

like image 39
Nils Avatar answered Feb 18 '26 07:02

Nils



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!