如何在基于贴图的javascript游戏中阻止某些贴图的移动

How to deny movement on some tiles in a tile-based javascript game?

本文关键字:移动 游戏 于贴图 javascript      更新时间:2023-09-26

我已经为游戏创建了地图,现在我想要在一些贴图上拒绝移动。例如,有些贴图是角色移动的路径,而另一些则是森林、草地或角色无法移动的地方。这是我的地图代码:

var mapLeft = 224;
var mapTop = 160;
var protagonistLeft;
var protagonistTop;
var tileProperties = [
    [ true,false,false,false,false,false,],
    [false,false,false,false,false,false,],
    [false,false,false,false,false,false,],
    [false,false,false,false,false,false,],
    [false,false,false,false,false,false,],
    [true, true, true, true,false,false,],
    [false,false,false,false,false,false,],
    [false,false,false,false,false,false,],
    [false,false,false,false,false,false,],
    [false,false,false,false,false,false,],
    [false,false,false,false,false,false,],
    [false,false,false,false,false,false,],
  ]

我在想这样的东西,但我不知道用什么来代替"拒绝运动"answers"允许运动":

if (tileProperties = true){
    allow movement  
}
else {
    deny movement
}
编辑:

我并没有真正移动玩家。它后面的地图在移动,玩家总是在中间。下面是代码:

function positionSettings() {
    document.getElementById("gameWindow").scrollLeft = mapLeft;
    document.getElementById("gameWindow").scrollTop = mapTop;
    document.getElementById("protagonist").style.left ="507px";
    document.getElementById("protagonist").style.top ="347px";
}
function moveMap(keystroke){
    switch(keystroke.keyCode){
        case 37:
            mapLeft = mapLeft - 8;
            positionSettings();
            break
        case 38:
            mapTop = mapTop - 8;
            positionSettings();
            break
        case 39:
            mapLeft = mapLeft + 8;
            positionSettings();
            break
        case 40:
            mapTop = mapTop + 8;
            positionSettings();
            break
    }
}
function loadMap(){
    for(updown=0;updown<50;updown++){
        for(leftright=0;leftright<50;leftright++){
            //alert(tileProperties[leftright][updown]);
            var tile = document.createElement("div");
            tile.setAttribute("class","mapTile");
            if(tileProperties[leftright][updown]){
                tile.setAttribute("style","background-color:#00FF00;left:"+ leftright * 32 +"px; top:"+ updown * 32+"px;");
            }
            else{
                tile.setAttribute("style","background-color:#FFFF00;left:"+ leftright * 32 +"px; top:"+ updown * 32+"px;");
            }
            var tileNum = document.createTextNode(leftright +":"+ updown);
            tile.appendChild(tileNum);
            document.getElementById("worldMap").appendChild(tile);
        }
    }
    positionSettings();
}
编辑:

这是我的HTML代码,如果它有帮助的话(也有一些样式代码,但它与运动无关,所以我不会在这里发布):

<body onload="loadMap()" onkeydown="moveMap(event)">
    <div id="gameWindow">
        <div id="worldMap">
        </div>
    </div>
        <div id="protagonist">
        </div>
</body>

更容易使用的是使用char map…例如:

M = ["wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww",
     "w::::::::::::::::::::::::::::r::::::w",
     "w:::::::::::::t::::::t::::::r:::::::w",
     "w:::::::t:t:::::::t::::::::bbb::X:::w",
     "w::::::t::::::::::::::::::::r:::::::w",
     "E::*::::::t:::t:::::::::t:::r:::::::w",
     "w::::::::::::::::::::::::::::r::::::w",
     "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww"];

例如,t表示一棵树,b表示一座桥,r表示一条河,w表示一堵墙,*表示玩家的初始位置,X表示要抓住的宝藏,E表示出口点(只有当你得到宝藏时才会打开门),等等。

然后你可以为每个标志创建一个映射,并使用:

var can_walk = {'b': true, ':': true, 'X':  true};
...
if (can_walk[M[y1][x1]]) {
    // Step ok, update coords
    x = x1; y = y1;
}

我做了一段时间的"游戏"的乐趣。它不完整,代码应该以更好的方式排列,但它应该对你有用:

JS

