แนวทางปฏิบัติที่ดีที่สุดสำหรับภาพเคลื่อนไหวของ Sprite


18

ฉันต้องการได้รับการจัดการที่ดีขึ้นเกี่ยวกับวิธีที่ผู้คนในโลกแห่งความจริงจัดการกับอนิเมชั่นของพวกเขา

คุณโหลดภาพขนาดใหญ่ 1 ภาพแล้ววาดสี่เหลี่ยมต่าง ๆ ตามเฟรมภาพเคลื่อนไหวหรือไม่?

คุณโหลดไฟล์ภาพ X ลงในอาร์เรย์และวาดรายการในอาร์เรย์โดยใช้เฟรมภาพเคลื่อนไหวหรือไม่?

คุณจัดการกับการเคลื่อนไหวที่มีความยาวต่างกันอย่างไรสำหรับสไปรต์ต่างๆ

สมมติว่าการเดินตัวละครใช้เวลา 4 - 8 เฟรมและคลื่นบนชายหาดใช้เวลาเพียง 2 - 3 เฟรม คุณจะรับมือกับสถานการณ์นั้นอย่างไร ดูด้านล่าง

Dim Waves(1) as Sprite
Dim Char(5) as Sprite

Sub Animate()
     Frame += 1
     Draw Char(Frame)
     Draw Waves(Frame)
     If Frame = 5 Then Frame = 0
End Sub

เห็นได้ชัดว่าคลื่นจะจบลงด้วยข้อผิดพลาดนอกขอบเขต

หรือคุณมีเทพดากังวลเกี่ยวกับภาพเคลื่อนไหวของตัวเองและไม่สนใจกรอบเลย การสไปรต์แต่ละครั้งจะรู้จักวงแอนิเมชั่นของตัวเองบ้างไหม?

คำตอบ:


23

วิธีที่ผมเคยทำมาแล้วในอดีตคือการแยกข้อมูลภาพเคลื่อนไหวจากการเล่นภาพเคลื่อนไหว Animationแล้วจะกลายเป็นพื้นอาร์เรย์ของFramesและคุณสมบัติบางอย่างที่อธิบายถึงวิธีการเคลื่อนไหวควรประพฤติ (ถ้าลูป ฯลฯ )

ฉันมักจะโหลดภาพหนึ่งภาพและวาดเป็นชิ้น ๆ

แต่ละอFrameนิเมชั่นนั้นเป็นรูปสี่เหลี่ยมผืนผ้าและระยะเวลา วิธีนี้ช่วยให้เฟรมบางเฟรมแสดงนานกว่าเฟรมอื่นซึ่งอาจเป็นหรือไม่ใช่สิ่งที่คุณต้องการ หากคุณต้องการให้เฟรมทั้งหมดในภาพเคลื่อนไหวแสดงเป็นระยะเวลาเท่ากันให้เก็บภาพนั้นไว้ในAnimationวัตถุของคุณ

สิ่งที่ตอบสนองความต้องการในการเล่นภาพเคลื่อนไหวมีของตัวเองซึ่งสามารถชี้ไปยังAnimationPlayer Animationวัตถุผู้เล่นจะดูแลการเล่นภาพเคลื่อนไหวและทำให้ "เฟรมปัจจุบัน" พร้อมใช้งาน

ข้อได้เปรียบสำหรับฉันนี้คือฉันสามารถมีอินสแตนซ์เดียวของAnimationวัตถุจำนวนมากที่สามารถชี้และเล่นส่วนต่าง ๆ ในเวลาเดียวกัน นอกจากนี้ยังง่ายต่อการเปลี่ยนภาพเคลื่อนไหวโดยเพียงแค่ชี้AnimationPlayerไปที่Animationวัตถุอื่นและรีเซ็ตการเล่น

แก้ไข : นี่คือการใช้งานจาวาสคริธรรมพื้นฐานของระบบที่อธิบายข้างต้น ฉันโยนมันเข้าด้วยกันในไม่กี่นาทีเป็นสาธิต รหัส "ของจริง" จะมีคุณสมบัติเพิ่มเติม คุณจะต้องมีเบราว์เซอร์ที่ทันสมัยที่รองรับทั้ง Canvas และ Data URI เพื่อให้สามารถใช้งานได้


1
เขาพูดอะไร. นอกจากนี้มักจะสะดวกในการชดเชย x / y สำหรับแต่ละเฟรมในภาพเคลื่อนไหวเพื่อให้คุณสามารถบรรจุรูปภาพสไปรต์ลงในกล่องขอบเขตของพวกเขาอย่างแน่นหนาได้ นอกจากนี้ยังช่วยให้คุณทำสิ่งพื้นฐานบางอย่างเช่นการกระตุกด้วยการใช้เพียงภาพเดียว
เอื้อเฟื้อเผื่อแผ่

ใช่ฉันเห็นด้วยอย่างยิ่ง อันที่จริงแล้วระบบภาพเคลื่อนไหวที่ฉันใช้นั้นสามารถทำได้ มันทำให้ง่ายขึ้นมากในการเปลี่ยนตำแหน่งของเฟรมใด ๆ โดยไม่ต้องไปแก้ไขข้อมูลภาพ
Zack The Human

ตัวอย่างการทำงานที่ดี WOW Thumbs up อยากจะแนะนำ
DFectuoso

