/// <summary> /// adds the object to the SpatialHash /// </summary> /// <param name="collider">Object.</param> public void Register(AABB collider) { var bounds = collider.Bounds; var p1 = CellCoords(bounds.X, bounds.Y); var p2 = CellCoords(bounds.Right, bounds.Bottom); // update our bounds to keep track of our grid size if (!GridBounds.Contains(p1)) { RectangleExt.Union(ref GridBounds, ref p1, out GridBounds); } if (!GridBounds.Contains(p2)) { RectangleExt.Union(ref GridBounds, ref p2, out GridBounds); } for (var x = p1.X; x <= p2.X; x++) { for (var y = p1.Y; y <= p2.Y; y++) { // we need to create the cell if there is none var c = CellAtPosition(x, y, true); c.Add(collider); } } }
/// <summary> /// gets a collision rect for the given side expanded to take into account motion /// </summary> /// <returns>The rect for side.</returns> /// <param name="side">Side.</param> /// <param name="motion">Motion.</param> Rectangle collisionRectForSide(Edge side, int motion) { Rectangle bounds; // for horizontal collision checks we use just a sliver for our bounds. Vertical gets the half rect so that it can properly push // up when intersecting a slope which is ignored when moving horizontally. if (side.isHorizontal()) { bounds = _boxColliderBounds.getRectEdgePortion(side); } else { bounds = _boxColliderBounds.getHalfRect(side); } // we contract horizontally for vertical movement and vertically for horizontal movement if (side.isVertical()) { RectangleExt.contract(ref bounds, colliderHorizontalInset, 0); } else { RectangleExt.contract(ref bounds, 0, colliderVerticalInset); } // finally expand the side in the direction of movement RectangleExt.expandSide(ref bounds, side, motion); return(bounds); }
/// <summary> /// adds the object to the SpatialHash /// </summary> /// <param name="collider">Object.</param> public void register(Collider collider) { var bounds = collider.bounds; collider.registeredPhysicsBounds = bounds; var p1 = cellCoords(bounds.x, bounds.y); var p2 = cellCoords(bounds.right, bounds.bottom); // update our bounds to keep track of our grid size if (!gridBounds.Contains(p1)) { RectangleExt.union(ref gridBounds, ref p1, out gridBounds); } if (!gridBounds.Contains(p2)) { RectangleExt.union(ref gridBounds, ref p2, out gridBounds); } for (var x = p1.X; x <= p2.X; x++) { for (var y = p1.Y; y <= p2.Y; y++) { // we need to create the cell if there is none var c = cellAtPosition(x, y, true); c.Add(collider); } } }
internal void Render() { #if DEBUG if (_runtimeInspector != null) { _runtimeInspector.Update(); _runtimeInspector.Render(); } #endif if (!isOpen) { return; } var screenWidth = Screen.Width; var screenHeight = Screen.Height; var workingWidth = screenWidth - 2 * HORIZONTAL_PADDING; Graphics.Instance.Batcher.Begin(); // setup the rect that encompases the command entry section var commandEntryRect = RectangleExt.FromFloats(HORIZONTAL_PADDING, screenHeight - LINE_HEIGHT * RenderScale, workingWidth, LINE_HEIGHT * RenderScale); // take into account text padding. move our location up a bit and expand the Rect to accommodate commandEntryRect.Location -= new Point(0, TEXT_PADDING_Y * 2); commandEntryRect.Height += TEXT_PADDING_Y * 2; Graphics.Instance.Batcher.DrawRect(commandEntryRect, Color.Black * OPACITY); var commandLineString = "> " + _currentText; if (_underscore) { commandLineString += "_"; } var commandTextPosition = commandEntryRect.Location.ToVector2() + new Vector2(TEXT_PADDING_X, TEXT_PADDING_Y); Graphics.Instance.Batcher.DrawString(Graphics.Instance.BitmapFont, commandLineString, commandTextPosition, Color.White, 0, Vector2.Zero, new Vector2(RenderScale), SpriteEffects.None, 0); if (_drawCommands.Count > 0) { // start with the total height of the text then add in padding. We have an extra padding because we pad each line and the top/bottom var height = LINE_HEIGHT * RenderScale * _drawCommands.Count; height += (_drawCommands.Count + 1) * TEXT_PADDING_Y; var topOfHistoryRect = commandEntryRect.Y - height - COMMAND_HISTORY_PADDING; Graphics.Instance.Batcher.DrawRect(HORIZONTAL_PADDING, topOfHistoryRect, workingWidth, height, Color.Black * OPACITY); var yPosFirstLine = topOfHistoryRect + height - TEXT_PADDING_Y - LINE_HEIGHT * RenderScale; for (var i = 0; i < _drawCommands.Count; i++) { var yPosCurrentLineAddition = (i * LINE_HEIGHT * RenderScale) + (i * TEXT_PADDING_Y); var position = new Vector2(HORIZONTAL_PADDING + TEXT_PADDING_X, yPosFirstLine - yPosCurrentLineAddition); var color = _drawCommands[i].IndexOf(">") == 0 ? Color.Yellow : Color.White; Graphics.Instance.Batcher.DrawString(Graphics.Instance.BitmapFont, _drawCommands[i], position, color, 0, Vector2.Zero, new Vector2(RenderScale), SpriteEffects.None, 0); } } Graphics.Instance.Batcher.End(); }
private void CreatePoints() { PointList.Clear(); ContentGrid.Children.Clear(); for (int i = 0; i < BezierDegree; i++) { var point = new RectangleExt(); PointList.Add(point); } }
public void PointYChanged(RectangleExt dataContext, TextChangedEventArgs e) { if ((e.OriginalSource as TextBox).Text != "" && !_isBlocked) { dataContext.Point.Y = double.Parse((e.OriginalSource as TextBox).Text); if (_insertedPoint != PointList.Count - 1 && _lastInputedRectangle != dataContext && PointList.IndexOf(dataContext) > _insertedPoint) { _insertedPoint++; } DrawBezier(); } _lastInputedRectangle = dataContext; }
/// <summary> /// Clips the specified screen aligned rectangle, specified relative to the transform matrix of the stage's Batch. The /// transform matrix and the stage's camera must not have rotational components. Calling this method must be followed by a call /// to clipEnd() if true is returned. /// </summary> public bool clipBegin(Batcher batcher, float x, float y, float width, float height) { if (width <= 0 || height <= 0) { return(false); } var tableBounds = RectangleExt.fromFloats(x, y, width, height); var scissorBounds = ScissorStack.calculateScissors(stage?.entity?.scene?.camera, batcher.transformMatrix, tableBounds); if (ScissorStack.pushScissors(scissorBounds)) { batcher.enableScissorTest(true); return(true); } return(false); }
private static void CollisionDraw(string txt, Graphics g, ILabelSymbolizer symb, IFeature f, MapArgs e, RectangleF labelBounds, List <RectangleF> existingLabels) { if (labelBounds == RectangleF.Empty || !RectangleExt.IntersectsWith(e.ImageRectangle, labelBounds)) { return; } if (symb.PreventCollisions) { if (!Collides(labelBounds, existingLabels)) { DrawLabel(g, txt, labelBounds, symb, f); existingLabels.Add(labelBounds); } } else { DrawLabel(g, txt, labelBounds, symb, f); } }
/// <summary> /// gets a collision rect for the given side expanded to take into account motion /// </summary> /// <returns>The rect for side.</returns> /// <param name="side">Side.</param> /// <param name="motion">Motion.</param> Rectangle collisionRectForSide(Edge side, int motion) { var bounds = (Rectangle)_collider.bounds; bounds = bounds.getHalfRect(side); // we contract horizontally for vertical movement and vertically for horizontal movement if (side.isVertical()) { RectangleExt.contract(ref bounds, colliderHorizontalInset, 0); } else { RectangleExt.contract(ref bounds, 0, colliderVerticalInset); } // finally expand the side in the direction of movement RectangleExt.expandSide(ref bounds, side, motion); return(bounds); }
/// <summary> /// gets a collision rect for the given side expanded to take into account motion /// </summary> /// <returns>The rect for side.</returns> /// <param name="sida">Side.</param> /// <param name="rörelse">Motion.</param> private Rectangle CollisionRectForSide(Edge sida, int rörelse) { Rectangle bounds = sida.IsHorizontal() ? BoxColliderGränser.GetRectEdgePortion(sida) : BoxColliderGränser.GetHalfRect(sida); // for horizontal collision checks we use just a sliver for our bounds. Vertical gets the half rect so that it can properly push // up when intersecting a slope which is ignored when moving horizontally. // we contract horizontally for vertical movement and vertically for horizontal movement if (sida.IsVertical()) { RectangleExt.Contract(ref bounds, ColliderHorizontalInset, 0); } else { RectangleExt.Contract(ref bounds, 0, ColliderVerticalInset); } // finally expand the side in the direction of movement RectangleExt.ExpandSide(ref bounds, sida, rörelse); return(bounds); }
private void hitMelee() { // perform a melee hit var meleeWeapon = entity.getComponent <MeleeWeapon>(); var dir = lastFacing == Direction.Right ? 1 : -1; var facingFlipScale = new Vector2(dir, 1); var offset = meleeWeapon.offset; offset = Vector2Ext.transform(offset, Matrix2D.createScale(facingFlipScale)); var reach = meleeWeapon.reach; // reflect X based on direction RectangleExt.scale(ref reach, facingFlipScale); // var swordCollider = new BoxCollider(offset.X + reach.X, // offset.Y + reach.Y, reach.Width, reach.Height); var swordCollider = new BoxCollider(0, 0, reach.Width, reach.Height); swordCollider.localOffset = new Vector2(offset.X + reach.X + reach.Width / 2f, offset.Y + reach.Y + reach.Height / 2f); entity.addComponent(swordCollider); collisionResults.Clear(); swordCollider.collidesWithAnyMultiple(Vector2.Zero, collisionResults); for (var i = 0; i < collisionResults.Count; i++) { var result = collisionResults[i]; var character = result.collider?.entity.getComponent <Character>(); if (character != null) { hurtCharacter(character); } } entity.removeComponent(swordCollider); }
public override void Layout() { var bg = _style.Background; var hScrollKnob = _style.HScrollKnob; var vScrollKnob = _style.VScrollKnob; float bgLeftWidth = 0, bgRightWidth = 0, bgTopHeight = 0, bgBottomHeight = 0; if (bg != null) { bgLeftWidth = bg.LeftWidth; bgRightWidth = bg.RightWidth; bgTopHeight = bg.TopHeight; bgBottomHeight = bg.BottomHeight; } var width = GetWidth(); var height = GetHeight(); var scrollbarHeight = 0f; if (hScrollKnob != null) { scrollbarHeight = hScrollKnob.MinHeight; } if (_style.HScroll != null) { scrollbarHeight = Math.Max(scrollbarHeight, _style.HScroll.MinHeight); } var scrollbarWidth = 0f; if (vScrollKnob != null) { scrollbarWidth = vScrollKnob.MinWidth; } if (_style.VScroll != null) { scrollbarWidth = Math.Max(scrollbarWidth, _style.VScroll.MinWidth); } // Get available space size by subtracting background's padded area. _areaWidth = width - bgLeftWidth - bgRightWidth; _areaHeight = height - bgTopHeight - bgBottomHeight; if (_widget == null) { return; } // Get widget's desired width. float widgetWidth, widgetHeight; if (_widget is ILayout) { var layout = _widget as ILayout; widgetWidth = layout.PreferredWidth; widgetHeight = layout.PreferredHeight; } else { widgetWidth = _widget.GetWidth(); widgetHeight = _widget.GetHeight(); } // Determine if horizontal/vertical scrollbars are needed. _scrollX = _forceScrollX || (widgetWidth > _areaWidth && !_disableX); _scrollY = _forceScrollY || (widgetHeight > _areaHeight && !_disableY); var fade = _fadeScrollBars; if (!fade) { // Check again, now taking into account the area that's taken up by any enabled scrollbars. if (_scrollY) { _areaWidth -= scrollbarWidth; if (!_scrollX && widgetWidth > _areaWidth && !_disableX) { _scrollX = true; } } if (_scrollX) { _areaHeight -= scrollbarHeight; if (!_scrollY && widgetHeight > _areaHeight && !_disableY) { _scrollY = true; _areaWidth -= scrollbarWidth; } } } // the bounds of the scrollable area for the widget. _widgetAreaBounds = RectangleExt.FromFloats(bgLeftWidth, bgBottomHeight, _areaWidth, _areaHeight); if (fade) { // Make sure widget is drawn under fading scrollbars. if (_scrollX && _scrollY) { _areaHeight -= scrollbarHeight; _areaWidth -= scrollbarWidth; } } else { if (_scrollbarsOnTop) { // Make sure widget is drawn under non-fading scrollbars. if (_scrollX) { _widgetAreaBounds.Height += (int)scrollbarHeight; } if (_scrollY) { _widgetAreaBounds.Width += (int)scrollbarWidth; } } else { // Offset widget area y for horizontal scrollbar at bottom. if (_scrollX && _hScrollOnBottom) { _widgetAreaBounds.Y += (int)scrollbarHeight; } // Offset widget area x for vertical scrollbar at left. if (_scrollY && !_vScrollOnRight) { _widgetAreaBounds.X += (int)scrollbarWidth; } } } // If the widget is smaller than the available space, make it take up the available space. widgetWidth = _disableX ? _areaWidth : Math.Max(_areaWidth, widgetWidth); widgetHeight = _disableY ? _areaHeight : Math.Max(_areaHeight, widgetHeight); _maxX = widgetWidth - _areaWidth; _maxY = widgetHeight - _areaHeight; if (fade) { // Make sure widget is drawn under fading scrollbars. if (_scrollX && _scrollY) { _maxY -= scrollbarHeight; _maxX -= scrollbarWidth; } } SetScrollX(Mathf.Clamp(_amountX, 0, _maxX)); SetScrollY(Mathf.Clamp(_amountY, 0, _maxY)); // Set the bounds and scroll knob sizes if scrollbars are needed. if (_scrollX) { if (hScrollKnob != null) { var hScrollHeight = _style.HScroll != null ? _style.HScroll.MinHeight : hScrollKnob.MinHeight; // The corner gap where the two scroll bars intersect might have to flip from right to left. var boundsX = _vScrollOnRight ? bgLeftWidth : bgLeftWidth + scrollbarWidth; // Scrollbar on the top or bottom. var boundsY = _hScrollOnBottom ? bgBottomHeight : height - bgTopHeight - hScrollHeight; _hScrollBounds = RectangleExt.FromFloats(boundsX, boundsY, _areaWidth, hScrollHeight); if (_variableSizeKnobs) { _hKnobBounds.Width = (int)Math.Max(hScrollKnob.MinWidth, (int)(_hScrollBounds.Width * _areaWidth / widgetWidth)); } else { _hKnobBounds.Width = (int)hScrollKnob.MinWidth; } _hKnobBounds.Height = (int)hScrollKnob.MinHeight; _hKnobBounds.X = _hScrollBounds.X + (int)((_hScrollBounds.Width - _hKnobBounds.Width) * GetScrollPercentX()); _hKnobBounds.Y = _hScrollBounds.Y; } else { _hScrollBounds = Rectangle.Empty; _hKnobBounds = Rectangle.Empty; } } if (_scrollY) { if (vScrollKnob != null) { var vScrollWidth = _style.VScroll != null ? _style.VScroll.MinWidth : vScrollKnob.MinWidth; // the small gap where the two scroll bars intersect might have to flip from bottom to top float boundsX, boundsY; if (_hScrollOnBottom) { boundsY = height - bgTopHeight - _areaHeight; } else { boundsY = bgBottomHeight; } // bar on the left or right if (_vScrollOnRight) { boundsX = width - bgRightWidth - vScrollWidth; } else { boundsX = bgLeftWidth; } _vScrollBounds = RectangleExt.FromFloats(boundsX, boundsY, vScrollWidth, _areaHeight); _vKnobBounds.Width = (int)vScrollKnob.MinWidth; if (_variableSizeKnobs) { _vKnobBounds.Height = (int)Math.Max(vScrollKnob.MinHeight, (int)(_vScrollBounds.Height * _areaHeight / widgetHeight)); } else { _vKnobBounds.Height = (int)vScrollKnob.MinHeight; } if (_vScrollOnRight) { _vKnobBounds.X = (int)(width - bgRightWidth - vScrollKnob.MinWidth); } else { _vKnobBounds.X = (int)bgLeftWidth; } _vKnobBounds.Y = _vScrollBounds.Y + (int)((_vScrollBounds.Height - _vKnobBounds.Height) * (1 - GetScrollPercentY())); } else { _vScrollBounds = Rectangle.Empty; _vKnobBounds = Rectangle.Empty; } } _widget.SetSize(widgetWidth, widgetHeight); if (_widget is ILayout) { ((ILayout)_widget).Validate(); } }
internal void drawInto(SpriteBatch spriteBatch, ref CharacterSource text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effect, float depth) { var flipAdjustment = Vector2.Zero; var flippedVert = (effect & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically; var flippedHorz = (effect & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally; if (flippedVert || flippedHorz) { Vector2 size; measureString(ref text, out size); if (flippedHorz) { origin.X *= -1; flipAdjustment.X = -size.X; } if (flippedVert) { origin.Y *= -1; flipAdjustment.Y = lineHeight - size.Y; } } var requiresTransformation = flippedHorz || flippedVert || rotation != 0f || scale != Vector2.One; if (requiresTransformation) { Matrix temp; Matrix.CreateTranslation(-origin.X, -origin.Y, 0f, out _transformationMatrix); Matrix.CreateScale((flippedHorz ? -scale.X : scale.X), (flippedVert ? -scale.Y : scale.Y), 1f, out temp); Matrix.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); Matrix.CreateTranslation(flipAdjustment.X, flipAdjustment.Y, 0, out temp); Matrix.Multiply(ref temp, ref _transformationMatrix, out _transformationMatrix); Matrix.CreateRotationZ(rotation, out temp); Matrix.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); Matrix.CreateTranslation(position.X, position.Y, 0f, out temp); Matrix.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); } BitmapFontRegion currentFontRegion = null; var offset = requiresTransformation ? Vector2.Zero : position - origin; for (var i = 0; i < text.Length; ++i) { var c = text[i]; if (c == '\r') { continue; } if (c == '\n') { offset.X = requiresTransformation ? 0f : position.X - origin.X; offset.Y += lineHeight; currentFontRegion = null; continue; } if (currentFontRegion != null) { offset.X += spacing + currentFontRegion.xAdvance; } if (!_characterMap.TryGetValue(c, out currentFontRegion)) { currentFontRegion = _defaultCharacterRegion; } var p = offset; if (flippedHorz) { p.X += currentFontRegion.width; } p.X += currentFontRegion.xOffset; if (flippedVert) { p.Y += currentFontRegion.height - lineHeight; } p.Y += currentFontRegion.yOffset; // transform our point if we need to if (requiresTransformation) { Vector2.Transform(ref p, ref _transformationMatrix, out p); } var destRect = RectangleExt.fromFloats ( p.X, p.Y, currentFontRegion.width * scale.X, currentFontRegion.height * scale.Y ); spriteBatch.Draw(currentFontRegion.subtexture, destRect, currentFontRegion.subtexture.sourceRect, color, rotation, Vector2.Zero, effect, depth); } }
public void DrawInto(Batcher batcher, ref FontCharacterSource text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effect, float depth) { var flipAdjustment = Vector2.Zero; var flippedVert = (effect & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically; var flippedHorz = (effect & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally; if (flippedVert || flippedHorz) { var size = MeasureString(ref text); if (flippedHorz) { origin.X *= -1; flipAdjustment.X = -size.X; } if (flippedVert) { origin.Y *= -1; flipAdjustment.Y = LineHeight - size.Y; } } var requiresTransformation = flippedHorz || flippedVert || rotation != 0f || scale != new Vector2(1); if (requiresTransformation) { Matrix2D temp; Matrix2D.CreateTranslation(-origin.X, -origin.Y, out _transformationMatrix); Matrix2D.CreateScale((flippedHorz ? -scale.X : scale.X), (flippedVert ? -scale.Y : scale.Y), out temp); Matrix2D.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); Matrix2D.CreateTranslation(flipAdjustment.X, flipAdjustment.Y, out temp); Matrix2D.Multiply(ref temp, ref _transformationMatrix, out _transformationMatrix); Matrix2D.CreateRotation(rotation, out temp); Matrix2D.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); Matrix2D.CreateTranslation(position.X, position.Y, out temp); Matrix2D.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); } var previousCharacter = ' '; Character currentChar = null; var offset = requiresTransformation ? Vector2.Zero : position - origin; for (var i = 0; i < text.Length; ++i) { var c = text[i]; if (c == '\r') { continue; } if (c == '\n') { offset.X = requiresTransformation ? 0f : position.X - origin.X; offset.Y += LineHeight; currentChar = null; continue; } if (currentChar != null) { offset.X += Spacing.X + currentChar.XAdvance; } currentChar = ContainsCharacter(c) ? this[c] : DefaultCharacter; var p = offset; if (flippedHorz) { p.X += currentChar.Bounds.Width; } p.X += currentChar.Offset.X + GetKerning(previousCharacter, currentChar.Char); if (flippedVert) { p.Y += currentChar.Bounds.Height - LineHeight; } p.Y += currentChar.Offset.Y; // transform our point if we need to if (requiresTransformation) { Vector2Ext.Transform(ref p, ref _transformationMatrix, out p); } var destRect = RectangleExt.FromFloats ( p.X, p.Y, currentChar.Bounds.Width * scale.X, currentChar.Bounds.Height * scale.Y ); batcher.Draw(Textures[currentChar.TexturePage], destRect, currentChar.Bounds, color, rotation, Vector2.Zero, effect, depth); previousCharacter = c; } }
/// <summary> /// This draws to the back buffer. If the Backbuffer doesn't exist, this will create one. /// This will not flip the back buffer to the front. /// </summary> /// <param name="args"></param> /// <param name="regions"></param> /// <param name="clipRectangles"></param> private void DrawWindows(MapArgs args, IList <Extent> regions, IList <Rectangle> clipRectangles) { Graphics g; if (args.Device != null) { g = args.Device; // A device on the MapArgs is optional, but overrides the normal buffering behaviors. } else { if (_backBuffer == null) { _backBuffer = new Bitmap(_bufferRectangle.Width, _bufferRectangle.Height); } g = Graphics.FromImage(_backBuffer); } int numBounds = Math.Min(regions.Count, clipRectangles.Count); for (int i = 0; i < numBounds; i++) { // For panning tiles, the region needs to be expanded. // This is not always 1 pixel. When very zoomed in, this could be many pixels, // but should correspond to 1 pixel in the source image. int dx = (int)Math.Ceiling(DataSet.Bounds.AffineCoefficients[1] * clipRectangles[i].Width / regions[i].Width); Rectangle r = RectangleExt.ExpandBy(clipRectangles[i], dx * 2); if (r.X < 0) { r.X = 0; } if (r.Y < 0) { r.Y = 0; } if (r.Width > 2 * clipRectangles[i].Width) { r.Width = 2 * clipRectangles[i].Width; } if (r.Height > 2 * clipRectangles[i].Height) { r.Height = 2 * clipRectangles[i].Height; } Extent env = regions[i].Reproportion(clipRectangles[i], r); Bitmap bmp; try { bmp = DataSet.GetBitmap(env, r); } catch { continue; } if (bmp == null) { continue; } g.DrawImage(bmp, r); bmp.Dispose(); } if (args.Device == null) { g.Dispose(); } }
public void RectangleMouseUp() { _selectedRectangle = null; }
public void RectangleMouseDown(MouseEventArgs e) { _selectedRectangle = PointList.FirstOrDefault(p => p.Rectangle == e.OriginalSource); }