i am struggling with angles in cocos creator.
I am trying to make my sprite facing my mouse when i am moving it. But i cant make it at all.
Image shows what i want to accomplish
I wanna from this gun to move and face the mouse, just like crosshair.
Ive done some coding, and this is what i have for now:
var canvas = cc.find('Canvas');
canvas.on('touchmove',function(event){
var pos = this.node.getPosition();
var ang = pos.angle(event.getLocation());
var degr = cc.misc.radiansToDegrees(ang);
this.node.setRotation(degr);
console.log(degr);
},this);
This is in onLoad function and connected to my gun sprite.
Related
I'm trying to get a clone of a raycasted object, and move the clone of the selected object in a <div>. The raycaster works just fine, but the CSS3DObject instance (the cloned 3d Object) is not shown in the scene. I have made another renderer (namely a CSS3DRenderer), in addition to the current WebGLRenderer, and basically my css3d code consists of this:
cssRenderer = new CSS3DRenderer();
cssRenderer.setSize(window.innerWidth, window.innerHeight);
cssRenderer.domElement.style.position = 'absolute';
cssRenderer.domElement.style.top = 0;
cssScene = new THREE.Scene();
document.body.appendChild(cssRenderer.domElement);
...
thumbnail = document.querySelector('.thumbnail');
thumbObject = new CSS3DObject(thumbnail);
....
targetClone = target.clone();
thumbObject.position.copy(targetClone.position);
cssScene.add(thumbObject);
and my render loop code, pertaining to this, is:
requestAnimationFrame(update);
renderer.render(scene, camera); // WebGLRenderer
cssRenderer.render(cssScene, camera); //CSS3DRenderer
My intention is to embed the cloned object (targetClone) in the CSS3DObject (thumbObject, which in actuality is an HTML element). The console shows no error, and I cannot see any reaction to this code whatsoever (except that the div travels to the center of model!) No matter if I select the div through traversing the DOM or making a fresh element by means of createElement, nothing is being embedded in the div. I suspect that everything is behind the scene(s). Any ideas how can I achieve this, and where I'm doing it wrong?
I want to show an image with a frame. Using <a-image> gives me a plane with the image.
<a-box src="path/to/img.jpg> however gives me the image but it's giving me the image 6 times. Is it possible to get the box with am image at the front and any color at all other sides?
I don't know if you can do this with Aframe (I don't think so), but you can do it with Threejs, by making an array of materials that contain a material for each box face, and applying that to the box mesh.
const loadManager = new THREE.LoadingManager();
const loader = new THREE.TextureLoader(loadManager);
const materials = [
new THREE.MeshBasicMaterial({map: loader.load('resources/images/flower-1.jpg')}),
new THREE.MeshBasicMaterial({map: loader.load('resources/images/flower-2.jpg')}),
new THREE.MeshBasicMaterial({map: loader.load('resources/images/flower-3.jpg')}),
new THREE.MeshBasicMaterial({map: loader.load('resources/images/flower-4.jpg')}),
new THREE.MeshBasicMaterial({map: loader.load('resources/images/flower-5.jpg')}),
new THREE.MeshBasicMaterial({map: loader.load('resources/images/flower-6.jpg')}),
];
loadManager.onLoad = () => {
const cube = new THREE.Mesh(geometry, materials);
scene.add(cube);
cubes.push(cube); // add to our list of cubes to rotate
};
you can place this code inside of a custom component that is attached the cube geometry.
Here is the tutorial that the above code was taken from, on threejsfundamentals.
I'm using ArcRotateCamera, when I click on mesh, I have to focus camera on
var camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 2, Math.PI / 2, 300, BABYLON.Vector3.Zero(), scene);
camera.setTarget(BABYLON.Vector3.Zero());
// on mesh click, focus in
var i = 2;
var pickInfo = scene.pick(scene.pointerX, scene.pointerY);
if (pickInfo.hit) {
pickInfo.pickedMesh.actionManager = new BABYLON.ActionManager(scene);
pickInfo.pickedMesh.actionManager.registerAction(
new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger,
function (event) {
camera.position = (new BABYLON.Vector3(pickInfo.pickedPoint.x, pickInfo.pickedPoint.y, camera.position.z + i));
i += 2;
})
);
}
this code changes mesh's z position but don't makes it in the center of screen
There are a few things that can be changed in your code.
1st - what you are doing is executing a code action after a click, instead of simply running the code in the callback after a pick has occurred. You are registering a pick action (technically user click) on right on the first frame, but only if the mouse was found in the right location at the right moment. My guess is that it didn't work every time (unless you scene is covered with meshes :-) )
2nd - you are changing the camera's position, instead of change the position to which it is looking. Changing the camera's position won't result in what you want (to see the selected mesh), it will move the camera to a new position while still focusing on the old position.
There are a few ways to solve this. The first is this:
scene.onPointerDown = function(evt, pickInfo) {
if(pickInfo.hit) {
camera.focusOn([pickInfo.pickedMesh], true);
}
}
The ArcRotate camera provides focusOn function that focuses on a group of meshes, while fixing the orientation of the camera. this is very helpful. You can see a demo here:
https://playground.babylonjs.com/#A1210C#51
Another solution would be to use the setTarget function:
https://playground.babylonjs.com/#A1210C#52
Which works a bit differently (notice the orientation change of the camera).
Another thing - use the pointer events integrated in Babylon, as they are saving you the extra call for a scene pick. pointer down is executed with the pickinfo integrated in the function, so you can get the picking info of the current pointer down / up / move each frame.
**** EDIT ****
After a new comment - since you want to animate the values, all you need to do is store the current values, calculate the new ones, and animate the values using the internal animation system (documentation here - https://doc.babylonjs.com/babylon101/animations#basic-animation) . There are many ways to achieve this, I took an old function and modernized it :-)
Here is the demo - https://playground.babylonjs.com/#A1210C#53
I have created a dice entity from six plane entities. However, when I click and drag the dice entity, instead of moving that dice, only one sided face gets dragged.
This can be tried hands on at link http://shrouded-chamber-73425.herokuapp.com/
Rather than creating a box from six planes, you should create one box and use a material that will render the dice faces for you. You can use three.js CubeTexture:
AFRAME.registerComponent('dice-texture', {
init: function () {
var box = this.el.getOrCreateObject3D('mesh');
var loader = new THREE.CubeTextureLoader();
loader.setPath('/images/diceTextures/');
var textureCube = loader.load([
'1.png', '2.png',
'3.png', '4.png',
'5.png', '6.png'
]);
box.material = new THREE.MeshStandardMaterial({envMap: textureCube);
}
});
<a-entity geometry="primitive: box" dice-texture></a-entity>
Then you can further optimize so that every box shares the same material so you aren't creating a new one each time.
I've got an issue that I simply can't figure out; probably because I don't have the correct knowledge.
I have a TMX map made in Tiled. The Map is bigger than the screen size (tiles are 32x32pixels and there are 100x100 tiles).
What I want to do is to be able to move the map by swiping the screen.
I've looked at various tutorials online and examined the paddle.m example but still can't get it to work.
All the tutorials I've come across all focus on moving a clamped centered sprite around a map...
Again, what I want to do is to be able to move the map by swiping/sliding the screen; much like when scrolling through your iPod or moving a picture around.
Can anyone help?
Here is my ccTouchMoved code
-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchPointMap = [touch locationInView: [touch view]];
touchPointMap = [[CCDirector sharedDirector] convertToGL: touchPointMap];
touchPointMap = [self convertToNodeSpace: touchPointMap];
CCLOG(#"Touch Point Map %lf, %lf", touchPointMap.x, touchPointMap.y);
self.position = CGPointMake(touchPointMap.x, touchPointMap.y);
}
To illustrate the problem I'm seeing on screen when I swipe the screen using the code above:
It seems that if I touch the center of the screen, the bottom left corner of the map will jump to that touched coordinate and will move with my touch until my touch is lifted.
The Map's bottom left corner will always move to where I begin my touch.
Also while the map is being moved, it flashes like crazy and if moved excessively, disappears entirely.
Thanks again All, much appreciated.
Best and Kind Regards,
hiro
I found the solution to the problem.
There's a very bright person in the Cocos2D community who has written a controller to not only pan around organically, but zoom in and out.
Link to Controller, example and preview movie
You wont need to write your touchBegan, Moved and End methods; this Controller does it all for you.
My init
self.theMap = [CCTMXTiledMap tiledMapWithTMXFile: #"city_map.tmx"];
self.bgLayer = [theMap layerNamed:#"bg"];
// boundingRect is the area you wish to pan around
CGRect boundingRect = CGRectMake(0, 0, 32*50, 16*50);
theMap.anchorPoint = ccp(0,0);
[self addChild: theMap z: -1];
// _controller is declared in the #interface as an object of CCPanZoomController
_controller = [[CCPanZoomController controllerWithNode:self] retain];
_controller.boundingRect = boundingRect;
_controller.zoomOutLimit = _controller.optimalZoomOutLimit;
_controller.zoomInLimit = 2.0f;
[_controller enableWithTouchPriority:0 swallowsTouches:YES];