如何创建世界治愈波效果?


14

我想将黑暗和令人沮丧的背景实时更改为快乐的草皮背景,以使快乐背景以游戏角色周围的半径显示。

如果愿意的话,幸福力量场

在自定义视图中渲染到画布时,如何尽可能高效地完成此操作?


更新: 这就是我的脑海:

    private int hModeX, hModeY;
    private float hModeRadius = 0.1f;
    private float hModeStart = 0;
    happyModeBg = Bitmap.createScaledBitmap(happyModeBg, getWidth(),getHeight(), true);
    hModeX = getWidth()/2;
    hModeY = getHeight()/2;

private void initHappyMode(Canvas canvas){
    hModeRadius = 75 * thread.getDelta();

    if(hModeRadius > 500) {
        hModeStart = timestep; //What is timestep?
    }

    //context.arc(x, y, radius, 0, 2 * Math.PI, false); <- your version
    canvas.save();
    canvas.drawArc(oval, startAngle, sweepAngle, useCenter, paint) // <- my version
    //context.clip(); <- dont know what this does or if there is an equivilant
    canvas.drawBitmap(happyModeBg, 0, 0, null);
    canvas.restore();
    //requestAnimationFrame(step); <- dont know what this does since I cant seem to find it for android

}

我过去canvas.drawArc()经常做个圆圈,但我肯定缺少某些东西。


1
从技术上讲,这叫“ 世界治疗波”
棘轮怪胎2014年

我只是在自定义视图上使用画布,该视图由我自己的游戏循环以
60

您可以两次渲染场景吗?一次用于修复版本,一次用于死亡版本,然后在不断增加的圆圈中绘制已修复的对象,直到该圆圈覆盖整个屏幕。
Wolfgang Skyler

那就是我一直在想的。只是不知道如何使用位图。而且我认为也许有更好的方法,因为一次渲染2 bgs非常昂贵
Green_qaue 2014年

2
我想我明白这是什么意思-Android的Canvas功能与HTML略有不同<canvas>,我以为您的意思是HTML !我已经编辑了答案,通过一些特定于Android的链接和示例代码来说明剪辑的总体工作原理。
Anko 2014年

Answers:


20

演示版

GameDev治疗波

GameDev 变身 :D

该代码使用一个canvas clip区域requestAnimationFrame以实现最大的质量和效率。(更好的生活。)

我以为你是说HTML canvas!即使您没有这样做,其他渲染引擎(例如,您可能已经说过的Android的2D渲染管道)也支持硬件加速的剪辑区域。该代码可能看起来相似。

requestAnimationFrame通过使用引擎(或其他平台提供的解决方案)请求动画帧,可以让引擎确定渲染时间,从而获得更高质量的动画。

这样可以在低范围的上网本和Android手机上流畅呈现。

说明

为了使它更通用,让我们真正地了解裁剪

假设我们有两个矩形:

两个矩形,一个重叠

裁剪在线条,点,图像或您可能要渲染的其他任何东西上的效果都一样。为了简单起见,我只是坚持使用矩形。

我们根本不希望红色矩形在此可见(黑色圆圈)。

两个矩形,红色矩形所需的黑色切出区域

因此,我们可以指示渲染器将红色矩形裁剪成该圆。

两个矩形; 红色的被剪掉了

换句话说,当绘制红色矩形时,将在所有地方绘制该矩形,除了该黑色圆圈将在的位置。

不同的渲染器具有不同的方式来指定要裁剪的区域。在JavaScript中,使用HTML <canvas>基本上是

// Draw the blue rectangle

context.save(); // Save the current state of the graphics context,
                // so we can go back to it.

// Draw the black circle
context.clip(); // Tell the renderer that was our clip region,
                // since the last `context.save()`.

// Draw the red rectangle.
// It will appear clipped by the black circle.

context.restore(); // Tell the renderer we should restore all
                   // the clipping settings back to what they were
                   // `context.save`d as.

// From here on, nothing is clipped anymore.

现在,在Android中Canvas,您将想要做类似的事情,但是渲染器期望代码略有不同:

// Draw the blue rectangle

canvas.save(); // Same idea as above -- just setting a point we can
               // restore to later.

// Now, `canvas.clipPath` expects a `Path` object.
// Let's create one that contains a circle.
Path path = new Path();
path.addCircle(100, 100, 100, Direction.CW); 
canvas.clipPath(path);

// Draw the red rectangle
// It will be clipped by the circle defined in the `path` that we
// used as the `clipPath`.

canvas.restore(); // Aaaand restore the state.

// Things drawn here won't be clipped anymore.

有关此问题的 Android 文档可能很方便。在StackOverflow上有一个类似这样的好问题,您可能想尝试更多的事情。


3

使用Ankos方法的工作实现:

canvas.drawBitmap(depressingBg, 0, 0, null);
canvas.save();
radius += 400*thread.getDelta(); // expansion speed
Path path = new Path();
// draw around player position
path.addCircle(player.x, player.y, radius, Direction.CW);
canvas.clipPath(path);
canvas.drawBitmap(happyBg, 0, 0, null);
canvas.restore();

感谢Anko的所有帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.