Android 2D 图形滚动速度差异
我在业余时间在 Android 中尝试 2D 图形,并且我对创建一个基于精灵的“沙盒”来玩的想法很感兴趣。我在网上浏览并找到了一些很好的教程,但我遇到了一个相当基本的问题:我的精灵移动得比地形快,并在地形上“滑行”。此外,他慢慢地超过了地形滚动并移动到视图的边缘。
我有一个动画精灵,我想将其移动到世界各地。我通过更改他的绝对坐标(在“update()”函数中设置 X 和 Y 位置并应用标量倍数来加快或减慢他移动的速度来实现这一点。
this.setXPos(currX + (speed * dx2));
this.setYPos(currY + (speed * dy2));
在该精灵下面,我正在绘制“位图中的“地形”。我想继续通过上面的坐标访问器移动该精灵,但也移动我的视图并滚动地形,以便精灵保持在相同的相对屏幕位置,但在“世界”中移动。我有一个不完美的实现,其中 player
是我的精灵,field
是我的地形:
@Override
protected void onDraw(Canvas canvas)
{
player.updateLocation(GameValues.speedScale);
field.update(new Point(player.getXPos(), player.getYPos()));
field.draw(canvas);
player.draw(canvas);
//more stuff here...
}
并且 field.update()
看起来像(警告:硬编码恐惧):
public void update(Point pt)
{
sourceRect.left = pt.x - 240;
sourceRect.right = pt.x + 240;
sourceRect.top = pt.y - 400;
sourceRect.bottom = pt.y + 400;
}
我的想法是,我最终会得到屏幕尺寸并使其不那么“黑客”,但很快就会得到一些东西,这很容易成为我感兴趣的问题的来源。 field.draw()
:
@Override
public void draw(Canvas canvas)
{
try
{
canvas.drawBitmap(fieldSheet, sourceRect, destRect, null);
}
catch(Exception e)
{
//Handle Exception...
}
}
你会注意到我正在使用 drawBitmap()
的重载,它接受源和目标 Rect,并且 field.update()
方法移动该 sourceRect 以匹配精灵的移动。如何使“相机(可以这么说)”保持在精灵的中心并适当地滚动地形?我原以为仅移动 sourceRect 并保持恒定的 destRect 就可以做到这一点,但现在我想我必须使用精灵在“世界”周围移动 destRect,同时保持相同的尺寸。
有没有更好的(阅读功能)方法来完成这项工作?我有点羞愧地来到这里,因为我认为这对我来说应该比看起来容易一些。任何和所有的帮助或建议表示赞赏。谢谢!
*编辑:*以与精灵相同的速度移动目标矩形
是否有意义?我想我将源矩形和目标矩形合并在一起,并让目标矩形保持不动。当我有机会尝试后(也许在午餐期间),我会更新结果。
*Edit_2:*更改目标矩形并没有让我到达那里,但是使用 View.scrollBy(x, y)
方法让我几乎完全满意。剩下要满足的问题是如何将滚动的视图“剪辑”到代表“字段”的矩形。我相信 View.getLeft()
和 View.getTop()
函数(按屏幕宽度和高度偏移)可用于指定 Rect< /code> 可以在“世界”的约束内虚拟移动,并阻止进一步的增量与
其中 x > 0,返回 0。View.scrollBy()
方法争论。我之所以采用这种方法,是因为 View
似乎没有定位在绝对空间中,并且即使在 View.getLeft()
调用之后也是如此>View.scrollBy(x, y)
I am experimenting with 2D graphics in Android during my off time, and I'm intrigued by the idea of creating a sprite based "sandbox" for playing around. I've looked around online and found some good tutorials, but I'm stuck with a fairly basic problem: My sprite moves faster than the terrain and "glides" over it. Also, he slowly outpaces the terrain scrolling and moves to the edge of the view.
I've got an animated sprite that I want to move around the world. I do so by changing his absolute coordinates(setting X and Y position in an 'update()' function and applying a scalar multiple to speed up or slow down the rate at which he's moving around.
this.setXPos(currX + (speed * dx2));
this.setYPos(currY + (speed * dy2));
Underneath that sprite, I'm drawing "terrain" from a bitmap. I want to continue to move that sprite around via the coordinate accessors above, but also move my view and scroll the terrain so that the sprite stays in the same relative screen location but moves through the "world". I have an imperfect implementation where player
is my sprite and field
is my terrain:
@Override
protected void onDraw(Canvas canvas)
{
player.updateLocation(GameValues.speedScale);
field.update(new Point(player.getXPos(), player.getYPos()));
field.draw(canvas);
player.draw(canvas);
//more stuff here...
}
And field.update()
looks like(Warning: Hard-coded scariness):
public void update(Point pt)
{
sourceRect.left = pt.x - 240;
sourceRect.right = pt.x + 240;
sourceRect.top = pt.y - 400;
sourceRect.bottom = pt.y + 400;
}
The thinking there was that I would eventually just get screen dimensions and make it less 'hack-y', but get something together quickly. This could easily be where my issue is coming from. Of immediate interest is field.draw()
:
@Override
public void draw(Canvas canvas)
{
try
{
canvas.drawBitmap(fieldSheet, sourceRect, destRect, null);
}
catch(Exception e)
{
//Handle Exception...
}
}
You'll notice I'm using the overload of drawBitmap()
that accepts a source and destination Rect and that the field.update()
method moves that sourceRect to match the movement of the sprite. How can I keep the "camera (so to speak)" centered on the sprite and scroll the terrain appropriately? I had thought that moving just the sourceRect and maintaining a constant destRect would do so, but now I'm thinking I have to move the destRect around the "world" with the sprite, while maintaining the same dimensions.
Is there a better (read functional) way of making this work? I'm coming here somewhat shamefully, since I think this should be somewhat easier than it seems to be for me. Any and all help or suggestions are appreciated. Thanks!
*Edit:*Does it make sense to also move the destination Rect
at the same speed as the sprite? I think I conflated the source and destination Rect
's and left the destRect immobile. I'll update with the results after I get a chance to try it (maybe during lunch).
*Edit_2:*Changing the destination rectangle didn't get me there, but using the View.scrollBy(x, y)
method gets me close to totally satisfied. The remaining question to be satisfied is how to "clip" the View scrolling to a rectangle that represents the "field". I believe that the View.getLeft()
and View.getTop()
functions, offset by the screen width and height, can be used to specify a Rect
that can be virtually moved around within the constraints of the "world" and block further deltas from being argued to the View.scrollBy()
method. The reason I look toward this approach is because the View
doesn't seem to be positioned in absolute space, and a View.getLeft()
call, even after a View.scrollBy(x, y)
where x > 0, returns a 0.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论