/// <summary> /// Constructs a copy of an Enemy Character. /// </summary> /// <param name="enemy">The Enemy to copy.</param> public Enemy(Enemy enemy) : base(new Rectangle(enemy.Position.X, enemy.Position.Y, enemy.Position.Width, enemy.Position.Height), enemy.Texture, enemy.Health, enemy.Weapon) { // Initialize Fields this.attackInterval = enemy.attackInterval; this.bodyDamage = enemy.bodyDamage; this.maxHeight = enemy.maxHeight; this.maxWidth = enemy.maxWidth; this.speed = enemy.speed; this.travelled = 0; this.name = enemy.name; this.enemyMovementType = enemy.enemyMovementType; this.player = enemy.player; this.random = enemy.random; this.currentFrame = random.Next(1000); // Initialize start direction dependent on the EnemyMovementType if (enemyMovementType == EnemyMovementType.LeftRight) { enemyDirection = EnemyDirection.Right; } else if (enemyMovementType == EnemyMovementType.Random) { randomDirectionNumber = random.Next(0, 8); } else if (enemyMovementType == EnemyMovementType.Rectangle) { enemyDirection = EnemyDirection.Right; } else if (enemyMovementType == EnemyMovementType.UpDown) { enemyDirection = EnemyDirection.Down; } }
IEnumerator EnterPatroll() { //If we already did the trigger event once and the player escaped us, start doing the normal follow path. if(MovementType == EnemyMovementType.WaitForTrigger && _playerInTrigger) { MovementType = EnemyMovementType.FollowPath; } yield return null; }
// Methods /// <summary> /// Loads all maps, weapons and enemies from the resource file /// </summary> public void LoadResources() { // Temporary Fields string currentEnemyName; int[] weaponFieldsParsed; int[] currentEnemyFields; string[] currentWeaponFields; int[,] tiles; BinaryReader reader; FileStream resources; // Initialize Temporary Fields tiles = new int[16, 16]; // Initialize Class Fields tileSize = 68; key = new Item(new Rectangle(500, 500, (int)(.75 * tileSize), (int)(.75 * tileSize)), keyTexture, false, true); spear = new MeleeWeapon(new Point((int)(1.2 * tileSize), (int)(.6 * tileSize)), swordTexture, 8, 20); sword = new MeleeWeapon(new Point((int)(.6 * tileSize), (int)(.6 * tileSize)), swordTexture, 5, 90, 5); player = new Player(new Rectangle(0, 0, (int)(.75 * tileSize), (int)(.75 * tileSize)), playerTexture, 300, sword); arrow = new Projectile(new Point((int)(.3 * tileSize), (int)(.08 * tileSize)), arrowTexture, 20); spell = new Projectile(new Point((int)(.3 * tileSize), (int)(.3 * tileSize)), spellTexture, 12); bow = new RangedWeapon(new Point((int)(.6 * tileSize), (int)(.6 * tileSize)), bowTexture, 2, arrow); wand = new RangedWeapon(new Point((int)(.75 * tileSize), (int)(.75 * tileSize)), wandTexture, 1, spell); maps = new List <Map>(); resourceEnemies = new List <Enemy>(); resourceWeapons = new List <Weapon>(); // Creates the enemyWeapons List enemyWeapons = new List <Weapon> { sword, spear, wand, bow }; // Loads Enemy Textures List <Texture2D> enemySprites = new List <Texture2D> { Content.Load <Texture2D>("enemies/archer"), Content.Load <Texture2D>("enemies/berserker"), Content.Load <Texture2D>("enemies/bug"), Content.Load <Texture2D>("enemies/sentry"), Content.Load <Texture2D>("enemies/knight"), Content.Load <Texture2D>("enemies/Wizard"), Content.Load <Texture2D>("enemies/tank"), Content.Load <Texture2D>("enemies/sentry"), Content.Load <Texture2D>("enemies/viking"), Content.Load <Texture2D>("enemies/wanderer") }; // Open FileStream and BinaryReader resources = File.OpenRead("../../../../../Resources/master.rsrc"); reader = new BinaryReader(resources); // While there is unread data, continue looping while (reader.PeekChar() != -1) { // Read a string that says "Map," "Enemy," or "Weapon" switch (reader.ReadString()) { case "Map": // Skip file name reader.ReadString(); // Assign all tiles to list for (int i = 0; i < tiles.GetLength(0); i++) { for (int j = 0; j < tiles.GetLength(1); j++) { tiles[i, j] = reader.ReadInt32(); } } // Add the Map to the List maps.Add(new Map(tileSize, tiles, floorTexture, wallTexture)); break; case "Enemy": // Enemy File Format (8 parameters from .enemy file): health, damage, attackSpeed, speed, xSize, ySize, movementType, weaponType // - All items are read in as strings but parsed to: (int, int, int, int, int, int, int, int) // Stores name of the Enemy file currentEnemyName = reader.ReadString(); // Initialize Enemy Fields currentEnemyFields = new int[8]; // Read in parameters for (int i = 0; i < currentEnemyFields.Length; i++) { currentEnemyFields[i] = int.Parse(reader.ReadString()); } // Sets the appropriate movement type based on the integer from the file EnemyMovementType movementType = EnemyMovementType.Chase; // default type if (currentEnemyFields[6] == 0) { movementType = EnemyMovementType.Chase; } else if (currentEnemyFields[6] == 1) { movementType = EnemyMovementType.LeftRight; } else if (currentEnemyFields[6] == 2) { movementType = EnemyMovementType.Random; } else if (currentEnemyFields[6] == 3) { movementType = EnemyMovementType.Rectangle; } else if (currentEnemyFields[6] == 4) { movementType = EnemyMovementType.UpDown; } // Add the enemy to the list of imported resource enemies resourceEnemies.Add(new Enemy(new Rectangle(0, 0, (int)(currentEnemyFields[4] / 10.0 * tileSize), (int)(currentEnemyFields[5] / 10.0 * tileSize)), // Enemy Size (position should be overridden in NextLevel() squareTexture, // Enemy Texture currentEnemyFields[0], // Health null, // Weapon currentEnemyFields[2], // Attack Interval currentEnemyFields[1], // Body Damage 150, // Default Max Travel Width 150, // Default Max Travel Height currentEnemyFields[3], // Travel Speed currentEnemyName, // Enemy Name movementType, // Enemy Movement Type player, // The Player random)); // Random Number Generator // Assigns Texture if applicable if (resourceEnemies.Count <= enemySprites.Count) { resourceEnemies[resourceEnemies.Count - 1].Texture = enemySprites[resourceEnemies.Count - 1]; } //Adds the weapon to the enemy if (currentEnemyFields[7] < 4 && currentEnemyFields[7] > -1) { // Adds the Weapon to the Enemy // If the field is a valid Weapon type if (currentEnemyFields[7] < 4 && currentEnemyFields[7] > -1) { // If the Weapon is a MeleeWeapon or RangedWeapon, set appropriately if (enemyWeapons[currentEnemyFields[7]] is MeleeWeapon) { resourceEnemies[resourceEnemies.Count - 1].Weapon = new MeleeWeapon((MeleeWeapon)enemyWeapons[currentEnemyFields[7]]); } else if (enemyWeapons[currentEnemyFields[7]] is RangedWeapon) { resourceEnemies[resourceEnemies.Count - 1].Weapon = new RangedWeapon((RangedWeapon)enemyWeapons[currentEnemyFields[7]]); } } } break; //####### TO-DO: Integrate this list of enemies into the game.. some helpful info: ###################################################### // - The enemies brought in do not have sizes, textures, set movement patterns, or max travelling dimensions // - Note that the current texture used is a square test texture // - I restate, in the .rsrc file, those ints are stored as strings. They are strings since they come out of the Enemy external tool. // They are then parsed to an array of ints here, and act as ints. No need to TryParse, the external tool only allows integers > 0 to be used. case "Weapon": // Weapon File Format (four parameters from .weapon file): name, damage, size, type // - All items are read in as strings, but the ints are parsed: (string, int, int, int) // Skips file name reader.ReadString(); // Intialize Fields currentWeaponFields = new string[4]; // holds the original four parameters in string form weaponFieldsParsed = new int[3]; // takes parameters 2 through 4 and converts them to ints // Read in four parameters for (int i = 0; i < 4; i++) { currentWeaponFields[i] = reader.ReadString(); } // Parse the last three parameters to integers, and store them in a separate array weaponFieldsParsed[0] = int.Parse(currentWeaponFields[1]); weaponFieldsParsed[1] = int.Parse(currentWeaponFields[2]); weaponFieldsParsed[2] = int.Parse(currentWeaponFields[3]); // Add the weapon to the list of imported resource weapons // based on its type: 0 - Sword, 1 - Spear, 2 - Wand, 3 - Bow // The weapon is a sword if (weaponFieldsParsed[2] == 0) { resourceWeapons.Add(new MeleeWeapon(new Point((int)(weaponFieldsParsed[1] * tileSize / 10), (int)(weaponFieldsParsed[1] * tileSize / 10)), swordTexture, weaponFieldsParsed[0], 90, 5)); } // The weapon is a spear else if (weaponFieldsParsed[2] == 1) { resourceWeapons.Add(new MeleeWeapon(new Point((int)(weaponFieldsParsed[1] * tileSize / 5), (int)(weaponFieldsParsed[1] * tileSize / 10)), swordTexture, weaponFieldsParsed[0], 20)); } // The weapon is a wand else if (weaponFieldsParsed[2] == 2) { resourceWeapons.Add(new RangedWeapon(new Point((int)(weaponFieldsParsed[1] * tileSize / 10), (int)(weaponFieldsParsed[1] * tileSize / 10)), wandTexture, weaponFieldsParsed[0], spell)); } // The weapon is a bow else { resourceWeapons.Add(new RangedWeapon(new Point((int)(weaponFieldsParsed[1] * tileSize / 10), (int)(weaponFieldsParsed[1] * tileSize / 10)), bowTexture, weaponFieldsParsed[0], arrow)); } // End weapon case break; //####### TO-DO: Integrate this list of weapons into the game.. some helpful info: ###################################################### // - The weapons brought in do not have textures, sizes, projectiles, spin speeds, or spin angles. // - The weapons brought in have durability and name fields that are not utilized by the constructors, // but are there if you want to use them. } } // Close the binary reader. reader.Close(); }
// Constructors /// <summary> /// Constructs an Enemy Character. /// </summary> /// <param name="position">The Rectangle representing the Enemy's position and size.</param> /// <param name="texture">The Texture2D representing the Enemy's texture.</param> /// <param name="health">The Enemy's health.</param> /// <param name="weapon">The Enemy's Weapon.</param> /// <param name="attackInterval">The time between the Enemy's attacks.</param> /// <param name="bodyDamage">The damage the Enemy deals with it's body.</param> /// <param name="maxWidth">The distance the Enemy can walk in the x direction.</param> /// <param name="maxHeight">The disatance the Enemy can walk in the y direction.</param> /// <param name="speed">The Enemy's speed.</param> /// <param name="name">The Enemy's name.</param> /// <param name="enemyMovementType">The Enemy's type of movement.</param> /// <param name="player">The Player Character.</param> /// <param name="random">A Random number generator.</param> public Enemy(Rectangle position, Texture2D texture, int health, Weapon weapon, int attackInterval, int bodyDamage, int maxWidth, int maxHeight, int speed, string name, EnemyMovementType enemyMovementType, Player player, Random random) : base(position, texture, health, weapon) { // Initialize Fields this.attackInterval = attackInterval; this.bodyDamage = bodyDamage; this.currentFrame = random.Next(1000); this.maxHeight = maxHeight; this.maxWidth = maxWidth; this.speed = speed; this.travelled = 0; this.name = name; this.enemyMovementType = enemyMovementType; this.player = player; this.random = random; // Initialize start direction dependent on the EnemyMovementType if (enemyMovementType == EnemyMovementType.LeftRight) { enemyDirection = EnemyDirection.Right; } else if (enemyMovementType == EnemyMovementType.Random) { randomDirectionNumber = random.Next(0, 8); } else if (enemyMovementType == EnemyMovementType.Rectangle) { enemyDirection = EnemyDirection.Right; } else if (enemyMovementType == EnemyMovementType.UpDown) { enemyDirection = EnemyDirection.Down; } }
public override void OnInspectorGUI() { // base.OnInspectorGUI(); movementSettingInst = (EnemyMovementSetting)target; EditorGUILayout.BeginVertical(); EditorGUILayout.LabelField("General settings:", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Movement type:"); EnemyMovementType newType = (EnemyMovementType)_movementType.enumValueIndex; newType = (EnemyMovementType)EditorGUILayout.EnumPopup(newType); _movementType.enumValueIndex = (int)newType; EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); _speed.floatValue = Mathf.Max(EditorGUILayout.FloatField(new GUIContent("Speed:", "For ground movement best average is 2, for flying is 0.05f"), _speed.floatValue), float.Epsilon); EditorGUILayout.EndHorizontal(); if (movementSettingInst.movementType == EnemyMovementType.FLYING) { EditorGUILayout.LabelField("Game zone constraints:", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); _xMin.floatValue = EditorGUILayout.FloatField("XMin & XMax: ", _xMin.floatValue); _xMax.floatValue = EditorGUILayout.FloatField(_xMax.floatValue); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); _yMin.floatValue = EditorGUILayout.FloatField("YMin & YMax: ", _yMin.floatValue); _yMax.floatValue = EditorGUILayout.FloatField(_yMax.floatValue); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); _zMin.floatValue = EditorGUILayout.FloatField("ZMin & ZMax: ", _zMin.floatValue); _zMax.floatValue = EditorGUILayout.FloatField(_zMax.floatValue); EditorGUILayout.EndHorizontal(); EditorGUILayout.LabelField("Pathfinding settings:", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Pathfinding algorithm:"); Pursuer.PathfindingAlgorithm newEnum = (Pursuer.PathfindingAlgorithm)_selectedPFAlg.enumValueIndex; newEnum = (Pursuer.PathfindingAlgorithm)EditorGUILayout.EnumPopup(newEnum); _selectedPFAlg.enumValueIndex = (int)newEnum; EditorGUILayout.EndHorizontal(); if (movementSettingInst.selectedPFAlg == Pursuer.PathfindingAlgorithm.AStar) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Heuristic factor:"); _heuristicFactor.floatValue = EditorGUILayout.Slider(_heuristicFactor.floatValue, .5f, 1f); EditorGUILayout.EndHorizontal(); } else { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("In-editor pathfinding traverce:"); _inEditorPathfindingTraverce.boolValue = EditorGUILayout.Toggle(_inEditorPathfindingTraverce.boolValue); EditorGUILayout.EndHorizontal(); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Number of pathfinding level: ", EditorStyles.wordWrappedLabel); SpaceManager sMInst = Component.FindObjectOfType <SpaceManager>(); if (sMInst != null) { _pathfindingLevel.intValue = EditorGUILayout.IntSlider(movementSettingInst.pathfindingLevel, 0, sMInst.gridDetailLevelsCount - 1); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Trajectory optimization:"); _trajectoryOptimization.boolValue = EditorGUILayout.Toggle(_trajectoryOptimization.boolValue); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Trajectory smoothing:"); _trajectorySmoothing.boolValue = EditorGUILayout.Toggle(_trajectorySmoothing.boolValue); EditorGUILayout.EndHorizontal(); EditorGUILayout.LabelField("Movement settings:", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Turn in the dir. of movement:"); _moveVectorOrientation.boolValue = EditorGUILayout.Toggle(_moveVectorOrientation.boolValue); EditorGUILayout.EndHorizontal(); if (_moveVectorOrientation.boolValue) { _turnSpeed.floatValue = Mathf.Max(EditorGUILayout.FloatField("Turn speed:", _turnSpeed.floatValue), float.Epsilon); } EditorGUILayout.LabelField("Other settings:", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Generate event messages:"); _generateEventMessages.boolValue = EditorGUILayout.Toggle(_generateEventMessages.boolValue); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Generate condition messages:"); _generateCondMessages.boolValue = EditorGUILayout.Toggle(_generateCondMessages.boolValue); EditorGUILayout.EndHorizontal(); EditorGUILayout.LabelField("Debug settings:", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("In-game trajectory trace:"); _tracePath.boolValue = EditorGUILayout.Toggle(_tracePath.boolValue); EditorGUILayout.EndHorizontal(); if (_tracePath.boolValue) { _lineWidth.floatValue = Mathf.Max(EditorGUILayout.FloatField("Line width:", _lineWidth.floatValue), .1f); _lineMaterial.objectReferenceValue = (Material)EditorGUILayout.ObjectField("Line material:", (Material)(_lineMaterial.objectReferenceValue), typeof(Material), true); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Show pathfinding area in the editor:"); _showPathfindingZone.boolValue = EditorGUILayout.Toggle(_showPathfindingZone.boolValue); EditorGUILayout.EndHorizontal(); } else { EditorGUILayout.LabelField("Movement settings:", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Stopping distance:"); _stoppingDistance.floatValue = EditorGUILayout.Slider(_stoppingDistance.floatValue, 1f, 10f); EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndVertical(); serializedObject.ApplyModifiedProperties(); }