0
\$\begingroup\$

Hi There this is my first Post on gamedev, and i hope everyone understand what i want :)

First of all my Code is an very Personal Version from one Github Isometric Map.

I Tryd now 2 Days to Add the animation loop inside my Code. But if i add them on Draw() is Lags, Or The Place-Building Mouseover is not working. Outside of Draw() it works but only if i mouseover over the Iso Map.

An Overview of the Map

[original]https://github.com/demorose/isometric-map

    var canvas  = document.getElementById('canBG');
    var context = canvas.getContext('2d');
    context.oncontextmenu = function () {return false; };   
    
    var c = document.getElementById('can');
    var ctx = c.getContext('2d');
    c.oncontextmenu = function () {return false; };

    var buildset = false;
    var lastSelected = new Tile();
    var tileSet = new Image();
    var tileWidth = 100;
    var tileHeight = 70;
    var visualHeight = 50;

    var tilesetOffset = 1;
    tileSet.src = 'images/baumap/tileset.png';

    var buildings = new Image();
    var buildingHeight = 150;
    buildings.src = 'images/baumap/building.png';

    // test
    var buildings1 = new Image();
    buildings1.src = 'images/baumap/10.png';

    var offsetX = window.innerWidth/2;
    var offsetY = window.innerHeight/6;
    var map = [];
    var showgrid = 0;

    window.addEventListener('resize', resizeCanvas, false);



    function Tile() {
        this.x=0;
        this.y=0;
        this.z=0;
        this.type='';
        this.selected = false;
        this.isConstructible = true;
        this.building = 0;
        this.level = 0;
        this.buildset = false;
        

        if (typeof(Tile.initialized) == 'undefined') {
            Tile.prototype.toScreen = function () {
                var screen = [];
                screen.x = offsetX - (this.y * tileWidth / 2) + (this.x * tileWidth / 2) - (tileWidth / 2);
                screen.y = offsetY + (this.y * visualHeight / 2) + (this.x * visualHeight / 2);
                return screen;
            };
            Tile.prototype.print = function (context) {
                var j;
                if(showgrid !== 0){
                        context.drawImage(tileSet, tileWidth * 0, 0 * tileHeight, tileWidth, tileHeight, this.toScreen().x, ((this.toScreen().y) - this.z), tileWidth, tileHeight);
                }
               if (this.selected) {

                        
                    if (!this.isConstructible){
                        if(this.buildset == true){
                            context.drawImage(buildings, tileWidth * this.building, 1 * buildingHeight, tileWidth, buildingHeight, this.toScreen().x, this.toScreen().y - (buildingHeight - visualHeight) - this.z, tileWidth, buildingHeight);
                        }
                        context.drawImage(tileSet, tileWidth * 1, 0 * tileHeight, tileWidth, tileHeight, this.toScreen().x, ((this.toScreen().y) - this.z), tileWidth, tileHeight);
                    } else {
                        if(this.buildset == true){
                            context.drawImage(buildings, tileWidth * this.building, 1 * buildingHeight, tileWidth, buildingHeight, this.toScreen().x, this.toScreen().y - (buildingHeight - visualHeight) - this.z, tileWidth, buildingHeight);
                        }else{
                            if(showgrid == 1){
                                context.drawImage(tileSet, tileWidth * 3, 0 * tileHeight, tileWidth, tileHeight, this.toScreen().x, ((this.toScreen().y) - this.z), tileWidth, tileHeight);
                            }else{
                                context.drawImage(tileSet, tileWidth * 0, 0 * tileHeight, tileWidth, tileHeight, this.toScreen().x, ((this.toScreen().y) - this.z), tileWidth, tileHeight);
                            }
                        }
                    
                    }
                    j = 1;
                }
                else {
                    j = 0;
                }

                if (this.building !== 0 && this.building !== 2 && this.building < 2) {

                    context.drawImage(buildings, tileWidth * 1, j * buildingHeight, tileWidth, buildingHeight, this.toScreen().x, this.toScreen().y - (buildingHeight - visualHeight) - this.z, tileWidth, buildingHeight);
        
                }else if(this.building == 2){
                    context.drawImage(buildings, tileWidth * 2, j * buildingHeight, tileWidth, buildingHeight, this.toScreen().x, this.toScreen().y - (buildingHeight - visualHeight) - this.z, tileWidth, buildingHeight);
                
                }else if(this.building > 2){
                    context.drawImage(buildings, tileWidth * this.building, j * buildingHeight, tileWidth, buildingHeight, this.toScreen().x, this.toScreen().y - (buildingHeight - visualHeight) - this.z, tileWidth, buildingHeight);

                }

            };
        }
    }

var lastset = 0;
    c.addEventListener('mousemove', function (evt) {
        var mousepos = getMousePos(c, evt);
        if (typeof(map[mousepos.x]) !== 'undefined') {
            if (typeof(map[mousepos.x][mousepos.y]) !== 'undefined') {
                if (map[mousepos.x][mousepos.y].selected !== true) {
                    lastSelected.selected = false;
                    map[mousepos.x][mousepos.y].selected = true;
                    
                    if(buildset == true){
                        map[mousepos.x][mousepos.y].buildset = true;
                        buildset = true;
                        if(map[mousepos.x][mousepos.y].building == 0){
                            map[mousepos.x][mousepos.y].building = building1;
                            lastset = map[mousepos.x][mousepos.y];
                        }
                        
                    }else{
                        map[mousepos.x][mousepos.y].buildset = false;
                        buildset = false;
                        lastset = 0;

                        
                    }
                    lastSelected = map[mousepos.x][mousepos.y];
                    draw();
                    if(lastset !== 0){
                    map[lastset.x][lastset.y].building = 0;
                    }
                }
            } else {
                if (lastSelected.selected) {
                    lastSelected.selected = false;
                    draw();
                    
                }
            }

        } else {
            if (lastSelected.selected) {
                lastSelected.selected = false;
                draw();
            }
        }
        
        
    });

    c.addEventListener('mousedown', function (evt) {
        switch (evt.button) {
        case 0:
            leftClick(evt);
            break;
        case 1:
            middleClick(evt);
            break;
        case 2:
            rightClick(evt);
            break;
        }
    });

    function draw() {
        c.width = window.innerWidth;
        c.height = window.innerHeight;
        var rect = c.getBoundingClientRect();
        
        var topLeft = (((toMapCoord(c, 0-rect.left-offsetX, 0-rect.top-offsetY).x) >= 0) ? toMapCoord(c, 0-rect.left-offsetX, 0-rect.top-offsetY).x: 0);
        var bottomRight = (((toMapCoord(c, c.width-rect.left-offsetX, c.height-rect.top-offsetY).x) >= 0) ? toMapCoord(c, c.width-rect.left-offsetX, c.height-rect.top-offsetY).x: 0);

        var topRight = (((toMapCoord(c, c.width-rect.left-offsetX, -rect.top-offsetY).y) >= 0) ? toMapCoord(c, c.width-rect.left-offsetX, -rect.top-offsetY).y: 0);
        var bottomLeft = (((toMapCoord(c, -rect.left-offsetX, c.height-rect.top-offsetY).y) >= 0) ? toMapCoord(c, -rect.left-offsetX, c.height-rect.top-offsetY).y: 0);

        for(var i=topLeft; i< bottomRight; i++){
            if(typeof(map[i]) != 'undefined'){
                for(var j=topRight; j<bottomLeft; j++){
                    if(typeof(map[i][j]) != 'undefined'){
                        map[i][j].print(ctx);
                        
                    }
                }
            }
        }
        
        
    }
    requestAnimationFrame(draw);
    function toscreen() {
        var screen = [];
        screen.x = offsetX - (tileWidth / 2) + (tileWidth / 2) - (tileWidth / 2);
        screen.y = offsetY + (visualHeight / 2) + ( visualHeight / 2);
        return screen;
    };
    var background = new Image();
    background.src = 'images/baumap/bg.png';
    
    function drawBG() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        var rect = canvas.getBoundingClientRect();
        context.drawImage(background, toscreen().x - 800, toscreen().y - 150,);
    }

    function resizeCanvas() {
        draw();
        drawBG();
    }

    function toMapCoord(canvas, x, y){
        var i = Math.floor((y + x/2)/visualHeight);
        var j = Math.floor((y - x/2)/visualHeight);

        return{
            x:i,
            y:j
        };
    }

    function getMousePos(canvas, e) {
        var rect = canvas.getBoundingClientRect();
        var x = e.clientX - rect.left-offsetX;
        var y = e.clientY-rect.top-offsetY;

        return toMapCoord(canvas, x, y);
    }
