如何使“相机”仅显示部分加载区域

Luk*_*ell 5 java swing 2d paint

我在找出一些东西时有一个小问题(很明显)。

我正在创建一个二维自上而下的mmorpg,并且在此游戏中,我希望玩家在瓷砖地图上移动,就像有人玩过《口袋妖怪》的游戏方式一样。

如果您还没有,请想象一下:我需要加载各个区域,从包含图像和位置(x,y)和对象(玩家,物品)的图块构造它们,但是玩家只能在时间,即20乘15瓦宽的区域,也就是100瓦高/宽瓦。我希望“摄像机”跟随玩家,使他保持居中,除非玩家到达加载区域的边缘。

我不一定需要代码,只需一个设计计划。我不知道该怎么办。

我当时正在考虑将整个加载区域分成10x10个瓷砖块(称为“块”)并加载它们,但是我仍然不确定如何从屏幕上加载碎片,并且仅在玩家处于范围内时显示它们。

图片应该描述它: 在此处输入图片说明

有任何想法吗?


我的解决方案: 解决此问题的方法是通过JScrollPanes和JPanels的美好世界。

我在JScrollPane中添加了一个3x3的JPanels块,添加了一些滚动和“ goto”方法来使JScrollPane居中/移动,瞧,我有了我的相机。

虽然我选择的答案对想要做2D相机工作的人来说有点通用,但是我做的方式实际上帮助我可视化了我做的更好的事情,因为实际上我有一个可以移动的物理“相机”(JScrollPane)我的“世界”(JPanel的3x3网格)

只是以为我会在这里张贴此信息,以防万一有人谷歌搜索答案而出现。:)

ale*_*kop 5

对于2D游戏,很容易找出哪些矩形块位于视图矩形内。基本上,在较大的世界矩形内绘制一个“视口”矩形。通过将视图偏移量除以图块大小,您可以轻松确定起始图块,然后仅在视图内部以适合的大小渲染图块。

首先,您正在使用三个坐标系:视图,世界和地图。视图坐标实质上是鼠标从视图左上角开始的偏移量。世界坐标是距图块0,0的左上角的像素距离。我假设您的世界从左上角开始。并且地图坐标是地图数组中的x,y索引。

您需要在这些之间进行转换,以进行“幻想”操作,例如滚动,找出鼠标下方的图块以及在视图中的正确坐标处绘制世界对象。因此,您将需要一些函数在这些系统之间进行转换:

// I haven't touched Java in years, but JavaScript should be easy enough to convey the point

var TileWidth = 40,
    TileHeight = 40;

function View() {
    this.viewOrigin = [0, 0];   // scroll offset
    this.viewSize = [600, 400];
    this.map = null;
    this.worldSize = [0, 0];
}

View.prototype.viewToWorld = function(v, w) {
    w[0] = v[0] + this.viewOrigin[0];
    w[1] = v[1] + this.viewOrigin[1];
};

View.prototype.worldToMap = function(w, m) {
    m[0] = Math.floor(w[0] / TileWidth);
    m[1] = Math.floor(w[1] / TileHeight);
}

View.prototype.mapToWorld = function(m, w) {
    w[0] = m[0] * TileWidth;
    w[1] = m[1] * TileHeight;
};

View.prototype.worldToView = function(w, v) {
    v[0] = w[0] - this.viewOrigin[0];
    v[1] = w[1] - this.viewOrigin[1];
}
Run Code Online (Sandbox Code Playgroud)

有了这些功能,我们现在可以渲染地图的可见部分。

View.prototype.draw = function() {
    var mapStartPos = [0, 0],
    worldStartPos = [0, 0],
    viewStartPos = [0, 0];
    mx, my, // map coordinates of current tile
    vx, vy; // view coordinates of current tile

    this.worldToMap(this.viewOrigin, mapStartPos); // which tile is closest to the view origin?
    this.mapToWorld(mapStartPos, worldStartPos);    // round world position to tile corner...
    this.worldToView(worldStartPos, viewStartPos);  // ... and then convert to view coordinates. this allows per-pixel scrolling

    mx = mapStartPos[0];
    my = mapStartPos[y];

    for (vy = viewStartPos[1]; vy < this.viewSize[1]; vy += TileHeight) {
        for (vx = viewStartPos[0]; vx < this.viewSize[0]; vy += TileWidth) {
            var tile = this.map.get(mx++, my);
            this.drawTile(tile, vx, vy);
        }
        mx = mapStartPos[0];
        my++;
        vy += TileHeight;
    }
};
Run Code Online (Sandbox Code Playgroud)

那应该工作。我没有时间整理一个可以正常运行的演示网页,但希望您能明白。通过更改viewOrigin,您可以滚动。要获取世界并在鼠标下绘制地图坐标,请使用viewToWorld和worldToMap函数。

如果您打算在等轴测视图(例如Diablo)上进行操作,那么事情将变得相当棘手。

祝好运!