var canvas = document.getElementById("grid");
var context = canvas.getContext("2d");
var tile = new Image();
var cursorImg = new Image();
cursorImg.src = "http://www.sebissimos.com/imgs/rmt_icon.png";
var game = function(document) {
    this.document = document;
    this.grid = {};
    this.cursor = {
        spriteImg: cursorImg,
        x: 0,
        y: 0,
        cellx: 2,
        celly: 2
    };
    this.tile = function(idx, idy, x, y, type) {
        this.idx = idx;
        this.idy = idy;
        this.x = x;
        this.y = y;
        this.sprite = new Image();
        if (type === "dirt") {
            this.walkable = true;
            this.sprite.src = 'http://vignette1.wikia.nocookie.net/tibia/images/0/0b/Dirt_%28Light%29.gif/revision/latest?cb=20091024213053&path-prefix=en';
        }
        if (type === "rock") {
            this.walkable = false;
            this.sprite.src = 'http://christessmer.com/sprites/tiles/grey_rock_tile.png';
        }
    };
    this.map = [
        ["rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock"],
        ["rock", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "rock"],
        ["rock", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "rock"],
        ["rock", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "rock"],
        ["rock", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "rock"],
        ["rock", "rock", "dirt", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "dirt", "rock", "rock"],
        ["rock", "dirt", "dirt", "dirt", "rock", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "rock"],
        ["rock", "dirt", "dirt", "dirt", "rock", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "rock", "dirt", "dirt", "dirt", "rock"],
        ["rock", "dirt", "dirt", "dirt", "rock", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "rock", "dirt", "dirt", "dirt", "rock"],
        ["rock", "dirt", "dirt", "dirt", "rock", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "rock", "dirt", "dirt", "dirt", "rock"],
        ["rock", "rock", "dirt", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "dirt", "rock", "rock"],
        ["rock", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "rock"],
        ["rock", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "rock"],
        ["rock", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "rock"],
        ["rock", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "rock"],
        ["rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock", "rock"]
    ];
    this.firstStart = true;
    this.initGrid();
};
game.prototype = {
    getInput: function(kc) {
        actualx = this.cursor.cellx;
        actualy = this.cursor.celly;
        if (kc == 37) {
            nextx = actualx - 1;
            if (this.grid.squares[actualy][nextx] != undefined && this.grid.squares[actualy][nextx].walkable)
                this.cursor.cellx = nextx;
        }
        if (kc == 38) {
            nexty = actualy - 1;
            if (this.grid.squares[nexty][actualx] != undefined && this.grid.squares[nexty][actualx].walkable)
                this.cursor.celly = nexty;
        }
        if (kc == 39) {
            nextx = actualx + 1;
            if (this.grid.squares[actualy][nextx] != undefined && this.grid.squares[actualy][nextx].walkable)
                this.cursor.cellx = nextx;
        }
        if (kc == 40) {
            nexty = actualy + 1;
            if (this.grid.squares[nexty][actualx] != undefined && this.grid.squares[nexty][actualx].walkable)
                this.cursor.celly = nexty;
        }
    },
    start: function() {
        game = this;
        var interval = setInterval(function() {
            game.draw();
        }, 10);
        function checkKey(e) {
            e = e || window.event;
            game.getInput(e.keyCode);
        }
        document.onkeydown = checkKey;
    },
    draw: function() {
        if (this.firstStart) {
            this.grid.squares.forEach(function(yrow) {
                yrow.forEach(function(cell) {
                    context.drawImage(cell.sprite, cell.x, cell.y);
                });
            });
        }
        context.drawImage(this.cursor.spriteImg, this.grid.squares[this.cursor.celly][this.cursor.cellx].x, this.grid.squares[this.cursor.celly][this.cursor.cellx].y);
    },
    initGrid: function() {
        this.grid.squaresize = 32;
        this.grid.squares = [];
        var idx = 0;
        var idy = 0;
        var posx = 0;
        var posy = 0;
        for (var y = 0; y < this.map.length; y += 1) {
            this.grid.squares[y] = [];
            for (var x = 0; x < this.map[y].length; x += 1) {
                this.grid.squares[idy][idx] = new this.tile(idx, idy, posx, posy, this.map[y][x]);
                idx++;
                posx = this.grid.squaresize * idx;
            }
            idx = 0;
            posx = 0;
            idy++;
            posy = this.grid.squaresize * idy;
        }
    }
};
window.onload = function() {
    test1 = new game(document);
    test1.start();
};
HTML

<canvas id="grid" width="800" height="600"></canvas>

jsfiddle示例:https://jsfiddle.net/xqjp4j72/7/编辑:现在有地图了

在移动前检查新位置是否有效。否则,什么都不做,让玩家保持在初始位置。

function moveMap(keystroke){
    switch(keystroke.keyCode){
        case 37:
            if (isValidTile(mapLeft - 8, mapTop)) {
                mapLeft = mapLeft - 8;
                positionSettings();
            } else {
                //Do nothing, as if no keypress, to ignore it
            }
            break;
        case 38:
            if (isValidTile(mapLeft, mapTop - 8)) {
                mapTop = mapTop - 8;
                positionSettings();
            } else {
                //Do nothing, as if no keypress, to ignore it
            }
            break;
        case 39:
            if (isValidTile(mapLeft + 8, mapTop)) {
                mapLeft = mapLeft + 8;
                positionSettings();
            } else {
                //Do nothing, as if no keypress, to ignore it
            }
            break;
        case 40:
            if (isValidTile(mapLeft, mapTop + 8)) {
                mapTop = mapTop + 8;
                positionSettings();
            } else {
                //Do nothing, as if no keypress, to ignore it
            }
            break;
    }
}
function isValidTile(leftright, updown) {
    if(!tileProperties[leftright][updown]) {
        return true;
    } else {
        return false;
    }
}