Find-Sprite.ps1
function Find-Sprite { <# .Synopsis Finds a Sprite .Description Finds a Sprite. This can find a sprite at a given -X,-Y coordinate, or find a sprite within a bounding box (defined by -X,-Width,-Y, and -Height) or find a srptie within a given -Radius from -X,-Y .Link Add-Sprite .Link Move-Sprite .Link Remove-Sprite .Example # Finds sprites in the current game map at 10,20 Find-Sprite -X 10 -Y 20 .Example # Finds sprites within the current game map at 10,20, or within a 3 pixel radius Find-Sprite -X 10 -Y 20 -Radius 3 #> param( # The X coordinate to look for a sprite. [Parameter(ValueFromPipelineByPropertyName)] [int] $X, # The Y coordinate to look for a sprite. [Parameter(ValueFromPipelineByPropertyName)] [int] $Y, # The width of an area in which to look for a sprite. # If -Width and -Height are passed, -X and -Y will be treated as the upper left. [Parameter(ValueFromPipelineByPropertyName)] [int] $Width, # The height of an area in which to look for a sprite. # If -Width and -Height are passed, -X and -Y will be treated as the upper right. [Parameter(ValueFromPipelineByPropertyName)] [int] $Height, # The radius of the search area. # If provided, the -X and -Y will be the center of a virtual square of coordinates [Parameter(ValueFromPipelineByPropertyName)] [int] $Radius, # If provided, will only find sprites of one or more given types. [Parameter(ValueFromPipelineByPropertyName)] [string[]] $Type ) begin { $collided = @() } process { if (-not $game) { return } $bounds = @( if ($x -ge 0 -and $y -ge 0) { if ($Width -and $Height) { # Block for ($ox =0; $ox -lt $Width; $ox++) { for ($oy =0; $oy -lt $Height; $oy++) { [PSCustomObject]@{ X = $x + $ox Y = $y + $oy SpatialHash = $game.GetSpatialHash($x + $ox,$y + $oy) PSTypeName='PowerArcade.Point' } } } } elseif ($Width) { # Row for ($ox=0;$ox -lt $Width;$ox++) { [PSCustomObject]@{ X = $x + $ox Y = $y SpatialHash = $game.GetSpatialHash($x + $ox,$y) PSTypeName='PowerArcade.Point' } } } elseif ($Height) { # Column for ($oy=0;$ox -lt $Height;$ox++) { [PSCustomObject]@{ X = $x Y = $y + $oy SpatialHash = $game.GetSpatialHash($x,$y + $oy) PSTypeName='PowerArcade.Point' } } } elseif ($Radius) { # Radius for ($ox = $x - $Radius; $ox -lt ($x + $Radius); $ox++) { for ($oy =$y - $Radius; $oy -lt ($y + $radius); $oy++) { [PSCustomObject]@{ X = $ox Y = $oy SpatialHash = $game.GetSpatialHash($ox,$oy) PSTypeName='PowerArcade.Point' } } } } else { # Point [PSCustomObject]@{ X = $x Y = $y SpatialHash = $game.GetSpatialHash($x,$y) PSTypeName='PowerArcade.Point' } } } ) :NextBoundsGroup foreach ($boundsGroup in $bounds | Group-Object SpatialHash | Sort-Object Count -Descending) { $spriteList = $game.CurrentLevel.SpatialMap[$boundsGroup.Name] :NextBound foreach ($b in $boundsGroup.Group) { $boundString = "$($b.X),$($b.Y)" :NextSprite foreach ($spriteRef in $spriteList) { $sprite = $game.CurrentLevel.SpritesById[$spriteRef.SpriteID] if ($type) { $typeMatch = $false foreach ($t in $type) { $typeMatch = $typeMatch -bor ($sprite.Type -like $t) } if (-not $typeMatch) { continue NextSprite } } if ($sprite.Bounds -contains $boundString) { # It's a hit! $sprite $collided+=$sprite } } } } if (-not $bounds) { if ($type -and $game.CurrentLevel.Sprites.Count) { :NextSprite foreach ($sprite in $game.CurrentLevel.Sprites) { $typeMatch = $false foreach ($t in $type) { $typeMatch = $typeMatch -bor ($sprite.Type -like $t) } if (-not $typeMatch) { continue NextSprite } $sprite } } } } } |