示例#1
0
        protected override void process(List <Entity> entities)
        {
            foreach (var entity in entities)
            {
                var camera      = entity.getComponent <Camera>();
                var cameraShake = entity.getComponent <CameraShakeComponent>();

                if (cameraShake.RemainingDuration > 0)
                {
                    if (!cameraShake.Shaking)
                    {
                        cameraShake.InitialPosition = camera.position;
                        cameraShake.Shaking         = true;
                    }
                    var angle           = Random.nextAngle();
                    var amountRemaining = cameraShake.RemainingDuration / cameraShake.Duration;
                    var radius          = Random.nextFloat() * cameraShake.Intensity * amountRemaining;

                    var x = radius * Mathf.cos(angle);
                    var y = radius * Mathf.sin(angle);
                    camera.position = new Vector2(cameraShake.InitialPosition.X + x, cameraShake.InitialPosition.Y + y);

                    cameraShake.RemainingDuration -= Time.deltaTime;
                }
                else if (cameraShake.Shaking)
                {
                    cameraShake.Shaking = false;
                    camera.position     = cameraShake.InitialPosition;
                }
            }
        }
        public override void update()
        {
            if (!entity.canSeeThePlayer())
            {
                _followLimitTick += Time.deltaTime;
                if (_followLimitTick >= 3.0f)
                {
                    fsm.resetStackTo(new EnemyOnePatrolState());
                }
            }
            if (entity.electricalDischargeCooldown > 0.0f)
            {
                entity.electricalDischargeCooldown = Math.Max(0, entity.electricalDischargeCooldown - Time.deltaTime);
            }
            var distance = entity.distanceToPlayer();

            entity.forceMovement(Vector2.UnitX * Math.Sign(distance));
            if (entity.canSeeThePlayer() && Math.Abs(distance) < 24)
            {
                fsm.pushState(new EnemyOnePunchState());
            }
            else if (entity.dangerousStage > 1 && entity.electricalDischargeCooldown <= 0.0f && entity.canSeeThePlayer() && Math.Abs(distance) < 40)
            {
                entity.electricalDischargeCooldown = 1f;
                var ran = Random.nextFloat();
                if (ran > 0.6)
                {
                    fsm.pushState(new EnemyOneElectricalDischargeState());
                }
            }
        }
示例#3
0
        public void Split(Point minPartitionSize, Point maxPartitionSize)
        {
            bool shouldSplit = true;

            if (Bounds.Width > minPartitionSize.X && Bounds.Width < maxPartitionSize.X &&
                Bounds.Height > minPartitionSize.Y && Bounds.Height < maxPartitionSize.Y)
            {
                var chance = (float)Math.Pow((Bounds.Width * Bounds.Height) / (maxPartitionSize.X * maxPartitionSize.Y), 2);
                shouldSplit = RNG.Chance(chance);
            }

            if (!shouldSplit)
            {
                Console.WriteLine($"Satisfied room size with {(Bounds.Width * Bounds.Height)} ({minPartitionSize.X * minPartitionSize.Y}-{maxPartitionSize.X * maxPartitionSize.Y})");
                return;
            }

            TryPartition(minPartitionSize);

            if (SubPartitions != null)
            {
                SubPartitions[0].Split(minPartitionSize, maxPartitionSize);
                SubPartitions[1].Split(minPartitionSize, maxPartitionSize);
            }
        }
示例#4
0
        private Vector2 RandomPointInRect(Rectangle rect)
        {
            var min   = new Vector2(rect.Left, rect.Top);
            var point = new Vector2(Random.nextInt(rect.Width), Random.nextInt(rect.Height));

            return(min + point);
        }
