/// <summary> /// Converts a point from client coordinates to world tile coordinates. /// </summary> public Vector VectorToTile(Vector point) { Vector world = camera.VectorToWorld(point); return new Vector( MathUtil.CeilingDivide(world.X, Tile.Width), MathUtil.CeilingDivide(world.Y, Tile.Height)); }
public TileCell this[int x, int y] { get { Vector point = new Vector(x, y); Section section = GetSectionFromPoint(point); Vector relativePoint = section.VectorToRelative(point); return section.Cells[relativePoint.X, relativePoint.Y]; } }
public void Pan(int amountX, int amountY) { translate -= new Vector(amountX, amountY) / scale; }
public void Apply(Graphics graphics) { graphics.ScaleTransform(scale, scale, MatrixOrder.Append); Vector center = new Vector(mapPanel.Width / 2, mapPanel.Height / 2); Vector translate = (this.translate * scale + center); graphics.TranslateTransform(translate.X, translate.Y, MatrixOrder.Append); }
public Camera(MapView mapPanel) { this.mapPanel = mapPanel; mapPanel.Resize += delegate(object sender, EventArgs args) { center = new Vector(mapPanel.Width / 2, mapPanel.Height / 2); }; }
public static Vector Sign(Vector vector) { return new Vector(Math.Sign(vector.x), Math.Sign(vector.y)); }
public static Vector Abs(Vector vector) { return new Vector(Math.Abs(vector.x), Math.Abs(vector.y)); }
private Vector GetIndexFromPoint(Vector point) { return GetIndexFromOffset(point / Section.Size); }
public Vector VectorToRelative(Vector absolutePoint) { return absolutePoint - (offset * Size); }
public Vector VectorToAbsolute(Vector relativePoint) { return relativePoint + (offset * Size); }
public Section(Vector offset) { this.offset = offset; for(int y = 0; y < Size; ++y) { for(int x = 0; x < Size; ++x) cells[x, y] = new TileCell(); } }
/// <summary> /// If the provided index is invalid (for example, if a component is negative), this /// function will expand the map so that it encompasses the index, and then return a /// new, valid index. This function will also initialize the section at the sepcified /// index if that section has not yet been initialized. /// </summary> /// <param name="index"> /// The index into the <c>sections</c> array to be validated. /// </param> /// <returns> /// An index into the <c>sections</c> array that is valid. /// </returns> private Vector ValidateIndex(Vector index) { Vector shift = new Vector(); if(index.X >= SectionWidth) shift += new Vector(index.X - SectionWidth + 1, 0); else if(index.X < 0) shift += new Vector(-index.X, 0); if(index.Y >= SectionHeight) shift += new Vector(0, index.Y - SectionHeight + 1); else if(index.Y < 0) shift += new Vector(0, -index.Y); Vector translate = Expand(shift); index += translate; if(sections[index.X, index.Y] == null) sections[index.X, index.Y] = new Section(GetOffsetFromIndex(index)); return index; }
private bool IsValidIndex(Vector index) { return (index.X >= 0 && index.X < SectionWidth) && (index.Y >= 0 && index.Y < SectionHeight); }
private Section GetSectionFromPoint(Vector point) { Vector index = ValidateIndex(GetIndexFromPoint(point)); return sections[index.X, index.Y]; }
private Vector GetOffsetFromIndex(Vector index) { return index - centerIndex; }
// Converts a point from client coordinates to world coordinates public Vector VectorToWorld(Vector point) { return (point - center) / scale - translate; }
public void Zoom(float amount, Vector target) { scale += amount; if(scale > ScaleMax) scale = ScaleMax; if(scale < ScaleMin) scale = ScaleMin; }
/// <summary> /// This function will expand the map in a certain direction, resizing the <c>sections</c> /// array and modifying <c>centerIndex</c>. /// </summary> /// <param name="shift"> /// A vector representing the direction to expand the map in. For example, if this vector /// is (1, 0), the map will be expanded horizontally to the right. /// </param> /// <remarks> /// If any element of the shift vector is negative (that is, if you are expanding upwards /// or to the left), the <c>sections</c> array will be shifted in the opposite direction /// to make room for the new row or column. The <c>centerIndex</c> will be modified to /// accomodate this change. /// </remarks> /// <returns> /// The amount the <c>sections</c> array was shifted. /// </returns> private Vector Expand(Vector shift) { Section[,] oldSections = sections; int oldWidth = SectionWidth, oldHeight = SectionHeight; sections = new Section[oldWidth + Math.Abs(shift.X), oldHeight + Math.Abs(shift.Y)]; Vector translate = new Vector(); if(shift.X < 0) translate.X = shift.X; if(shift.Y < 0) translate.Y = shift.Y; for(int y = 0; y < oldHeight; ++y) { for(int x = 0; x < oldWidth; ++x) sections[x + translate.X, y + translate.Y] = oldSections[x, y]; } centerIndex += translate; return translate; }
protected override void OnMouseMove(MouseEventArgs args) { base.OnMouseMove(args); if(panState != PanState.None) { if(panState == PanState.Pending) { panState = PanState.Active; Cursor = Cursors.SizeAll; } Vector mousePosition = (Vector)args.Location; Vector delta = lastMousePosition - mousePosition; camera.Pan(delta.X, delta.Y); Refresh(); } lastMousePosition = (Vector)args.Location; }
private Vector GetIndexFromOffset(Vector index) { return index + centerIndex; }