ปิดครั้งแรกผมรู้ว่าสิ่งที่ปัญหาภาพวาดของฉันเป็นและฉันมีความคิดที่แตกต่างกันเกี่ยวกับวิธีการแก้มัน ฉันมาที่นี่เพื่อหาวิธีการปรับเฟรมที่ถูกวาดเพื่อให้ "ภาพลวงตา" มีมิติเท่ากันได้รับการดูแล
ฉันกำลังเขียนเกมดูนกแบบ 2 มิติที่เกิดขึ้นในอวกาศ ฉันกำลังพยายามใช้กราฟิกสามมิติในโลกที่อัพอยู่เหนือไม่มีโลกหมุนของเกมเหมือนในเกมไอโซโทปดั้งเดิม (โปรดจำไว้ว่าเกมเกิดขึ้นในอวกาศไม่มีภูมิประเทศ) นี่คือตัวอย่างสไปรต์ที่ฉันพยายามใช้: http://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64.pngหมุน 64 ครั้งเกี่ยวกับแกนตั้งของมันในมุมมอง 35 องศา (aka, ISO) ภาพถูกสร้างขึ้นดังนั้นสิ่งนี้สามารถเปลี่ยนแปลงได้
เพื่อความชัดเจนฉันได้บอกว่าทิศเหนือ (ขึ้น) คือ 0 องศาและทิศตะวันออก (ขวา) คือ 90
ปัญหาของฉันคือผีสางของฉันไม่ได้ดูเหมือนว่ามันจะหันหน้าไปทางที่เกมคิดว่าเป็นเพราะความแตกต่างในเครื่องบิน 3 มิติที่ใช้ ไม่แน่ใจว่าฉันใช้คำศัพท์อย่างถูกต้องหรือไม่ยานอวกาศของฉันหมุนไปในระนาบเดียวและระนาบมุมมองกำลังคาดหวังว่าสิ่งต่าง ๆ จะหมุนบนเครื่องบินของตัวเอง นี่คือภาพของปัญหา:
http://cell.stat-life.com/images/stories/AsteroidOutpost/ProjectIssue.png ด้านซ้ายฉันมีมุมมองด้านข้างทางขวาฉันมีมุมมองจากบนลงล่าง ด้านบนฉันมีมุมมองของยานอวกาศ / แผ่นสไปรต์ของโลก ที่ด้านล่างฉันมีสิ่งที่เทพดาดูเหมือนเมื่อวาดลงบนหน้าจอ
ที่ด้านบนขวาเป็นเวอร์ชั่นที่เรียบง่ายของวิธีการหมุนยานอวกาศของฉัน (แม้จะมีการแยกองศาระหว่างแต่ละเฟรม) ที่มุมล่างขวาคือมุมที่สไปรต์ดูเหมือนว่ากำลังหันหน้าไปเมื่อวาดมุมใดมุมหนึ่งบนหน้าจอ ปัญหานี้เกิดขึ้นอย่างชัดเจนที่สุดประมาณ 45 องศา นี่คือภาพที่วางซ้อนกับเส้น "ระนาบหน้าจอ" ซึ่งชี้ไปในทิศทางที่เรือควรหันเข้าหา: http://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64RedLine.pngเส้นสีแดงควรเสมอจะชี้ไปในทิศทางเดียวกันกับเรือ แต่เป็นคุณสามารถมองเห็นปัญหาการฉายที่เป็นสาเหตุของปัญหา ฉันหวังว่าฉันจะอธิบายปัญหาได้ดีพอ
แก้ไข: เส้นสีแดงหมุนบนระนาบหน้าจอในขณะที่ยานอวกาศหมุนบน "ระนาบเรือ" ดังนั้นความแตกต่างอย่างมากระหว่างมุมเรือและมุมหน้าจอเมื่อวาด สิ้นสุดการแก้ไข
มันดูค่อนข้างแปลกเมื่อเรือลำนี้ยิงลำแสงเลเซอร์ไปที่เป้าหมายที่อยู่ด้านหนึ่งเมื่อมันควรจะยิงตรงไปข้างหน้า
ดังนั้น ... คำตอบที่ฉันได้มาคือ:
- หยุดพยายามปลอมมุมมองภาพวาดสามมิติไปใหญ่หรือกลับบ้าน หมุนโลกของฉันแล้ว (PS: นี่จะแก้ไขปัญหาของฉันใช่ไหม)
- เปลี่ยนแผ่นสไปรต์ของฉัน (อย่างใด) เพื่อให้มีเฟรมที่แสดงถึง "มุมหน้าจอ" ที่โมเดลจะถูกดู ดังนั้นเมื่อฉันขอภาพ 45 องศาจริง ๆ แล้วมันจะดูเหมือน 45 องศาบนหน้าจอ
- เปลี่ยนระบบการเรนเดอร์ของฉันเพื่อจับเฟรมอื่นจากแผ่นสไปรต์ (อย่างใด) โดยรู้ว่าการที่เฟรม "ปกติ" นั้นดูตลก ดังนั้นแทนที่จะคว้าเฟรม 45 องศามันจะคว้า ... 33 องศาเฟรม (แค่เดา) เพื่อให้มันดูถูกต้องสำหรับผู้ใช้
- เพียงแค่ใช้ 3D! มันง่ายกว่าผู้ชายมาก
สำหรับหนึ่ง:โซลูชันใดที่คุณจะแนะนำ ฉันเอนตัวไปทาง 2 แม้ว่าฉันจะรู้ว่ามันผิด จำไว้ว่าฉันมีสิทธิ์เข้าถึงเครื่องมือสร้างสไปรต์ได้อย่างสมบูรณ์ วิธีที่ 3 จะเป็นตัวเลือกที่สองของฉัน ทั้งสองวิธีนี้ต้องการให้ฉันใช้คณิตศาสตร์กับมุมเพื่อให้ได้ผลลัพธ์ตามที่ต้องการ Btw ฉันได้เพิ่ม # 4 ไว้เป็นเรื่องตลกฉันไม่ต้องการย้ายไปเป็น 3D
สำหรับสอง:การใช้วิธีที่ 2 หรือ 3 ฉันจะปรับมุมอินพุทหรือเอาท์พุทได้อย่างไร ฉันไม่ใช่คนที่เก่งในเรื่องการฉาย 3 มิติและการฝึกอบรม 3 มิติ (ให้การฝึกอบรม 2D อย่างเดียว) และคณิตศาสตร์อะไรก็ตามที่อาจใช้เพื่อให้ได้ผลลัพธ์ตามที่ฉันต้องการ
คิดออกมาดัง ๆ ที่นี่: ถ้าฉันเอาเวกเตอร์หนึ่งหน่วยหันหน้าไปในทิศทางที่ฉันต้องการให้เรือมอง (บนระนาบหน้าจอ) จากนั้นฉายภาพนั้นลงบนระนาบของเรือ ทิศเหนือคือฉันควรจะมีมุมของกราฟิกเรือที่ฉันต้องการแสดง ขวา? (วิธีแก้ปัญหาสำหรับ # 3) ผู้ชาย ... ฉันไม่สามารถทำงานได้
แก้ไข:
ฉันรู้ว่าปัญหายากที่จะเห็นภาพด้วยภาพนิ่งดังนั้นฉันได้ปฏิบัติตาม Sprite Library Visual Tester ของฉันเพื่อแสดงปัญหา: http://cell.stat-life.com/downloads/SpriteLibVisualTest.zipต้องใช้XNA 4.0แอปพลิเคชันนี้คือ เพียงหมุนเทพดาและวาดเส้นจากจุดศูนย์กลางออกไปที่มุมเกมคิดว่าควรหันหน้าเข้าหาเรือ
แก้ไข 8 ก.ย.
ต่อจากย่อหน้าที่ "คิดออกมาดัง": แทนที่จะใช้การฉายภาพ (เพราะมันดูยาก) ฉันคิดว่าฉันสามารถเอาเวกเตอร์หน่วยหันหน้าไปทางทิศเหนือ (0x, 1y, 0z) ให้ใช้เมทริกซ์เพื่อหมุนมุม เทพดาหันหน้าไปทางจริงจากนั้นหมุนอีกครั้งจาก "ระนาบดู" ออกไปด้านนอก "ระนาบผี" รอบแกน X แล้ว ... แบน เวกเตอร์ (โดยพื้นฐานแล้วฉายกลับ) ไปยังระนาบการดูโดยใช้ X และ Y เท่านั้น (ไม่สนใจ Z) จากนั้นใช้เวกเตอร์แบนใหม่นั้นฉันสามารถกำหนดมุมของมันและใช้มันเพื่อ ... บางสิ่งบางอย่าง ฉันจะคิดเพิ่มเติมภายหลัง
แก้ไข ก.ย. 8 (2)
ฉันพยายามติดตามความคิดของฉันจากด้านบนด้วยความสำเร็จใช่ไหม ดังนั้น ... เพื่อให้ได้เส้นสีแดงดูเหมือนว่ามันจะออกมาจากยานอวกาศของฉัน (เพื่อทดสอบเท่านั้น) ฉันทำสิ่งต่อไปนี้:
Vector3 vect = new Vector3(0, 1, 0);
vect = Vector3.Transform(vect, Matrix.CreateRotationZ(rotation));
vect = Vector3.Transform(vect, Matrix.CreateRotationY((float)((Math.PI / 2) - MathHelper.ToRadians(AngleFromHorizon))));
Vector2 flattenedVect = new Vector2(vect.X, vect.Y);
float adjustedRotation = (float)(getAngle(flattenedVect.X, flattenedVect.Y));
rotation
มุมของหน้าจออยู่ที่ไหนและadjustedRotation
ตอนนี้มุมของหน้าจออยู่บนระนาบสไปรต์ ฉันไม่รู้ว่าทำไมฉันต้องหมุน Y แทน X แต่อาจเป็นเรื่องเกี่ยวกับ 3D ที่ฉันไม่รู้
ดังนั้นตอนนี้ฉันมีข้อมูลเพิ่มเติม แต่ฉันจะใช้สิ่งนี้เพื่อเลือกเฟรมที่เหมาะสมได้อย่างไร บางทีแทนที่จะหมุนจากระนาบมุมมองไปที่ระนาบสไปรต์แล้วจึงฉายกลับมาฉันควรพยายามทำอย่างอื่นรอบ ๆ นี่คือสไปรท์ของฉันที่มีเส้นสีแดงที่ปรับแล้ว แต่สิ่งที่ฉันต้องการทำคือการปรับโมเดลไม่ใช่บรรทัด: http://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64RedLineCorrected.png
แก้ไข 9 ก.ย.
Horay! มันได้รับการแก้ไข! ฉันจะอธิบายสิ่งที่ฉันทำเพื่อแก้ไข:
ฉันทำตามคำแนะนำของ eBusiness และ "squished" โดยระบบพิกัดโลก (หรือยืด ... ) นี่เป็นวิธีแก้ปัญหา # 1 แม้ว่าฉันจะอยู่ภายใต้การแสดงผลที่ฉันจะต้องหมุนระบบพิกัดโลกของฉันเกี่ยวกับระบบ coord ของหน้าจอ ไม่จริง! ขึ้นยัง + y และขวายัง + x ฉันปรับเปลี่ยนวิธีการ WorldToScreen และ ScreenToWorld ของฉันเพื่อแปลงระหว่างโลกและพิกัดหน้าจออย่างถูกต้อง วิธีการเหล่านี้อาจไม่เหมาะสม แต่นี่เป็นเพียงสองวิธีใน codebase ของฉันที่ต้องเปลี่ยน
public Vector2 ScreenToWorld(float x, float y)
{
float deltaX = x - (size.Width / 2f);
float deltaY = y - (size.Height / 2f);
deltaX = deltaX * scaleFactor / (float)Math.Sqrt(3);
deltaY = deltaY * scaleFactor;
return new Vector2(focusWorldPoint.X + deltaX, focusWorldPoint.Y + deltaY);
}
public Vector2 WorldToScreen(float x, float y)
{
float deltaX = x - focusWorldPoint.X;
float deltaY = y - focusWorldPoint.Y;
deltaX = deltaX / scaleFactor * (float)Math.Sqrt(3);
deltaY = deltaY / scaleFactor;
return new Vector2(size.Width / 2f + deltaX, size.Height / 2f + deltaY);
}
นั่นมัน! การเปลี่ยนวิธีการทั้งสองนั้นมีผลต่อทุกอย่างอื่น: สิ่งที่ฉันกำลังดูอยู่ที่วัตถุที่วาดที่ฉันคลิกทุกอย่าง ยานอวกาศของฉันตอนนี้ดูที่เป้าหมายที่กำลังยิงโดยตรงและทุกอย่างก็เข้าที่ ฉันจะทำการทดลองกับการฉายภาพแบบออโทกราฟฟีดูว่ามันทำให้ทุกอย่างดูสมจริงขึ้นหรือไม่