虽然例8-8已经可以运行,但是还存在一个重要不足:地球和月球之间的旋转关系还没有实现,本小节将依靠相对坐标系的便利,实现月球的公转。
(1)要实现moon围绕earth的公转,需要考虑相对坐标系的问题。
在创建例8-8的时候,已经规定earth和moon都是earth_system实例内部的对象,所以earth_system是earth和moon的父容器。如果对earth和moon应用变换矩阵,则变换将根据earth_system的相对坐标系进行。虽然moon公转的实现方法不限一途,但最便捷的方法是借助earth_system对象的相对坐标系。在earth_system对象内部,将earth对象的中心移动到相对坐标系的坐标原点,并修改moon的位置,使其符合常识。相对坐标系的关系请参考图:

根据相对坐标系修改好earth和moon的位置,再根据实现地球公转的方法,编写代码实现月球公转,其原理就较为简单了。
(2)打开例8-8对其进行补充修改。增加函数inneranim()控制earth_system对象内部的旋转:
……
var myMatrix_inner:Matrix=earth_system.moon.transform.matrix;
……
transtimer.start();
……
function inneranim(){
myMatrix_inner.rotate(Math.PI/10);
earth_system.moon.transform.matrix=myMatrix_inner;
}
……
function transtimerHandler(event:TimerEvent):void {
//动画代码编写入口
//rootanim();//暂时注释掉地球公转
inneranim();
}
为了演示清楚,请在动画代码入口处暂时注释掉rootanim()的调用。
(3)运行修改后的程序,可以看到,在程序运行时月球开始围绕地球转动了。代码的本质是moon围绕earth_system的相对坐标系原点旋转,但由于在设计阶段借用了相对坐标系,使得earth的中心恰巧处在earth_system相对坐标系的原点位置,极大的简化了代码量。
取消对rootanim()的注释,完整的运行例8-8。通过这短短几行代码,地球的公转和月球的公转都被表现了出来!进一步增加代码,还可以轻松实现earth和moon的自转,请有兴趣的读者尝试。
图展示了动画运行阶段的分镜头:

因为例8-8借助设计阶段的巧妙安排,使得编程中许多调整位置的步骤被省略。这就有效精简了代码,使得程序简短高效。在项目分析阶段,应该尽量利用设计带来的便利,简化编程步骤;同时也要尽量发挥程序的灵活性优势,减少设计阶段的重复工作量。
附上例8-8的完整程序代码如下:
var transtimer:Timer = new Timer(50, 150);
transtimer.addEventListener("timer", transtimerHandler);
transtimer.addEventListener("timerComplete", transComplete);
//为动画美观,移动动画对象到出发点
earth_system.x=345;
earth_system.y=5;
//拷贝动画对象的变换矩阵
var myMatrix:Matrix=earth_system.transform.matrix;
var myMatrix_inner:Matrix=earth_system.moon.transform.matrix;
//定时器开始
transtimer.start();
//控制地球公转
function rootanim(){
myMatrix.rotate(Math.PI/3650);
earth_system.transform.matrix=myMatrix;
}
//控制月球公转
function inneranim(){
myMatrix_inner.rotate(Math.PI/10);
earth_system.moon.transform.matrix=myMatrix_inner;
}
//定时器触发响应
function transtimerHandler(event:TimerEvent):void {
//动画代码编写入口
rootanim();//调用地球公转
inneranim();//调用月球公转
}
//重设定时器
function transComplete(event:TimerEvent):void {
transtimer.reset();
transtimer.start();
}
月球公转动画实现
1718

被折叠的 条评论
为什么被折叠?



