如何拥有一台“相机”只显示加载区域的一部分
我在弄清楚一些事情时遇到了一些问题(显然)。
我正在创建一个 2D 自上而下的大型多人在线角色扮演游戏,在这款游戏中,我希望玩家能够在平铺地图上移动,类似于 Pokemon 游戏的工作方式(如果有人玩过的话)。
如果还没有,请想象一下:我需要加载各个区域,用包含图像和位置(x,y)和对象(玩家,物品)的图块构建它们,但玩家只能在某个位置看到其中的一部分。时间,即 20 x 15 格宽的区域,可以是 100 格高/宽。我希望“摄像机”跟随玩家,将他保持在中心,除非玩家到达加载区域的边缘。
我不一定需要代码,只需要一个设计计划。我不知道该怎么做这种事情。
我正在考虑可能将整个加载区域分割成 10x10 的图块,称为“块”并加载它们,但我仍然不确定如何将图块加载到屏幕外并仅在玩家处于范围内时才显示它们。
图片应该描述一下:
有什么想法吗?
我的解决方案: 我解决这个问题的方法是通过 JScrollPanes 和 JPanel 的奇妙世界。
我在 JScrollPane 内部添加了一个 3x3 的 JPanel 块,添加了几个滚动和“goto”方法用于居中/移动 JScrollPane,瞧,我有了相机。
虽然我选择的答案对于想要使用 2d 相机的人来说有点通用东西,我这样做的方式实际上帮助我更好地想象我正在做的事情,因为我实际上有一个物理“相机”(JScrollPane)可以在我的“世界”(JPanels 的 3x3 网格)中移动
只是想我会把这个贴在这里,以防有人在谷歌上搜索答案而出现这个问题。 :)
I'm having a little problem with figuring something out (Obviously).
I'm creating a 2D Top-down mmorpg, and in this game I wish the player to move around a tiled map similar to the way the game Pokemon worked, if anyone has ever played it.
If you have not, picture this: I need to load various areas, constructing them from tiles which contain an image and a location (x, y) and objects (players, items) but the player can only see a portion of it at a time, namely a 20 by 15 tile-wide area, which can be 100s of tiles tall/wide. I want the "camera" to follow the player, keeping him in the center, unless the player reaches the edge of the loaded area.
I don't need code necessarily, just a design plan. I have no idea how to go about this kind of thing.
I was thinking of possibly splitting up the entire loaded area into 10x10 tile pieces, called "Blocks" and loading them, but I'm still not sure how to load pieces off screen and only show them when the player is in range.
The picture should describe it:
Any ideas?
My solution:
The way I solved this problem was through the wonderful world of JScrollPanes and JPanels.
I added a 3x3 block of JPanels inside of a JScrollPane, added a couple scrolling and "goto" methods for centering/moving the JScrollPane around, and voila, I had my camera.
While the answer I chose was a little more generic to people wanting to do 2d camera stuff, the way I did it actually helped me visualize what I was doing a little better since I actually had a physical "Camera" (JScrollPane) to move around my "World" (3x3 Grid of JPanels)
Just thought I would post this here in case anyone was googling for an answer and this came up. :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
对于 2D 游戏,如果图块是矩形,则很容易找出哪些图块落在视图矩形内。基本上,在更大的世界矩形内绘制一个“视口”矩形。通过将视图偏移量除以图块大小,您可以轻松确定起始图块,然后仅渲染适合视图内的图块。
首先,您在三个坐标系中工作:视图、世界和地图。视图坐标本质上是鼠标相对于视图左上角的偏移量。世界坐标是距图块 0, 0 左上角的像素距离。我假设您的世界从左上角开始。地图坐标是地图数组中的 x、y 索引。
您需要在这些之间进行转换,以便执行“奇特”的操作,例如滚动、确定鼠标下方的图块以及在视图中的正确坐标处绘制世界对象。因此,您需要一些函数来在这些系统之间进行转换:
有了这些函数,我们现在可以渲染地图的可见部分......
这应该可行。我没有时间制作一个可用的演示网页,但我希望您能明白。
通过更改 viewOrigin 您可以滚动。要获取鼠标下的世界和地图坐标,请使用 viewToWorld 和 worldToMap 函数。
如果您计划使用等距视图,即《暗黑破坏神》,那么事情就会变得相当棘手。
祝你好运!
For a 2D game, it's quite easy to figure out which tiles fall within a view rectangle, if the tiles are rectangular. Basically, picture a "viewport" rectangle inside the larger world rectangle. By dividing the view offsets by the tile sizes you can easily determine the starting tile, and then just render the tiles in that fit inside the view.
First off, you're working in three coordinate systems: view, world, and map. The view coordinates are essentially mouse offsets from the upper left corner of the view. World coordinates are pixels distances from the upper left corner of tile 0, 0. I'm assuming your world starts in the upper left corner. And map cooridnates are x, y indices into the map array.
You'll need to convert between these in order to do "fancy" things like scrolling, figuring out which tile is under the mouse, and drawing world objects at the correct coordinates in the view. So, you'll need some functions to convert between these systems:
Armed with these functions we can now render the visible portion of the map...
That should work. I didn't have time to put together a working demo webpage, but I hope you get the idea.
By changing viewOrigin you can scroll around. To get the world, and map coordinates under the mouse, use the viewToWorld and worldToMap functions.
If you're planning on an isometric view i.e. Diablo, then things get considerably trickier.
Good luck!
我做这样的事情的方法是保留一个名为“cameraPosition”或其他名称的变量。然后,在所有对象的
draw
方法中,使用cameraPosition
来偏移所有物体的位置。例如:岩石位于
[100,50]
,而相机位于[75,75]
。这意味着岩石应绘制在[25,-25]
([100,50] - [75,75]
的结果)。您可能需要稍微调整一下才能使其正常工作(例如,您可能必须补偿窗口大小)。请注意,您还应该进行一些剔除 - 如果想要在
[2460,-830]
处绘制某些内容,您可能不想费心绘制它。The way I would do such a thing is to keep a variable called
cameraPosition
or something. Then, in thedraw
method of all objects, usecameraPosition
to offset the locations of everything.For example: A rock is at
[100,50]
, while the camera is at[75,75]
. This means the rock should be drawn at[25,-25]
(the result of[100,50] - [75,75]
).You might have to tweak this a bit to make it work (for example maybe you have to compensate for window size). Note that you should also do a bit of culling - if something wants to be drawn at
[2460,-830]
, you probably don't want to bother drawing it.一种方法是沿着双缓冲( Java 双缓冲 )和 blitting(http://download.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html )。甚至还有与之相关的设计模式( http:// www.javalobby.org/forums/thread.jspa?threadID=16867&tstart=0)。
One approach is along the lines of double buffering ( Java Double Buffering ) and blitting ( http://download.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html ). There is even a design pattern associated with it ( http://www.javalobby.org/forums/thread.jspa?threadID=16867&tstart=0 ).