public override Node Render(SpriteBatch batch) { //Draw.FillRectangleCentered(batch, AbsXY, new Vector2(24,32), Color.CadetBlue, 0f); //Draw.FillRectangleCentered(batch, AbsXY + new Vector2(0,14), new Vector2(18,12), Color.CadetBlue, 0f); //Draw.Polygon(batch, _hotPoints.Values.ToArray(), Color.RoyalBlue, 2f, XY + _parent.AbsXY); Draw.FillRectangle(batch, AbsRect, Color.CadetBlue); //Draw.Circle(batch, AbsXY, 8, 6, Color.Yellow, 2f); Draw.Rectangle(batch, AbsRect, Color.Gray, 2f); bool flipX = _direction < 0 ? true : false; //_sprite.Render(batch, AbsX, AbsY + _rect.Height / 2, Color.White, 1f, 1f, 0, 0, 0, flipX ? SpriteEffects.FlipHorizontally : SpriteEffects.None, flipX); //batch.Draw(Game1._text_Hero, AbsXY - new Vector2(Game1._text_Hero.Width / 2, Game1._text_Hero.Height/2 + 14), Color.White); //Draw.Line(batch, AbsXY, AbsXY + new Vector2(0, _tileMapLayer._map2D._tileH), Color.Red, 3); // Debug : Draw _collideP if (_showContactPoint) { for (int i = 0; i < _cPoints.Length; ++i) { if (null != _cPoints[i]) { //if (i==(int)HotPoints.RU || i==(int)HotPoints.RD) // Draw.Line(batch, XY + _parent.AbsXY, _parent.AbsXY + _contactPoints[i]._pointContact, Color.LightSlateGray, 2f); Color color = Color.GreenYellow; // Raycast line //Vector2 raycast = _finalVector * 2f; //Draw.Line(batch, _contactPoints[i]._pos - raycast + _parent.AbsXY, _contactPoints[i]._pos + raycast + _parent.AbsXY, Color.MediumVioletRed, 1f); Draw.Line(batch, _cPoints[i]._pos - _cPoints[i]._raycast + _parent.AbsXY, _cPoints[i]._pos + _cPoints[i]._raycast + _parent.AbsXY, Color.MediumVioletRed, 1f); if (_cPoints[i]._isContact) { color = Color.Red; // Polygon of contact point Draw.PolyLine(batch, _cPoints[i]._polygon, Color.White, 1f, _parent.AbsXY + _cPoints[i]._offset); Line line = _cPoints[i]._lineContact; // Line of contact point Draw.Line(batch, line.A + _parent.AbsXY, line.B + _parent.AbsXY, Color.Aqua, 3f); // Point of intersect raycast line & line Contact Draw.Point(batch, _cPoints[i]._pointContact + _parent.AbsXY, 3f, Color.ForestGreen); // Name of the point contact } if (i == (int)HSpots.EL) { Draw.Line(batch, _cPoints[i]._firstline.A + _parent.AbsXY, _cPoints[i]._firstline.B + _parent.AbsXY, Color.Magenta, 2f); Draw.TopCenterString(batch, Game1._fontMain, _cPoints[i]._pos.Y.ToString("0") + "," + _cPoints[i]._pos.Y.ToString("0"), _cPoints[i]._pos.X + _parent.AbsX, _cPoints[i]._pos.Y + _parent.AbsY, Color.White); } // Contact point Draw.Point(batch, _cPoints[i]._pos + _parent.AbsXY, 1, color); } //Draw.Point(batch, new Vector2(_mapPosX * _tileW + _tileW/2, _mapPosY * _tileW +_tileH/2) + _parent.AbsXY, 4, Color.Gold); //Draw.LeftTopString(batch, Game1._fontMain, TILE_AT_L.ToString(), _mapPosX * _tileW + _tileW/ 2 + _parent.AbsX, _mapPosY * _tileW +_tileH/2 + _parent.AbsY, Color.Goldenrod); } //Draw.TopCenterString(batch, Game1._fontMain, "oldStatus = " + _oldStatus, AbsX, AbsY + 48, Color.Gray); //Draw.TopCenterString(batch, Game1._fontMain, CAN_CLIMB_L + "<EDGE>" + CAN_CLIMB_R, AbsX, AbsY + 64, Color.GreenYellow); Draw.TopCenterString(batch, Game1._fontMain, "PUSH " + _isPush, AbsX, AbsY + 48, Color.Violet); if (_status == Status.IS_JUMP) { Draw.TopCenterString(batch, Game1._fontMain, "JUMP", AbsX, AbsY - 48, Color.Yellow); } if (_status == Status.IS_FALL) { Draw.TopCenterString(batch, Game1._fontMain, "FALL", AbsX, AbsY - 48, Color.Red); } if (_status == Status.IS_LAND) { Draw.TopCenterString(batch, Game1._fontMain, "LAND", AbsX, AbsY - 48, Color.Orange); } if (_status == Status.IS_GRAB) { Draw.TopCenterString(batch, Game1._fontMain, "GRAB " + _ticGrab, AbsX, AbsY - 48, Color.Honeydew); } if (_status == Status.IS_CLIMB) { Draw.TopCenterString(batch, Game1._fontMain, "CLIMB" + _ticAutoMove, AbsX, AbsY - 48, Color.Honeydew); } Draw.Line(batch, _landLineA + _parent.AbsXY, _landLineB + _parent.AbsXY, Color.Green, 2f); Draw.Point(batch, _pointLandCollision + _parent.AbsXY, 4f, Color.RoyalBlue); Draw.Line(batch, AbsXY, AbsXY - Geo.GetVector(_landRadian) * 40, Color.LimeGreen, 1f); Draw.Line(batch, AbsXY, AbsXY + Geo.GetVector(_landRadian) * 40, Color.LimeGreen, 1f); Draw.Line(batch, AbsXY, AbsXY + Geo.GetVector(_angleMove.X) * _velocity.X * 40, Color.MediumVioletRed, 2f); Draw.Line(batch, AbsXY, AbsXY + Geo.GetVector(_angleMove.Y) * _velocity.Y * 40, Color.DarkOliveGreen, 2f); Draw.TopCenterString(batch, Game1._fontMain, $"[{_x.ToString("0")} , { _y.ToString("0")}]", AbsX, AbsY - 64, Color.Yellow); Draw.TopCenterString(batch, Game1._fontMain, $"{ _sumVector.X.ToString("0.0")}|{ _sumVector.Y.ToString("0.0")}", AbsX, AbsY + 64, Color.Yellow); Draw.TopCenterString(batch, Game1._fontMain, $"{ _velocity.X.ToString("0.0")}|{ _velocity.Y.ToString("0.0")}", AbsX, AbsY + 80, Color.MonoGameOrange); // Ddebug Raycast ! Draw.Rectangle(batch, new RectangleF(_mapPosX * _tileW + _parent.AbsX, _mapPosY * _tileH + _parent.AbsY, _tileW, _tileH), Color.Yellow); Level.DrawLine(batch, (int)_x, (int)_y, _mouse.AbsX, _mouse.AbsY, _tileW, _tileH, Color.OrangeRed, new Point(_parent.AbsX, _parent.AbsY)); } if (_status == Status.IS_GRAB) { Draw.Point(batch, _ledgeGrip + _parent.AbsXY, 4f, Color.MonoGameOrange); } //Draw.CenterStringXY(batch, Game1._fontMain, $"{_pointLandCollision_L.Y.ToString("0")}:{_pointLandCollision_R.Y.ToString("0")}", AbsX, AbsY + 32, Color.Ivory); return(base.Render(batch)); }
public override Node Update(GameTime gameTime) { CAN_MOVE_UP = true; CAN_MOVE_DOWN = true; CAN_MOVE_LEFT = true; CAN_MOVE_RIGHT = true; CAN_GRAB_L = false; CAN_GRAB_R = false; //CAN_WALL_JUMP = false; _deltaX = _x - _oldX; _deltaY = _y - _oldY; UpdateRect(); if (!_isMove) { if (_status == Status.IS_LAND) { DecelerateX(2f); } else { DecelerateX(2f); } } // Lateral Move State _isPush = false; _isMove = false; _onMove = false; // Jump Move State //_onJump = false; //_onFall = false; //_sumVector.X = Geo.GetVector(_angleMove.X).X; //_sumVector.Y = Geo.GetVector(_angleMove.Y).Y; _sumVector = Geo.GetVector(_angleMove.X) * _velocity.X + Geo.GetVector(_angleMove.Y) * _velocity.Y; if (MOVE_LEFT && MOVE_RIGHT) { _sumVector.X = 0f; } //_finalVector.X = _sumVector.X * _velocity.X; //_finalVector.Y = _sumVector.Y * _velocity.Y; _finalVector = _sumVector; //_finalVector.X = Geo.GetVector(_angleMove.X).X * _velocity.X; //_finalVector.Y = Geo.GetVector(_angleMove.Y).Y * _velocity.Y; #region Collisions Test if (_hSpots.Count > 0) { // Reset all collide point to false ! for (int i = 0; i < _hSpots.Count; i++) { _cPoints[i]._isContact = false; _cPoints[i]._hotPoint = _hSpots[i]; _cPoints[i]._pos = XY + _hSpots[i] + _finalVector; _cPoints[i]._mapX = (int)(_cPoints[i]._pos.X / _tileW); _cPoints[i]._mapY = (int)(_cPoints[i]._pos.Y / _tileH); _cPoints[i]._offset = new Vector2(_cPoints[i]._mapX * _tileW, _cPoints[i]._mapY * _tileH); _cPoints[i]._tile = _map2D.Get(_cPoints[i]._mapX, _cPoints[i]._mapY); //_CollidePointInPolygon = false; if (null != _cPoints[i]._tile) { // check the tileset if collide in polygon if (_tileMapLayer._tileSets.ContainsKey(_cPoints[i]._tile._id)) { TileSet tileset = _tileMapLayer._tileSets[_cPoints[i]._tile._id]; _cPoints[i]._polygon = tileset._polygonCollision; if (_cPoints[i]._polygon != null) { // get polygon[] in the tile where is the contactPoint of the global Tileset _cPoints[i].GetLineContact(_cPoints[i]._offset, _cPoints[i]._polygon); _cPoints[i]._isContact = Collision2D.PointInPolygon(_cPoints[i]._pos, _cPoints[i]._polygon, _cPoints[i]._polygon.Length, _cPoints[i]._offset) && _cPoints[i]._tile._isCollidable && _cPoints[i]._tile._passLevel > PASS_LEVEL; // && _contactPoints[i]._successRaycast; } } } } // Point Test // Up Top #region Contact : UP / TOP if (_cPoints[(int)HSpots.UL]._isContact && _status == Status.IS_JUMP) { CAN_MOVE_UP = false; //_topY = _topY_L = _contactPoints[(int)HotPoints.UL]._mapY * _tileH + _tileH + _rect.Height / 2 + 2; _topY = _topY_L = _cPoints[(int)HSpots.UL]._pointContact.Y + _rect.Height / 2 + 2; } if (_cPoints[(int)HSpots.UR]._isContact && _status == Status.IS_JUMP) { CAN_MOVE_UP = false; //_topY = _topY_R = _contactPoints[(int)HotPoints.UR]._mapY * _tileH + _tileH + _rect.Height / 2 + 2; _topY = _topY_R = _cPoints[(int)HSpots.UR]._pointContact.Y + _rect.Height / 2 + 2; } if (_cPoints[(int)HSpots.UL]._isContact && _cPoints[(int)HSpots.UR]._isContact && _status == Status.IS_JUMP) { if (_topY_L > _topY_R) { _topY = _topY_L; } else { _topY = _topY_R; } } #endregion #region Contact : DOWN / BOTTOM if (_cPoints[(int)HSpots.DL]._isContact) { CAN_MOVE_DOWN = false; _landLineA = _landLineA_L = _cPoints[(int)HSpots.DL]._polygon[0] + _cPoints[(int)HSpots.DL]._offset; _landLineB = _landLineB_L = _cPoints[(int)HSpots.DL]._polygon[1] + _cPoints[(int)HSpots.DL]._offset; _landRadian = _landRadian_L = Geo.GetRadian(_landLineA, _landLineB); //_pointLandCollision = _pointLandCollision_L = Collision2D.LineLineIntersection(_landLineA, _landLineB, _contactPoints[(int)HotPoints.DL]._pos, _contactPoints[(int)HotPoints.DL]._pos + _contactPoints[(int)HotPoints.DL]._raycast); _pointLandCollision = _pointLandCollision_L = _cPoints[(int)HSpots.DL]._pointContact; _landY = _landY_L = _pointLandCollision_L.Y - _rect.Height / 2 - 2; } if (_cPoints[(int)HSpots.DR]._isContact) { CAN_MOVE_DOWN = false; _landLineA = _landLineA_R = _cPoints[(int)HSpots.DR]._polygon[0] + _cPoints[(int)HSpots.DR]._offset; _landLineB = _landLineB_R = _cPoints[(int)HSpots.DR]._polygon[1] + _cPoints[(int)HSpots.DR]._offset; _landRadian = _landRadian_R = Geo.GetRadian(_landLineA, _landLineB); //_pointLandCollision = _pointLandCollision_R = Collision2D.LineLineIntersection(_landLineA, _landLineB, _contactPoints[(int)HotPoints.DR]._pos, _contactPoints[(int)HotPoints.DR]._pos + _contactPoints[(int)HotPoints.DR]._raycast); _pointLandCollision = _pointLandCollision_R = _cPoints[(int)HSpots.DR]._pointContact; _landY = _landY_R = _pointLandCollision_R.Y - _rect.Height / 2 - 2; } #endregion #region Contact : LEFT & RIGHT // Limit Side Move // LEFT if (_cPoints[(int)HSpots.LU]._isContact && MOVE_LEFT) { CAN_MOVE_LEFT = false; //_sideL = _contactPoints[(int)HotPoints.LU]._mapX * _tileW + _tileW + _rect.Width / 2 + 2; _sideL = _cPoints[(int)HSpots.LU]._pointContact.X + _rect.Width / 2 + 2; } if (_cPoints[(int)HSpots.LD]._isContact && MOVE_LEFT) { CAN_MOVE_LEFT = false; //_sideL = _contactPoints[(int)HotPoints.LD]._mapX * _tileW + _tileW + _rect.Width / 2 + 2; _sideL = _cPoints[(int)HSpots.LD]._pointContact.X + _rect.Width / 2 + 2; } // RIGHT if (_cPoints[(int)HSpots.RU]._isContact && MOVE_RIGHT) { CAN_MOVE_RIGHT = false; //_sideR = _contactPoints[(int)HotPoints.RU]._mapX * _tileW - _rect.Width / 2 - 2; _sideR = _cPoints[(int)HSpots.RU]._pointContact.X - _rect.Width / 2 - 2; } if (_cPoints[(int)HSpots.RD]._isContact && MOVE_RIGHT) { CAN_MOVE_RIGHT = false; //_sideR = _contactPoints[(int)HotPoints.RD]._mapX * _tileW - _rect.Width / 2 - 2; _sideR = _cPoints[(int)HSpots.RD]._pointContact.X - _rect.Width / 2 - 2; } // Type Slope = 3 if (_cPoints[(int)HSpots.LU]._tile != null) { if (!_cPoints[(int)HSpots.LU]._isContact && _cPoints[(int)HSpots.LU]._tile._type == 3 && MOVE_LEFT) // && _contactPoints[(int)CPoint.DL]._isContact { //CAN_MOVE_DOWN = false; _landLineA = _landLineA_L = _cPoints[(int)HSpots.LU]._polygon[0] + _cPoints[(int)HSpots.LU]._offset; _landLineB = _landLineB_L = _cPoints[(int)HSpots.LU]._polygon[1] + _cPoints[(int)HSpots.LU]._offset; _landRadian = _landRadian_L = Geo.GetRadian(_landLineA, _landLineB); if (_cPoints[(int)HSpots.DL]._isContact) { CAN_MOVE_DOWN = false; _pointLandCollision = _pointLandCollision_L = Collision2D.LineLineIntersection(_landLineA, _landLineB, _cPoints[(int)HSpots.DL]._pos, _cPoints[(int)HSpots.DL]._pos + _cPoints[(int)HSpots.DL]._raycast); //_pointLandCollision = _pointLandCollision_L = _cPoints[(int)HSpots.DL]._pointContact; _landY = _landY_L = _pointLandCollision_L.Y - _rect.Height / 2 - 2; } } } if (_cPoints[(int)HSpots.RU]._tile != null) { if (!_cPoints[(int)HSpots.RU]._isContact && _cPoints[(int)HSpots.RU]._tile._type == 3 && MOVE_RIGHT) // && _contactPoints[(int)CPoint.DL]._isContact { //CAN_MOVE_DOWN = false; _landLineA = _landLineA_R = _cPoints[(int)HSpots.RU]._polygon[0] + _cPoints[(int)HSpots.RU]._offset; _landLineB = _landLineB_R = _cPoints[(int)HSpots.RU]._polygon[1] + _cPoints[(int)HSpots.RU]._offset; _landRadian = _landRadian_R = Geo.GetRadian(_landLineA, _landLineB); if (_cPoints[(int)HSpots.DR]._isContact) { CAN_MOVE_DOWN = false; _pointLandCollision = _pointLandCollision_R = Collision2D.LineLineIntersection(_landLineA, _landLineB, _cPoints[(int)HSpots.DR]._pos, _cPoints[(int)HSpots.DR]._pos + _cPoints[(int)HSpots.DR]._raycast); //_pointLandCollision = _pointLandCollision_R = _cPoints[(int)HSpots.DR]._pointContact; _landY = _landY_R = _pointLandCollision_R.Y - _rect.Height / 2 - 2; } } } // Choose best LandY Left or Right //if (MOVE_LEFT && _contactPoints[(int)CPoint.DL]._isContact) if (_cPoints[(int)HSpots.DL]._isContact && _cPoints[(int)HSpots.DR]._isContact) { //Console.Write("< BOTH LAND L & R >"); if (_pointLandCollision_L.Y < _pointLandCollision_R.Y) //if (_landY_L < _landY_R) { _pointLandCollision = _pointLandCollision_L; _landLineA = _landLineA_L; _landLineB = _landLineB_L; _landRadian = _landRadian_L; //_landY_R = _landY = _landY_L; _landY = _landY_L; _contactPointDown = _cPoints[(int)HSpots.DL]; } else //if (MOVE_RIGHT && _contactPoints[(int)CPoint.DR]._isContact) if (_pointLandCollision_L.Y > _pointLandCollision_R.Y) { _pointLandCollision = _pointLandCollision_R; _landLineA = _landLineA_R; _landLineB = _landLineB_R; _landRadian = _landRadian_R; //_landY_L = _landY = _landY_R; _landY = _landY_R; _contactPointDown = _cPoints[(int)HSpots.DR]; } } #endregion #region Contact : GRAB LEDGE if (CAN_MOVE_UP && CAN_MOVE_DOWN && !CAN_MOVE_LEFT && _cPoints[(int)HSpots.EL]._isContact && Math.Abs(_cPoints[(int)HSpots.EL]._pos.Y - _cPoints[(int)HSpots.EL]._firstline.B.Y) <= 8) { TileMap tileU = _map2D.Get(_cPoints[(int)HSpots.EL]._mapX, _cPoints[(int)HSpots.EL]._mapY - 1); bool climbable = false; if (tileU == null) { climbable = true; } else if (tileU._id != Const.NoIndex) // test is tile at up is empty or not, if not then test is climbable on Left { if (tileU._tileSet._properties.ContainsKey("ClimbR")) { climbable = true; } } else { climbable = true; } if (climbable && !CAN_GRAB_L) { CAN_GRAB_L = true; _grabY = _cPoints[(int)HSpots.EL]._firstline.B.Y - _hSpots[(int)HSpots.EL].Y; _ledgeGrip.X = _cPoints[(int)HSpots.EL]._firstline.B.X; _ledgeGrip.Y = _cPoints[(int)HSpots.EL]._firstline.B.Y; } } if (CAN_MOVE_UP && CAN_MOVE_DOWN && !CAN_MOVE_RIGHT && _cPoints[(int)HSpots.ER]._isContact && Math.Abs(_cPoints[(int)HSpots.ER]._pos.Y - _cPoints[(int)HSpots.ER]._firstline.A.Y) <= 8) { TileMap tileU = _map2D.Get(_cPoints[(int)HSpots.ER]._mapX, _cPoints[(int)HSpots.ER]._mapY - 1); bool climbable = false; if (tileU == null) { climbable = true; } else if (tileU._id != Const.NoIndex) // test is tile at up is empty or not, if not then test is climbable on Left { if (tileU._tileSet._properties.ContainsKey("ClimbL")) { climbable = true; } } else { climbable = true; } if (climbable && !CAN_GRAB_R) { CAN_GRAB_R = true; _grabY = _cPoints[(int)HSpots.ER]._firstline.A.Y - _hSpots[(int)HSpots.ER].Y; _ledgeGrip.X = _cPoints[(int)HSpots.ER]._firstline.A.X; _ledgeGrip.Y = _cPoints[(int)HSpots.ER]._firstline.A.Y; } } #endregion } #endregion #region CAN MOVE TEST & Pre Collision Raycast if (!CAN_MOVE_DOWN) { if (_status != Status.IS_LAND) { _preCollisionRayCastY = (_y + _finalVector.Y) - _landY; _finalVector.Y -= _preCollisionRayCastY; //_y = _landY ; //_finalVector.Y = 0; Land(); } } if (!CAN_MOVE_UP) { Console.WriteLine("!! Touch Top !!"); _preCollisionRayCastY = (_y + _finalVector.Y) - _topY; _finalVector.Y -= _preCollisionRayCastY; } if (!CAN_MOVE_LEFT) //if (_contactPoints[(int)HotPoints.LU]._isContact || _contactPoints[(int)HotPoints.LD]._isContact) { _preCollisionRayCastX = (_x + _finalVector.X) - _sideL; _finalVector.X -= _preCollisionRayCastX; if (MOVE_LEFT) { _isPush = true; if (!CAN_WALL_JUMP_R && _status == Status.IS_FALL && CAN_MOVE_UP && _cPoints[(int)HSpots.EL]._isContact) { Console.WriteLine("CAN WALL JUMP R"); _onCanWallJump = true; CAN_WALL_JUMP_R = true; } } } if (!CAN_MOVE_RIGHT) //if (_contactPoints[(int)HotPoints.RU]._isContact || _contactPoints[(int)HotPoints.RD]._isContact) { _preCollisionRayCastX = (_x + _finalVector.X) - _sideR; _finalVector.X -= _preCollisionRayCastX; if (MOVE_RIGHT) { _isPush = true; if (!CAN_WALL_JUMP_L && _status == Status.IS_FALL && CAN_MOVE_UP && _cPoints[(int)HSpots.ER]._isContact) { Console.WriteLine("CAN WALL JUMP L"); _onCanWallJump = true; CAN_WALL_JUMP_L = true; } } } if (((CAN_GRAB_L && !CAN_MOVE_LEFT) || (CAN_GRAB_R && !CAN_MOVE_RIGHT)) && _isPush && _status == Status.IS_FALL) { _preCollisionRayCastY = (_y + _finalVector.Y) - _grabY; _finalVector.Y -= _preCollisionRayCastY; //Console.WriteLine($"---------------------> _grabY = {_grabY} _preCollisionRayCastY = {_preCollisionRayCastY}"); if (CAN_GRAB_L) { Grab(ref IS_GRAB_L); } if (CAN_GRAB_R) { Grab(ref IS_GRAB_R); } } #endregion #region Status if (_status == Status.IS_FALL) { float factor = 1f; if (((CAN_WALL_JUMP_L && _cPoints[(int)HSpots.ER]._isContact) || (CAN_WALL_JUMP_R && _cPoints[(int)HSpots.EL]._isContact)) && _isPush && CAN_MOVE_UP) { factor = .05f; // Slow down when grip wall } _velocity.Y += _acceleration.Y * factor; if (_velocity.Y >= _speedMax.Y) { _velocity.Y = _speedMax.Y; } } if (_status == Status.IS_LAND && _velocity.Y == 0) { if (CAN_MOVE_DOWN) { Fall(); } //_contactX = _x - _contactDown._mapX * _tileW; _contactY = _contactDown._mapY * _tileH; //_contactY = -((_contactY - _landLineA.Y) + (_landLineB.Y - _landLineA.Y) / (_landLineA.X - _landLineB.X) * _contactX) ; //_contactY = _contactY + _contactDown._mapY * _tileH; //Console.WriteLine($"_contactX = {_contactX} : {_contactY}"); //if (_contactDown._isContact) // _y = _contactY - _rect.Height / 2 - 2; } if (_status == Status.IS_GRAB) { ++_ticGrab; if (_ticGrab >= _tempoGrab) { _ticGrab = _tempoGrab; if (CAN_GRAB_L) { CAN_GRAB_L = false; CAN_CLIMB_L = true; } if (CAN_GRAB_R) { CAN_GRAB_R = false; CAN_CLIMB_R = true; } if (!_isPush) // When release button push then readyToClimb ! { _readyToClimb = true; if (MOVE_UP) { Console.WriteLine($"Climb < {IS_GRAB_L} - {IS_GRAB_R} > : MOVE_UP"); if (IS_GRAB_L) { Climb(-1); } if (IS_GRAB_R) { Climb(1); } } if (MOVE_DOWN) { Fall(); } } else if (MOVE_JUMP) { Console.WriteLine($"Climb < {IS_GRAB_L} - {IS_GRAB_R} > : MOVE_JUMP"); _readyToClimb = true; if (IS_GRAB_L) { Climb(-1); } if (IS_GRAB_R) { Climb(1); } } } } if (_status == Status.IS_CLIMB) { if (AUTO_UP) { _y += -4f; ++_ticAutoUp; if (_ticAutoUp > _rect.Height / 4) { _ticAutoUp = 0; _ticAutoMove = 0; AUTO_UP = false; AUTO_MOVE = true; } } if (AUTO_MOVE) { _y += -.5f; ++_ticAutoMove; if (_ticAutoMove > _rect.Width / 4) { AUTO_MOVE = false; _directionAutoMove = 0; //Fall(); SetStatus(Status.IS_LAND); } if (_directionAutoMove < 0) { _landRadian = Geo.GetRadian(_cPoints[(int)HSpots.EL]._firstline.B, _cPoints[(int)HSpots.EL]._firstline.A); MoveL(); } if (_directionAutoMove > 0) { _landRadian = Geo.GetRadian(_cPoints[(int)HSpots.ER]._firstline.A, _cPoints[(int)HSpots.ER]._firstline.B); MoveR(); } } } if (_status == Status.IS_JUMP) { _velocity.Y += -_deceleration.Y; if (_velocity.Y <= 0 || !CAN_MOVE_UP) { Fall(); } } #endregion #region Jump Helper when left Land or Grab if (_onFall && _status == Status.IS_FALL && (_oldStatus == Status.IS_LAND || (_status == Status.IS_GRAB && !_isPush))) { _isJustFall = true; _ticJustFall = 0; //Console.Write("<Just Fall from land >"); } if (_isJustFall) { //if (!CAN_MOVE_UP) //{ // _isJustFall = false; // SetStatus(Status.IS_FALL); Fall(); //} if (MOVE_JUMP && !_onJump) // second chance to jump { Console.WriteLine("Helper Jump !"); SetStatus(Status.IS_LAND); Jump(_speedMax.Y); } ++_ticJustFall; if (_ticJustFall > _maxTicJustFall) { //Console.Write("< Stop jump helper >"); _isJustFall = false; _ticJustFall = 0; } } if (_onCanWallJump) { Console.WriteLine("ON Can Wall Jump !"); _onCanWallJump = false; _velocity.Y = 0f; } #endregion #region Trigger if (_onLand) { _onLand = false; _velocity.Y = 0; _velocity.X = 0; } if (_onFall) { _onFall = false; _angleMove.Y = Geo.RAD_D; _velocity.X = 0; _velocity.Y = 0; } if (_onJump) { _onJump = false; } if (_onGrab) { _onGrab = false; //_isJustGrab = true; _velocity.Y = 0; } if (_onClimb) { _onClimb = false; //System.Console.Write("< ON_CLIMB >"); } #endregion _oldX = _x; _oldY = _y; _x += _finalVector.X; //* (float)gameTime.ElapsedGameTime.TotalSeconds * 100; _y += _finalVector.Y; //* (float)gameTime.ElapsedGameTime.TotalSeconds * 100; MOVE_UP = false; MOVE_DOWN = false; MOVE_LEFT = false; MOVE_RIGHT = false; MOVE_JUMP = false; MOVE_FALL = false; return(base.Update(gameTime)); }