无需大修即可使我的画布可滚动

发布于 11-16 07:06 字数 398 浏览 4 评论 0原文

我正在为 Android 开发一款 2D 游戏,主要是为了学习 Android 应用程序编程的细节,所以我自然会遇到很多难题需要解决。目前,我的主要活动实例化一个自定义类,该类扩展 SurfaceView 并实现 SurfaceHolder.Callback。该视图实例化一个线程,该线程处理大部分逻辑和所有图形处理(这包括实例化画布并在其上绘图。等等)。

好吧,由于我是初学者,所以当我开始设计画布时,我并没有想到比屏幕大得多,并允许用户滚动查看画布的所有部分...但是,这就是我需要做的,

如果有一种简单的方法可以做到这一点,请告诉我

。最好的猜测是将画布的实际创建放入一个扩展 ScrollView 的单独的类,并且以某种方式从我的线程调用该画布的所有 Draw() 这可能吗?我的点击事件实际上是从主活动中捕获的(仅供参考)。

I'm in the process of developing a 2-D game for android which primarily i'm using as an experience to learn the in's and out's of programming for android apps, so naturally i run into a lot of puzzles to work through. Currently, my main activity instantiates a custom class which extends SurfaceView and implements SurfaceHolder.Callback. This view instantiates a thread which handles most of the logic and all the graphics processing (this includes instantiating a canvas and drawing to it., etc.

Well, being that I am a beginner I wasn't thinking when I started that designing the canvas to be much larger than the screen and to allow users to scroll around to see all parts of the canvas... but alas, that's what I need to happen.

If there is an easy way to do this, please let me know.

My best guess is putting the actual creation of the canvas in a separate class which extends ScrollView and somehow just calling all the Draw()'s to that canvas from my thread. is this possible? my click events are actually captured from the main activity (just fyi).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

耳钉梦2024-11-23 07:06:06

最好的选择是使用相机来平移画布。执行如下操作:

// Creates a new camera object
Camera mCam = new Camera();
float startX;
float startY;

@Override
public void onTouch(MotionEvent event)
{
    if(event.getAction() == MotionEvent.ACTION_DOWN)
    {
        startX = event.getX();
        startY = event.getY();
    }
    else if(event.getAction() == MotionEvent.ACTION_MOVE)
    {
        float x = event.getX();
        float y = event.getY();

        // Lets you translate the camera by the difference
        mCam.translate(x -startX, startY - y, 0.f);
        startX = event.getX();
        startY = event.getY();
    }
}

@Override
public void onDraw(Canvas canvas)
{
    // Draw here the objects you want static in the background
    canvas.drawBitmap(mBackground, 0, 0, null);

    canvas.save();
    mCam.applyToCanvas();

    // Draw here the objects you want to move
    canvas.drawBitmap(mBall, 0, 0, null);

    canvas.restore();

    // Draw here the objects you want static on the forebround
    canvas.drawBitmap(mScore, 0, 0, null);
}

请注意,您正在 0,0 处绘制 mBall,但由于相机平移,它会移动指定的量。我希望这有帮助。玩得开心 :)

The best option would be to use a Camera to translate the canvas. Do something like this:

// Creates a new camera object
Camera mCam = new Camera();
float startX;
float startY;

@Override
public void onTouch(MotionEvent event)
{
    if(event.getAction() == MotionEvent.ACTION_DOWN)
    {
        startX = event.getX();
        startY = event.getY();
    }
    else if(event.getAction() == MotionEvent.ACTION_MOVE)
    {
        float x = event.getX();
        float y = event.getY();

        // Lets you translate the camera by the difference
        mCam.translate(x -startX, startY - y, 0.f);
        startX = event.getX();
        startY = event.getY();
    }
}

@Override
public void onDraw(Canvas canvas)
{
    // Draw here the objects you want static in the background
    canvas.drawBitmap(mBackground, 0, 0, null);

    canvas.save();
    mCam.applyToCanvas();

    // Draw here the objects you want to move
    canvas.drawBitmap(mBall, 0, 0, null);

    canvas.restore();

    // Draw here the objects you want static on the forebround
    canvas.drawBitmap(mScore, 0, 0, null);
}

Notice that you are drawing mBall at 0,0 but due to the camera translation it will move by the amount specified. I hope this helps. Have fun :)

清欢2024-11-23 07:06:06

我对这个问题进行了思考,并想出了(如果我自己不这么说的话)一个出色的、相对简单且优雅的解决方案。抱歉自吹自擂,但我真的很高兴我能够想出这个。

