public override ICodeBlock GenerateFields(ICodeBlock codeBlock, SaveClasses.IElement element) { #region Get the ContentManager variable to use string contentManagerName = "ContentManagerName"; if (element is ScreenSave) { contentManagerName = (element as ScreenSave).ContentManagerForCodeGeneration; } #endregion if (element is EntitySave) { codeBlock.Line("static object mLockObject = new object();"); codeBlock.Line("static System.Collections.Generic.List<string> mRegisteredUnloads = new System.Collections.Generic.List<string>();"); #region Keep track of whether we've already registered an unload method and if StaticContent has been loaded codeBlock.Line("static System.Collections.Generic.List<string> LoadedContentManagers = new System.Collections.Generic.List<string>();"); #endregion } for (int i = 0; i < element.ReferencedFiles.Count; i++) { AppendFieldOrPropertyForReferencedFile(codeBlock, element.ReferencedFiles[i], element.Name, element, contentManagerName); //stringBuilder.AppendLine(GetFieldForReferencedFile(mSaveObject.ReferencedFiles[i])); } return codeBlock; }
public override void GenerateInitializeEnd(ICodeBlock codeBlock) { codeBlock.Line("#if DEBUG && WINDOWS"); codeBlock.Line("InitializeFileWatch();"); codeBlock.Line("#endif"); }
public override ICodeBlock GenerateAddToManagers(ICodeBlock codeBlock, IElement element) { if (ShouldGenerate) { foreach (var layer in GetObjectsForGumLayers(element)) { var rfs = GetScreenRfsIn(element); if (rfs != null) { codeBlock.Line(layer.InstanceName + "Gum = RenderingLibrary.SystemManagers.Default.Renderer.AddLayer();"); codeBlock.Line(rfs.GetInstanceName() + ".AddGumLayerToFrbLayer(" + layer.InstanceName + "Gum, " + layer.InstanceName + ");"); } } // todo: Need to register the layer here foreach (var item in element.AllNamedObjects.Where(item => GumPluginCodeGenerator.IsGue(item) && !string.IsNullOrEmpty(item.LayerOn) && NamedObjectSaveCodeGenerator.GetFieldCodeGenerationType(item) == CodeGenerationType.Full)) { codeBlock.Line(item.FieldName + ".MoveToLayer(" + item.LayerOn + "Gum);"); } } return base.GenerateAddToManagers(codeBlock, element); }
public override ICodeBlock GenerateFields(ICodeBlock codeBlock, SaveClasses.IElement element) { codeBlock.Line("#if DEBUG"); codeBlock.Line("static bool HasBeenLoadedWithGlobalContentManager = false;"); codeBlock.Line("#endif"); return codeBlock; }
public override ICodeBlock GenerateFields(ICodeBlock codeBlock, IElement element) { if (IsLoadingScreen(element)) { codeBlock.Line("double mSavedTargetElapedTime;"); codeBlock.Line("private static System.Action<FlatRedBall.Screens.Screen> nextCallback;"); } return codeBlock; }
public override void GenerateAdditionalMethods(ICodeBlock codeBlock) { codeBlock.Line("#if DEBUG && WINDOWS"); codeBlock.Line("static System.IO.FileSystemWatcher watcher;"); GenerateInitialize(codeBlock); GenerateHandleFileChanged(codeBlock); codeBlock.Line("#endif"); }
public override ICodeBlock GenerateInitialize(ICodeBlock codeBlock, IElement element) { if (element is EntitySave && ((EntitySave)element).ImplementsIWindow && ((EntitySave)element).GetInheritsFromIWindow() == false) { codeBlock.Line("this.Click += CallLosePush;"); codeBlock.Line("this.RollOff += CallLosePush;"); } return codeBlock; }
public override ICodeBlock GenerateAdditionalMethods(ICodeBlock codeBlock, IElement element) { if (element is EntitySave && ((EntitySave)element).ImplementsIDrawableBatch) { var entitySave = element as EntitySave; codeBlock.Line("void FlatRedBall.Graphics.IDrawableBatch.Update(){}"); codeBlock.Line("void FlatRedBall.Graphics.IDrawableBatch.Destroy(){}"); } return codeBlock; }
public override ICodeBlock GenerateFields(ICodeBlock codeBlock, FlatRedBall.Glue.SaveClasses.IElement element) { if (element.SupportsAdvancedInterpolation()) { foreach (var enumName in element.GetStateEnumNames()) { codeBlock.Line("FlatRedBall.Glue.StateInterpolation.Tweener " + TweenerNameFor(enumName) + ";"); codeBlock.Line(enumName + " mFrom" + enumName + "Tween;"); codeBlock.Line(enumName + " mTo" + enumName + "Tween;"); } } return codeBlock; }
private void GenerateInterpolateBetween(ElementSave elementSave, ICodeBlock currentBlock, string enumType, IEnumerable<StateSave> states) { // We used to only generate these if there was were any states in this category, but // since Gum generated code supports dynamic states, there could be states in a category // even if they're not defined in Gum. //if (states.Count() > 0) { currentBlock = currentBlock.Function("public void", "InterpolateBetween", enumType + " firstState, " + enumType + " secondState, float interpolationValue"); GenerateDebugCheckForInterpolationValueNaN(currentBlock); Dictionary<VariableSave, InterpolationCharacteristic> interpolationCharacteristics = new Dictionary<VariableSave, InterpolationCharacteristic>(); CreateStartingValueVariables(elementSave, states, currentBlock, interpolationCharacteristics); currentBlock = currentBlock.Switch("firstState"); currentBlock = SetInterpolateBetweenValuesForStates(elementSave, enumType, states, currentBlock, interpolationCharacteristics, FirstValue); currentBlock = currentBlock.End(); currentBlock = currentBlock.Switch("secondState"); currentBlock = SetInterpolateBetweenValuesForStates(elementSave, enumType, states, currentBlock, interpolationCharacteristics, SecondValue); currentBlock = currentBlock.End(); currentBlock = AssignValuesUsingStartingValues(elementSave, currentBlock, interpolationCharacteristics); currentBlock = currentBlock.If("interpolationValue < 1"); string fieldToAssign; if (enumType == "VariableState") { fieldToAssign = "mCurrentVariableState"; } else { fieldToAssign = "mCurrent" + enumType + "State"; } currentBlock.Line(fieldToAssign + " = firstState;"); currentBlock = currentBlock.End().Else(); currentBlock.Line(fieldToAssign + " = secondState;"); currentBlock = currentBlock.End(); } }
private void GenerateAnimateForCategory(ICodeBlock currentBlock, string categoryName, List<Gum.DataTypes.Variables.StateSave> states) { string propertyToAssign; if (categoryName == "VariableState") { propertyToAssign = "this.CurrentVariableState"; } else { propertyToAssign = "this.Current" + categoryName + "State"; } currentBlock = currentBlock.Function("public void", "Animate", "System.Collections.Generic.IEnumerable<FlatRedBall.Gum.Keyframe<" + categoryName + ">> keyframes"); { currentBlock.Line("bool isFirst = true;"); currentBlock.Line("FlatRedBall.Gum.Keyframe<" + categoryName + "> lastKeyframe = null;"); var foreachBlock = currentBlock.ForEach("var frame in keyframes"); { var ifBlock = foreachBlock.If("isFirst"); { ifBlock.Line("isFirst = false;"); ifBlock.Line(propertyToAssign + " = frame.State;"); } var elseBlock = ifBlock.End().Else(); { elseBlock.Line("float timeToTake = frame.Time - lastKeyframe.Time;"); elseBlock.Line("var fromState = lastKeyframe.State;"); elseBlock.Line("var toState = frame.State;"); elseBlock.Line("var interpolationType = lastKeyframe.InterpolationType;"); elseBlock.Line("var easing = lastKeyframe.Easing;"); elseBlock.Line( "System.Action action = () => this.InterpolateTo(fromState, toState, timeToTake, interpolationType, easing, {});"); elseBlock.Line( "FlatRedBall.Instructions.DelegateInstruction instruction = new FlatRedBall.Instructions.DelegateInstruction(action);"); elseBlock.Line("instruction.Target = this;"); elseBlock.Line("instruction.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + lastKeyframe.Time;"); elseBlock.Line("FlatRedBall.Instructions.InstructionManager.Instructions.Add(instruction);"); } foreachBlock.Line("lastKeyframe = frame;"); } } }
public override ICodeBlock GenerateFields(ICodeBlock codeBlock, IElement element) { foreach (EventResponseSave ers in element.Events) { bool isTunneling = ers.GetIsTunneling(); bool isExposing = ers.GetIsExposing(); bool shouldCreateMember = isExposing || isTunneling; if (!shouldCreateMember) { shouldCreateMember = !string.IsNullOrEmpty(ers.DelegateType); } if (shouldCreateMember) { string delegateType = ers.GetEffectiveDelegateType(element); codeBlock.Line("public event " + delegateType + " " + ers.EventName + ";"); } } return codeBlock; }
private void GenerateInitializeLevel(ICodeBlock codeBlock, IElement element) { #region /////////////////////////////////Early out//////////////////////////////// bool shouldGenerate = GetIfShouldGenerate(element); if (!shouldGenerate) { return; } ///////////////////////////////End early out///////////////////////////// #endregion codeBlock.Line("FlatRedBall.TileGraphics.LayeredTileMap CurrentTileMap;"); var function = codeBlock.Function("void", "InitializeLevel", "string levelName"); GenerateInitializeLevelObjects(function); GenerateInitializeCamera(function); GenerateAddCollisionAndEntities(function); GenerateInitializeAnimations(function); }
private static void TryGenerateRemoveShapeCollectionFromManagers(ICodeBlock codeBlock, IElement element) { if (element.IsICollidable()) { codeBlock.Line("mGeneratedCollision.RemoveFromManagers(clearThis: false);"); } }
public static void GenerateTimedEmit(ICodeBlock codeBlock, NamedObjectSave nos) { if (!nos.IsDisabled && nos.AddToManagers && !nos.DefinedByBase && nos.IsEmitter()) { codeBlock.Line(nos.InstanceName + ".TimedEmit();"); } }
public override ICodeBlock GenerateActivity(ICodeBlock codeBlock, IElement element) { if(IsLoadingScreen(element)) { codeBlock.Line("AsyncActivity();"); } return codeBlock; }
public static void GenerateTimedEmit(ICodeBlock codeBlock, ReferencedFileSave rfs, IElement element) { if (rfs.LoadedAtRuntime && !rfs.LoadedOnlyWhenReferenced && (element is ScreenSave || rfs.IsSharedStatic == false) && !string.IsNullOrEmpty(rfs.Name) && FileManager.GetExtension(rfs.Name) == "emix") { codeBlock.Line(rfs.GetInstanceName() + ".TimedEmit();"); } }
public override ICodeBlock GenerateFields(ICodeBlock codeBlock, IElement element) { if (IsLoadingScreen(element)) { codeBlock.Line("double mSavedTargetElapedTime;"); } return codeBlock; }
public override ICodeBlock GenerateAdditionalMethods(ICodeBlock codeBlock, FlatRedBall.Glue.SaveClasses.IElement element) { //////////////////////////EARLY OUT////////////////////////////////////// if (element is ScreenSave) { return codeBlock; } ///////////////////////END EARLY OUT///////////////////////////////////// codeBlock = codeBlock.Function("public void", "MoveToLayer", "Layer layerToMoveTo"); foreach (NamedObjectSave nos in element.NamedObjects) { if (!nos.IsDisabled) { if (nos.GetAssetTypeInfo() != null && !string.IsNullOrEmpty(nos.GetAssetTypeInfo().RemoveFromLayerMethod)) { NamedObjectSaveCodeGenerator.AddIfConditionalSymbolIfNecesssary(codeBlock, nos); bool shouldSkip = GetShouldSkip(nos); if (!shouldSkip) { codeBlock.If("LayerProvidedByContainer != null") .Line(nos.GetAssetTypeInfo().RemoveFromLayerMethod.Replace("this", nos.InstanceName).Replace("mLayer", "LayerProvidedByContainer") + ";") .End(); codeBlock.Line(nos.GetAssetTypeInfo().LayeredAddToManagersMethod[0].Replace("this", nos.InstanceName).Replace("mLayer", "layerToMoveTo") + ";"); } NamedObjectSaveCodeGenerator.AddEndIfIfNecessary(codeBlock, nos); } else if (nos.SourceType == SourceType.Entity && !string.IsNullOrEmpty(nos.SourceClassType)) { NamedObjectSaveCodeGenerator.AddIfConditionalSymbolIfNecesssary(codeBlock, nos); codeBlock.Line(nos.InstanceName + ".MoveToLayer(layerToMoveTo);"); NamedObjectSaveCodeGenerator.AddEndIfIfNecessary(codeBlock, nos); } } } codeBlock.Line("LayerProvidedByContainer = layerToMoveTo;"); codeBlock = codeBlock.End(); return codeBlock; }
public override void GenerateRemoveFromManagers(ICodeBlock codeBlock, IElement element) { if(ShouldGenerate(element)) { codeBlock.Line( "FlatRedBall.SpriteManager.RemoveDrawableBatch(this);"); } }
public override ICodeBlock GenerateActivity(ICodeBlock codeBlock, FlatRedBall.Glue.SaveClasses.IElement element) { if (Active) { codeBlock.Line("TimeManager.SumTimeSection(\"Throwaway\");"); } return codeBlock; }
public override ICodeBlock GenerateLoadStaticContent(ICodeBlock codeBlock, SaveClasses.IElement element) { #region For debugging record if we're using a global content manager codeBlock.Line("#if DEBUG"); codeBlock.If("contentManagerName == FlatRedBall.FlatRedBallServices.GlobalContentManager") .Line("HasBeenLoadedWithGlobalContentManager = true;"); codeBlock.ElseIf("HasBeenLoadedWithGlobalContentManager") .Line("throw new System.Exception(\"This type has been loaded with a Global content manager, then loaded with a non-global. This can lead to a lot of bugs\");"); codeBlock.Line("#endif"); #endregion return codeBlock; }
public static void GenerateFields(IElement saveObject, ICodeBlock codeBlock) { if (ObjectFinder.Self.GlueProject.PerformanceSettingsSave.RecordInitializeSegments && saveObject is ScreenSave) { codeBlock.Line("FlatRedBall.Performance.Measurement.Section mSection;"); } }
public override ICodeBlock GenerateAddToManagers(ICodeBlock codeBlock, IElement element) { if (ShouldGenerate(element)) { var entity = element as EntitySave; codeBlock.Line( "FlatRedBall.SpriteManager.AddToLayer((FlatRedBall.Graphics.IDrawableBatch)this, layerToAddTo);"); } return codeBlock; }
public override ICodeBlock GenerateFields(ICodeBlock codeBlock, IElement element) { if (ShouldGenerate) { foreach (var layer in GetObjectsForGumLayers(element)) { codeBlock.Line("global::RenderingLibrary.Graphics.Layer " + layer.InstanceName + "Gum;"); } } return codeBlock; }
private void GenerateInterface(ICodeBlock codeBlock, BehaviorSave behavior) { foreach (var category in behavior.Categories) { string propertyName = behavior.Name + category.Name; codeBlock.Line($"{propertyName} Current{propertyName}State {{set;}}"); } }
public override ICodeBlock GenerateActivity(ICodeBlock codeBlock, FlatRedBall.Glue.SaveClasses.IElement element) { if (element.SupportsAdvancedInterpolation()) { foreach (var enumName in element.GetStateEnumNames()) { codeBlock.Line(TweenerNameFor(enumName) + ".Update(FlatRedBall.TimeManager.SecondDifference);"); } } return codeBlock; }
public override ICodeBlock GeneratePostInitialize(ICodeBlock codeBlock, IElement element) { if (element.IsICollidable()) { codeBlock.Line("mGeneratedCollision = new FlatRedBall.Math.Geometry.ShapeCollection();"); foreach (var item in element.NamedObjects.Where(item=>item.IncludeInICollidable)) { string addCall = item.GetAddToShapeCollection(); if (!string.IsNullOrEmpty(addCall)) { codeBlock.Line("mGeneratedCollision." + addCall + "(" + item.FieldName + ");"); } } } return codeBlock; }
public static void HandleWriteInstanceVariableAssignment(NamedObjectSave instance, ICodeBlock code, InstructionSave variable) { var shouldHandle = variable.Member == "AtlasedTexture" && instance.SourceClassType == "Sprite"; if(shouldHandle) { var memberName = instance.InstanceName; // The code should look something like: // // SpriteInstance.AtlasedTexture = FlatRedBall.Graphics.Texture.AtlasLoader.LoadAtlasedTexture("asdf"); // // But I still need to make the AtlasLoader keep track of all loaded assets, and I need to have a "priority" system code = code.Block(); { // eventually this might exist //var atlas = instance.GetInstructionFromMember(""); // for now we assume that the texture packer project is in global content var rfs = GlueState.Self.CurrentGlueProject.GlobalFiles.FirstOrDefault(item => { var ati = item.GetAssetTypeInfo(); if(ati != null) { return ati == AtiManager.Self.TextureAtlasAti; } return false; }); if (rfs != null) { var atlas = $"{GlueState.Self.ProjectNamespace}.GlobalContent.{rfs.GetInstanceName()}"; code.Line($"var atlas = {atlas};"); code.Line($"{memberName}.AtlasedTexture = atlas.Sprite(\"{variable.Value}\");"); } } } }
public override ICodeBlock GenerateActivity(ICodeBlock codeBlock, IElement element) { var collection = ParentPlugin.GlueCommands.TreeNodeCommands.GetProperty<StateChainCollection>(element, StateChainsPlugin.PropertyName); if (collection == null) return codeBlock; if(collection.StateChains.Count > 0) { codeBlock.Line("ManageStateChains();"); } return codeBlock; }
// We need to make this be part of the function so that we can have everything be async //static List<string> mUsingStrings = new List<string>(); internal static void GenerateUsingStatements(ICodeBlock codeBlock, IElement SaveObject) { List <string> usingStrings = new List <string>(); if (SaveObject is EntitySave) { EntitySave asEntitySave = (EntitySave)SaveObject; bool hasScreensInProject = ProjectManager.GlueProjectSave.Screens.Count != 0; if (hasScreensInProject) { usingStrings.Add(ProjectManager.ProjectNamespace + ".Screens"); } // I don't think we need this anymore //mUsingStrings.Add("Matrix = Microsoft.Xna.Framework.Matrix"); // Since Entities inherit are IDestroyable usingStrings.Add("FlatRedBall.Graphics"); // And since we want a Visible property, we'll have extension methods for Lists of this usingStrings.Add("FlatRedBall.Math"); if (asEntitySave.CreatedByOtherEntities) { usingStrings.Add(ProjectManager.ProjectNamespace + ".Performance"); } if (asEntitySave.ImplementsIClickable || asEntitySave.ImplementsIWindow) { usingStrings.Add("FlatRedBall.Gui"); } } // We are phasing this out: //mUsingStrings.Add("FlatRedBall.Broadcasting"); #region Add the using PROJECT.Factories if necessary if (ProjectManager.GlueProjectSave.Entities.Count != 0) { // add their usings for (int i = 0; i < ProjectManager.GlueProjectSave.Entities.Count; i++) { EntitySave entitySave = ProjectManager.GlueProjectSave.Entities[i]; string entityNamespace = FileManager.MakeRelative(FileManager.GetDirectory(entitySave.Name)).Replace('/', '.'); entityNamespace = ProjectManager.ProjectNamespace + "." + entityNamespace.Substring(0, entityNamespace.Length - 1); if (!usingStrings.Contains(entityNamespace)) { usingStrings.Add(entityNamespace); } } for (int i = 0; i < ProjectManager.GlueProjectSave.Entities.Count; i++) { if (ProjectManager.GlueProjectSave.Entities[i].CreatedByOtherEntities) { usingStrings.Add(ProjectManager.ProjectNamespace + ".Factories"); break; } } } #endregion usingStrings.Add("FlatRedBall"); usingStrings.Add("FlatRedBall.Screens"); usingStrings.Add("System"); usingStrings.Add("System.Collections.Generic"); usingStrings.Add("System.Text"); bool shouldAddUsingForDataTypes = false; for (int i = 0; i < SaveObject.ReferencedFiles.Count; i++) { if (FileManager.GetExtension(SaveObject.ReferencedFiles[i].Name) == "csv") { shouldAddUsingForDataTypes = true; break; } } if (shouldAddUsingForDataTypes) { usingStrings.Add(ProjectManager.ProjectNamespace + ".DataTypes"); usingStrings.Add("FlatRedBall.IO.Csv"); } NamedObjectSaveCodeGenerator.AddUsingsForNamedObjects(usingStrings, SaveObject); if (ObjectFinder.Self.GlueProject.UsesTranslation) { usingStrings.Add("FlatRedBall.Localization"); } // Plugins don't generate using statements. // This is intentional so we don't get naming conflicts // Remove duplicates StringFunctions.RemoveDuplicates(usingStrings); foreach (string s in usingStrings.Distinct()) { codeBlock.Line("using " + s + ";"); } }
private void GenerateGetCurrentValuesOnStateForCategory(ICodeBlock currentBlock, ElementSave container, string categoryName, List <Gum.DataTypes.Variables.StateSave> states, bool addValues = false) { string methodName = "GetCurrentValuesOnState"; if (addValues) { methodName = "AddToCurrentValuesWithState"; } currentBlock = currentBlock.Function("private Gum.DataTypes.Variables.StateSave", methodName, categoryName + " state"); currentBlock.Line("Gum.DataTypes.Variables.StateSave newState = new Gum.DataTypes.Variables.StateSave();"); var switchBlock = currentBlock.Switch("state"); { foreach (var state in states) { var caseBlock = switchBlock.Case(categoryName + "." + state.MemberNameInCode()); { foreach (var variable in state.Variables.Where(item => GetIfShouldGenerateStateVariable(item, container))) { string memberNameInCode = variable.MemberNameInCode(container, VariableNamesToReplaceForStates); caseBlock.Line("newState.Variables.Add(new Gum.DataTypes.Variables.VariableSave()"); var instantiatorBlock = caseBlock.Block(); { instantiatorBlock.Line("SetsValue = true,"); // Don't use memberNameInCode - states from the XML files will not, and we want this // to behave the same so merging (used in interpolation) works properly //instantiatorBlock.Line("Name = \"" + memberNameInCode + "\","); instantiatorBlock.Line("Name = \"" + variable.Name + "\","); instantiatorBlock.Line($"Type = \"{variable.Type}\","); string valueString = "Value = " + memberNameInCode + ""; if (addValues && IsVariableNumeric(variable)) { string variableValue = variable.Value.ToString(); bool isEntireAssignment; GueDerivingClassCodeGenerator.Self.AdjustVariableValueIfNecessary(variable, container, ref variableValue, out isEntireAssignment); if (isEntireAssignment) { valueString = variableValue; } else { valueString += " + " + variableValue; } } instantiatorBlock.Line(valueString); } caseBlock.Line(");"); } } } } currentBlock.Line("return newState;"); }
private void GenerateBorderOutline(NamedObjectSave namedObjectSave, ICodeBlock codeBlock) { T Get <T>(string name) { return(namedObjectSave.Properties.GetValue <T>(name)); } var tileSize = Get <float>(nameof(TileShapeCollectionPropertiesViewModel.CollisionTileSize)); var tileSizeString = tileSize.ToString(CultureInfo.InvariantCulture) + "f"; var leftFill = Get <float>(nameof(TileShapeCollectionPropertiesViewModel.CollisionFillLeft)); var leftFillString = leftFill.ToString(CultureInfo.InvariantCulture) + "f"; var topFill = Get <float>(nameof(TileShapeCollectionPropertiesViewModel.CollisionFillTop)); var topFillString = topFill.ToString(CultureInfo.InvariantCulture) + "f"; var widthFill = Get <int>(nameof(TileShapeCollectionPropertiesViewModel.CollisionFillWidth)); var heightFill = Get <int>(nameof(TileShapeCollectionPropertiesViewModel.CollisionFillHeight)); var remainderX = leftFill % tileSize; var remainderY = topFill % tileSize; var instanceName = namedObjectSave.FieldName; codeBlock.Line($"{instanceName}.GridSize = {tileSizeString};"); //TileShapeCollectionInstance.GridSize = gridSize; codeBlock.Line($"{instanceName}.LeftSeedX = {remainderX.ToString(CultureInfo.InvariantCulture)};"); codeBlock.Line($"{instanceName}.BottomSeedY = {remainderY.ToString(CultureInfo.InvariantCulture)};"); codeBlock.Line($"{instanceName}.SortAxis = FlatRedBall.Math.Axis.X;"); //TileShapeCollectionInstance.SortAxis = FlatRedBall.Math.Axis.X; var xFor = codeBlock.For($"int x = 0; x < {widthFill}; x++"); //int(int x = 0; x < width; x++) //{ var ifBlock = xFor.If($"x == 0 || x == {widthFill} - 1"); var yFor = ifBlock.For($"int y = 0; y < {heightFill}; y++"); // for (int y = 0; y < height; y++) // { yFor.Line( $"{instanceName}.AddCollisionAtWorld(" + $"{leftFillString} + x * {tileSize} + {tileSize} / 2.0f," + $"{topFillString} - y * {tileSize} - {tileSize} / 2.0f);"); // TileShapeCollectionInstance.AddCollisionAtWorld( // left + x * gridSize + gridSize / 2.0f, // top - y * gridSize - gridSize / 2.0f); // } //} var elseBlock = ifBlock.End().Else(); elseBlock.Line( $"{instanceName}.AddCollisionAtWorld(" + $"{leftFillString} + x * {tileSize} + {tileSize} / 2.0f," + $"{topFillString} - {tileSize} / 2.0f);"); elseBlock.Line( $"{instanceName}.AddCollisionAtWorld(" + $"{leftFillString} + x * {tileSize} + {tileSize} / 2.0f," + $"{topFillString} - {heightFill - 1} * {tileSize} - {tileSize} / 2.0f);"); }
private void GenerateCodeFor(NamedObjectSave namedObjectSave, ICodeBlock codeBlock) { if (namedObjectSave.DefinedByBase == false) { // don't generate if it's defined by base, the base class defines the properties // for now. Maybe eventually derived classes can override or change the behavior? // Not sure, that definitely does not seem like standard behavior, so maybe we leave // it to codegen. var sourceName = namedObjectSave.SourceNameWithoutParenthesis; T Get <T>(string name) { return(namedObjectSave.Properties.GetValue <T>(name)); } var creationOptions = Get <CollisionCreationOptions>( nameof(TileShapeCollectionPropertiesViewModel.CollisionCreationOptions)); var sourceType = namedObjectSave.SourceType; if (sourceType == SourceType.File) { codeBlock.Line($"//The NamedObject {namedObjectSave} has a SourceType of {sourceType}, so it may not instantiate " + $"properly. If you are experiencing a NullReferenceException, consider changing the" + $"SourceType to {SourceType.FlatRedBallType}"); } var isVisible = namedObjectSave.GetCustomVariable("Visible")?.ValueAsBool == true; if (!isVisible) { codeBlock.Line("// normally we wait to set variables until after the object is created, but in this case if the"); codeBlock.Line("// TileShapeCollection doesn't have its Visible set before creating the tiles, it can result in"); codeBlock.Line("// really bad performance issues, as shapes will be made visible, then invisible. Really bad perf!"); codeBlock.Line($"{namedObjectSave.InstanceName}.Visible = false;"); } switch (creationOptions) { case CollisionCreationOptions.Empty: // do nothing break; case CollisionCreationOptions.FillCompletely: GenerateFillCompletely(namedObjectSave, codeBlock); break; case CollisionCreationOptions.BorderOutline: GenerateBorderOutline(namedObjectSave, codeBlock); break; case CollisionCreationOptions.FromLayer: // not handled: GenerateFromLayerCollision(namedObjectSave, codeBlock); break; case CollisionCreationOptions.FromProperties: GenerateFromProperties(namedObjectSave, codeBlock); break; case CollisionCreationOptions.FromType: GenerateFromTileType(namedObjectSave, codeBlock); break; } } }
private void GeneratePartialMethods(ElementSave elementSave, ICodeBlock currentBlock) { currentBlock.Line("partial void CustomInitialize();"); }
private void CreateInstructionForInterpolationRelative(StateCodeGeneratorContext context, ICodeBlock currentBlock, AnimatedStateSave previousState, AnimatedStateSave currentState) { if (previousState != null) { currentBlock.Line("var toReturn = new FlatRedBall.Instructions.DelegateInstruction(() =>"); { currentBlock = currentBlock.Block(); // Is the start clone necessary? currentBlock.Line("var relativeStart = ElementSave.AllStates.FirstOrDefault(item => item.Name == \"" + previousState.StateName + "\").Clone();"); currentBlock.Line("var relativeEnd = ElementSave.AllStates.FirstOrDefault(item => item.Name == \"" + currentState.StateName + "\").Clone();"); currentBlock.Line("Gum.DataTypes.Variables.StateSaveExtensionMethods.SubtractFromThis(relativeEnd, relativeStart);"); currentBlock.Line("var difference = relativeEnd;"); string categoryName = "VariableState"; var category = context.Element.Categories.FirstOrDefault(item => item.States.Any(stateCandidate => stateCandidate.Name == currentState.StateName)); string enumValue = currentState.StateName; if (currentState.StateName.Contains('/')) { var split = currentState.StateName.Split('/'); category = context.Element.Categories.FirstOrDefault(item => item.Name == split[0]); enumValue = split[1]; } if (category != null) { categoryName = category.Name; } currentBlock.Line("Gum.DataTypes.Variables.StateSave first = GetCurrentValuesOnState(" + categoryName + "." + enumValue + ");"); currentBlock.Line("Gum.DataTypes.Variables.StateSave second = first.Clone();"); currentBlock.Line("Gum.DataTypes.Variables.StateSaveExtensionMethods.AddIntoThis(second, difference);"); string interpolationTime = ToFloatString(currentState.Time - previousState.Time); string easing = "FlatRedBall.Glue.StateInterpolation.Easing." + previousState.Easing; string interpolationType = "FlatRedBall.Glue.StateInterpolation.InterpolationType." + previousState.InterpolationType; currentBlock.Line( string.Format("FlatRedBall.Glue.StateInterpolation.Tweener tweener = new FlatRedBall.Glue.StateInterpolation.Tweener(from: 0, to: 1, duration: {0}, type: {1}, easing: {2});", interpolationTime, interpolationType, easing)); currentBlock.Line("tweener.Owner = this;"); currentBlock.Line("tweener.PositionChanged = newPosition => this.InterpolateBetween(first, second, newPosition);"); currentBlock.Line("tweener.Start();"); currentBlock.Line("StateInterpolationPlugin.TweenerManager.Self.Add(tweener);"); currentBlock = currentBlock.End(); } currentBlock.Line(");"); string previousStateTime = ToFloatString(previousState.Time); currentBlock.Line("toReturn.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + " + previousStateTime + ";"); currentBlock.Line("toReturn.Target = target;"); currentBlock.Line("yield return toReturn;"); } }
private void GenerateGetEnumerableFor(StateCodeGeneratorContext context, ICodeBlock currentBlock, AnimationSave animation, AbsoluteOrRelative absoluteOrRelative) { string animationType = "VariableState"; string animationName = animation.PropertyNameInCode(); if (absoluteOrRelative == AbsoluteOrRelative.Relative) { animationName += "Relative"; } string propertyName = animationName + "Instructions"; // Instructions used to be public - the user would grab them and add them to the InstructionManager, // but now everything is encased in an Animation object which handles stopping itself and provides a simple // Play method. const string signature = "private System.Collections.Generic.IEnumerable<FlatRedBall.Instructions.Instruction>"; if (animation.States.Count == 0 && animation.Animations.Count == 0) { currentBlock = currentBlock.Function(signature, propertyName, "object target"); currentBlock.Line("yield break;"); } else if (absoluteOrRelative == AbsoluteOrRelative.Relative && animation.States.Count < 2 && animation.Animations.Count == 0) { currentBlock = currentBlock.Function(signature, propertyName, "object target"); currentBlock.Line("yield break;"); } else { if (animation.States.Count != 0) { var firstState = context.Element.AllStates.FirstOrDefault(item => item.Name == animation.States.First().StateName); var category = context.Element.Categories.FirstOrDefault(item => item.States.Contains(firstState)); if (category != null) { animationType = category.Name; } } currentBlock = currentBlock.Function(signature, propertyName, "object target"); GenerateOrderedStateAndSubAnimationCode(context, currentBlock, animation, animationType, absoluteOrRelative); if (animation.Loops) { currentBlock = currentBlock.Block(); currentBlock.Line("var toReturn = new FlatRedBall.Instructions.DelegateInstruction( " + "() => FlatRedBall.Instructions.InstructionManager.Instructions.AddRange(this." + propertyName + "(target)));"); string executionTime = "0.0f"; if (animation.States.Count != 0) { executionTime = ToFloatString(animation.States.Last().Time); } currentBlock.Line("toReturn.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + " + executionTime + ";"); currentBlock.Line("toReturn.Target = target;"); currentBlock.Line("yield return toReturn;"); currentBlock = currentBlock.End(); } } }
private void CreateInstructionForInterpolationAbsolute(StateCodeGeneratorContext context, ICodeBlock currentBlock, string animationType, AnimatedStateSave previousState, AnimatedStateSave currentState, string animationName) { if (previousState == null) { string variableStateName = null; variableStateName = "CurrentVariableState"; if (currentState.StateName.Contains("/")) { var split = currentState.StateName.Split('/'); animationType = split[0]; } if (animationType != "VariableState") { variableStateName = "Current" + animationType + "State"; } // todo: Change this on categories //System.Action action = () => this.CurrentState = fromState; string enumValue = currentState.StateName; if (enumValue.Contains("/")) { enumValue = enumValue.Split('/')[1]; } currentBlock.Line("var toReturn = new FlatRedBall.Instructions.DelegateInstruction( ()=> this." + variableStateName + " = " + animationType + "." + enumValue + ");"); currentBlock.Line("toReturn.TimeToExecute = FlatRedBall.TimeManager.CurrentTime;"); currentBlock.Line("toReturn.Target = target;"); } else { var previousCategory = context.Element.Categories.FirstOrDefault(item => item.States.Any(stateCandiate => stateCandiate.Name == previousState.StateName)); var currentCategory = context.Element.Categories.FirstOrDefault(item => item.States.Any(stateCandiate => stateCandiate.Name == currentState.StateName)); // Now that we interpolateTo a single state, we don't // need to pass in the StateSave object: //bool differentCategories = previousCategory != currentCategory; // November 3, 2015 // Gum uses a "cumulative // state" system, so that each // keyframe in an animation will // tween with variables both before // and after. // The code as of the time of the writing // of this comment does InterpolateBetween // two states, which does not consider the state // of the object and only tweens variables common // to the two states. This makes the runtime behave // different than Glue, and it also makes the runtime // behave in confusing ways as authors don't often think // about the individual variables that may be set in a state. // We can solve this by instead doing Interpolate to between the // current state of the instance and the state that we are interpolating // to. Going to accomplish this by getting rid of the "from" state: //string fromState = null; string toState = null; string enumValue = currentState.StateName; if (currentState.StateName.Contains("/")) { currentCategory = context.Element.Categories.FirstOrDefault(item => item.Name == currentState.StateName.Split('/')[0]); enumValue = currentState.StateName.Split('/')[1]; } //if (differentCategories) //{ //fromState = "this.ElementSave.AllStates.FirstOrDefault(item => item.Name == \"" + previousState.StateName + "\")"; //toState = "this.ElementSave.AllStates.FirstOrDefault(item => item.Name == \"" + currentState.StateName + "\")"; //} //else //{ //fromState = animationType + "." + previousState.StateName; if (currentCategory == null) { toState = "VariableState." + enumValue; } else { toState = currentCategory.Name + "." + enumValue; } //} string previousStateTime = ToFloatString(previousState.Time); string interpolationTime = ToFloatString(currentState.Time - previousState.Time); string easing = "FlatRedBall.Glue.StateInterpolation.Easing." + previousState.Easing; string interpolationType = "FlatRedBall.Glue.StateInterpolation.InterpolationType." + previousState.InterpolationType; var line = "var toReturn = new FlatRedBall.Instructions.DelegateInstruction( () => this.InterpolateTo(" + string.Format("{0}, {1}, {2}, {3}, {4}));", toState, interpolationTime, interpolationType, easing, animationName); currentBlock.Line(line); currentBlock.Line("toReturn.Target = target;"); currentBlock.Line("toReturn.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + " + previousStateTime + ";"); } currentBlock.Line("yield return toReturn;"); //System.Action action = () => this.InterpolateTo(fromState, toState, timeToTake, interpolationType, easing); }
private void GenerateAnimationMember(StateCodeGeneratorContext context, ICodeBlock currentBlock, AnimationSave animation, AbsoluteOrRelative absoluteOrRelative) { string propertyName = animation.PropertyNameInCode(); if (absoluteOrRelative == AbsoluteOrRelative.Relative) { propertyName += "Relative"; } string referencedInstructionProperty = propertyName + "Instructions"; // Force the property to be upper-case, since the field is lower-case: // We want to generate something like: //private FlatRedBall.Gum.Animation.GumAnimation uncategorizedAnimation; //public FlatRedBall.Gum.Animation.GumAnimation UncategorizedAnimation //{ // get // { // if (uncategorizedAnimation == null) // { // uncategorizedAnimation = new FlatRedBall.Gum.Animation.GumAnimation(1, () => UncategorizedAnimationInstructions); // uncategorizedAnimation.AddEvent("Event1", 3.0f); // } // return uncategorizedAnimation; // } //} var firstCharacterLower = propertyName.Substring(0, 1).ToLowerInvariant(); var fieldName = firstCharacterLower + propertyName.Substring(1); currentBlock.Line($"private FlatRedBall.Gum.Animation.GumAnimation {fieldName};"); currentBlock = currentBlock.Property("public FlatRedBall.Gum.Animation.GumAnimation", propertyName).Get(); float length = GetAnimationLength(context.Element, animation); string lengthAsString = ToFloatString(length); var ifBlock = currentBlock.If($"{fieldName} == null"); { ifBlock.Line( $"{fieldName} = new FlatRedBall.Gum.Animation.GumAnimation({lengthAsString}, {referencedInstructionProperty});"); foreach (var namedEvent in animation.Events) { string timeAsString = ToFloatString(namedEvent.Time); ifBlock.Line( $"{fieldName}.AddEvent(\"{namedEvent.Name}\", {timeAsString});"); } foreach (var subAnimation in animation.Animations) { if (string.IsNullOrEmpty(subAnimation.SourceObject) == false) { ifBlock.Line($"{fieldName}.SubAnimations.Add({subAnimation.PropertyNameInCode()});"); } } } currentBlock.Line($"return {fieldName};"); }
private static bool GenerateLoadAsyncCode(ICodeBlock classLevelBlock, ICodeBlock initializeBlock) { bool loadAsync = ProjectManager.GlueProjectSave.GlobalContentSettingsSave.LoadAsynchronously; if (loadAsync) { GenerateInitializeAsync(initializeBlock); } loadAsync = ProjectManager.GlueProjectSave.GlobalContentSettingsSave.LoadAsynchronously; if (loadAsync) { classLevelBlock._(); classLevelBlock.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING"); classLevelBlock .Function("static void", "RequestContentLoad", "string contentName") .Lock("LoadMethodList") .Line("int index = -1;") .For("int i = 0; i < LoadMethodList.Count; i++") .If("LoadMethodList[i].Name == contentName") .Line("index = i;") .Line("break;") .End() .End() .If("index != -1") .Line("NamedDelegate delegateToShuffle = LoadMethodList[index];") .Line("LoadMethodList.RemoveAt(index);") .Line("LoadMethodList.Insert(0, delegateToShuffle);") .End() .End() .End(); classLevelBlock.Line("#endif"); classLevelBlock._(); classLevelBlock.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING"); classLevelBlock .Function("static void", "AsyncInitialize", "") .Line("#if XBOX360") .Line("// We can not use threads 0 or 2") .Line("// Async screen loading uses thread 4, so we'll use 3 here") .Line("Thread.CurrentThread.SetProcessorAffinity(3);") .Line("#endif") .Line("bool shouldLoop = LoadMethodList.Count != 0;") .While("shouldLoop") .Line("System.Action action = null;") .Lock("LoadMethodList") .Line("action = LoadMethodList[0].LoadMethod;") .Line("LoadMethodList.RemoveAt(0);") .Line("shouldLoop = LoadMethodList.Count != 0 && !ShouldStopLoading;") .End() .Line("action();") .End() .Line("IsInitialized = true;") ._() .End(); classLevelBlock.Line("#endif"); //stringBuilder.AppendLine("\t\t\tstring ContentManagerName = \"Global\";"); } return(loadAsync); }
private static ICodeBlock GenerateCurrentStateProperty(IElement element, ICodeBlock codeBlock, string enumType, List <StateSave> states) { var createField = false; if (enumType == "VariableState" && !DoesBaseHaveUncategorizedStates(element)) //Uncategorized and not base { createField = true; } else if (enumType != "VariableState") //Check if this state category exists in a parent entity { if (element.BaseElement != null) { var categories = GetAllStateCategoryNames(ObjectFinder.Self.GetIElement(element.BaseElement), true); if (!categories.Any(category => category == enumType)) { createField = true; } } else { createField = true; } } string variableNameModifier = enumType; if (enumType == "VariableState") { variableNameModifier = ""; } string qualifiedEnumType = element.Name.Replace("\\", ".").Replace("/", ".") + "." + enumType; if (states.Count != 0) { string variableToLookFor = "Current" + variableNameModifier + "State"; CustomVariable customVariable = element.GetCustomVariable(variableToLookFor); bool hasEvent = customVariable != null && customVariable.CreatesEvent; #region Header and Getter stuff - simple stuff with no logic if (createField) { codeBlock .Line(string.Format("protected int mCurrent{0}State = 0;", variableNameModifier)); } string publicWithOptionalNew = "public"; if (ShouldUseNewKeyword(element, enumType)) { publicWithOptionalNew += " new"; } var setBlock = codeBlock .Property(publicWithOptionalNew + " " + qualifiedEnumType, "Current" + variableNameModifier + "State") .Get() .If(string.Format("System.Enum.IsDefined(typeof({0}), mCurrent{1}State)", enumType, variableNameModifier)) .Line(string.Format("return ({0})mCurrent{1}State;", enumType, variableNameModifier)) .End() .Else() .Line(string.Format("return {0}.Unknown;", enumType)) .End() .End() .Set(); #endregion #region Set the state value and call an event if necessary bool stillNeedsToAssignValue = true; if (element is EntitySave) { EntitySave asEntitySave = element as EntitySave; //if (!string.IsNullOrEmpty(asEntitySave.CurrentStateChange)) //{ // setBlock // .If("value != mCurrent" + variableNameModifier + "State") // .Line("mCurrent" + variableNameModifier + "State = value;") // .Line(asEntitySave.CurrentStateChange + "(this, null);"); // stillNeedsToAssignValue = false; //} } if (hasEvent) { EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.Before, variableToLookFor, element); } if (stillNeedsToAssignValue) { setBlock.Line("mCurrent" + variableNameModifier + "State = (int)value;"); } #endregion var switchBlock = setBlock.Switch("Current" + variableNameModifier + "State"); switchBlock.Case(enumType + ".Uninitialized"); switchBlock.Case(enumType + ".Unknown"); foreach (StateSave stateSave in states) { GenerateCurrentStateCodeForIndividualState(element, switchBlock, stateSave, enumType); } if ((enumType == "VariableState" && DoesBaseHaveUncategorizedStates(element)) || (!string.IsNullOrEmpty(element.BaseElement) && GetAllStateCategoryNames(ObjectFinder.Self.GetIElement(element.BaseElement), true).Any(category => category == enumType))) { switchBlock.Default() .Line("base.Current" + variableNameModifier + "State = base.Current" + variableNameModifier + "State;"); } if (hasEvent) { EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.After, variableToLookFor, element); } } return(codeBlock); }
private void GenerateSpriteVariableUpdateDependenciesFor(ICodeBlock codeBlock, string name, List <string> managementValues) { // Even if the sprite is performing its attachments it needs to be manually updated codeBlock.Line($"FlatRedBall.SpriteManager.ManualUpdate({name});"); }
private static void GenerateInitializeAsync(ICodeBlock currentBlock) { currentBlock.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING"); currentBlock.Line("NamedDelegate namedDelegate = new NamedDelegate();"); foreach (ReferencedFileSave rfs in ProjectManager.GlueProjectSave.GlobalFiles) { if (!IsRfsHighPriority(rfs) && !rfs.LoadedOnlyWhenReferenced && rfs.LoadedAtRuntime) { currentBlock.Line("namedDelegate.Name = \"" + rfs.Name + "\";"); currentBlock.Line("namedDelegate.LoadMethod = Load" + rfs.Name.Replace("/", "_").Replace(".", "_") + ";"); currentBlock.Line("LoadMethodList.Add( namedDelegate );"); } } currentBlock._(); currentBlock.Line("#if WINDOWS_8"); currentBlock.Line("System.Threading.Tasks.Task.Run((System.Action)AsyncInitialize);"); currentBlock.Line("#else"); currentBlock.Line("ThreadStart threadStart = new ThreadStart(AsyncInitialize);"); currentBlock.Line("Thread thread = new Thread(threadStart);"); currentBlock.Line("thread.Name = \"GlobalContent Async load\";"); currentBlock.Line("thread.Start();"); currentBlock.Line("#endif"); currentBlock.Line("#endif"); }
public override ICodeBlock GenerateAdditionalMethods(ICodeBlock codeBlock, IElement element) { ///////////////////Early Out/////////////////////////////// if (!GetIfIsTopDown(element)) { return(codeBlock); } /////////////////End Early Out///////////////////////////// codeBlock.Line( @" #region Top-Down Methods /// <summary> /// Sets the MovementInput to either the keyboard or /// Xbox360GamePad index 0. This can be overridden by base classes to default /// to different input devices. /// </summary> protected virtual void InitializeInput() { if (FlatRedBall.Input.InputManager.Xbox360GamePads[0].IsConnected) { InitializeTopDownInput(FlatRedBall.Input.InputManager.Xbox360GamePads[0]); } else { InitializeTopDownInput(FlatRedBall.Input.InputManager.Keyboard); } InputEnabled = true; } public void InitializeTopDownInput(FlatRedBall.Input.IInputDevice inputDevice) { this.MovementInput = inputDevice.Default2DInput; this.InputDevice = inputDevice; InputEnabled = true; CustomInitializeTopDownInput(); } partial void CustomInitializeTopDownInput(); private void ApplyMovementInput() { ////////early out///////// if(mCurrentMovement == null) { return; } //////end early out var velocity = this.Velocity; var desiredVelocity = Microsoft.Xna.Framework.Vector3.Zero; if(InputEnabled) { desiredVelocity = new Microsoft.Xna.Framework.Vector3(MovementInput.X, MovementInput.Y, velocity.Z) * mCurrentMovement.MaxSpeed * TopDownSpeedMultiplier; } var difference = desiredVelocity - velocity; Acceleration = Microsoft.Xna.Framework.Vector3.Zero; var differenceLength = difference.Length(); const float differenceEpsilon = .1f; if (differenceLength > differenceEpsilon) { var isMoving = velocity.X != 0 || velocity.Y != 0; var isDesiredVelocityNonZero = desiredVelocity.X != 0 || desiredVelocity.Y != 0; // A 0 to 1 ratio of acceleration to deceleration, where 1 means the player is accelerating completely, // and 0 means decelerating completely. This value will often be between 0 and 1 because the player may // set desired velocity perpendicular to the current velocity float accelerationRatio = 1; if(isMoving && isDesiredVelocityNonZero == false) { // slowing down completely accelerationRatio = 0; } else if(isMoving == false && isDesiredVelocityNonZero) { accelerationRatio = 1; } else { // both is moving and has a non-zero desired value var movementAngle = (float)Math.Atan2(velocity.Y, velocity.X); var desiredAngle = (float)Math.Atan2(difference.Y, difference.X); accelerationRatio = 1- Math.Abs(FlatRedBall.Math.MathFunctions.AngleToAngle(movementAngle, desiredAngle)) / (float)Math.PI; } var secondsToTake = Microsoft.Xna.Framework.MathHelper.Lerp( mCurrentMovement.DecelerationTime, mCurrentMovement.AccelerationTime, accelerationRatio); if(secondsToTake == 0) { this.Acceleration = Microsoft.Xna.Framework.Vector3.Zero; this.Velocity = desiredVelocity; } else { var accelerationMagnitude = TopDownSpeedMultiplier * mCurrentMovement.MaxSpeed / secondsToTake; var nonNormalizedDifference = difference; difference.Normalize(); var accelerationToSet = accelerationMagnitude * difference; var expectedVelocityToAdd = accelerationToSet * TimeManager.SecondDifference; if(expectedVelocityToAdd.Length() > nonNormalizedDifference.Length()) { // we will overshoot it, so let's adjust the acceleration accordingly: var ratioOfToAdd = nonNormalizedDifference.Length() / expectedVelocityToAdd.Length(); this.Acceleration = accelerationToSet * ratioOfToAdd; } else { this.Acceleration = accelerationToSet; } } const float velocityEpsilon = .1f; var shouldAssignDirection = this.Velocity.Length() > velocityEpsilon || difference.Length() > 0; // player stopped moving, don't apply direction if(this.Velocity.LengthSquared() == 0) { shouldAssignDirection = false; } if (shouldAssignDirection && mCurrentMovement.UpdateDirectionFromVelocity) { mDirectionFacing = TopDownDirectionExtensions.FromDirection(XVelocity, YVelocity, PossibleDirections); } } else { Velocity = desiredVelocity; Acceleration = Microsoft.Xna.Framework.Vector3.Zero; } } #endregion "); return(codeBlock); }
public override ICodeBlock GenerateAdditionalMethods(ICodeBlock codeBlock, IElement element) { if (IsLoadingScreen(element)) { codeBlock .Line("static string mNextScreenToLoad;") .Property("public static string", "NextScreenToLoad") .Get() .Line("return mNextScreenToLoad;") .End() .Set() .Line("mNextScreenToLoad = value;") .End() .End(); string screenName = FileManager.RemovePath(element.Name); codeBlock .Function("public static void", "TransitionToScreen", "System.Type screenType, System.Action<FlatRedBall.Screens.Screen> screenCreatedCallback = null") .Line("TransitionToScreen(screenType.FullName, screenCreatedCallback);") .End(); codeBlock .Function("public static void", "TransitionToScreen", "string screenName, System.Action<FlatRedBall.Screens.Screen> screenCreatedCallback = null") .Line("Screen currentScreen = ScreenManager.CurrentScreen;") .Line("currentScreen.IsActivityFinished = true;") .Line("currentScreen.NextScreen = typeof(" + screenName + ").FullName;") .Line("mNextScreenToLoad = screenName;") .Line("nextCallback = screenCreatedCallback;") .End(); codeBlock .Function("void", "AsyncActivity", "") .Switch("AsyncLoadingState") .Case("FlatRedBall.Screens.AsyncLoadingState.NotStarted") .If("!string.IsNullOrEmpty(mNextScreenToLoad)") .Line("#if REQUIRES_PRIMARY_THREAD_LOADING") .If("HasDrawBeenCalled") .Line("MoveToScreen(mNextScreenToLoad);") .End() .Line("#else") .Line("StartAsyncLoad(mNextScreenToLoad);") .Line("#endif") .End() .End() .Case("FlatRedBall.Screens.AsyncLoadingState.LoadingScreen") .End() .Case("FlatRedBall.Screens.AsyncLoadingState.Done") // The loading screen can be used to rehydrate. .Line("FlatRedBall.Screens.ScreenManager.ShouldActivateScreen = false;") .Line("FlatRedBall.Screens.ScreenManager.MoveToScreen(mNextScreenToLoad, nextCallback);") .End() .End() .End(); } return(codeBlock); }
public override ICodeBlock GenerateFields(ICodeBlock codeBlock, IElement element) { /////////////////Early Out////////////////////// if (GetIfIsTopDown(element) == false) { return(codeBlock); } //////////////End Early Out////////////////////// /// codeBlock.Line("#region Top Down Fields"); codeBlock.Line("DataTypes.TopDownValues mCurrentMovement;"); codeBlock.Line("public float TopDownSpeedMultiplier { get; set; } = 1;"); codeBlock.Line("/// <summary>"); codeBlock.Line("/// The current movement variables used when applying input."); codeBlock.Line("/// </summary>"); codeBlock.Property("public DataTypes.TopDownValues", "CurrentMovement") .Get() .Line("return mCurrentMovement;"); codeBlock.Property("public FlatRedBall.Input.IInputDevice", "InputDevice") .Line("get;") .Line("private set;"); codeBlock.Line("TopDownDirection mDirectionFacing;"); codeBlock.Line("/// <summary>"); codeBlock.Line("/// Which direciton the character is facing."); codeBlock.Line("/// </summary>"); codeBlock.Property("protected TopDownDirection", "DirectionFacing") .Get() .Line("return mDirectionFacing;"); codeBlock.Property("public PossibleDirections", "PossibleDirections") .AutoGet().End() .AutoSet(); codeBlock.Line("/// <summary>"); codeBlock.Line("/// The input object which controls the horizontal movement of the character."); codeBlock.Line("/// Common examples include a d-pad, analog stick, or keyboard keys."); codeBlock.Line("/// </summary>"); codeBlock.AutoProperty("public FlatRedBall.Input.I2DInput", "MovementInput"); codeBlock.Line("/// <summary>"); codeBlock.Line("/// Whether input is read to control the movement of the character."); codeBlock.Line("/// This can be turned off if the player should not be able to control"); codeBlock.Line("/// the character."); codeBlock.Line("/// </summary>"); codeBlock.AutoProperty("public bool", "InputEnabled"); codeBlock.Line("#endregion"); return(codeBlock); }