Ejemplo n.º 1
0
 /// <summary>
 /// Positions a minion (e.g. a ship) using any of the spawn areas in the arena.
 /// </summary>
 public static void PositionNewMinion(Gob minion, Arena arena)
 {
     Func<IGeomPrimitive, int, IEnumerable<Vector2>> getRandomPoses = (area, count) =>
         Enumerable.Range(0, count)
         .Select(x => arena.GetFreePosition(LARGE_GOB_PHYSICAL_RADIUS, area));
     var spawnPoses = arena.Gobs.All<SpawnPlayer>()
         .SelectMany(spawn => getRandomPoses(spawn._spawnArea, 5));
     var poses = spawnPoses.Any()
         ? spawnPoses
         : getRandomPoses(new Rectangle(Vector2.Zero, arena.Dimensions), 20);
     var posesWithThreats = poses
         .Select(pos => new { pos, mood = GetMood(minion, pos) })
         .ToList()
         .OrderByDescending(x => x.mood)
         .ToList();
     var bestMood = posesWithThreats[0].mood;
     var bestSpawns = posesWithThreats.TakeWhile(x => x.mood == bestMood).ToList();
     var bestPos = bestSpawns[RandomHelper.GetRandomInt(bestSpawns.Count)].pos;
     minion.ResetPos(bestPos, Vector2.Zero, Gob.DEFAULT_ROTATION);
 }
Ejemplo n.º 2
0
        private void GobCreation(Gob gob, int createCount, int i, int emitType, ref List<Particle> particles)
        {
            // Find out emission parameters.
            // We have to loop because some choices of parameters may not be wanted.
            int maxAttempts = 20;
            bool attemptOk = false;
            for (int attempt = 0; !attemptOk && attempt < maxAttempts; ++attempt)
            {
                bool lastAttempt = attempt == maxAttempts - 1;
                attemptOk = true;
                int random = RandomHelper.GetRandomInt();
                float directionAngle, rotation;
                Vector2 directionUnit, pos, move;
                switch (Peng.ParticleCoordinates)
                {
                    case Peng.CoordinateSystem.Peng:
                        RandomHelper.GetRandomCirclePoint(_radius, -_sprayAngle, _sprayAngle,
                            out pos, out directionUnit, out directionAngle);
                        move = _initialVelocity.GetValue(0, random) * directionUnit;
                        switch (_facingType)
                        {
                            case FacingType.Directed: rotation = 0; break;
                            case FacingType.Forward: rotation = directionAngle; break;
                            case FacingType.Random: rotation = RandomHelper.GetRandomFloat(0, MathHelper.TwoPi); break;
                            default: throw new Exception("SprayEmitter: Unhandled particle facing type " + _facingType);
                        }
                        break;
                    case Peng.CoordinateSystem.Game:
                        {
                            float posWeight = (i + 1) / (float)createCount;
                            var startPos = Peng.OldDrawPos;
                            var endPos = Peng.Pos + Peng.DrawPosOffset;
                            var iPos = Vector2.Lerp(startPos, endPos, posWeight);
                            var drawRotation = Peng.Rotation + Peng.DrawRotationOffset;
                            RandomHelper.GetRandomCirclePoint(_radius, drawRotation - _sprayAngle, drawRotation + _sprayAngle,
                                out pos, out directionUnit, out directionAngle);
                            pos += iPos;
                            move = Peng.Move + _initialVelocity.GetValue(0, random) * directionUnit;

                            // HACK: 'move' will be added to 'pos' in PhysicalUpdater during this same frame
                            pos -= move * (float)Peng.Game.GameTime.ElapsedGameTime.TotalSeconds;

                            switch (_facingType)
                            {
                                case FacingType.Directed: rotation = Peng.Rotation; break;
                                case FacingType.Forward: rotation = directionAngle; break;
                                case FacingType.Random: rotation = RandomHelper.GetRandomFloat(0, MathHelper.TwoPi); break;
                                default: throw new Exception("SprayEmitter: Unhandled particle facing type " + _facingType);
                            }
                        }
                        break;
                    case Peng.CoordinateSystem.FixedToPeng:
                        pos = Vector2.Zero;
                        move = Vector2.Zero;
                        rotation = 0;
                        directionAngle = 0;
                        break;
                    default:
                        throw new ApplicationException("SprayEmitter: Unhandled peng coordinate system " + Peng.ParticleCoordinates);
                }

                // Set the thing's parameters.
                if (emitType < TextureNames.Length)
                {
                    var particle = new Particle
                    {
                        Alpha = 1,
                        Move = move,
                        PengInput = Peng.Input,
                        Pos = pos,
                        Random = random,
                        Direction = directionAngle,
                        DirectionVector = Vector2.UnitX.Rotate(directionAngle),
                        Rotation = rotation,
                        Scale = 1,
                        Texture = Peng.Game.Content.Load<Texture2D>(TextureNames[emitType]),
                    };
                    particles.Add(particle);
                }
                else
                {
                    // Bail out if the position is not free for the gob.
                    if (!lastAttempt && !Peng.Arena.IsFreePosition(new Circle(pos, Gob.SMALL_GOB_PHYSICAL_RADIUS)))
                    {
                        attemptOk = false;
                        continue;
                    }
                    gob.Owner = Peng.Owner;
                    gob.ResetPos(pos, move, rotation);
                    Peng.Arena.Gobs.Add(gob);
                }
            }
        }