示例#5
0
        private void TryPartition(Point minPartitionSize)
        {
            var horizontalBias = Math.Min(Bounds.Width / Bounds.Height, 1);
            var verticalBias   = Math.Min(Bounds.Height / Bounds.Width, 1);
            int splitAt;
            int tries = 0, maxRetries = 5;

            bool isValidSplit;
            bool isHorizontalSplit;

            do
            {
                isHorizontalSplit = RNG.Chance(50 + horizontalBias * 20 - verticalBias * 20);
                var splitPercent = 0.5f + 0.5f * (RNG.NextFloat() - 0.5f);

                if (isHorizontalSplit)
                {
                    tries++;

                    splitAt = (int)Mathf.Lerp(0, Bounds.Width, splitPercent);
                    var remainder = Bounds.Width - splitAt;

                    isValidSplit = splitAt >= minPartitionSize.X && remainder >= minPartitionSize.X;
                }
                else
                {
                    splitAt = (int)Mathf.Lerp(0, Bounds.Height, splitPercent);
                    var remainder = Bounds.Height - splitAt;

                    isValidSplit = splitAt >= minPartitionSize.Y && remainder >= minPartitionSize.Y;
                }
                tries++;
            } while (!isValidSplit && tries < maxRetries);

            if (!isValidSplit)
            {
                Console.WriteLine($"Reached minimum space constraints {Bounds.Width} x {Bounds.Height}");
                return;
            }

            if (isHorizontalSplit)
            {
                SubPartitions    = new BinarySpacePartition[2];
                SubPartitions[0] = new BinarySpacePartition(Bounds.X, Bounds.Y,
                                                            splitAt, Bounds.Height);
                SubPartitions[1] = new BinarySpacePartition(Bounds.X + splitAt,
                                                            Bounds.Y, Bounds.Width - splitAt, Bounds.Height);
                Console.WriteLine($"Split width {Bounds.Width} into {SubPartitions[0].Bounds.Width} + {SubPartitions[1].Bounds.Width}");
            }
            else
            {
                SubPartitions    = new BinarySpacePartition[2];
                SubPartitions[0] = new BinarySpacePartition(Bounds.X, Bounds.Y,
                                                            Bounds.Width, splitAt);
                SubPartitions[1] = new BinarySpacePartition(Bounds.X, Bounds.Y + splitAt,
                                                            Bounds.Width, Bounds.Height - splitAt);
                Console.WriteLine($"Split height {Bounds.Height} into {SubPartitions[0].Bounds.Height} + {SubPartitions[1].Bounds.Height}");
            }
        }
示例#6
0
        private void SpawnFog()
        {
            var x         = Random.range(0, _map.width);
            var y         = Random.range(0, _map.height);
            var fogEntity = scene.createEntity($"fog{++_fogId}", new Vector2(x, y));

            fogEntity.addComponent(new Fog(_fogTexture, _crystalTexture));
        }
示例#7
0
        /// <summary>
        /// Sets rng and loads tilesheet
        /// </summary>
        private void PrepareGeneration()
        {
            if (_settings.Seed != null)
            {
                RNG.SetSeed(_settings.Seed.Value);
            }

            _sheet = YamlSerializer.Deserialize <TileSheet>(_settings.TileSheet);
            _sheet.Load();
        }
示例#8
0
        public void Update()
        {
            var fruitsPerSec = developmentSpeed;
            var growFruit    = Random.Chance(fruitsPerSec * Time.DeltaTime * UpdateInterval);

            if (fruits < maxFruits && Time.TotalTime > fruitTimer && growFruit)
            {
                // spawn a fruit
                var fruitOffset = Random.Range(new Vector2(-fruitSpawnRange), new Vector2(fruitSpawnRange));
                var capNt       = Entity.Scene.CreateEntity(null, Entity.Position + fruitOffset)
                                  .SetTag(Constants.Tags.THING);
                var fruit = capNt.AddComponent <Capsule>();
                fruit.firstAvailableAt = Time.TotalTime + ripeningTime;
                fruit.creator          = this;
                fruit.energy           = Random.Range(fruitBaseValue * 0.6f, fruitBaseValue * 2.2f);
                fruit.body.velocity    = Vector2.Zero;
                childFruits.Add(fruit);
                fruits++;

                fruitTimer = Time.TotalTime + Random.Range(1.4f, 3.4f) * developmentSpeed;
            }

            // update existing fruits
            var growthPoints = 0;

            if (fruits > 0)
            {
                var rmFruits = new HashSet <Capsule>();
                foreach (var child in childFruits)
                {
                    var toChild = Entity.Position - child.Entity?.Position;
                    if (child.acquired || !toChild.HasValue || toChild.Value.LengthSquared() > childRange * childRange)
                    {
                        fruits--;
                        harvest++;
                        growthPoints++;
                        rmFruits.Add(child);
                    }
                }

                childFruits.RemoveAll(x => rmFruits.Contains(x));
            }

            // update general tree growth
            growthTimer -= developmentSpeed * growthPoints * 10f;
            if (Time.TotalTime > growthTimer)
            {
                stage++; // upgrade stage
                if (stage > 10)
                {
                    stage = 10;             // clamp to max stage
                }
                updateStage();
            }
        }
