Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

JavaScript Can't get past size five...

kalma

Coder
First of all, this is just what I started for fun and when I started I knew nothing about html, css, javascript, mysql, or php. So that's where you should expect my level of code and understanding to be so treat me accordingly. I have an issue with a game I started writing because I was at a long winded family function with nothing but my phone and access to my server.

I have a grid of hexes on which the game is played. The ID of the hex is a tile value (0-254), the value of the name tag is the coordinates in the hex grid expressed as X and Y coordinates, and value tag holds the coordinates of the tile in X, Y, and Z. It's an uneven map with a 12 hex row followed by an 11 hex row. I'm considering changing this to equal 12 tile rows but I just haven't yet. The game is my attempt at recreating Strategic Commander for the Palm OS but on a hex grid. So a game in the vein of Stellaris.

My problem comes into play with selecting hexes at radius N to show how far away from any given planet ships can travel. I have it working to a point but it isn't good enough so I'm here asking for help in not only fixing it but understanding it. My highlight functions follow:

Code:
var spd=5;
var spacetiles = document.getElementsByClassName("space");
var lrow=getrowlength(spacetiles);
var srow=lrow-1;
var totaltiles=spacetiles.length;
var i=0;

var spacecolor="rgba(0, 0, 0, 0)";
var axiscolor="rgba(0, 0, 0, 0)";
var spacehole="rgba(85, 136, 238, 0.50)";
var axishole="rgba(85, 136, 238, 0.50)";
var highlightcolor="rgba(85,136,238,0.50)";

function getrowlength(spacetiles) {
    var i=0;
    var tilecount=0;
    while (parseInt(spacetiles[i].getAttribute("name").split(",")[1])<1) {
        tilecount=tilecount+1;
        i=i+1;
    }
    return tilecount;
}

for (i = 0; i < totaltiles; i++) {
    spacetiles[i].addEventListener('click', function() {
        highlight(this, spd);
    }, false);
}

function clearselect() {
    for (i = 0; i < this.totaltiles; i++) {
        if (this.spacetiles[i].classList.contains("space")) {
            this.spacetiles[i].style.backgroundColor=spacecolor;
        }
        if (this.spacetiles[i].classList.contains("axis")) {
            this.spacetiles[i].style.backgroundColor=axiscolor;
        }
    }
}

function highlight(loc, spd) {
var cen=spd-3;
var i=0;
var cell = loc.getAttribute("id");
var X=parseInt(dgebi(cell).getAttribute("name").split(",")[0]);
var Y=parseInt(dgebi(cell).getAttribute("name").split(",")[1]);

var yaa = parseInt(cell) - (lrow * spd);
var yab = parseInt(cell) - (srow * spd);
var l = parseInt(cell) - spd;

var r = parseInt(cell) + spd;
var yba = parseInt(cell) + (srow * spd);
var ybb = parseInt(cell) + (lrow * spd);
var count=spd-1;

clearselect();

    for (i=l; i<=r; i++) {
        if (i>=0) {
            if (i<totaltiles) {
                var currentX=parseInt(dgebi(i).getAttribute("name").split(",")[0]);
                    var currentY=parseInt(dgebi(i).getAttribute("name").split(",")[1]);
                    if (l>-1) {
                        var lX=parseInt(dgebi(l).getAttribute("name").split(",")[0]);
                    }
                    if (r<totaltiles) {
                        var rX=parseInt(dgebi(r).getAttribute("name").split(",")[0]);
                    }
                    if (X>=5) {
                        if (currentX<lX) {
                            //skip
                        } else {
                            setStyle(i).backgroundColor=highlightcolor;
                        }
                    }
                    if (X<5) {
                        if (currentX>rX) {
                            //skip
                        } else {
                            setStyle(i).backgroundColor=highlightcolor;
                        }
                    }
            } else {
                //skip
            }
        }
    }
    while (count>=0) {
        for (i=yaa+(count)*srow; i<=yab+(count)*lrow; i++) {
            if (i>=0) {
                if (i<totaltiles) {
                    var currentX=parseInt(dgebi(i).getAttribute("name").split(",")[0]);
                    var currentY=parseInt(dgebi(i).getAttribute("name").split(",")[1]);
                    if (l>-1) {
                        var lX=parseInt(dgebi(l).getAttribute("name").split(",")[0]);
                    }
                    if (r<totaltiles) {
                        var rX=parseInt(dgebi(r).getAttribute("name").split(",")[0]);
                    }
                    if (X>=5) {
                        if (currentX<lX) {
                            //skip
                        } else {
                            setStyle(i).backgroundColor=highlightcolor;
                        }
                    }
                    if (X<5) {
                        if (currentX>rX) {
                            //skip
                        } else {
                            setStyle(i).backgroundColor=highlightcolor;
                        }
                    }
                } else {
                    //skip
                }
            }
        }
        for (i=yba-(count)*lrow; i<=ybb-(count)*srow; i++) {
            if (i>=0) {
                if (i<totaltiles) {
                    var currentX=parseInt(dgebi(i).getAttribute("name").split(",")[0]);
                    var currentY=parseInt(dgebi(i).getAttribute("name").split(",")[1]);
                    if (l>-1) {
                        var lX=parseInt(dgebi(l).getAttribute("name").split(",")[0]);
                    }
                    if (r<totaltiles) {
                        var rX=parseInt(dgebi(r).getAttribute("name").split(",")[0]);
                    }
                    if (X>=5) {
                        if (currentX<lX) {
                            //skip
                        } else {
                            setStyle(i).backgroundColor=highlightcolor;
                        }
                    }
                    if (X<5) {
                        if (currentX>rX) {
                            //skip
                        } else {
                            setStyle(i).backgroundColor=highlightcolor;
                        }
                    }
                } else {
                    //skip
                }
            }
        }
        count--;
    }
}

Right now, I create the highlight one line at a time and move down to the next. I first draw the top, or l (which was originally supposed to be left because that's how I get the bounds) and then I draw the bottom (or r because of the previous reason). Because I use single numbers in the cells ID, the highlight wraps around the map like it's a tube so I look for when the line of hexes being drawn moves either up or down and I skip drawing the unneeded tiles. This works all the way up until size 5. After that, the skipping of a unneeded hexes interferes with the drawing of the needed ones and so the highlight no longer looks nice and round. This would be acceptable but for the fact that as the size increases, the amount of weird also increases.

The rush when I got this working was just as incredible as the disappointment of realizing that it's still not good enough.

Look, I honestly know already that this project is a little too ambitious for me to start off with but I also know that I could finish it if I could work out this issue. I also know my code is bad. Like I said, I just started playing with it. The whole project lives online HERE (if this link is against the rules, I apologize). Keep in mind that this is written on and with the screen of my iPhone 6s plus in mind. Also, on PC to see the map where I'm talking about, you have to find the button in the dom and make it not hidden. It shows up on my phone but not on the PC. I don't know why.

Finally, I'm willing to bet my left shoe that there is a better way to do this. I just don't know what that is. I feel slightly stupid for not being able to figure it out. I found a site with everything about hex grids anyone should want to know but the jargon and the sheer amount of material there makes it hard to understand. I'm actually happy to have gotten this far with just the internet. If my code is so bad that it's hopeless for me to continue, that's fine and I need to know that but just be gentle about it, okay?

Any help in getting the highlight to function past size 5 would be most appreciated. If I'm asking too much or if this isn't the right place to ask for help like this, let me know. I asked on stackoverflow and it didn't go very well so I deleted it. I still don't get the underlying purpose of that site: a help forum where one gets blasted for asking for help. Still, I'm super autistic (really, not a joke) so if I've done something inappropriate please understand that I don't mean it, or realize it.

Thanks in advance for the help if you offer it. If not, thanks for reading it at least, I guess.

The Kalma.
(I know they are a bad group in trek but it still sounds cool).

PS: I got some of the code off the internet. Any use you might want to make of it is fine by me. Again, this is just a project for the fun of it. If you make something cool, I'd love to see it.
 
Last edited:
Because your posted code does nothing I went to your website and just hit the start button. It hung up on the Generating Galaxy page. It never gets off the ground.
I did mention this in my op... But I'll re-post. Oh the phone, it properly shows the button to continue to the map but on the pc browser, you have to go into inspect and make it not hidden. I don't know why this happens but it wasn't a big enough deal for me to fix it. I will now. EDIT: I fixed it. For now. I really want to know why one showed and the other didn't but that problem isn't pressing.

Javascript needs html to show itself working. HTML need CSS. Please post all of it.
OH! I read a rule that said not to post anything other than relevant code. I'll post more code, sure.

The previous code was map.js

map.css
CSS:
#main {
    border:0px solid steelblue;
    //background-color:rgb(5,5,5);
    color:#afafaf;
    position: fixed;
    top:0;
    left:50%;
    transform:translateX(-46%);
    width:100%;
    height:100%;
    overflow:hidden;
    border-bottom:none;
    display:none;
}
#container {
    --s: 30px;
    --m: 0.5px;
    --f: calc(1.732 * var(--s) + 8 * var(--m)  - 2px);

    position: relative;
   
    margin-left:auto;
    margin-right:auto;
   
    width:100%;
    height:100%;
    border:0px solid cyan;
    font-size: 0;
    z-index:300;
    overflow:hidden;
    padding:1%;
}
#container::before {
    content: "";
    width: calc(var(--s)/2 + var(--m));
    float: left;
    height: 100%;
    shape-outside: repeating-linear-gradient(
#0000 0 calc(var(--f) - 10px), #000  0 var(--f));
}
.space {
    /* left:-6%; */
    transform:translateX(6%);
    text-align: center;
    line-height:20px;
    font-size:xx-small;
    width: var(--s);
    margin: var(--m);
    height: calc(var(--s)*1.1547);
    display: inline-block;
    clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%);
    background-color: rgba(85, 85, 85, 0.5);
    margin-bottom: calc(var(--m) - var(--s)*0.2885);
    z-index:300;
}
.axis {
    background-color:rgba(80, 80, 80, 0.5);
}

map.php
PHP:
<div id="main" class="seldiv">
    <div id="container">
        <?php
            $v=0;
            $s=0;

            for ($y=0; $y<=22; $y++) {
                for ($x=0; $x<=11; $x++) {
                    $dy=$y-11;
                    $dx=$x-$s;
                    $dz=-$dx-$dy;
                    /* if ($x==0 && $y==0) {
                        echo "<div id='$v' name='$x,$y' value='$dx,$dy,$dz' class='space axis play'></div>\n\r";
                        $v++;
                    } else { */
                        if ($y&1==1 && $x==11) {
                            //skip
                            $s++;
                        } else {
                            if ($dx==0 || $dy==0 || $dz==0) {
                                echo "<div id='$v' name='$x,$y' value='$dx,$dy,$dz' class='space axis'>$x,$y</div>\n";
                                $v++;
                            } else {
                                echo "<div id='$v' name='$x,$y' value='$dx,$dy,$dz' class='space'>$x,$y</div>\n";
                                $v++;
                            }
                        /* } */
                    }  
                }
                echo "\n<br />\n\n";
            }
        ?>
    </div>
</div>

I'm happy to post all of it if it gets help.

I do very much appreciate you're looking at it. I'd really like the game to be good.

Thanks.
 
Last edited:
I've edited the highlight function. Now, I can make a cross at X radius but I have yet to figure it how to fill it in. I'm still working on it. My new code follows:


JavaScript:
function highlight(tile,size) {
    clearselect();
   
    var x=parseInt(tile.getAttribute("name").split(",")[0]);
    var y=parseInt(tile.getAttribute("name").split(",")[1]);
    var l=x-size;
    var r=x+size;
    var t=y-size;
    var b=y+size;

    for (i=l;i<=r;i++) {
        if (dgebn(i+","+y)!=null) {
            dgebn(i+","+y).style.backgroundColor=highlightcolor;
        }
    }
    for (i=t;i<=b;i++) {
        if (dgebn(x+","+i)!=null) {
            dgebn(x+","+i).style.backgroundColor=highlightcolor;
        }
    }
}

Any help filling it in now would be most appreciated. There has to be a better way but I'm not smart enough to find it right now.

Thanks for the input so far!
 
I've been working on this still and now I've managed to make a hex box. Any help with the maths to round the box off to a circle would be appreciated.

I guess, if nothing else, the box will work.

All my new code is is the previous code with the two for loops put together. The second loop should make it round but how to do that remains elusive. But I'll keep working.

JavaScript:
function highlight(tile,size) {
    clearselect();
    
    var x=parseInt(tile.getAttribute("name").split(",")[0]);
    var y=parseInt(tile.getAttribute("name").split(",")[1]);
    var l=x-size;
    var r=x+size;
    var t=y-size;
    var b=y+size;
    
    for (i=l;i<=r;i++) {
        for (j=t;j<=b;j++) {
            if (dgebn(i+","+j)!=null) {
                dgebn(i+","+j).style.backgroundColor=highlightcolor;
            }
        }
    }
}
 
I have finally gotten back to working on this issue. My latest code can be found at the following codepen: Hex Selection (Oval Issue)

It now makes more of an oval rather than the square it was previously. I figure it has to do with the offset nature of hex tiles. I admit that I do not currently understand how to fix the issue but I'm hoping to in time. Any help with this would be most appreciated.

My newest code follows:

Code:
var spacetiles = document.getElementsByClassName("space");
var totaltiles=spacetiles.length;
var size=3;
var i=0;

var lrow=getrowlength(spacetiles);
var srow=lrow-1;

var highlightcolor="rgba(85,136,238,0.50)";
var spacecolor="rgba(85, 85, 85, 0.5)";

var ycount=size-1;
var xcount=size-1;

for (i = 0; i < totaltiles; i++) {
    spacetiles[i].addEventListener('click', function() {
        highlight(this,size);
    }, false);
}

function getrowlength(spacetiles) {
    var tilecount=0;
    while (parseInt(spacetiles[i].getAttribute("name").split(",")[1])<1) {
        tilecount=tilecount+1;
        i=i+1;
    }
    return tilecount;
}

function clearselect() {
    for (i = 0; i < this.totaltiles; i++) {
        if (this.spacetiles[i].classList.contains("space")) {
            this.spacetiles[i].style.backgroundColor=spacecolor;
        }
    }
}

function highlight(tile,size) {
clearselect();

var centerX=parseInt(tile.getAttribute("name").split(",")[0]);
var centerY=parseInt(tile.getAttribute("name").split(",")[1]);

for (i=0;i<totaltiles;i++) {
    var currentTile=spacetiles[i];
    var x=parseInt(currentTile.getAttribute("name").split(",")[0]);
    var y=parseInt(currentTile.getAttribute("name").split(",")[1]);

        if (Math.max(Math.abs(x-centerX),Math.abs(y-centerY),Math.abs(x+y-centerX-centerY))<=size) {
            currentTile.style.backgroundColor=highlightcolor;
        }
    }
}

I look forward to any replies which may be forthcoming and thank you in advance.

Kalma
 
Back
Top Bottom