如果有人考虑使用这种方法,有几个条件使其成为一个不错的选择。首先,我的所有对象都是使用 setBounds(int,int,int,int) 方法具有预定义位置的可绘制对象,所有对象还存储自己的坐标以在画布上绘制位置,并且所有对象都在哈希图中调用,这允许我调用并处理所有存在的对象。

现在我在想kabuko所说的以及绘制巨大的画布是如何浪费的以及id如何遇到点击事件问题,这就是我想到这个的时候。

当屏幕触摸事件发生在屏幕边缘附近时,将调用自定义方法 Scroll(),该方法循环遍历每个对象,并根据用户尝试滚动的方向调整存储的对象位置坐标。在增加对象位置后,它(并行)增加一对 x 和 y 偏移量的变量。然后,该偏移量会被考虑到触摸事件的坐标中,以便无论屏幕滚动到什么位置,仍然可以通过触摸选择对象。

然后为了性能的考虑,一个简单的 if 语句使得只有当对象坐标落在屏幕范围内时才在对象上调用绘制。

抱歉幸灾乐祸,但我真的很惊讶,也给自己留下了深刻的印象,哈哈。我实际上只编写了大约一个月的代码,但我几乎已经有了一个功能齐全的 2D 策略游戏!

Java 傻瓜得到了回报,哈哈。

I slept on the problem and came up with (if i don't say so myself) A brilliant, relatively simple and elegant solution. Sorry to toot my own horn but I was literally ecstatic that i was able to come up with this.

If anyone is thinking of using this method there are a couple of conditions that made this a good choice. First, all of my objects are drawables with predefined locations using the setBounds(int,int,int,int) method, all objects also store their own coordinates for the location to draw on the canvas and all objects are called in hashmaps which allows me to call and process all the objects in existence.

Now I was thinking about what kabuko said and how it's such a waste to draw a huge canvas and how id run into click event problems, that's when I came up with this.

when a screen touch event occurs near the edge of the screen, a custom method Scroll() is called which loops through every object and adjusts the stored coordinates of the object location depending on which direction the user is trying to scroll. after it increments the objects location, it (in parallel) increments a pair of variables for x and y offset. This offset is then factored into the coordinates of the touch events so that objects can still be selected by touch regardless of the position the screen is scrolled to.

then for performance's sake a simple if statement makes it so that draw is only called on an object if that objects coordinates fall in the range of the screen.

Sorry to gloat but I really surprised and impressed myself with this, haha. I've really only been coding about a month and I almost have a fully functional 2D strategy game!

Java for dummies paid off, lol.

终止放荡2024-11-23 07:06:06

你可以尝试一下你的方法,尽管这并不是我自己使用过的策略。不过,我怀疑您无论如何都会遇到这种方法的一些问题。如果您的游戏已经使用触摸进行输入,那么您将会遇到冲突。另外,如果性能是一个问题(特别是如果您有动画),您就不想采用这种方法。

如果您要处理线程,性能可能很重要。绘图是昂贵的,如果你制作一个巨大的画布,你将不得不渲染整个东西,这会花费你。您应该只绘制屏幕上的内容(或多或少)。抱歉,但您可能需要进行“重大修改”……

也就是说,处理滚动确实没有那么糟糕。您可能拥有所绘制的所有内容的坐标。您需要做的就是跟踪“当前坐标”,然后将绘图 x 和 y 平移为当前的 x 和 y。处理性能问题,你可以做很多事情,但这开始有点偏离主题了。如果您想了解更多信息,请观看这​​些视频:

http://www.youtube.com/ watch?v=U4Bk5rmIpic

http://www.youtube.com/watch?v=7-62tRHLcHk

You could give your approach a try, even though it's not really a strategy I'd ever use myself. I suspect you're going to run into some issues with that approach anyway though. If your game already uses touch for input, you're going to have conflicts. Also, if performance is at all a concern (especially if you have any animation), you don't want go with this approach.

If you're going as far as dealing with threading, performance probably matters. Drawing is expensive, and if you make a huge canvas, you'll have to be rendering the whole thing and it will cost you. You should only draw what's on the screen (more or less). Sorry, but you'll probably need a "major overhaul"...

That said, it's really not that bad to deal with scrolling. You probably have coordinates for everything you're drawing. All you need to do is keep track of your "current coordinates" and then translate your drawing x and y by your current x and y. Dealing with the performance stuff, there's a lot you can do, but that's starting to get a bit off-topic. Take a look at these videos if you want to know more:

http://www.youtube.com/watch?v=U4Bk5rmIpic

http://www.youtube.com/watch?v=7-62tRHLcHk

战皆罪2024-11-23 07:06:06

横向卷轴游戏的简单技巧是将你的世界分成多个图块,每个图块都有指定的面积。

The simple trick with side-scrolling games is to divide your world into tiles, where each tile has a specified amount of area.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文