示例#9
0
 public override void update()
 {
     if (!entity.MovableArea.contains(entity.entity.position))
     {
         var diffToCenter = diffToMovableAreaCenter();
         var dirToPoint   = Math.Sign(diffToCenter);
         // ReSharper disable once CompareOfFloatsByEqualityOperator
         if (_dir != dirToPoint)
         {
             _dir *= -1;
         }
         entity.forceMovement(Vector2.UnitX * _dir);
     }
     else
     {
         _moveTime -= Time.deltaTime;
     }
     if (_moveTime <= 0)
     {
         fsm.resetStackTo(new EnemyImpThinking());
     }
     if (entity.sawThePlayer())
     {
         entity.turnToPlayer();
         fsm.resetStackTo(new EnemyImpJumpAttack());
         entity.unseeThePlayer();
     }
     if (entity.canSeeThePlayer())
     {
         entity.turnToPlayer();
         var distance = entity.distanceToPlayer();
         if (Math.Abs(distance) < 60)
         {
             var rand = Random.nextFloat(1);
             if (rand < 0.7)
             {
                 fsm.resetStackTo(new EnemyImpAttackPlayer());
             }
             else
             {
                 fsm.resetStackTo(new EnemyImpJumpAttack());
             }
         }
         else
         {
             fsm.resetStackTo(new EnemyImpJumpAttack());
         }
     }
 }
示例#10
0
        public override void begin()
        {
            entity.sprite.play("walking");

            var direction    = Random.nextInt(2) == 0 ? -1 : 1;
            var halfArea     = entity.MovableArea.width / 2;
            var diffToCenter = diffToMovableAreaCenter();
            var dirToPoint   = Math.Sign(diffToCenter);

            if (Math.Abs(diffToCenter) > halfArea / 2 && direction != dirToPoint)
            {
                direction = Random.nextFloat() >= 0.4f ? dirToPoint : direction;
            }

            entity.forceMovement(Vector2.UnitX * direction);
            _moveTime = 0.5f + Random.nextFloat(1);
            _dir      = direction;
        }
        public override void update()
        {
            if (!entity.canSeeThePlayer())
            {
                _followLimitTick += Time.deltaTime;
                if (_followLimitTick >= 3.0f)
                {
                    fsm.resetStackTo(new EnemyDronePatrolState());
                }
            }
            var distance = entity.distanceToPlayer();

            entity.forceMovement(Vector2.UnitX * Math.Sign(distance));
            if (entity.shotCooldown > 0.0f)
            {
                entity.shotCooldown -= Time.deltaTime;
                if (entity.canSeeThePlayer())
                {
                    entity.forceMovement(Vector2.Zero);
                }
                return;
            }
            if (entity.canSeeThePlayer())
            {
                if (entity.dangerousStage == 1 && distance < 70)
                {
                    entity.shotCooldown = 1.0f;
                    fsm.pushState(new EnemyDroneShotState());
                }
                if (entity.dangerousStage == 2 && distance < 70)
                {
                    entity.shotCooldown = 0.8f;
                    if (Random.nextFloat() > 0.4)
                    {
                        fsm.pushState(new EnemyDroneCanonShotState());
                    }
                    else
                    {
                        fsm.pushState(new EnemyDroneShotState());
                    }
                }
            }
        }
示例#12
0
        /// <summary>
        /// Place torches
        /// </summary>
        private void Stage7()
        {
            foreach (var room in _rooms)
            {
                var chance = 0.05f;
                foreach (var x in Enumerable.Range(room.Bounds.X, room.Bounds.Width))
                {
                    foreach (var y in Enumerable.Range(room.Bounds.Y, room.Bounds.Height))
                    {
                        if (x != room.Bounds.Left && x != room.Bounds.Right - 1 && y != room.Bounds.Top && y != room.Bounds.Bottom - 1)
                        {
                            continue;
                        }
                        if (x == room.Bounds.Left && (y == room.Bounds.Bottom - 1 || y == room.Bounds.Top))
                        {
                            continue;
                        }
                        if (x == room.Bounds.Right - 1 && (y == room.Bounds.Bottom - 1 || y == room.Bounds.Top))
                        {
                            continue;
                        }
                        if (_tileMap[x, y] != TileType.Wall)
                        {
                            continue;
                        }

                        if (RNG.Chance(chance))
                        {
                            _entities.Add(EntityFactory.Presets
                                          .Torch(_settings.TorchColor)
                                          .AtPosition(x * Tile.Width + 8, y * Tile.Height + 8)
                                          .Create());

                            chance = 0f;
                        }
                        else
                        {
                            chance += 0.015f;
                        }
                    }
                }
            }
        }
示例#13
0
        public override void onAddedToEntity()
        {
            entity.addComponent(_fog);
            entity.addComponent(_crystal);

            var scale = Random.range(0.05f, 0.2f);

            entity.scale = new Vector2(scale);

            TweenExt.tweenColorTo(_fog, new Color(1f, 0, 0, 1f), _fadeInTimeSeconds).start();
            TweenExt.tweenColorTo(_crystal, new Color(1f, 0, 0, 1f), _fadeInTimeSeconds).start();

            Core.schedule(_durationSeconds, _ =>
                          TweenExt.tweenColorTo(_fog, new Color(0.1f, 0, 0, 0), _fadeOutTimeSeconds)
                          .start());
            Core.schedule(_durationSeconds, _ =>
                          TweenExt.tweenColorTo(_crystal, new Color(0.1f, 0, 0, 0), _fadeOutTimeSeconds)
                          .setCompletionHandler(__ => entity?.destroy())
                          .start());
        }
示例#14
0
        /// <summary>
        /// For each partition, fit a rectangle into it, leaving a certain space around it for variation
        /// </summary>
        /// <param name="partition"></param>
        /// <returns></returns>
        private Room FitRectangleIntoPartition(BinarySpacePartition partition)
        {
            var wiggleWidth  = (partition.Bounds.Width - _settings.MinRoomSize.X) / 2;
            var wiggleHeight = (partition.Bounds.Height - _settings.MinRoomSize.Y) / 2;

            var width  = _settings.MinRoomSize.X + RNG.NextInt(wiggleWidth);
            var height = _settings.MinRoomSize.Y + RNG.NextInt(wiggleHeight);

            var x = RNG.NextInt(wiggleWidth);
            var y = RNG.NextInt(wiggleHeight);


            var bounds = new Rectangle(partition.Bounds.X + x, partition.Bounds.Y + y, width, height);
            var room   = new Room()
            {
                Bounds = bounds
            };

            return(room);
        }
示例#15
0
        public void createBulletEffect(Vector2 direction, Vector2 position)
        {
            if (_playerComponent.entity == null)
            {
                return;
            }

            var randIndex    = Random.nextInt(2);
            var effect       = _playerComponent.entity.scene.createEntity();
            var effectSprite = effect.addComponent(new AnimatedSprite(BulletEffectTexture, "default"));

            effectSprite.CreateAnimation("default", 0.07f, false);
            effectSprite.AddFrames("default", new List <Rectangle>
            {
                new Rectangle(randIndex == 0 ? 0 : 60, 0, 20, 20),
                new Rectangle(randIndex == 0 ? 20 : 80, 0, 20, 20),
                new Rectangle(randIndex == 0 ? 40 : 100, 0, 20, 20),
            });
            effectSprite.spriteEffects = direction.X < 0 ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
            effect.position            = position + 10 * direction.X * Vector2.UnitX;
            effect.addComponent <SpriteEffectComponent>();
        }
示例#16
0
        /// <summary>
        /// Connects specified rooms by creating connectors to form a corridor
        /// </summary>
        private void ConnectRooms(Room a, Room b)
        {
            if (a == b)
            {
                return;
            }

            var leftMost   = a.Bounds.Center.X < b.Bounds.Center.X ? a.Bounds : b.Bounds;
            var rightMost  = a.Bounds == leftMost ? b.Bounds : a.Bounds;
            var topMost    = a.Bounds.Center.Y < b.Bounds.Center.Y ? a.Bounds : b.Bounds;
            var bottomMost = a.Bounds == topMost ? b.Bounds : a.Bounds;

            var size     = RNG.Choose(4, 5, 6);
            var midPoint = new Point(rightMost.Center.X + size / 2, bottomMost.Center.Y - size / 2);

            var horizontalCorridor = new Rectangle(leftMost.Center.X - size / 2, midPoint.Y - size / 2, midPoint.X - leftMost.Center.X + size / 2, size);
            var verticalCorridor   = new Rectangle(topMost.Center.X - size / 2, topMost.Center.Y - size / 2, size, midPoint.Y - topMost.Center.Y + size);

            a.Connect(b);

            _connectors.Add(new Connector(CropRectangle(horizontalCorridor), CropRectangle(verticalCorridor)));
        }
示例#17
0
        private void throwRock()
        {
            var playerScene = _playerEntity.scene as SceneMap;
            var areaBounds  = _currentBattle.collider.bounds;

            // create enemy entity
            if (playerScene != null)
            {
                var rock        = playerScene.createEntity();
                var rockTexture = playerScene.content.Load <Texture2D>(Content.Misc.rock);
                var rockSprite  = rock.addComponent(new AnimatedSprite(rockTexture, "default"));
                rockSprite.CreateAnimation("default", 1.0f);
                rockSprite.AddFrames("default", new List <Rectangle>
                {
                    new Rectangle(0, 0, 16, 16)
                });

                var px = areaBounds.left + Random.nextInt((int)areaBounds.width);
                rock.position = new Vector2(px, 0);
                rock.addComponent(new BoxCollider(-7, -7, 14, 14));

                _rocks.Add(rock);
            }
        }
示例#18
0
        private void updateBattle()
        {
            if (canThrowRocks())
            {
                _throwRockInterval -= Time.deltaTime;
                if (_throwRockInterval <= 0.0f)
                {
                    _throwRockInterval = 1 + Random.nextFloat(5);
                    throwRock();
                }
            }
            foreach (var rock in _rocks)
            {
                rock.position += new Vector2(0, 500 * Time.deltaTime);
                var             col = rock.getComponent <BoxCollider>();
                CollisionResult res;
                if (col.collidesWith(_playerEntity.getComponent <BoxCollider>(), out res))
                {
                    _playerEntity.getComponent <BattleComponent>().onHit(res);
                }
                if (rock.position.Y > _systemManager.TiledMap.heightInPixels)
                {
                    _rocksToRemove.Add(rock);
                }
            }
            foreach (var rockEntity in _rocksToRemove)
            {
                rockEntity.destroy();
                _rocks.Remove(rockEntity);
            }
            _rocksToRemove.Clear();

            if (_spawnInterval > 0.0f)
            {
                _spawnInterval -= Time.deltaTime;
                return;
            }

            foreach (var enemy in _enemies)
            {
                if (enemy.getComponent <BattleComponent>().Dying)
                {
                    _enemiesToRemove.Add(enemy);
                    _enemiesDefeated++;
                }
            }
            _enemiesToRemove.ForEach(x => _enemies.Remove(x));
            _enemiesToRemove.Clear();

            if (_currentWave >= _currentBattle.Waves.Length)
            {
                _waitingPlayerToCrossBarrier = true;
                _mapHud.showGo();
                resetBattle();
                return;
            }

            if (_enemiesDefeated >= _currentBattle.Waves[_currentWave])
            {
                _currentWave++;
                _enemiesDefeated = 0;
                _enemiesSpawned  = 0;
                _spawnInterval   = 0.5f;
            }

            if (_spawnInterval <= 0.0f && _enemiesSpawned < _currentBattle.Waves[_currentWave])
            {
                var playerScene  = _playerEntity.scene as SceneMap;
                var enemyName    = _currentBattle.Enemies.randomItem();
                var areaCollider = _currentBattle.collider;
                var areaBounds   = areaCollider.bounds;

                // create enemy entity
                if (playerScene != null)
                {
                    EnemyComponent enemyComponent;
                    var            enemy       = playerScene.createEnemy(enemyName, false, out enemyComponent);
                    var            widthOffset = areaBounds.width * 0.1f;
                    var            positionX   = areaBounds.x + widthOffset + Random.nextFloat(areaBounds.width - widthOffset * 2);
                    enemy.setPosition(positionX, areaBounds.y + areaCollider.height);

                    var spawnable = enemyComponent as ISpawnableEnemy;
                    if (spawnable != null)
                    {
                        spawnable.GoToSpawnState();
                        spawnable.MovableArea = areaBounds;
                    }

                    _enemies.Add(enemy);
                }

                _spawnInterval = 0.4f;
                _enemiesSpawned++;
            }
        }
