/// <summary> /// Constructor for deserialization. /// </summary> /// <param name="info">info is the serialization info to deserialize with</param> /// <param name="context">context is the context in which to deserialize...?</param> protected SunburnSprite_cl(SerializationInfo info, StreamingContext context) { mBaseRenderableEffectName = info.GetString("TextureName"); mRectangle = (FloatRectangle)info.GetValue("Rectangle", typeof(FloatRectangle)); mSize = (Vector2)info.GetValue("SpriteSize", typeof(Vector2)); }
/// <summary> /// On the update, the animated component sets the image on the renderable component to the current frame of animation. /// </summary> public void Update() { Animation currentAnimation = Animations[mCurrentAnimation]; RotationComponent rotation = (RotationComponent)(mParentEntity.GetComponentOfType(typeof(RotationComponent))); RotationComponent.CardinalDirections animDirection = (rotation == null) ? RotationComponent.CardinalDirections.NONE : rotation.GetCardinalOrientation(); mAccumulatedFrameTime += Game_cl.BaseInstance.Timer.UnpausedElapsedMilliseconds * Math.Abs(mSpeed); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TODO: Make the value '1000.0f / 30.0f' be a private static variable or something instead of always calculating it multiple times every frame. [JSD 09/27/11] ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (mAccumulatedFrameTime > 1000.0f / 30.0f /* The time needed to advance one frame at 30fps */) { mAccumulatedFrameTime -= 1000.0f / 30.0f; FloatRectangle rect = new FloatRectangle(); Script script = new Script(); bool playReversed = false; if (mSpeed < 0) { playReversed = true; } bool spriteFlipped; currentAnimation.GetFrameInfo(ref mCurrentKey, ref mFramesOnKey, ref rect, ref script, animDirection, out spriteFlipped, playReversed); ProcessScript(script); SunburnSprite_cl currentSprite = ((RenderableComponent_cl)mParentEntity.GetComponentOfType(typeof(RenderableComponent_cl))).Sprite; currentSprite.LoadContent(currentAnimation.TextureName); currentSprite.Flipped = spriteFlipped; currentSprite.Rectangle = rect; // Process motion delta channels here. PhysicsComponent_cl physics = ((PhysicsComponent_cl)mParentEntity.GetComponentOfType(typeof(PhysicsComponent_cl))); Dictionary<int, Vector2> motionDeltas = null; currentAnimation.GetMotionDeltas(mCurrentKey, out motionDeltas); if (motionDeltas != null) { foreach (KeyValuePair<int, Vector2> deltaPair in motionDeltas) { if (DoesUseMotionDelta(deltaPair.Key)) { Vector2 motionDelta = deltaPair.Value; float timeBasedConstant = Game_cl.BaseInstance.Timer.UnpausedElapsedMilliseconds / (currentAnimation.FrameDurations[mCurrentKey] * 1000.0f / 30.0f); Vector2 forwardDelta; Vector2 upwardDelta; // Not a TODO, but what's going on here? Just curious // - JSD switch (deltaPair.Key) { /************************************************************************ * HACK: * Hacking for Finale. Motion delta coming from the tool as (X, Y) will translate * to horizontal and vertical movement on the 2D plane. Positive X is in the * current direction the character is facing. Positive Y is always up. * * Larsson Burch - 2011/11/16 - 13:26 ************************************************************************/ case 0: // Position motionDelta.X *= timeBasedConstant; motionDelta.Y *= timeBasedConstant; forwardDelta = rotation.Direction * motionDelta.X; upwardDelta = rotation.DirectionUp * motionDelta.Y; physics.AddedPosition = new Vector2((forwardDelta.X + upwardDelta.X), (forwardDelta.Y + upwardDelta.Y)); break; case 1: case 2: case 3: case 4: case 5: // Velocity motionDelta.X *= timeBasedConstant; motionDelta.Y *= timeBasedConstant; // tested values - motionDelta: 4.0, Density: 10, Area = 16, Mass = 160 forwardDelta = rotation.Direction * motionDelta.X; upwardDelta = rotation.DirectionUp * motionDelta.Y; Vector2 newVelocity = new Vector2((forwardDelta.X + upwardDelta.X), (forwardDelta.Y + upwardDelta.Y)); if (newVelocity.Length() > 0) { physics.Velocity = newVelocity; } break; case 6: case 7: case 8: case 9: case 10: // Force motionDelta.X *= timeBasedConstant * 1000.0f; // scale, N to kN motionDelta.Y *= timeBasedConstant * 1000.0f; // tested values - motionDelta: 4.0-8.0, Density: 10, Area = 16, Mass = 160 forwardDelta = rotation.Direction * motionDelta.X; upwardDelta = rotation.DirectionUp * motionDelta.Y; physics.Force = new Vector2((forwardDelta.X + upwardDelta.X), (forwardDelta.Y + upwardDelta.Y)); break; case 11: case 12: case 13: case 14: case 15: // Impulse motionDelta.X *= timeBasedConstant * 1000.0f; // scale, N to kN motionDelta.Y *= timeBasedConstant * 1000.0f; // tested values - motionDelta: 0.1, Density: 10, Area = 16, Mass = 160 forwardDelta = rotation.Direction * motionDelta.X; upwardDelta = rotation.DirectionUp * motionDelta.Y; Vector2 newImpulse = new Vector2((forwardDelta.X + upwardDelta.X), (forwardDelta.Y + upwardDelta.Y)); if (newImpulse.Length() > 0) { physics.Impulse = newImpulse; } break; case 16: case 17: case 18: case 19: case 20: // Jump Impulse motionDelta.X *= 1000.0f; // scale, N to kN motionDelta.Y *= 1000.0f; // tested values - motionDelta: 0.1, Density: 10, Area = 16, Mass = 160 forwardDelta = rotation.Direction * motionDelta.X; upwardDelta = rotation.DirectionUp * motionDelta.Y; physics.JumpImpulse = new Vector2((forwardDelta.X + upwardDelta.X), (forwardDelta.Y + upwardDelta.Y)); break; case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: default: forwardDelta = rotation.Orientation * motionDelta.Y; upwardDelta = rotation.OrientationRight * motionDelta.X; ((PositionComponent_cl)mParentEntity.GetComponentOfType(typeof(PositionComponent_cl))).SetPosition2D(((PositionComponent_cl)mParentEntity.GetComponentOfType(typeof(PositionComponent_cl))).Position2D.X + forwardDelta.X + upwardDelta.X, ((PositionComponent_cl)mParentEntity.GetComponentOfType(typeof(PositionComponent_cl))).Position2D.Y + (forwardDelta.Y + upwardDelta.Y) * 0.57735f); break; } } } } } }
/// <summary> /// QueueAnimation is the method by which we tell a new animation to play from the beginning. /// </summary> /// <param name="animationName">animationName is the string name by which the animation we want to play is /// indexed into the hashmap.</param> /// <param name="frame"></param> /// <param name="speed"></param> public void QueueAnimation(string animationName, int frame = 0, float speed = 1.0f) { // f**k - took out the check to see if this animation is already playing so that we can jump to frames in a current anim... is this okay? RotationComponent rotation = (RotationComponent)(mParentEntity.GetComponentOfType(typeof(RotationComponent))); RotationComponent.CardinalDirections animDirection = RotationComponent.CardinalDirections.NONE; if (rotation != null) { animDirection = rotation.GetCardinalOrientation(); } mCurrentAnimation = animationName; Animation currentAnimation = Animations[mCurrentAnimation]; FloatRectangle rect = new FloatRectangle(); Script script = new Script(); bool spriteFlipped; mCurrentKey = frame; mFramesOnKey = 0; currentAnimation.GetFrameInfo(ref mCurrentKey, ref mFramesOnKey, ref rect, ref script, animDirection, out spriteFlipped, false); mCurrentKey = frame; mFramesOnKey = 0; //ProcessScripts(scripts); SunburnSprite_cl currentSprite = ((RenderableComponent_cl)mParentEntity.GetComponentOfType(typeof(RenderableComponent_cl))).Sprite; currentSprite.Rectangle = rect; currentSprite.LoadContent(currentAnimation.TextureName); mSpeed = speed; }
/// <summary> /// /// </summary> /// <param name="currentKey"></param> /// <param name="framesOnKey"></param> /// <param name="rect"></param> /// <param name="script"></param> /// <param name="direction"></param> /// <param name="spriteFlipped"></param> /// <param name="reversed"></param> public virtual void GetFrameInfo(ref int currentKey, ref int framesOnKey, ref FloatRectangle rect, ref Script script, RotationComponent.CardinalDirections direction, out bool spriteFlipped,bool reversed = false) { framesOnKey++; if (framesOnKey > mFrameDurations[currentKey]) { framesOnKey = 0; if (reversed) { currentKey--; if (currentKey < 0) { currentKey = mFrames[DirectionMap[RotationComponent.CardinalDirections.N]].Count - 1; } } else { currentKey++; if (currentKey > mFrames[DirectionMap[RotationComponent.CardinalDirections.N]].Count - 1) { currentKey = 0; } } } if (mFrames.Count == 1) { rect = mFrames[RotationComponent.CardinalDirections.NONE][currentKey]; } else { rect = mFrames[mDirectionMap[direction]][currentKey]; } if (direction > RotationComponent.CardinalDirections.S && mDirectionMap[RotationComponent.CardinalDirections.SW] != RotationComponent.CardinalDirections.SW) { spriteFlipped = true; } else { spriteFlipped = false; } script.AddRange(mWholeAnimationScript); if (mFrameScripts.ContainsKey(currentKey)) { script.AddRange(mFrameScripts[currentKey]); } }
/// <summary> /// /// </summary> /// <param name="direction"></param> /// <param name="frame"></param> /// <param name="index"></param> public void AddFrame(RotationComponent.CardinalDirections direction, FloatRectangle frame, int index) { // Add a keyframe dictionary if one doesn't exist for the specified direction. if(mFrames.ContainsKey(direction) == false) { mFrames.Add(direction, new KeyFrameDictionary()); } if (mFrames[direction].ContainsKey(index)) { mFrames[direction][index] = frame; } else { mFrames[direction].Add(index, frame); } // Make sure a script exists for this keyframe index if(mFrameScripts.ContainsKey(index) == false) { mFrameScripts.Add(index, new Script()); } if (direction == RotationComponent.CardinalDirections.NONE) { foreach (RotationComponent.CardinalDirections animDirection in Enum.GetValues(typeof(RotationComponent.CardinalDirections))) { mDirectionMap[animDirection] = RotationComponent.CardinalDirections.NONE; } } }
private void mAddFrameButton_Click(object sender, EventArgs e) { if (mSpriteSheetImage != null) { mSelectionRect.X = mPictureBox.SelectionRect.X; mSelectionRect.Y = mPictureBox.SelectionRect.Y; mSelectionRect.Width = mPictureBox.SelectionRect.Width; mSelectionRect.Height = mPictureBox.SelectionRect.Height; if ((mSelectionRect.Width > 0) && (mSelectionRect.Height > 0)) { StopAnimation(); Bitmap imageToCopy = new Bitmap(mSpriteSheetImage); if (mSelectionRect.Width > mGridWidth) { if (mSelectionRect.Height > mGridHeight) { MessageBox.Show("Select only one row or column."); return; } int numCells = mSelectionRect.Width / mGridWidth; for (int i = 0; i < numCells; i++) { System.Drawing.Rectangle cellRect = new System.Drawing.Rectangle(mPictureBox.SelectionRect.X + (i * mGridWidth), mPictureBox.SelectionRect.Y, mGridWidth, mGridHeight); FloatRectangle cellFloatRect = new FloatRectangle(); cellFloatRect.U = cellRect.X / (float)mSpriteSheetWidth; cellFloatRect.V = cellRect.Y / (float)mSpriteSheetHeight; cellFloatRect.Width = (float)cellRect.Width / mSpriteSheetWidth; cellFloatRect.Height = (float)cellRect.Height / mSpriteSheetHeight; if (mMultidirCheckBox.Checked) { mCurrentAnimation.AddFrame(GetDirectionFromString(mDirectionComboBox.Text), cellFloatRect, mCurrentAnimation.Frames[mCurrentAnimation.DirectionMap[GetDirectionFromString(mDirectionComboBox.Text)]].Count); } else { mCurrentAnimation.AddFrame(RotationComponent.CardinalDirections.NONE, cellFloatRect, mCurrentAnimation.Frames[mCurrentAnimation.DirectionMap[RotationComponent.CardinalDirections.NONE]].Count); } Bitmap croppedImage = imageToCopy.Clone(cellRect, imageToCopy.PixelFormat); mKeyframeImageList.Add(croppedImage); mImageView.AddImage(mKeyframeImageList[mKeyframeImageList.Count - 1]); mImageView.PictureBoxes[mImageView.PictureBoxes.Count - 1].MouseClick += new System.Windows.Forms.MouseEventHandler(imageViewKeyframe_Click); if (!mCurrentAnimation.FrameDurations.ContainsKey(mKeyframeImageList.Count - 1)) { mCurrentAnimation.FrameDurations.Add(mCurrentAnimation.FrameDurations.Count, 1); } } } else if (mSelectionRect.Height > mGridHeight) { if (mSelectionRect.Width > mGridWidth) { MessageBox.Show("Select only one row or column."); return; } int numCells = mSelectionRect.Height / mGridHeight; for (int i = 0; i < numCells; i++) { System.Drawing.Rectangle cellRect = new System.Drawing.Rectangle(mPictureBox.SelectionRect.X, mPictureBox.SelectionRect.Y + (i * mGridHeight), mGridWidth, mGridHeight); FloatRectangle cellFloatRect = new FloatRectangle(); cellFloatRect.U = cellRect.X / (float)mSpriteSheetWidth; cellFloatRect.V = cellRect.Y / (float)mSpriteSheetHeight; cellFloatRect.Width = (float)cellRect.Width / mSpriteSheetWidth; cellFloatRect.Height = (float)cellRect.Height / mSpriteSheetHeight; if (mMultidirCheckBox.Checked) { mCurrentAnimation.AddFrame(GetDirectionFromString(mDirectionComboBox.Text), cellFloatRect, mCurrentAnimation.Frames[mCurrentAnimation.DirectionMap[GetDirectionFromString(mDirectionComboBox.Text)]].Count); } else { mCurrentAnimation.AddFrame(RotationComponent.CardinalDirections.NONE, cellFloatRect, mCurrentAnimation.Frames[mCurrentAnimation.DirectionMap[RotationComponent.CardinalDirections.NONE]].Count); } Bitmap croppedImage = imageToCopy.Clone(cellRect, imageToCopy.PixelFormat); mKeyframeImageList.Add(croppedImage); mImageView.AddImage(mKeyframeImageList[mKeyframeImageList.Count - 1]); mImageView.PictureBoxes[mImageView.PictureBoxes.Count - 1].MouseClick += new System.Windows.Forms.MouseEventHandler(imageViewKeyframe_Click); if (!mCurrentAnimation.FrameDurations.ContainsKey(mKeyframeImageList.Count - 1)) { mCurrentAnimation.FrameDurations.Add(mCurrentAnimation.FrameDurations.Count, 1); } } } else { FloatRectangle selectionFloatRect = new FloatRectangle(); selectionFloatRect.U = mSelectionRect.X / (float)mSpriteSheetWidth; selectionFloatRect.V = mSelectionRect.Y / (float)mSpriteSheetHeight; selectionFloatRect.Width = (float)mSelectionRect.Width / mSpriteSheetWidth; selectionFloatRect.Height = (float)mSelectionRect.Height / mSpriteSheetHeight; if (mMultidirCheckBox.Checked) { mCurrentAnimation.AddFrame(GetDirectionFromString(mDirectionComboBox.Text), selectionFloatRect, mCurrentAnimation.Frames[mCurrentAnimation.DirectionMap[GetDirectionFromString(mDirectionComboBox.Text)]].Count); } else { mCurrentAnimation.AddFrame(RotationComponent.CardinalDirections.NONE, selectionFloatRect, mCurrentAnimation.Frames[mCurrentAnimation.DirectionMap[RotationComponent.CardinalDirections.NONE]].Count); } Bitmap croppedImage = imageToCopy.Clone(mPictureBox.SelectionRect, imageToCopy.PixelFormat); mKeyframeImageList.Add(croppedImage); mImageView.AddImage(mKeyframeImageList[mKeyframeImageList.Count - 1]); mImageView.PictureBoxes[mImageView.PictureBoxes.Count - 1].MouseClick += new System.Windows.Forms.MouseEventHandler(imageViewKeyframe_Click); if (!mCurrentAnimation.FrameDurations.ContainsKey(mKeyframeImageList.Count-1)) { mCurrentAnimation.FrameDurations.Add(mCurrentAnimation.FrameDurations.Count, 1); } } } else { MessageBox.Show("Make a selection in the SpriteSheet first!"); } } else { MessageBox.Show("Load a SpriteSheet first!"); } }