/// <summary> /// 将镜头中心平移到指定的区块 /// </summary> /// <param name="r">区块的横向编号,值域[0, 14],其中7是屏幕纵向正中</param> /// <param name="c">区块的纵向编号,值域[0, 32],其中0是屏幕横向正中</param> public static void Translate(int r, int c) { // 计算运动轨迹 var orgPoint = SCamera3D.GetScreenCoordination(SCamera3D.lastFocusRow, SCamera3D.lastFocusCol); var destPoint = SCamera3D.GetScreenCoordination(r, c); var delta = SCamera3D.GetManhattanDistance(destPoint, orgPoint); var actualBeginPoint = ViewManager.View3D.ST3D_Camera.Position; // 动画 Point3DAnimationUsingKeyFrames v3dAni = new Point3DAnimationUsingKeyFrames(); EasingPoint3DKeyFrame k1 = new EasingPoint3DKeyFrame() { Value = new Point3D(actualBeginPoint.X, actualBeginPoint.Y, SCamera3D.lastZIndex), KeyTime = TimeSpan.FromMilliseconds(0), EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut } }; EasingPoint3DKeyFrame k2 = new EasingPoint3DKeyFrame() { Value = new Point3D(actualBeginPoint.X + delta.X, actualBeginPoint.Y + delta.Y, SCamera3D.lastZIndex), KeyTime = TimeSpan.FromMilliseconds(SCamera3D.animationTimeMS), EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut } }; v3dAni.KeyFrames.Add(k1); v3dAni.KeyFrames.Add(k2); v3dAni.FillBehavior = FillBehavior.Stop; AnimationClock aniClock = v3dAni.CreateClock(); lock (SCamera3D.AnimatingStorySet) { SCamera3D.AnimatingStorySet.Add(aniClock); } v3dAni.Completed += delegate { lock (SCamera3D.AnimatingStorySet) { SCamera3D.AnimatingStorySet.Remove(aniClock); } ViewManager.View3D.ST3D_Camera.Position = new Point3D(actualBeginPoint.X + delta.X, actualBeginPoint.Y + delta.Y, SCamera3D.lastZIndex); }; ViewManager.View3D.ST3D_Camera.BeginAnimation(ProjectionCamera.PositionProperty, v3dAni); // 更新后台 Director.ScrMana.SCameraFocusRow = SCamera3D.lastFocusRow = r; Director.ScrMana.SCameraFocusCol = SCamera3D.lastFocusCol = c; Director.ScrMana.SCameraScale = SCamera3D.lastZIndex; }
/// <summary> /// 初始化镜头系统,必须在使用场景镜头系统前调用它 /// </summary> public static void Init() { // 动画属性 SCamera3D.SCameraAnimationTimeMS = 500; // 尺度初始化 Director.ScrMana.SCameraScale = SCamera3D.orginalCameraZIndex; Director.ScrMana.SCameraFocusCol = 0; Director.ScrMana.SCameraFocusRow = GlobalConfigContext.GAME_SCAMERA_SCR_ROWCOUNT / 2; // 计算区块的横向中点坐标 double blockWidth = SCamera3D.scrWidth / (GlobalConfigContext.GAME_SCAMERA_SCR_COLCOUNT - GlobalConfigContext.GAME_SCAMERA_SCR_SINGLEBLOODCOLCOUNT); double blockOffset = blockWidth / 2.0; var xArr = new double[GlobalConfigContext.GAME_SCAMERA_SCR_COLCOUNT + 1]; for (int i = GlobalConfigContext.GAME_SCAMERA_SCR_COLCOUNT; i >= 1; i--) { xArr[i] = 0 - blockOffset - blockWidth * (GlobalConfigContext.GAME_SCAMERA_SCR_COLCOUNT / 2.0 - i); } xArr[0] = 0; // 计算区块的可视区间 SCamera3D.CharacterBlockList = new List <Tuple <Point3D, Point3D, Point3D, Point3D> >(); for (int i = 0; i <= GlobalConfigContext.GAME_SCAMERA_SCR_COLCOUNT; i++) { var LeftBottom = new Point3D(xArr[i] - 2.031, -4.252, 0); var RightBottom = new Point3D(xArr[i] + 2.031, -4.252, 0); var LeftUp = new Point3D(xArr[i] - 2.031, 1.652, 0); var RightUp = new Point3D(xArr[i] + 2.031, 1.652, 0); SCamera3D.CharacterBlockList.Add(new Tuple <Point3D, Point3D, Point3D, Point3D>(LeftBottom, RightBottom, LeftUp, RightUp)); } // 计算区块中点坐标 double blockHeight = SCamera3D.scrHeight / GlobalConfigContext.GAME_SCAMERA_SCR_ROWCOUNT; SCamera3D.screenPointMap = new Point[GlobalConfigContext.GAME_SCAMERA_SCR_ROWCOUNT, GlobalConfigContext.GAME_SCAMERA_SCR_COLCOUNT + 1]; for (int i = 0; i < GlobalConfigContext.GAME_SCAMERA_SCR_ROWCOUNT; i++) { // 变量j从1开始,为0预留位置,0是预留给屏幕横向的中央 for (int j = 1; j <= GlobalConfigContext.GAME_SCAMERA_SCR_COLCOUNT; j++) { SCamera3D.screenPointMap[i, j] = new Point(xArr[j], (i - GlobalConfigContext.GAME_SCAMERA_SCR_ROWCOUNT / 2) * blockHeight); } } for (int i = 0; i < GlobalConfigContext.GAME_SCAMERA_SCR_ROWCOUNT; i++) { SCamera3D.screenPointMap[i, 0] = new Point(xArr[0], (i - GlobalConfigContext.GAME_SCAMERA_SCR_ROWCOUNT / 2) * blockHeight); } // 计算标准曼哈顿距离表 SCamera3D.manhattanDistanceMap = new Dictionary <Point, Dictionary <Point, Point> >(); for (int i = 0; i < GlobalConfigContext.GAME_SCAMERA_SCR_ROWCOUNT; i++) { for (int j = 0; j <= GlobalConfigContext.GAME_SCAMERA_SCR_COLCOUNT; j++) { var pt = SCamera3D.screenPointMap[i, j]; if (SCamera3D.manhattanDistanceMap.ContainsKey(pt) == false) { SCamera3D.manhattanDistanceMap[pt] = new Dictionary <Point, Point>(); } for (int m = 0; m < GlobalConfigContext.GAME_SCAMERA_SCR_ROWCOUNT; m++) { for (int n = 0; n <= GlobalConfigContext.GAME_SCAMERA_SCR_COLCOUNT; n++) { var rhsPt = SCamera3D.screenPointMap[m, n]; SCamera3D.manhattanDistanceMap[pt][rhsPt] = SCamera3D.GetManhattanDistance(pt, rhsPt); } } } } }
/// <summary> /// 进入场景并做默认拉长焦距效果 /// </summary> public static void PostEnterScene() { SCamera3D.ResumeBlackFrame(); SCamera3D.ResetFocus(true); }
/// <summary> /// 布置场景结束并准备进入时调用此方法以准备动画 /// </summary> public static void PreviewEnterScene() { ViewManager.View3D.ST3D_Camera.Position = new Point3D(0, 0, SCamera3D.orginalCameraZIndex); SCamera3D.FocusOn(GlobalConfigContext.GAME_SCAMERA_SCR_ROWCOUNT / 2, 0, 1.8, true); }
/// <summary> /// 在镜头聚焦的区块上调整焦距 /// </summary> /// <param name="ratio">缩放的倍率,值域(0.0, +∞),原始尺寸对应于1.0</param> public static void Focus(double ratio) { SCamera3D.FocusOn(Director.ScrMana.SCameraFocusRow, Director.ScrMana.SCameraFocusCol, ratio); }