简体   繁体   English

HTML5 Canvas游戏错误

[英]HTML5 Canvas Game Bug

I have been designing a game for a University project, and I thought it would be fun to make a map editor first so I can eventually make the maps using visual aids rather than placing numbers in an array or SQL database. 我一直在为大学项目设计游戏,我认为首先制作地图编辑器会很有趣,这样我最终可以使用视觉辅助工具制作地图,而不必在数组或SQL数据库中放置数字。

But anyway, almost everything is working correctly. 但是无论如何,几乎所有东西都可以正常工作。 Almost everything... I can change tiles and place objects, the only problem is that when I want to clear the object by resetting the array to 0 according the position on the map, it bugs out and gives me a strange error. 几乎所有内容...我可以更改图块和放置对象,唯一的问题是,当我想通过根据地图上的位置将数组重置为0来清除对象时,它会出错并给我一个奇怪的错误。

Here is the link to my game: http://81.98.176.230/silverpolis/game/canvas_test4.php 这是我的游戏的链接:http: //81.98.176.230/silverpolis/game/canvas_test4.php

And here is the code if you would prefer to look at this instead, I don't know what part has gone wrong so I cannot pin point the function I need to show you: 这是代码,如果您想看一下它,我不知道哪一部分出了问题,所以我无法指出需要向您展示的功能:

<style>
body{
    background:#333;
    font-family:Verdana, Geneva, sans-serif;
    font-size:11px;
    color:#FFF;
}

#page-wrapper{
    margin:auto;
    width:1280px;
}

#interface-wrapper{
    background:#222;
    padding:5px;
}
</style>

<div id="page-wrapper">
    <canvas id="viewport" width="1280" height="760" style="background:#111;"></canvas>

    <div id="interface-wrapper">
        <span>Select Placement Type</span>
        <select id="selectPlacementType">
            <option value="0">Tile</option>
            <option value="1">Object</option>
        </select>
        <span>Select Tile Type</span>
        <select id="selectTileType">
            <option value="0">Grass</option>
            <option value="1">Water</option>
            <option value="2">Lava</option>
            <option value="3">Pavement</option>
        </select>
        <span>Select Object Type</span>
        <select id="selectObjType">
            <option value="0">Clear</option>
            <option value="1">Tree</option>
        </select>
        <input type="button" value="Reset Map" onClick="tileMapPopulate(); objMapPopulate();" />
    </div>
</div>

