gpt4 book ai didi

java - 如何让 "Camera"只显示加载区域的一部分

转载 作者:搜寻专家 更新时间:2023-10-31 19:57:53 24 4
gpt4 key购买 nike

我在解决问题时遇到了一点问题(很明显)。

我正在创建一个 2D 自上而下的 mmorpg,在这个游戏中,我希望玩家可以在类似于 Pokemon 游戏的工作方式的平铺 map 上移动,如果有人玩过的话。

如果你还没有,想象一下:我需要加载各种区域,从包含图像和位置 (x, y) 和对象(玩家、元素)的图 block 构建它们,但玩家只能看到一部分一次,即 20 x 15 瓦宽的区域,可以是 100 瓦高/宽。我希望“相机”跟随玩家,将他保持在中心位置,除非玩家到达加载区域的边缘。

我不一定需要代码,只需要一个设计方案。我不知道如何处理这种事情。

我正在考虑可能将整个加载区域分成 10x10 block ,称为“ block ”并加载它们,但我仍然不确定如何在屏幕外加载 block 并且只在玩家在范围内时显示它们.

图片应该描述一下: enter image description here

有什么想法吗?


我的解决方案:我解决这个问题的方法是通过 JScrollPanes 和 JPanels 的奇妙世界。

我在 JScrollPane 中添加了一个 3x3 的 JPanel block ,添加了几个滚动和“goto”方法来使 JScrollPane 居中/四处移动,瞧,我有了相机。

虽然我选择的答案对于想要做 2d 相机的人来说有点通用,但我这样做的方式实际上帮助我更好地想象我在做什么,因为我实际上有一个物理“相机” (JScrollPane) 在我的“世界”中移动(JPanel 的 3x3 网格)

只是想我会把这个贴在这里,以防万一有人在谷歌上搜索答案而出现这个问题。 :)

最佳答案

对于 2D 游戏,如果图 block 是矩形的,则很容易找出哪些图 block 落在 View 矩形内。基本上,在较大的世界矩形内描绘一个“视口(viewport)”矩形。通过将 View 偏移量除以图 block 大小,您可以轻松确定起始图 block ,然后只渲染适合 View 的图 block 。

首先,您在三个坐标系中工作: View 、世界和 map 。 View 坐标本质上是鼠标距 View 左上角的偏移量。世界坐标是距图 block 0、0 左上角的像素距离。我假设您的世界从左上角开始。 map 坐标是 map 数组中的 x、y 索引。

您需要在它们之间进行转换,以便执行“花哨”的操作,例如滚动、确定鼠标下方的图 block 以及在 View 中的正确坐标处绘制世界对象。因此,您需要一些函数在这些系统之间进行转换:

// 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];
}

有了这些函数,我们现在可以渲染 map 的可见部分...

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;
}
};

那应该行得通。我没有时间整理一个可用的演示网页,但我希望你能理解。通过更改 viewOrigin,您可以滚动。要获取鼠标下的世界和 map 坐标,请使用 viewToWorld 和 worldToMap 函数。

如果您计划使用等距 View ,例如暗黑破坏神,那么事情会变得相当棘手。

祝你好运!

关于java - 如何让 "Camera"只显示加载区域的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7772566/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com