I am trying to use cocos2dx 3.3 to build games.
we create a physicisworld with
cc.Scene:createWithPhysics()
and i add a camera like this
local camera = cc.Camera:createOrthographic(width,height,0,1)
camera:setCameraFlag(cc.CameraFlag.USER1)
camera:setPosition3D(cc.vec3(0, 0, 0))
and I add this camera to the layer
I just want to bind the sprite with camera
so I code in layer function update
function PlayLayer:update(delta)
--camera
local camera = self.camera
local speed = 100*delta
local winsize = cc.Director:getInstance():getWinSize()
local player = self.player
player:update()
player:setX(player:getX() + speed)
local postiony = 180
self.camera:setPositionX(player:getX() )
end
I set the camera move with sprite,however the sprite is moving and the position of camera is also changed. but, there is no effect. the sprite just move out of the screen.
Am I wrong. please help me with this question. thank you!
Related
I'm trying to draw a billboarded quad using SceneKit and ARKit. I have basic billboarding working, however when I roll the camera the billboard also rotates in place. This video shows this in action as I roll the camera to the left (the smily face is the billboard):
Instead I'd like the billboard to still face the camera but keep oriented vertically in the scene, no matter what the camera is doing
Here's how I compute billboarding:
// inside frame update function
struct Vertex {
var position: SIMD3<Float>
var texCoord: SIMD2<Float>
}
let halfSize = Float(0.25)
let cameraNode = sceneView.scene.rootNode.childNodes.first!
let modelTransform = self.scnNode.simdWorldTransform
let viewTransform = cameraNode.simdWorldTransform.inverse
let modelViewTransform = viewTransform * modelTransform
let right = SIMD3<Float>(modelViewTransform[0][0], modelViewTransform[1][0], modelViewTransform[2][0]);
let up = SIMD3<Float>(modelViewTransform[0][1], modelViewTransform[1][1], modelViewTransform[2][1]);
// drawBuffer is a MTL buffer of vertex data
let data = drawBuffer.contents().bindMemory(to: ParticleVertex.self, capacity: 4)
data[0].position = (right + up) * halfSize
data[0].texCoord = SIMD2<Float>(0, 0)
data[1].position = -(right - up) * halfSize
data[1].texCoord = SIMD2<Float>(1, 0)
data[2].position = (right - up) * halfSize
data[2].texCoord = SIMD2<Float>(0, 1)
data[3].position = -(right + up) * halfSize
data[3].texCoord = SIMD2<Float>(1, 1)
Again this gets the billboard facing the camera correctly, however when I roll the camera, the billboard rotates along with it.
What I'd like instead is for the billboard to point towards the camera but keep its orientation in the world. Any suggestions on how to fix this?
Note that my code example is simplified so I can't use SCNBillboardConstraint or anything like that; I need to be able to compute the billboarding myself
Here's the solution I came up with: create a new node that matches the camera's position and rotation, but without any roll:
let tempNode = SCNNode()
tempNode.simdWorldPosition = cameraNode.simdWorldPosition
// This changes the node's pitch and yaw, but not roll
tempNode.simdLook(at: cameraNode.simdConvertPosition(SIMD3<Float>(0, 0, 1), to: nil))
let view = tempNode.simdWorldTransform.inverse
let modelViewTransform = view * node.simdWorldTransform
This keeps the billboard pointing upwards in world space, even as the camera rolls.
I had actually tried doing this earlier by setting tempNode.eulerAngles.z = 0, however that seems to effect the rest of the transform matrix in unexpected ways
There's probably a way to do this without creating a temporary node too but this works well enough for me
I am trying to fix the camera to a sprite node “players.first!” and I managed to do so using SKConstraints as follows
func setupWorld(){
let playerCamera = SKCameraNode()
let background = SKSpriteNode(imageNamed: platformType + "BG")
var cameraFollow = [SKConstraint]()
cameraFollow.append(SKConstraint.distance(SKRange(constantValue: 0), to: players.first!))
playerCamera.constraints = cameraFollow
background.zPosition = layers().backgroundLayer
background.constraints = cameraFollow
background.size = self.size
self.addChild(playerCamera)
self.camera = playerCamera
self.addChild(background)
physicsWorld.contactDelegate = self
addEmitter()
}
But this keeps the camera fixed to the exact location of the node, I want the camera to be shifted to the right of the node “players.first!” (only in X dimension) and I couldn’t manage to do so with SKConstraints, note that the node is moving fast so updating the position of the camera in the update function makes the camera jitter.
This image is explaining my issue
Constrain the camera to an empty SKNode and make it a child node of the first player which is offset to the right in the frame of the player. This can be accomplished in the scene editor or programmatically by setting this dummy node's position to something like CGPoint(x: 100, y: 0). When the player moves, this node will also move, dragging the camera along with it; and since the camera is focused on this node, the nodes in the same 'world' of the player will appropriately appear to move in the opposite direction while maintaining the look you want for the player.
EDIT: If the player rotates
If the player needs to rotate, the above configuration will result in the entire node world revolving around the fixed empty node. To prevent this, instead place an empty SKNode that acts as the fixed camera point which will be called "cameraLocation" and the player node into another empty SKNode which will be called "pseudoPlayer". Constrain the camera to "cameraLocation". Moving the "pseudoPlayer" node will then move both the camera's fixed point (so that the camera moves) and the player node while only resulting in the rotation of the player and not the entire world.
NOTE: The only potential drawback is that in order to move the player correctly through the world, you must move the "pseudoPlayer" instead.
I am trying to make ludo game in scenekit but i dont know how to make an object move from one plane (boxes in ludo game for path ) to another plane. PLEASE HELP ME
It is simple just add the position to your SCNNode() object.
let boxNode1 = SCNNode(geometry: cubeGeometry1)
boxNode1.position = SCNVector3(X,Y,Z)
I am trying to move implement bouncing balls using ARKit. I want the balls coming from one end of screen bouncing and moving out of screen.
Can anyone please recommend best approach or point to sample code to implement this?
Can I use UIBezierPath to create a path and move SCNNode along the path. If yes, how can I move the node along path.
Create a scene and a ball Node. Use force direction for ball Node and animate the ball Node with Physics. This is just an example.
// Create a new scene
guard let scene = SCNScene(named: "BouncingBalls.scn", inDirectory: "art.scnassets") else { return }
sceneView.scene = scene
// Add physics bodies
guard let ballsNode = scene.rootNode.childNode(withName: "balls", recursively: true) else { return }
let forceDirection = SCNVector3Make(0, 3, 0)
for ballNode in ballsNode.childNodes {
let physicsBody = SCNPhysicsBody(type: .dynamic, shape: nil)
physicsBody.applyForce(forceDirection, asImpulse: true)
ballNode.physicsBody = physicsBody
}
Try this in View didLoad. Hope this works.
The best way to get what you want is to use a predefined animation or dynamics that was made in such 3D apps as Autodesk Maya, Autodesk 3dsMax, or Maxon Cinema4D.
After producing a ball animation (or dynamics, it's up to you) you need to bake this animation (baking is a process of keyframe generation for every frame instead of using interpolated curve) and export this scene as a .dae file format. ARKit/SceneKit supports not only .dae animations but also brand-new format .usdz.
SceneKit API (as well as other Apple frameworks' APIs) is not designed for 3D animation.
I'm setting up my camera node programatically. My goal is to have the camera follow the player node's x axis, but have the y axis of the camera higher than "player.position.y", something like "player.position.y + 300".
I found this after googling a while about this issue:
cam.position = CGPoint(x: player.position.x, y: player.position.y + 500)
I put this in didMove(to:) along with the setup of the camera:
cam = SKCameraNode() //initialize and assign an instance of SKCameraNode to the cam variable.
self.camera = cam //set the scene's camera to reference cam
//cam.setScale(1.3)
cam.position = CGPoint(x: player.position.x, y: player.position.y + 500)
addChild(cam) //have cam be a child
I've tried putting it before and after the add child(cam) line, but the cam.position line had no effect.
I've tried both setting my camera up as a child of the player node and the scene, but with either method I can get the camera to follow the player but I can't figure out how to manipulate the X and Y separately. The only way Ive been able to affect the cameras position is using "set scale" but thats more of a global zoom in/out.
Any advice would be greatly appreciated.
EDIT: The first part of the answer is all I needed:
cam = SKCameraNode()
player.addChild(cam)
cam.position = CGPoint(x:0,y:500)
self.camera = cam
Why not just make camera a child of player, then set the relative position to +500, so that you never have to worry about setting the camera x position again
cam = SKCameraNode()
player.addChild(cam)
cam.position = CGPoint(x:0,y:500)
self.camera = cam
Then on your end update, set your camera y based on what you need:
let cam = player.childNode[0] as! SKCameraNode //Do whatever you need to do to find the camera
cam.position.y = 500 - player.position.y //This way if the player goes up 1 point, the camera moves down one point thus keeping it on the same spot