ข้อ จำกัด ที่สำคัญของประเภทภาพเคลื่อนไหวคือตัวเลขไม่สามารถดูจากมุมที่แตกต่าง - เดินออกไปจากผู้ชมเดินไปที่ผู้ชม ฯลฯ หรือฉันผิด?
Majid Fouladpour

@MajidFouladpour ฉันไม่คิดว่ามีข้อ จำกัด ประเภทใดที่ใช้เทคนิคนี้ คุณมีอนิเมชั่น AnimationData ที่แตกต่างกันสำหรับแต่ละมุมมอง
Zack The Human

1

ฉันจะให้อนิเมชั่นรู้จำนวนเฟรมที่มี สถานที่และวิธีเก็บรักษาสิ่งเหล่านี้ค่อนข้างไม่เกี่ยวข้องยกเว้นปัญหาด้านประสิทธิภาพ (เช่นคุณอาจต้องการเก็บไว้ในพื้นผิวเดียวกัน) ฉันจะไม่เพิ่ม 1 จำนวน framecount ฉันจะเพิ่ม deltaTime * animSpeed ​​และแปลงค่านั้นเป็นจำนวนเต็มเมื่อแสดง วิธีนี้ทำให้คุณสามารถชะลอหรือเพิ่มความเร็วของภาพเคลื่อนไหวและมีอัตราเฟรมอิสระ

ดังนั้นผีสางจะมีภาพเคลื่อนไหวที่ปรับปรุงตัวเอง


0

ทำไมไม่เพียงแค่มีจำนวนเฟรมสำหรับแต่ละวัตถุของคุณเก็บไว้? ส่วนตัวฉันส่งจำนวนเฟรมในภาพเคลื่อนไหวไปยังวัตถุของฉันในตัวสร้างของพวกเขาจากนั้นฉันมีฟังก์ชั่นมาตรฐาน Animate () ซึ่งใช้จำนวนเฟรมในภาพเคลื่อนไหว


0

มันขึ้นอยู่กับการใช้งาน ในเอ็นจิ้นของฉันฉันทำแอนิเมชันทั้ง Direct3D และ DirectDraw

ใน DirectDraw ฉันสร้างภาพใหญ่หนึ่งภาพ ทุกอย่างได้รับการจัดเก็บไว้ในหน่วยความจำของระบบอย่างไรก็ตามในที่สุดก็มาถึงบล็อกข้อมูลแบบหนึ่งมิติ

ข้อดี:

  • เคลื่อนย้ายง่ายระหว่างเฟรม เปลี่ยนตัวชี้เริ่มเพิ่มระยะห่าง (ความกว้างของภาพรวม) ทุก ๆ y และคุณสีทอง

จุดด้อย:

  • ไม่เพียงแค่คัดลอกหนึ่งเฟรมไปยังหน้าจอคุณต้องทำด้วยตนเอง

  • บล็อกยักษ์แห่งความทรงจำ เฟรมเร่งรีบมาด้วยการลงโทษ

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

ข้อดี:

  • คุณสามารถคัดลอกเฟรมตรงไปที่หน้าจอเพราะมันเป็นเอนทิตีที่แยกกันทั้งหมด

จุดด้อย:

  • หน่วยความจำขาดการจัดตำแหน่ง

0

ในเกมของฉันฉันได้ให้ Sprite base class ความรู้เกี่ยวกับวิธีการวาดตัวเองและองค์ประกอบภาพเคลื่อนไหวทั้งหมดสืบทอดความรู้นั้น: จำนวนและระยะเวลาของเฟรมภาพเคลื่อนไหว, ตำแหน่งบนหน้าจอ, ฯลฯ เกมหลักวนซ้ำทั้งหมด ของสไปรต์ขอให้แต่ละคนวาดตัวเองตามที่เห็นสมควร ดูเหมือนว่าจะทำงานได้ค่อนข้างดีและเป็นมอดูลัสเล็กน้อยในการบูต: หากคุณเพิ่ม sprite ใหม่ที่มีลูปแอนิเมชันต่าง ๆ (หรือซับซ้อนยิ่งขึ้น: สถานะแอนิเมชันหลายตัว) คุณไม่จำเป็นต้องย้อนกลับไปเขียน Animate ของคุณใหม่ () รูทีนเพื่อรองรับความซับซ้อนเพิ่มเติม:

Dim Waves as Sprite
Dim Char as Sprite

Sub Animate()
     Char.update()
     Waves.update()
End Sub

ทุกครั้งที่มีการเรียกเมธอด update () ของ sprite จะรู้ได้ว่าควรวาดใหม่เฟรมเดียวกันกับครั้งที่แล้วย้ายไปที่เฟรมถัดไปในภาพเคลื่อนไหวปัจจุบันเปลี่ยนเป็นภาพเคลื่อนไหวใหม่เป็นต้น

สิ่งนี้มีประโยชน์เพิ่มเติมในการทำให้การปรับเฟรมให้ง่ายขึ้นเพื่อรองรับความเร็วในการเรนเดอร์นาฬิกา / แพลตฟอร์มที่แตกต่างกันเพราะการเปลี่ยนแปลงเพียงอย่างเดียวคือความถี่ที่คุณเรียกแอนนิเมท ()

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