Ivar Ivar - 22 days ago 6
HTML Question

How to prevent randomly generated images from overlapping using Javascript

I'm trying to spawn randomly generated targets on the screen using a function to copy an invisible image of the target to be spawned at a random place within the screen using window object properties.
For this to happen I think the image have to have position set to absolute, but then several images may be spawned in a way that they will overlap, how can I prevent this from happening?

The div element where I copy my first image and also store the other copies.

<div id="targetsDiv">
<img src="target2.png" alt="target_shot" class="target" />
</div>


Inside the script:

var x_pixels = window.innerWidth - 180;
var y_pixels = window.innerHeight - 180;
var x_midScreen = window.innerWidth / 2;
var y_midScreen = window.innerHeight / 2;

var xRandom = Math.floor(Math.random()*x_pixels) +1;
var yRandom = Math.floor(Math.random()*y_pixels) +1;

var targetCollection = document.getElementById("targetsDiv");
var targetCopy = targetCollection.innerHTML
var targetList = document.getElementsByClassName("target");
targetList[0].style.display = "none";
var targetNr = 1;

var numberOfSpawns = 3;

function spawnTargets () {
while (targetNr <= numberOfSpawns) {
if ((xRandom < x_midScreen - 126 || xRandom > x_midScreen + 26) || (yRandom < y_midScreen - 126 || yRandom > y_midScreen + 26)) {
targetCollection.innerHTML += targetCopy;
targetList[targetNr].style.left = xRandom + "px";
targetList[targetNr].style.top = yRandom + "px";
targetNr++;
}
xRandom = Math.floor(Math.random()*x_pixels) +1;
yRandom = Math.floor(Math.random()*y_pixels) +1;
}
}


PS: I appreciate all help, tips and tweaks that you guys provide:) Thanks for helping

Answer

The area you want to exclude in the centre of the screen is rather large, and on my little laptop, there isn't even any room to still show the random positioned images.

But anyway, this piece of code should do the job -- I added some infinite loop protection which on my PC was a life-saver:

HTML (added style attribute)

<div id="targetsDiv">
    <img src="target2.png" alt="target_shot" class="target" 
        style="visibility:hidden"/>
</div>

JavaScript:

window.addEventListener('load', function () {
    var targetCollection = document.getElementById("targetsDiv");
    var template = document.getElementsByClassName("target")[0];

    var targetWidth = template.offsetWidth;
    var targetHeight = template.offsetHeight;
    var x_pixels = window.innerWidth - targetWidth;
    var y_pixels = window.innerHeight - targetHeight;
    var x_midScreen = window.innerWidth / 2;
    var y_midScreen = window.innerHeight / 2;
    function spawnTargets (numberOfSpawns) {
        var targets = [];
        var count = 0; // infinite recursion protection
        for (var i = 0; i < numberOfSpawns; i++) {
            do {
                do {
                    var x = Math.floor(Math.random()*x_pixels);
                    var y = Math.floor(Math.random()*y_pixels);
                    if (count++ > 200) {
                        console.log('give up');
                        return;
                    }
                } while ((x >= x_midScreen-450 && x <= x_midScreen+300) && (y >= y_midScreen-350 || y <= y_midScreen+200));

                for (var j = 0; j < i; j++) {
                    if (x >= targets[j].x - targetWidth && x <= targets[j].x + targetWidth && 
                        y >= targets[j].y - targetHeight && y <= targets[j].y + targetHeight) break; // not ok!
                }
            } while (j < i);
            targets.push({x, y});

            img = document.createElement('img');
            img.src = template.src;
            img.setAttribute('width', targetWidth + 'px');
            img.setAttribute('height', targetHeight + 'px');
            img.className = template.className;
            targetCollection.appendChild(img);
            img.style.left = x + "px";
            img.style.top = y + "px";
        }
    }
    spawnTargets(3);
});
Comments