var building1 = 0;
function getbinfo (id){
            $.ajax({
            method: "POST",
            url: "../ajax.php?a=binfo",
            data: { building: id }
            }).done(function( data ) {
                $('.gebinfo').remove();
                $('.geb2info').remove();
                if(data.allowedtobuild === true){
                    var button = '<button class="bau">Bauen</button>';
                }else{
                    var button = 'Nicht genug Resourcen';
                }
                
                $('.start').append('<div class="gebinfo"><h3>'+data.name+'</h3><p>'+data.beschreibung+'</p><br><br><span><b>Kosten:</b><br>Eisen: '+data.keisen+'<br>Kristall: '+data.kkristall+'<br>Trinium: '+data.ktrinium+'<br><br>Bauzeit: '+data.bauzeit+'</span><br>'+button+'<button class="schliessen">Schließen</button></div>');
$(".gebinfo").find(".bau").click(function () {
        building1 = id;buildset = true;
        return false;
});
$(".gebinfo").find(".schliessen").click(function () {
$('.gebinfo').remove();
building1 = 0;buildset  = false;
        return false;
});
}); 
    
}

$('#bi_2').on('click',function(){ getbinfo (2); });
$('#bi_3').on('click',function(){ getbinfo (3); });

function getbinfo2 (id, x, y){
            $.ajax({
            method: "POST",
            url: "../ajax.php?a=binfo",
            data: { building: id, x: x, y: y }
            }).done(function( data ) {
                $('.geb2info').remove();
                $('.gebinfo').remove();
                
                if(data.allowedtobuild === true){
                    var button = '<button class="ausbau">Ausbau auf Level 2</button>';
                }else{
                    var button = 'Nicht genug Resourcen';
                }
                
                $('.start').append('\
                    <div class="geb2info">\
                        <div style="float:right;top:0px;font-weight:bold;">Level 1</div>\
                        <h3>'+data.name+'</h3>\
                        <p>'+data.beschreibung+'</p>\
                        <br><br><span><b>Kosten:</b><br>Eisen: '+data.keisen+'<br>Kristall: '+data.kkristall+'<br>Trinium: '+data.ktrinium+'<br><br>Bauzeit: '+data.bauzeit+'</span><br>'+button+'<button class="schliessen">Schließen</button></div>');

$(".geb2info").find(".schliessen").click(function () {
$('.geb2info').remove();
        return false;
});
}); 
    
}

    function leftClick(evt) {
        var mousepos = getMousePos(c,evt);
        if(typeof(map[mousepos.x]) !== 'undefined'){
            if(typeof(map[mousepos.x][mousepos.y]) !== 'undefined'){
                if(map[mousepos.x][mousepos.y].isConstructible){
                    if(building1 !== 0){
                        map[mousepos.x][mousepos.y].isConstructible = false;
                        map[mousepos.x][mousepos.y].building = building1;
                        
                        $.ajax({
                            method: "POST",
                            url: "../ajax.php?a=baue",
                            data: { x: mousepos.x, y: mousepos.y, building: building1 }
                        });                 
                        
                        draw();
                    building1 = 0;
                    map[mousepos.x][mousepos.y].buildset = false;
                    buildset = false;
                    }
                } else {
                    getbinfo2(map[mousepos.x][mousepos.y].building, mousepos.x, mousepos.y);
                    console.log(map[mousepos.x][mousepos.y]);
                    map[mousepos.x][mousepos.y].buildset = false;
                    buildset = false;

                    
                }
                
            }
        }
        return false;
    }

    function rightClick(evt) {
        var mousepos = getMousePos(c,evt);
        if(typeof(map[mousepos.x]) !== 'undefined'){
            if(typeof(map[mousepos.x][mousepos.y]) !== 'undefined'){
                if(map[mousepos.x][mousepos.y].building !== 0) {
                    map[mousepos.x][mousepos.y].isConstructible = true;
                    map[mousepos.x][mousepos.y].building = 0;
                        $.ajax({
                            method: "POST",
                            url: "../ajax.php?a=bauweg",
                            data: { x: mousepos.x, y: mousepos.y }
                        });

                }
                    building1 = 0;
                    map[mousepos.x][mousepos.y].buildset = false;
                    buildset = false;
                draw();
            }
        }
        return false;
    }

    var startX;
    var startY;
    function middleClick(evt) {
        var elementToChange = document.getElementsByTagName("body")[0];
        elementToChange.style.cursor = "url('images/baumap/deplace.png'), auto";
        startX = evt.clientX;
        startY = evt.clientY;
        c.addEventListener('mousemove', dragMap, false);
        c.addEventListener('mouseup', function(){
        c.removeEventListener('mousemove', dragMap, false);
        var elementToChange = document.getElementsByTagName("body")[0];
        elementToChange.style.cursor = "url('images/baumap/cursor.png'), auto";
        });
    }

    function dragMap(evt){
        if(evt.offsetX){
            offsetX += evt.clientX-startX;
            offsetY += evt.clientY-startY;
            startX = evt.clientX;
            startY = evt.clientY;
        }
        draw();
        drawBG();
    }

      $('#gridcheckbox').change(function(){
          if(showgrid == 1){
              showgrid = 0;
                      draw();
        drawBG();
          }else{
            showgrid = 1;
                    draw();
        drawBG();
          }
            //console.log(showgrid);

        });

    for (var a = 0; a <= 15; a++) {

        if (map[a] === void 0){
            map[a] = [];
        }
        for (var b=0;b<=15;b++){
            var tile = new Tile();
            tile.type = 3;
            //tile.type = Math.floor((Math.random()*4)+1);  
            <?php
                $buildings = new Buildings;
    
                echo "var test = ".json_encode($buildings->get_buildings($user->get_lastplanet())).";";
            ?>
            $.each(test, function(i, v) {
            if (v.x == a && v.y == b) {
                tile.building = v.building;
                tile.level = v.level;
                tile.isConstructible = false;
                return;
            }
            });
            if(tile.type === 1){
                tile.isConstructible = false;
            }
            tile.x = a;
            tile.y = b;
            map[a][b] = tile;
        }
    }

        tileSet.onload = resizeCanvas();
        
        background.onload = function() {
    drawBG();
    draw();
};
drawBG();

I tryd to add few animate Functions and call them from the Draw function and from outside. I think my Problem is with my Loops for the Drag Map and the Tiles. But im not sure. :)

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

Every call of requestAnimationFrame(draw); results in the draw function being called exactly once, not contiguous on every following frame.

When you want a contiguous drawing loop, then the draw-function needs to reschedule itself by calling requestAnimationFrame for itself:

function draw() {
    /*               *
     *  drawing code * 
     *               */

    requestAnimationFrame(draw);
}

requestAnimationFrame(draw);

You can then remove all other calls to the draw function, because the canvas gets permanently repainted while the browser tab is visible. You in fact must get rid of them, because otherwise you are going to create multiple parallel drawing loops which will tank your framerate. If you still think you have situations where you need to call the draw-function once without creating a loop (I doubt it, though), then you can structure your drawing-code like this:

function draw() {
    /*               *
     *  drawing code * 
     *               */
}

function drawLoop() {
    draw()
    requestAnimationFrame(drawLoop);
}

requestAnimationFrame(drawLoop);

That means you have a function drawLoop which reschedules itself while the original draw function can still be called individually.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks thats it! after i removed all other draw() calls ;) \$\endgroup\$
    – Tobias B.
    Jan 13, 2023 at 9:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .