/// <summary> /// Moves block over an arbitrairy vector /// </summary> /// <param name="xoff">x movement</param> /// <param name="yoff">y movement</param> /// <returns>Movement succeeded</returns> protected Boolean Move(Int32 xoff, Int32 yoff) { if(this.Field.Collides(this.Block, this.X + xoff, this.Y + yoff)) return false; Event e = new Event(); Int32 prevx = X; Int32 prevy = Y; Double prevtime = this.LastMoveTime; Double newtime = this.Field.Timeline.CurrentTime; var wasRot = this.LastMoveIsRotation; var wasKick = this.LastMoveIsKick; e.Undo = () => { this.Field.CurrentBlock.X = prevx; this.Field.CurrentBlock.Y = prevy; this.LastMoveTime = prevtime; this.LastMoveIsRotation = wasRot; this.LastMoveIsKick = wasKick; }; Int32 newx = X + xoff; Int32 newy = Y + yoff; e.Apply = () => { this.Field.CurrentBlock.X = newx; this.Field.CurrentBlock.Y = newy; this.LastMoveTime = newtime; this.LastMoveIsRotation = false; this.LastMoveIsKick = false; }; this.Field.Timeline.Add(e); return true; }
/// <summary> /// Rotates a block an arbitrary direction /// </summary> /// <param name="dir">Direction to rotate</param> /// <returns>Rotation succeeded</returns> protected Boolean Rotate(Int32 dir) { int rot = this.Block.Rotation; this.Block.Rotation += dir; Int32[,] wallkicks = (dir > 0) ? Wallkick.WallkickData.RightMovements[new Tuple<int, int>(this.Block.Width, this.Block.Rotation)] : Wallkick.WallkickData.LeftMovements[new Tuple<int, int>(this.Block.Width, this.Block.Rotation)]; // Tries to wall kick until block doesn't collide for(Int32 i = 0; i < wallkicks.GetLength(0); i++) { if (this.Field.Collides(Block, X + wallkicks[i, 0], Y + wallkicks[i, 1])) continue; Event e = new Event(); Int32 prevx = X; Int32 prevy = Y; Double prevtime = this.LastMoveTime; Double newtime = Field.Timeline.CurrentTime; var wasRot = this.LastMoveIsRotation; var wasKick = this.LastMoveIsKick; e.Undo = () => { this.X = prevx; this.Y = prevy; this.Block.Rotation = rot; this.LastMoveTime = prevtime; this.LastMoveIsRotation = wasRot; this.LastMoveIsKick = wasKick; }; Int32 newx = X + wallkicks[i, 0]; Int32 newy = Y + wallkicks[i, 1]; Int32 newrot = rot + dir; e.Apply = () => { this.Field.CurrentBlock.X = newx; this.Field.CurrentBlock.Y = newy; this.Field.CurrentBlock.Block.Rotation = newrot; this.LastMoveTime = newtime; this.LastMoveIsRotation = true; this.LastMoveIsKick = i > 0; }; this.Field.Timeline.Add(e); return true; } // Rotation failed this.Block.Rotation -= dir; return false; }
/// <summary> /// Adds an event /// </summary> /// <param name="action">event to register</param> /// <returns>Event time</returns> public Double Add(Event action) { action.Time = this.CurrentTime; action.Apply(); this.Events.Push(action); return action.Time; }