<script type="text/javascript">

    // Start the game
    window.onload = init;

    // Set cavas properties
    var c = document.getElementById("viewport");
    var ctx = c.getContext("2d");
    var cWidth = 1280;
    var cHeight = 760;

    // Setup sprite initialisation
    var spriteDir = "./lib/icons/own_icons/";
    var spritesLoaded = 0;
    var spriteLoadTimer;

    // Set map tile properties
    var tileWidth = 80;
    var tileHeight = 40;
    var tileMap = new Array();
    tileTypes = Array("grass.png", "water.png", "lava.png", "pavement.png");
    tileSprite = new Array();

    // Set object tile properties
    var objWidth = 80;
    var objHeight = 80;
    var objMap = new Array();
    objTypes = Array("tree.png");
    objSprite = new Array();

    // Set special tile properties
    spcTypes = Array("hover.png", "logo.png");
    spcSprite = new Array();

    // Populate a preset map size to the array
    var tileMapSizeX = 20;
    var tileMapSizeY = 20;

    function tileMapPopulate(){
        for(i = 0; i < tileMapSizeX; i++){
            tileMap[i] = new Array();

            for(j = 0; j < tileMapSizeY; j++){
                tileMap[i].push(0);
            }
        }
    }

    function objMapPopulate(){
        for(i = 0; i < tileMapSizeX; i++){
            objMap[i] = new Array();

            for(j = 0; j < tileMapSizeY; j++){
                objMap[i].push(0);
            }
        }
    }

    // Set map offsets for map positioning
    var mapOffsetX = 500;
    var mapOffsetY = 50;

    // Setup mouse properties
    var mouseX;
    var mouseY;

    // Loads all sprites from tileTypes[]
    function spriteLoad(){
        for(i = 0; i < tileTypes.length; i++){
            tileSprite[i] = new Image();
            tileSprite[i].src = spriteDir + tileTypes[i];
            tileSprite[i].onload = function(){
                spritesLoaded++;
            }
        }

        for(i = 0; i < objTypes.length; i++){
            objSprite[i] = new Image();
            objSprite[i].src = spriteDir + objTypes[i];
            objSprite[i].onload = function(){
                spritesLoaded++;
            }
        }

        for(i = 0; i < spcTypes.length; i++){
            spcSprite[i] = new Image();
            spcSprite[i].src = spriteDir + spcTypes[i];
            spcSprite[i].onload = function(){
                spritesLoaded++;
            }
        }
    }

    // Checks if all sprites have loaded
    function spriteLoadCheck(){
        if(spritesLoaded == tileTypes.length + objTypes.length + spcTypes.length){
            clearInterval(spriteLoadTimer);
            spriteLoadTimer = setInterval(gameUpdate, 50);
        }
    }

    // Draws the map tiles
    function drawMap(){
        for(i = 0; i < tileMap.length; i++){
            for(j = 0; j < tileMap[i].length; j++){
                var drawTile = tileMap[i][j];
                var drawObj = objMap[i][j];

                var tileXPos = (i - j) * tileHeight + mapOffsetX;
                var tileYPos = (i + j) * tileHeight / 2 + mapOffsetY;

                ctx.drawImage(tileSprite[drawTile], tileXPos, tileYPos);

                if(drawObj){
                    ctx.drawImage(objSprite[drawObj - 1], tileXPos, tileYPos - (objSprite[drawObj - 1].height / 2));
                }

                if(i == mouseX && j == mouseY){
                    ctx.drawImage(spcSprite[0], tileXPos, tileYPos);
                }
            }
        }
    }

    // Set map scrolling variables
    var mapOffsetXScroll;
    var mapOffsetYScroll;
    var mapOffsetScrollBorder = 20;
    var mapOffsetScrollSpeed = 10;

    // Check if the mouse has moved onto or off the edge of the canvas and draw indicators
    function mapScroller(){
        ctx.fillStyle = 'rgba(255, 0, 0, 0.2)';

        if(mapOffsetXScroll == 'left'){
            mapOffsetX += mapOffsetScrollSpeed;
            ctx.fillRect(mapOffsetScrollBorder, mapOffsetScrollBorder, mapOffsetScrollBorder * 2, cHeight - (mapOffsetScrollBorder * 2));
        }

        if(mapOffsetXScroll == 'right'){
            mapOffsetX -= mapOffsetScrollSpeed;
            ctx.fillRect(cWidth - (mapOffsetScrollBorder * 3), mapOffsetScrollBorder, mapOffsetScrollBorder * 2, cHeight - (mapOffsetScrollBorder * 2))
        }

        if(mapOffsetYScroll == 'up'){
            mapOffsetY += mapOffsetScrollSpeed;
            ctx.fillRect(mapOffsetScrollBorder, mapOffsetScrollBorder, cWidth - (mapOffsetScrollBorder * 2), mapOffsetScrollBorder * 2)
        }

        if(mapOffsetYScroll == 'down'){
            mapOffsetY -= mapOffsetScrollSpeed;
            ctx.fillRect(mapOffsetScrollBorder, cHeight - (mapOffsetScrollBorder * 3), cWidth - (mapOffsetScrollBorder * 2), mapOffsetScrollBorder * 2)
        }
    }

    // Get the mouse coordinates in relation to the map and checks if mouse is on edge of the canvas for scrolling
    function mouseCheck(e){
        var x = e.pageX;
        var y = e.pageY;

        // Move the map if the screen goes towards the egdes
        if((x < c.offsetLeft + (mapOffsetScrollBorder * 3)) && (x > c.offsetLeft + mapOffsetScrollBorder)){
            mapOffsetXScroll = 'left';
        }
        else if((x > c.offsetLeft + cWidth - (mapOffsetScrollBorder * 3)) && (x < c.offsetLeft + cWidth - mapOffsetScrollBorder)){
            mapOffsetXScroll = 'right';
        }
        else
        {
            mapOffsetXScroll = 0;
        }

        if((y < c.offsetTop + (mapOffsetScrollBorder * 3)) && (y > c.offsetTop + mapOffsetScrollBorder)){
            mapOffsetYScroll = 'up';
        }
        else if((y > c.offsetTop + cHeight - (mapOffsetScrollBorder * 3)) && (y < c.offsetTop + cHeight - mapOffsetScrollBorder)){
            mapOffsetYScroll = 'down';
        }
        else
        {
            mapOffsetYScroll = 0;
        }

        // Compensate for isometric tiling
        mouseY = (2 * (y - c.offsetTop - mapOffsetY) - x + c.offsetLeft + mapOffsetX) / 2;
        mouseX = x + mouseY - mapOffsetX - tileHeight - c.offsetLeft;

        mouseY = Math.round(mouseY / tileHeight);
        mouseX = Math.round(mouseX / tileHeight);
    }

    // Changes the tile that mouse is over
    function mouseClick(e){
        var placementType = document.getElementById('selectPlacementType').value;
        var tileType = document.getElementById('selectTileType').value;
        var objType = document.getElementById('selectObjType').value;

        // Check that the mouse is exactly over a tile and not off the map
        if(placementType == 0){
            for(i = 0; i < tileMap.length; i++){
                for(j = 0; j < tileMap[i].length; j++){
                    if(i == mouseX && j == mouseY){
                        tileMap[mouseX][mouseY] = tileType;
                    }
                }
            }
        }

        // Check that the mouse is exactly over a tile and not off the map
        if(placementType == 1){
            for(i = 0; i < objMap.length; i++){
                for(j = 0; j < objMap[i].length; j++){
                    if(i == mouseX && j == mouseY){
                        objMap[mouseX][mouseY] = objType;
                    }
                }
            }
        }
    }

    // Paints onto the canvas
    function drawCanvas(){
        drawMap();
    }

    // Update game elements every 50 milliseconds
    function gameUpdate(){
        ctx.clearRect(0, 0, cWidth, cHeight);

        drawCanvas();
        mapScroller();
        drawDebugText();
    }

    // Setup debugging text
    function drawDebugText(){
        ctx.font = "10pt Courier New";
        ctx.fillStyle = "#FFF";
        ctx.fillText(mouseX + ',' + mouseY, 0, 10);
    }

    // Setup intital load events
    function init(){
        tileMapPopulate();
        objMapPopulate();

        spriteLoad();
        spriteLoadTimer = setInterval(spriteLoadCheck, 100);

        c.addEventListener("mousemove", mouseCheck, false);
        c.addEventListener("mouseup", mouseClick, false);
    }

</script>

You're using numbers in the map array, but the value from the select element puts a string "0" in instead. 您在地图数组中使用数字,但是select元素中的值将字符串"0"放入其中。

Then later, this line: 然后,此行:

 var drawObj = objMap[i][j];
 ...
 if(drawObj){

Unexpectedly evaluates to true. 意外地得出结果为true。 Remember that the 'falsyness' of "0" only applies when using == : 请记住,只有在使用==时,“虚假性”的"0"才适用:

 if(0)  // true
 if("0") // true
 if("0" == true) // false
 if("0" == false) // true

There's a couple of ways you could get around this: 有两种方法可以解决此问题:

  if(drawObj == true){

But I think it would be better to do this earlier on: 但是我认为最好早些时候这样做:

  objMap[mouseX][mouseY] = parseInt(objType,10);

As a general rule, I'd recommend never using == or if(varname) in Javascript. 通常,我建议不要在Javascript中使用==if(varname)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM