예제 #1
0
파일: Pistol.cs 프로젝트: virvar/StillAlive
 internal override void Strike(Character owner, Character target)
 {
     // после выстрела можно запускать таймер блокировки выстрелов (реализация скорострельности)
     // может быть это не тот уровень, на котором нужно учитывать скорострельность,
     // может её надо учитывать на стадии "button1_Click"?
     target.Health -= (byte)((owner.DamagePerSecond + base.DamagePerSecond) / base.StrikesPerSecond);
 }
예제 #2
0
파일: Sprite.cs 프로젝트: virvar/StillAlive
 /// <summary>
 /// Вызывается, когда игра отрисовывается.
 /// </summary>
 /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
 public void Draw(GameTime gameTime, SpriteBatch spriteBatch, Character character)
 {
     spriteBatch.Draw(textureImage,
         character.Position,
         new Rectangle(currentFrame.X * frameSize.X,
             currentFrame.Y * frameSize.Y,
             frameSize.X, frameSize.Y),
             Color.White, 0, Vector2.Zero,
             1f, SpriteEffects.None, 0);
 }
예제 #3
0
파일: Grid.cs 프로젝트: virvar/StillAlive
 public void Relocate(Character character)
 {
     Point oldZone = GetZone(character.Position);
     Point newZone = GetZone(character.MoveBehavior.NewPosition);
     if (newZone.X != oldZone.X || newZone.Y != oldZone.Y)
     {
         Characters[oldZone.X][oldZone.Y].Remove(character);
         Characters[newZone.X][newZone.Y].Add(character);
     }
 }
예제 #4
0
 public Point GetPositionOnGrid(Character character)
 {
     int newZoneX = (int)Math.Floor(character.Position.X / _tileSize);
     int newZoneY = (int)Math.Floor(character.Position.Y / _tileSize);
     return new Point(newZoneX, newZoneY);
 }
예제 #5
0
 public MonsterMoveAStar(Character character, Level level, params Character[] targets)
     : base(character, targets)
 {
     _grid = GetSimplifiedGrid(level);
     _AStar = new AStar();
 }
예제 #6
0
 public void Fight(Character enemy)
 {
     Weapon.Strike(this, enemy);
 }
예제 #7
0
 public NetPlayer(IMessenger messenger, Character character)
 {
     this.Messenger = messenger;
     this.Character = character;
     ClientPacket.PlayerId = (byte)character.Id;
 }
예제 #8
0
 private bool CheckVoxel(Character shooter, float shootingTime, Vector2 direction, Point voxel)
 {
     bool result = false;
     // проверяем попадания в объекты
     // зона попадания
     Rectangle hitArea = new Rectangle(voxel.X * Level.ZoneSize, voxel.Y * Level.ZoneSize, (voxel.X + 1) * Level.ZoneSize, (voxel.Y + 1) * Level.ZoneSize);
     foreach (var solid in _gameState.Grid.Solids[voxel.X][voxel.Y])
     {
         Vector2 hitPos = GetHitPosition(direction, shooter, solid);
         if (hitPos.X != -1)
         {
             if (hitPos.X < shooter.Position.X && hitPos.X > hitArea.X)
             {
                 hitArea.X = (int)hitPos.X;
                 result = true;
             }
             if (hitPos.X > shooter.Position.X && hitPos.X < hitArea.Width)
             {
                 hitArea.Width = (int)hitPos.X;
                 result = true;
             }
             if (hitPos.Y < shooter.Position.Y && hitPos.Y > hitArea.Y)
             {
                 hitArea.Y = (int)hitPos.Y;
                 result = true;
             }
             if (hitPos.Y > shooter.Position.Y && hitPos.Y < hitArea.Height)
             {
                 hitArea.Height = (int)hitPos.Y;
                 result = true;
             }
         }
     }
     // проверяем попадания в игроков
     Character[] playersInVoxel = _gameState.Grid.Characters[voxel.X][voxel.Y].ToArray();
     foreach (var player in playersInVoxel)
     {
         if (player != shooter)
         {
             if (((player.Position.X >= shooter.Position.X && player.Position.X <= hitArea.Width) ||
                 (player.Position.X <= shooter.Position.X && player.Position.X >= hitArea.X))
                 &&
                 ((player.Position.Y >= shooter.Position.Y && player.Position.Y <= hitArea.Height) ||
                 (player.Position.Y <= shooter.Position.Y && player.Position.Y >= hitArea.Y)))
             {
                 Vector2 hitPos = GetHitPosition(direction, shooter, player);
                 if (hitPos.X != -1)
                 {
                     ApplyHit(shooter, player, shootingTime);
                 }
             }
         }
     }
     return result;
 }
예제 #9
0
 public void RemoveTarget(Character target)
 {
     Targets.Remove(target);
 }
예제 #10
0
 public void AddTarget(Character target)
 {
     Targets.Add(target);
 }
예제 #11
0
 public StupidMonsterMove(Character character, params Character[] targets)
 {
     Character = character;
     Targets = new List<Character>(targets);
 }
예제 #12
0
파일: Weapon.cs 프로젝트: virvar/StillAlive
 internal abstract void Strike(Character owner, Character target);
예제 #13
0
 private void DeepCorrection(Character character, Solid solid)
 {
     Vector2 newPos = character.MoveBehavior.NewPosition;
     float charRectLeft = newPos.X - (character.CollisionOffset.X >> 1);
     float charRectTop = newPos.Y - (character.CollisionOffset.Y >> 1);
     float charRectRight = newPos.X + (character.CollisionOffset.X >> 1);
     float charRectBottom = newPos.Y + (character.CollisionOffset.Y >> 1);
     Vector2 minDelta = Vector2.Zero;
     float minDeltaLength = 0;
     Vector2[] axes = new Vector2[solid.Axes.Length + 2];
     axes[0] = new Vector2(1, 0);
     axes[1] = new Vector2(0, 1);
     solid.Axes.CopyTo(axes, 2);
     foreach (var axis in axes)
     {
         // проекция персонажа
         Vector2 projBegin1;
         projBegin1 = GetProjection(new Vector2(charRectLeft, charRectTop), axis);
         Vector2 proj = GetProjection(new Vector2(charRectLeft, charRectBottom), axis);
         if ((proj.X < projBegin1.X) || ((proj.X == projBegin1.X) && (proj.Y < projBegin1.Y)))
             projBegin1 = proj;
         Vector2 projEnd1;
         projEnd1 = GetProjection(new Vector2(charRectRight, charRectTop), axis);
         proj = GetProjection(new Vector2(charRectRight, charRectBottom), axis);
         if ((proj.X > projEnd1.X) || ((proj.X == projEnd1.X) && (proj.Y > projEnd1.Y)))
             projEnd1 = proj;
         // проекция тела
         Vector2 projBegin2;
         Vector2 projEnd2;
         projBegin2 = projEnd2 = GetProjection(solid.Vertices[0], axis);
         for (int i = 1; i < solid.Vertices.Length; i++)
         {
             proj = GetProjection(solid.Vertices[i], axis);
             if ((proj.X < projBegin2.X) || ((proj.X == projBegin2.X) && (proj.Y < projBegin2.Y)))
                 projBegin2 = proj;
             else if ((proj.X > projEnd2.X) || ((proj.X == projEnd2.X) && (proj.Y > projEnd2.Y)))
                 projEnd2 = proj;
         }
         Vector2 delta = Vector2.Zero;
         Vector2 d1 = projEnd1 - projBegin2;
         if ((d1.X > 0) || ((d1.X == 0) && (d1.Y > 0)))
         {
             Vector2 d2 = projEnd2 - projBegin1;
             if ((d2.X > 0) || ((d2.X == 0) && (d2.Y > 0)))
             {
                 if ((d1.X < d2.X) || ((d1.X == d2.X) && (d1.Y <= d2.Y)))
                 {
                     delta = -d1;
                 }
                 else
                 {
                     delta = d2;
                 }
             }
         }
         if (delta == Vector2.Zero)
         {
             return;
         }
         float deltaLength = delta.Length();
         if ((minDelta == Vector2.Zero) || (deltaLength < minDeltaLength))
         {
             minDelta = delta;
             minDeltaLength = deltaLength;
         }
     }
     character.MoveBehavior.NewPosition += minDelta;
 }
예제 #14
0
 public NetPlayer(IMessenger messenger, Character character, TimeSpan createTime)
     : this(messenger, character)
 {
     LastUpdate = createTime;
 }
예제 #15
0
 private void ApplyHit(Character shooter, Character player, float shootingTime)
 {
     player.Health -= shootingTime * shooter.DamagePerSecond;
     if (player.Health <= 0)
     {
         // добавляем игрока в точку респауна зону и удаляем с зоны, в которой он был
         int x = (int)Math.Floor(player.Position.X / Level.ZoneSize);
         int y = (int)Math.Floor(player.Position.Y / Level.ZoneSize);
         _gameState.Grid.Characters[x][y].Remove(player);
         player.Position = _gameState.Level.GetRespawnPosition();
         int newX = (int)Math.Floor(player.Position.X / Level.ZoneSize);
         int newY = (int)Math.Floor(player.Position.Y / Level.ZoneSize);
         _gameState.Grid.Characters[newX][newY].Add(player);
         player.Health = Character.MaxHealth;
         _gameState.Scores[shooter.Id].Kills++;
         _gameState.Scores[player.Id].Deaths++;
         foreach (var netPlayer in _gameState.NetPlayers.Values)
         {
             netPlayer.ServerPacket.PlayersPositions[player.Id] = (ProtoVector2)player.Position;
             netPlayer.ServerPacket.PlayersHealths[(byte)player.Id] = (byte)player.Health;
         }
     }
     else
     {
         foreach (var netPlayer in _gameState.NetPlayers.Values)
         {
             netPlayer.ServerPacket.PlayersHealths[(byte)player.Id] = (byte)player.Health;
         }
     }
 }
예제 #16
0
 private void CheckHits(Character shooter, Vector2 direction, float shootingTime)
 {
     int voxelSize = Level.ZoneSize;
     // координаты ячейки, в которой находится начало луча
     int X = (int)Math.Floor(shooter.Position.X / voxelSize);
     int Y = (int)Math.Floor(shooter.Position.Y / voxelSize);
     // шаг по ячейкам в направлении луча
     int stepX = (direction.X > 0) ? 1 : -1;
     int stepY = (direction.Y > 0) ? 1 : -1;
     // расстояние вдоль луча до первой вертикальной линии, которую пересекает луч
     Vector2 horIntersection = GetIntersectionPosition(shooter.Position, direction, new Vector2((X + (stepX > 0 ? 1 : 0)) * voxelSize, 0), new Vector2(0, 1)) - shooter.Position;
     float tMaxX = horIntersection.Length();
     // расстояние вдоль луча до первой горизонтальной линии, которую пересекает луч
     Vector2 verIntersection = GetIntersectionPosition(shooter.Position, direction, new Vector2(0, (Y + (stepY > 0 ? 1 : 0)) * voxelSize), new Vector2(1, 0)) - shooter.Position;
     float tMaxY = verIntersection.Length();
     // расстояние вдоль луча, которое нужно пройти, чтобы заполнить ширину ячейки
     Vector2 fillWidth = GetIntersectionPosition(Vector2.Zero, direction, new Vector2(voxelSize, 0), new Vector2(0, 1));
     float tDeltaX = fillWidth.Length();
     // расстояние вдоль луча, которое нужно пройти, чтобы заполнить высоту ячейки
     Vector2 fillHeigth = GetIntersectionPosition(Vector2.Zero, direction, new Vector2(0, voxelSize), new Vector2(1, 0));
     float tDeltaY = fillHeigth.Length();
     // обоходим последовательно ячейки, которые пересекает луч
     while (true)
     {
         if (CheckVoxel(shooter, shootingTime, direction, new Point(X, Y)))
         {
             break;
         }
         if (tMaxX < tMaxY)
         {
             tMaxX += tDeltaX;
             X += stepX;
             if (X < 0 || X >= _gameState.Grid.Width)
             {
                 break;
             }
         }
         else
         {
             tMaxY += tDeltaY;
             Y += stepY;
             if (Y < 0 || Y >= _gameState.Grid.Height)
             {
                 break;
             }
         }
     }
 }
예제 #17
0
파일: Grid.cs 프로젝트: virvar/StillAlive
 public void Put(Character character)
 {
     int x = (int)Math.Floor(character.Position.X / Level.ZoneSize);
     int y = (int)Math.Floor(character.Position.Y / Level.ZoneSize);
     Characters[x][y].Add(character);
 }
예제 #18
0
 /// <summary>
 /// Возвращает точку пересечения луча с объектом.
 /// </summary>
 /// <param name="angle"></param>
 /// <param name="koef"></param>
 /// <param name="shooter"></param>
 /// <param name="target"></param>
 /// <returns></returns>
 private Vector2 GetHitPosition(Vector2 direction, Character shooter, ISolid target)
 {
     Vector2 hitPosition = new Vector2(-1);
     Vector2 p0 = shooter.Position;
     float minX = float.PositiveInfinity;
     float minY = float.PositiveInfinity;
     // пересечение с отрезками полигона
     Vector2[] vertices = target.Vertices;
     Vector2 prevV = vertices[vertices.Length - 1];
     for (int i = 0; i < vertices.Length; i++)
     {
         Vector2 curV = vertices[i];
         Vector2 intr = GetIntersectionPosition(shooter.Position, direction, curV, curV - prevV);
         float x = intr.X;
         float y = intr.Y;
         // точка пересечения прямых в пределах отрезка
         if (((x >= prevV.X) && (x < curV.X)) ||
             ((x >= curV.X) && (x < prevV.X)) ||
             ((y >= prevV.Y) && (y < curV.Y)) ||
             ((y >= curV.Y) && (y < prevV.Y)))
         {
             // точка пересечения в направлении стрельбы
             Vector2 delta = new Vector2(x - p0.X, y - p0.Y);
             if (((delta.X >= 0 && direction.X >= 0) || (delta.X < 0 && direction.X < 0)) &&
                 ((delta.Y >= 0 && direction.Y >= 0) || (delta.Y < 0 && direction.Y < 0)))
             {
                 if (delta.X != 0)
                 {
                     float positiveDeltaX = Math.Abs(delta.X);
                     if (positiveDeltaX < minX)
                     {
                         minX = positiveDeltaX;
                         hitPosition = new Vector2((float)x, (float)y);
                     }
                 }
                 else
                 {
                     float positiveDeltaY = Math.Abs(delta.Y);
                     if (positiveDeltaY < minY)
                     {
                         minY = positiveDeltaY;
                         hitPosition = new Vector2((float)x, (float)y);
                     }
                 }
             }
         }
         prevV = curV;
     }
     return hitPosition;
 }
예제 #19
0
 public PlayerMove1(Character character)
 {
     this._character = character;
 }