Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get a list of nodes in an specific area?

I'm working in a side-scolling game and I need to know what nodes are in an area to implement something like "line of sight". Right now I'm trying using enumerateBodyiesInRect() however it's detecting bodies that are 20px or more from the evaluated rect and I cannot figure out why it's so imprecise.

This is what I'm trying now:

import SpriteKit
import CoreMotion

class GameScene: SKScene, SKPhysicsContactDelegate
{
var player = SKShapeNode()
var world = SKShapeNode()
var rShape = SKShapeNode()

override func didMoveToView(view: SKView) {
    self.physicsWorld.contactDelegate = self
    self.scaleMode = SKSceneScaleMode.AspectFit
    self.size = view.bounds.size

    // Add world
    world = SKShapeNode(rectOfSize: view.bounds.size)
    world.physicsBody = SKPhysicsBody(edgeLoopFromPath: world.path)
    world.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2) // Move camera
    self.addChild(world)

    // Add player
    player = SKShapeNode(rectOfSize: CGSize(width: 25, height: 25))
    player.physicsBody = SKPhysicsBody(rectangleOfSize: player.frame.size)
    player.physicsBody.dynamic = false
    player.strokeColor = SKColor.blueColor()
    player.fillColor = SKColor.blueColor()
    player.position = CGPointMake(90, -50)
    world.addChild(player)
    }


override func update(currentTime: CFTimeInterval) {
    // Define rect position and size (area that will be evaluated for bodies)
    var r : CGRect = CGRect(x: 200, y: 200, width: 25, height: 25)

    // Show rect for debug
    rShape.removeFromParent()
    rShape = SKShapeNode(rect: r)
    rShape.strokeColor = SKColor.redColor()
    self.addChild(rShape)

    // Evaluate rect
    rShape.fillColor = SKColor.clearColor()
    self.physicsWorld.enumerateBodiesInRect(r) {
        (body: SKPhysicsBody!, stop: UnsafePointer<ObjCBool>) in
         self.rShape.fillColor = SKColor.redColor() // Paint the area blue if it detects a node
         }
    }
}

This code should show the evaluated rect and ray on the screen (for debugging purposes) and paint them red if they contact the player node. However you can see in the screenshot how it turns red when the player is 25px or more away from it, it's like if the drawing is a little bit off, or smaller than the actual area being evaluated. You can copy paste it to a project to duplicate the problem.

Could this be because this is just beta or am I doing something wrong?

The rect should only be red only if the player is inside it (blue square), however it's red when the player is near

like image 285
lisovaccaro Avatar asked Jul 20 '14 14:07

lisovaccaro


1 Answers

You are creating a physical world where there is a specific rectangle that has 'special properties' - this is the rectangle that you use in enumerateBodiesInRect(). Why not create an invisible, inert physical body with the required rectangular dimension and then use SKPhysicsBody to check for collisions and/or contacts? You could then use allContactedBodies() or some delegate callbacks to learn what other bodies are inside your special rectangle.

Think of it like a 'tractor beam' or a 'warp rectangle'.

like image 190
GoZoner Avatar answered Sep 27 '22 16:09

GoZoner