示例#19
0
        public override void update()
        {
            base.update();

            // Glitch
            if (_glitchCooldown <= 0.0f)
            {
                _pixelGlitchPostProcessor.horizontalOffset = 3 + Random.nextInt(10);
                _glitchTimer = Core.schedule(Math.Min(0.01f + Random.nextFloat() / 10, 0.1f), t =>
                {
                    _pixelGlitchPostProcessor.horizontalOffset = 0;
                });
                _glitchCooldown = 2 + Random.nextInt(3);
            }
            else
            {
                _glitchCooldown -= Time.deltaTime;
            }

            // Bloom
            _bloomPulseTick += Time.deltaTime / 10;
            settings         = new BloomSettings(0.5f, PulseTime(_bloomPulseTick), 0.9f, 1, 1, 1);
            _bloomPostProcessor.setBloomSettings(settings);

            // Menu
            var input     = Core.getGlobalManager <InputManager>();
            var lastIndex = _index;

            if (!_fading && input.UpButton.isPressed)
            {
                _index = _index - 1 < 0 ? _cursorPositions.Length - 1 : _index - 1;
            }
            if (!_fading && input.DownButton.isPressed)
            {
                _index = _index + 1 >= _cursorPositions.Length ? 0 : _index + 1;
            }

            if (lastIndex != _index)
            {
                AudioManager.switchSe.Play(0.5f);
                _cursorSprite.transform.position = _cursorPositions[_index];
            }

            if (!_fading && input.SelectButton.isPressed)
            {
                if (Core.isOnTransition())
                {
                    return;
                }

                AudioManager.select.Play(0.5f);
                _fading = true;
                if (_index == 0)
                {
                    Core.startSceneTransition(new FadeTransition(() => new SceneMap())
                    {
                        fadeOutDuration = 3.0f
                    });
                }
                else
                {
                    Core.exit();
                }
            }
        }
        public override void update()
        {
            base.update();
            if (!entity.canStartTheAttacks)
            {
                return;
            }
            if (!_setFirstCooldown && entity.canSeeThePlayer())
            {
                _setFirstCooldown = true;
                _attackCooldown   = 1.0f;
            }
            else if (!_setFirstCooldown)
            {
                return;
            }

            if (_attackCooldown > 0.0f)
            {
                _attackCooldown -= Time.deltaTime;
                return;
            }

            float rand;

            if (!entity.canSeeThePlayer())
            {
                if (entity.hpRate() > 0.5f)
                {
                    fsm.pushState(new EnemyBossMissilesAttack());
                    _attackCooldown = 1.5f;
                }
                else
                {
                    rand = Random.nextFloat();
                    if (rand > 0.3f)
                    {
                        fsm.pushState(new EnemyBossMissilesAttack());
                        _attackCooldown = 1.5f;
                    }
                    else
                    {
                        fsm.pushState(new EnemyBossBigLaserAttack());
                        _attackCooldown = 3f;
                    }
                }
                return;
            }

            rand = Random.nextFloat();
            if (rand > 0.6f)
            {
                fsm.pushState(new EnemyBossClawAttack());
                _attackCooldown = 1f;
            }
            else if (rand > 0.4f)
            {
                fsm.pushState(new EnemyBossLaserAttack());
                _attackCooldown = 1f;
            }
            else if (entity.hpRate() > 0.5f || rand > 0.2f)
            {
                fsm.pushState(new EnemyBossMissilesAttack());
                _attackCooldown = 1.5f;
            }
            else
            {
                fsm.pushState(new EnemyBossBigLaserAttack());
                _attackCooldown = 3f;
            }
        }
示例#21
0
 public override void begin()
 {
     entity.sprite.play("stand");
     _thinkingTime = _lessTime ? Random.nextFloat(1) : 1 + Random.nextFloat(2);
 }