ForgeableSum Posted August 17, 2016 Share Posted August 17, 2016 I have strong suspicions that the world x/y property on Phaser.Sprite (which I think replaced the old toGlobal method) is buggy and would like to figure out a way to manually calculate the absolute position of a sprite. Suppose I have a sprite child of a sprite child of a sprite child of the world. spriteA ([0,0], rotation: 0) > spriteB ([0,0], rotation: 0) > spriteC ([0,0], rotation: 0) > world. We all know if the sprites have no rotations, you can easily calculate the absolute positions by adding the parent positions, e.g. the absolute world position of spriteA would be: var xValue = spriteA.x + spriteB.x + spriteC.x; var yValue = spriteA.y + spriteB.y + spriteC.y; But what about when the child sprites have rotations and offsets. e.g.: spriteA ([15,34], rotation: 2.3) > spriteB ([30,0], rotation: 0) > spriteC ([1400,1000], rotation: .6) > world. How then will you calculate absolute world positions? Because simply adding the x/y won't work as it doesn't take rotation into account. I suspect using Phaser.Point.rotate will be involved but I'm not sure exactly how to solve this and I ran out of patience testing different parameters. Someone please help me figure this out! Link to comment Share on other sites More sharing options...
TickleMeElmo Posted August 17, 2016 Share Posted August 17, 2016 Not sure if this is what you're looking for, but let's say we have these: parent {x: 100, y:100, rotation: Math.PI*0.5} child {x: 50, y: 50, rotation: 0} so you want to get the global cords of the child right?, var childDisFromParent = Math.sqrt(child.x*child.x + child.y*child.y) var childRotFromParent = Math.atan2(child.y, child.x) var childActualPos = { x: Math.cos(childRotFromParent + Parent.rotation) * childDisFromParent + parent.x, y: Math.sin(childRotFromParent + Parent.rotation) * childDisFromParent + parent.y } I'm quite sure there's probably a lot better way of doing this, but this thing is first that I had in mind ForgeableSum 1 Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 17, 2016 Author Share Posted August 17, 2016 This looks promising ... I will try it and report back, thanks! Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 17, 2016 Author Share Posted August 17, 2016 Here's my implementation. Unfortunately, it doesn't work ... bullets are beginning somewhere near the sprites though. Bug guess what? Where the bullets start are affected by the camera position once again! function getAbsolutePosition(sprite) { var child = sprite; var spriteParent = child.parent; var absPosition; while (spriteParent.name != '_stage_root') { var childDisFromParent = Math.sqrt(child.x * child.x + child.y * child.y) var childRotFromParent = Math.atan2(child.y, child.x) var absX = Math.cos(childRotFromParent + spriteParent.rotation) * childDisFromParent + spriteParent.x; var absY = Math.sin(childRotFromParent + spriteParent.rotation) * childDisFromParent + spriteParent.y; if (absPosition == undefined) { absPosition = { x: absX, y: absY } } else { absPosition.x += absX, absPosition.y += absY } child = spriteParent; spriteParent = spriteParent.parent; } return absPosition; } P.S. Just changed parent to spriteParent because parent is a global variable used by the window. Link to comment Share on other sites More sharing options...
TickleMeElmo Posted August 17, 2016 Share Posted August 17, 2016 hmm, It feels like maybe you don't use anchor in the middle for sprite or bullet? Also I can't see why camera position should affect bullets position any way. how exactly does camera position affect it? Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 17, 2016 Author Share Posted August 17, 2016 It's truly bizarre. I have a mini map which shows where all the bullets are starting from and going on the map. When I move the camera away from the sprites, the start x/y position of the bullets changes drastically as if they are relative to the camera. It's the same exact thing that was happening when I was using .world. And yes, I have checked - all my sprites are using .5 as an anchor. Link to comment Share on other sites More sharing options...
TickleMeElmo Posted August 17, 2016 Share Posted August 17, 2016 Oh! got it, camera position changes Phaser.World position, if you move camera to x: 20, y:10, then Phaser.World position will be x:-20, y-10, and in that while loop you're also considering in the Phaser.World which probably is the cause of this issue. So use while(spriteParent.name != "__world" ) { //code here } instead Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 17, 2016 Author Share Posted August 17, 2016 hmm, the positions are no longer affected by the camera. However, They are way further down the map then they should. If I had to guess, their x/y properties are twice as far, as if they are unnecessarily adding the unit position relative to the world. Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 17, 2016 Author Share Posted August 17, 2016 If I do this at the very end: absPosition.x = absPosition.x * .5; absPosition.y = absPosition.y * .5; I get results that are close. The bullets are still offset from the muzzle flashes. I suspect chopping the number in half isn't a solution :). Link to comment Share on other sites More sharing options...
TickleMeElmo Posted August 17, 2016 Share Posted August 17, 2016 (edited) function getAbsolutePosition(sprite) { var child = sprite; var spriteParent = child.parent; var absPosition; while (spriteParent.name != '__world') { var childDisFromParent = Math.sqrt(child.x * child.x + child.y * child.y) var childRotFromParent = Math.atan2(child.y, child.x) var absX = Math.cos(childRotFromParent + spriteParent.rotation) * childDisFromParent; var absY = Math.sin(childRotFromParent + spriteParent.rotation) * childDisFromParent; if (absPosition == undefined) { absPosition = { x: absX, y: absY } } else { absPosition.x += absX, absPosition.y += absY } child = spriteParent; spriteParent = spriteParent.parent; } return absPosition; } Try this, I have a suspicion that this should work Edited August 17, 2016 by TickleMeElmo Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 17, 2016 Author Share Posted August 17, 2016 7 minutes ago, TickleMeElmo said: function getAbsolutePosition(sprite) { var child = sprite; var spriteParent = child.parent; var absPosition; while (spriteParent.name != '_stage_root') { var childDisFromParent = Math.sqrt(child.x * child.x + child.y * child.y) var childRotFromParent = Math.atan2(child.y, child.x) var absX = Math.cos(childRotFromParent + spriteParent.rotation) * childDisFromParent + spriteParent.x; var absY = Math.sin(childRotFromParent + spriteParent.rotation) * childDisFromParent + spriteParent.x; if (absPosition == undefined) { absPosition = { x: absX, y: absY } } else { absPosition.x += spriteParent.x, absPosition.y += spriteParent.y } child = spriteParent; spriteParent = spriteParent.parent; } return absPosition; } Try this, I have a suspicion that this should work(in case you only have on parent of that sprite rotated) Hmm, now the bullets are starting from the very top left of the map, so it seems to be the opposite problem (before bullets were starting at bottom right). The bullets should be starting near the center of the map as that's where the test sprites are. Btw, I very much appreciate the help and will send you a free copy of my game once it's finished. I never imagined I would be spending 2 days trying to get the absolute position of a child sprite. That's one of those things you assume the framework will handle. P.S. Why does Phaser take the camera location into account on the world property? How does the camera have anything to do with the absolute position of a sprite in the world. Is that intentional? Link to comment Share on other sites More sharing options...
TickleMeElmo Posted August 17, 2016 Share Posted August 17, 2016 oh yeah, sorry, I just edited the code try again now, (getting a bit late so I'm starting to produce not the brightest codes, night coding isn't for everyone you know) Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 17, 2016 Author Share Posted August 17, 2016 8 minutes ago, TickleMeElmo said: oh yeah, sorry, I just edited the code try again now, (getting a bit late so I'm starting to produce not the brightest codes, night coding isn't for everyone you know) Just tried it now. The results mirror the results using .world x/y on the muzzle flash (lowest child in hierarchy). The only difference is the results are no longer skewed by camera movement, which is a good thing. However, they bullet start x/y doesn't rotate perfectly along with the muzzle flash. Of course, everything is where it's supposed to be if nothing is rotated. But pretty much every child/parent is rotated in my case. Link to comment Share on other sites More sharing options...
TickleMeElmo Posted August 17, 2016 Share Posted August 17, 2016 Send me the child parent tree(include just the cords and rotation, and the bullet start pos) at some random test, or show me the part of code about the childs parents etc. Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 17, 2016 Author Share Posted August 17, 2016 Top of tree to bottom (all objects are anchored by .5): world group ("game objects" [0,0], rotation = 0) sprite ("unit", [345,600],rotation = .785) sprite ("gun", [-7,0],rotation = 2.486) sprite ("muzzleFlash", [32,-23],rotation = 1.5) The bullet is in a separate group which is the child of the world. So when I fire the bullet, I'm trying to get it to start exactly where the muzzle flash sprite is. I should note that the muzzle flash moves to arbitrary coordinates based on which gun is firing (these are double and triple guns), like so: msprite.x = unit.guns[gunIndex].multi[currentMulti][0]; msprite.y = unit.guns[gunIndex].multi[currentMulti][1]; unit.guns[gunIndex].currentMulti++ So the first time the gun fires, it will be at: [32, -23], And the second time: [32, 22] Then currentMulti is reset to zero and it goes back to [32, -23]. It's just dawned on my that may be where the miscalculation is, because those arbitrary movements assume 0 rotations. But how can I calculate the x/y, taking all the world transforms into account? Link to comment Share on other sites More sharing options...
TickleMeElmo Posted August 17, 2016 Share Posted August 17, 2016 and what is the code output for this(the bullet cords)? Don't have the time right now to test it myself Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 17, 2016 Author Share Posted August 17, 2016 Here are some example results: unit position: {x: 4361.8046108200615, y: 4299.997671575902, type: 25} unit rotation: -0.014180800172453928 gun position {x: 50, y: 15, type: 25} gun rotation: 2.440526462913298 muzzle flash position: {x: 20, y: 0, type: 25} muzzle flash rotation: 0 gun bullet start (results): {x: 4396.729190524387, y: 4327.1878029138115, type: 25} Link to comment Share on other sites More sharing options...
TickleMeElmo Posted August 17, 2016 Share Posted August 17, 2016 and the desired result is? Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 17, 2016 Author Share Posted August 17, 2016 the only way I know it's not the desired result is because the bullet is not starting where the muzzle flash is. but I don't know the actual x/y of what is desired. Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 17, 2016 Author Share Posted August 17, 2016 btw, here are some more test results (everything is in the same order): game2.js:1864 P…r.Point {x: 4356.86049998745, y: 4300, type: 25} -0.012042771838760834 P…r.Point {x: 50, y: 15, type: 25} 2.3884880298189324 P…r.Point {x: 20, y: 0, type: 25} 0 P…r.Point {x: 4392.446129251321, y: 4328.0749300625785, type: 25} game2.js:1864 P…r.Point {x: 4356.86049998745, y: 4300, type: 25} -0.012042771838760834 P…r.Point {x: 50, y: -15, type: 25} 2.1412993755593033 P…r.Point {x: 20, y: 0, type: 25} 0 P…r.Point {x: 4395.875127157528, y: 4301.23155181026, type: 25} game2.js:1864 P…r.Point {x: 3592.809754647056, y: 3687.190245352944, type: 25} -0.7853981633974483 P…r.Point {x: -7, y: 0, type: 25} 2.917026544114841 P…r.Point {x: 32, y: 22, type: 25} 0 P…r.Point {x: 3551.764466450548, y: 3677.8182631932104, type: 25} game2.js:1864 P…r.Point {x: 5165.6067975568885, y: 4285.995071426674, type: 25} 0.12767083478338517 P…r.Point {x: 50, y: 15, type: 25} 2.9450681640327123 P…r.Point {x: 20, y: 0, type: 25} 0 P…r.Point {x: 5193.674967799077, y: 4311.144440777133, type: 25} game2.js:1864 P…r.Point {x: 5165.6067975568885, y: 4285.995071426674, type: 25} 0.12767083478338517 P…r.Point {x: 50, y: -15, type: 25} 2.910269127507492 P…r.Point {x: 20, y: 0, type: 25} 0 P…r.Point {x: 5197.642442777036, y: 4282.0686882863665, type: 25} Link to comment Share on other sites More sharing options...
TickleMeElmo Posted August 17, 2016 Share Posted August 17, 2016 could you send a picture of that bullet firing, so that the muzzle is also there Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 17, 2016 Author Share Posted August 17, 2016 Top is example of start x/y of bullet being wrong and bottom is correct: http://imgur.com/a/fV0gp Note that the bottom has nothing rotated. See how with the top, the bullet is starting behind the gun, because it isn't starting at the correct x/y. Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 17, 2016 Author Share Posted August 17, 2016 I had this wacky solution a while back which worked perfectly about 95% of the time. Unfortunately, it was affected by camera movement. about 5% of the time, if you moved the camera, it would offset everything incorrectly. msprite is muzzleflash sprite, startPosition is bullet start x/y: var position = msprite.toGlobal(msprite); position.x = game.camera.x + position.x; position.y = game.camera.y + position.y; unit.guns.startPosition = position; But with that, the bullet always started right on top of the muzzle flash sprites, as intended. Link to comment Share on other sites More sharing options...
TickleMeElmo Posted August 17, 2016 Share Posted August 17, 2016 okey, I'm quite confused right now, will continue looking into this tomorrow ForgeableSum 1 Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 17, 2016 Author Share Posted August 17, 2016 3 minutes ago, TickleMeElmo said: okey, I'm quite confused right now, will continue looking into this tomorrow You and me both. Okay, thanks :). Link to comment Share on other sites More sharing options...
Recommended Posts