ฉันจะสร้างเอฟเฟกต์ World Healing Wave ได้อย่างไร


14

ฉันต้องการเปลี่ยนพื้นหลังที่มืดและหดหู่ของฉันให้เป็นพื้นหลังหญ้าที่มีความสุขแบบเรียลไทม์ดังนั้นฉากหลังที่มีความสุขจะปรากฏในรัศมีรอบตัวละครเกม

Forcefield ของความสุขถ้าคุณจะ

วิธีนี้สามารถทำได้อย่างมีประสิทธิภาพเท่าที่เป็นไปได้เมื่อแสดงไปยังผืนผ้าใบในมุมมองที่กำหนดเอง


ปรับปรุง: นี่คือวิธีการทำงานในหัวของฉัน:

    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
เทคนิคเรียกว่าWorld Healing Wave
ratchet freak

ฉันใช้ Canvas ในมุมมองที่กำหนดเองซึ่งดำเนินการโดยลูปเกมของฉันเองที่ 60fps
Green_qaue

คุณช่วยแสดงฉากสองครั้งได้ไหม? หนึ่งครั้งสำหรับรุ่นที่หายเป็นปกติหนึ่งครั้งสำหรับรุ่นที่ตายแล้วจากนั้นก็ดึงผู้ที่หายเป็นปกติในวงกลมที่เพิ่มขึ้นเรื่อย ๆ จนกระทั่งวงกลมครอบคลุมทั้งหน้าจอ
Wolfgang Skyler

นั่นคือสิ่งที่ฉันคิด แค่ไม่รู้ว่าจะทำยังไงกับบิตแมป และฉันอาจจะมีวิธีที่ดีกว่าเนื่องจากการแสดงผล 2 bgs ในครั้งเดียวมีค่าใช้จ่ายสูงมาก
Green_qaue

2
ฉันคิดว่าฉันเห็นสิ่งที่สับสนเกี่ยวกับ - Android Canvasทำในสิ่งที่แตกต่างจาก HTML เล็กน้อย<canvas>ซึ่งฉันคิดว่าคุณหมายถึง! ฉันได้แก้ไขคำตอบของฉันเพื่ออธิบายวิธีการตัดโดยทั่วไปโดยมีลิงก์เฉพาะสำหรับ Android และโค้ดตัวอย่าง
Anko

คำตอบ:


20

การสาธิต

เกมDev Healing Wave

GameDev Meta : Henshin Main !! : D

รหัสใช้canvas clipภูมิภาคและrequestAnimationFrameเพื่อคุณภาพและประสิทธิภาพสูงสุด (มันมีชีวิตที่ดีขึ้น)

ฉันคิดว่าคุณหมายถึง HTML canvas! แม้ว่าคุณจะไม่ได้เอ็นจิ้นการเรนเดอร์ตัวอื่น (เช่นไปป์ไลน์เรนเดอร์ 2D ของ Android ซึ่งคุณอาจต้องการ) ก็รองรับเช่นกันขอบเขตของคลิปที่เร่งด้วยฮาร์ดแวร์ รหัสอาจมีลักษณะคล้ายกัน

ขอเฟรมภาพเคลื่อนไหวด้วย 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 สำหรับความช่วยเหลือทั้งหมด!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.