เช่นเดียวกับจิมมี่กล่าวว่าวงรีน่าจะเหมาะกับการเคลื่อนไหวนี้มากขึ้น นี่คือแนวคิดบางส่วนเกี่ยวกับวิธีการใช้งานจริงโดยมีรายละเอียดเพิ่มเติมเล็กน้อยสำหรับผู้ที่สนใจ
ใช้เวลา
สำหรับผู้เริ่มคุณต้องมีตัวแปรเพื่อติดตามเวลาในโลกของเกม คุณสามารถนำไปใช้ในแบบที่คุณชอบได้ แต่นี่คือตัวอย่าง ฉันจะใช้ตัวแปรที่เรียกhours
ว่าแตกต่างกันไปตั้งแต่ 0 ถึง 24 (แม้ว่าจะถึง 24 มันจะย้อนกลับไปที่ 0)
ต่างจากชีวิตจริงฉันจะแค่คิดว่าวันนั้นเริ่มต้นที่ 0 ชั่วโมงและกลางคืนเริ่มต้นที่ 12 ชั่วโมง นี่จะทำให้การคำนวณบางอย่างง่ายขึ้น
ฉันจะกำหนดอัตราที่เวลาของเกมเปลี่ยนแปลงไปตามเวลาจริง ในตัวอย่างนี้เวลาจริงทุกสองนาทีจะตรงกับหนึ่งชั่วโมงในเกม
float hours = 0.0f; // From 0 to 24 wrapping around
const float HoursPerSecond = 1f / 120f; // E.g. 2 minutes = 1 hour ingame
public void Update(float elapsed)
{
hours += elapsed * HoursPerSecond; // Advance clock
if(hours >= 24f) hours -= 24f; // Wrap around 24 hours
}
องค์ประกอบ
ตอนนี้ก่อนที่จะตั้งค่าการเคลื่อนไหวของดวงอาทิตย์ของเราเราต้องระบุพารามิเตอร์บางอย่าง โดยเฉพาะอย่างยิ่งที่ค่า X ใดที่เพิ่มขึ้นจากขอบฟ้าและที่ค่า X ใดที่ตกอยู่ในขอบฟ้า นอกจากนี้สิ่งที่ Y สอดคล้องกับเส้นขอบฟ้าและสิ่งที่เขาควรจะสูงกว่าเส้นนั้น
float startX = 0;
float endX = 1000;
float horizonY = worldHeight/2;
float amplitudeY = 200;
การคำนวณพิกัดของดวงอาทิตย์
ตอนนี้ถึงเวลาที่จะคำนวณตำแหน่งของดวงอาทิตย์ของเราตามเวลาที่กำหนดในแต่ละวัน ฉันจะใช้ฟังก์ชันพารามิเตอร์แบบเดียวกับที่จิมมี่ใช้ แต่มีโดเมนตั้งแต่ [0..2PI] แทน (เพื่อให้ดวงอาทิตย์กลับสู่ตำแหน่งเดิมในเวลารุ่งสาง):
x = (1-cos (t)) / 2
y = sin (t)
นี่เป็นฟังก์ชั่นที่ดีเพราะค่า X แตกต่างจาก 0 ถึง 1 แล้วกลับไปที่ 0 อีกครั้ง (ซึ่งเราจะทำการจับคู่กับค่าเริ่มต้นและสิ้นสุด X ของดวงอาทิตย์) และค่า Y เริ่มต้นที่ 0 และเลื่อนขึ้นไป 1 และย้อนกลับ เป็น 0 อีกครั้ง (ซึ่งจะเป็นส่วนวันของเรา) จากนั้นทำซ้ำสิ่งเดียวกันที่แน่นอนในด้านลบก่อนที่จะกลับไปที่ตำแหน่งเดิม (ซึ่งจะเป็นคืนของเราแม้ว่าดวงอาทิตย์จะไม่ถูกดึงมาที่จุดนี้)
ขั้นตอนแรกคือการปรับจำนวนชั่วโมงจากช่วง [0..24) เป็นช่วงของฟังก์ชันของเราซึ่งคือ [0..2PI):
float t = (hours / 24f) * MathHelper.TwoPi; // Scale: [0..24) to [0..2PI)
ต่อไปเราใช้ฟังก์ชั่นเพื่อรับค่าระหว่าง 0 และ 1 ที่ฉันพูดถึงข้างต้น:
float horizontal = (float)((1-Math.Cos(t)) / 2f); // Changes: 0 1 0
float vertical = (float)(Math.Sin(t)); // Changes: 0 1 0 -1 0
และในที่สุดเราก็ปรับค่าเหล่านั้นโดยใช้พารามิเตอร์ของดวงอาทิตย์:
float sunX = startX + (endX - startX) * horizontal; // From startX to endX and back
float sunY = horizonY + amplitydeY * vertical; // Up and down around horizonY