Author Topic: Maintaining items' local coordinates to inventory GUI container  (Read 1769 times)

NateTheGreatt

  • Member
  • **
  • Posts: 83
  • Karma: +0/-0
  • smell the sound
    • View Profile
    • n8bit
How can I create a floating inventory GUI that maintains the X and Y positions of all objects inside of it locally? Meaning if I click and drag the inventory GUI, all of the sprites will go with it. I thought of using an FlxGroup but wasn't sure how to maintain the local coordinates of the contained objects :S
« Last Edit: Sat, Aug 13, 2011 by NateTheGreatt »
"A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away."
-Antoine de Saint-Exupery

Titch

  • Contributor
  • ****
  • Posts: 270
  • Karma: +0/-0
  • Thing with the guy in the place.
    • View Profile
Extends FlxGroup. Add the following.

Code: [Select]
public function get x():int { return _x; }

public function set x(value:int):void
{
var diff:int = value - _x;
for each (var item:* in members)
{
if (item is FlxObject)item.x += diff
}
_x = value;
}

public function get y():int { return _y; }

public function set y(value:int):void
{
var diff:int = value - _y;
for each (var item:* in members)
{
if (item is FlxObject)item.y += diff
}
_y = value;
}

It -might- start to lag with a lots of objects since it has to iterate through all the items in members.
Free cake whippings every day at #flixel on irc.freenode.net.

NateTheGreatt

  • Member
  • **
  • Posts: 83
  • Karma: +0/-0
  • smell the sound
    • View Profile
    • n8bit
Extends FlxGroup. Add the following.

Code: [Select]
public function get x():int { return _x; }

public function set x(value:int):void
{
var diff:int = value - _x;
for each (var item:* in members)
{
if (item is FlxObject)item.x += diff
}
_x = value;
}

public function get y():int { return _y; }

public function set y(value:int):void
{
var diff:int = value - _y;
for each (var item:* in members)
{
if (item is FlxObject)item.y += diff
}
_y = value;
}

It -might- start to lag with a lots of objects since it has to iterate through all the items in members.

You are so helpful. This looks great, thank you!

Another question: I made the GUI for this draggable, but I can only make it work when the GUI.x = mouse.screenX - GUI.width/2 and same with Y. Is there a way I can drag the item from where I clicked it?
« Last Edit: Sun, Aug 14, 2011 by NateTheGreatt »
"A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away."
-Antoine de Saint-Exupery

foosety

  • Member
  • **
  • Posts: 88
  • Karma: +0/-0
    • View Profile
Yes it's actually very simple, this is what I did where mySprite global sprite I want to move around that I defined earlier. And myBox is the box containing the sprite.
Make sure to enableDrag and whatnot. Parameters for the mouseSnap function were useless in my case, not sure if they are necessary.

Code: [Select]

myBox.mousePressedCallback = mouseSnap;
myBox.mouseReleasedCallback = mouseRelease;

private function mouseSnap(spritetosnap:FlxExtendedSprite, x:int, y:int):void
{
mySprite.x = FlxG.mouse.x - mySprite.width / 2;
                        mySprite.y = FlxG.mouse.y - mySprite.height / 2;
mySprite.startDrag();
}

private function mouseRelease(spritetosnap:FlxExtendedSprite, x:int, y:int):void
{
mySprite.stopDrag();
}


You are so helpful. This looks great, thank you!

Another question: I made the GUI for this draggable, but I can only make it work when the GUI.x = mouse.screenX - GUI.width/2 and same with Y. Is there a way I can drag the item from where I clicked it?


NateTheGreatt

  • Member
  • **
  • Posts: 83
  • Karma: +0/-0
  • smell the sound
    • View Profile
    • n8bit
Yes it's actually very simple, this is what I did where mySprite global sprite I want to move around that I defined earlier. And myBox is the box containing the sprite.
Make sure to enableDrag and whatnot. Parameters for the mouseSnap function were useless in my case, not sure if they are necessary.

Code: [Select]

myBox.mousePressedCallback = mouseSnap;
myBox.mouseReleasedCallback = mouseRelease;

private function mouseSnap(spritetosnap:FlxExtendedSprite, x:int, y:int):void
{
mySprite.x = FlxG.mouse.x - mySprite.width / 2;
                        mySprite.y = FlxG.mouse.y - mySprite.height / 2;
mySprite.startDrag();
}

private function mouseRelease(spritetosnap:FlxExtendedSprite, x:int, y:int):void
{
mySprite.stopDrag();
}

I'm confused, it looks like your code sets it to drag from the middle of the sprite, as well. I'm trying to achieve a drag that doesn't snap to the center.
"A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away."
-Antoine de Saint-Exupery

foosety

  • Member
  • **
  • Posts: 88
  • Karma: +0/-0
    • View Profile
Yea for me I set it to the sent of my mouse you could simply set it to FlxG.mouse.x and y if you want want it to go to the center of the sprite.

Titch

  • Contributor
  • ****
  • Posts: 270
  • Karma: +0/-0
  • Thing with the guy in the place.
    • View Profile
To keep the offset just use a point storing the distance between the mouse and the object when it's clicked on and then add it back to the position whilst you are dragging it around.

Psuedo code ahead:-
(I've probably screwed up the +/- signs for working out the offset distances)
Code: [Select]
var m_mouseOffset:FlxPoint = new FlxPoint()
var m_isDragged:Boolean

private function onDragInit ():void
{
m_mouseOffset.x = mouse.x - this.x;
m_mouseOffset.y = mouse.y - this.y;
}

public function onDrag()
{
if (m_isDragged)
{
x = mouse.x + mouse_offset.x;
y = mouse.y + mouse_offset.y;
}
else
{
onDragInit()
m_isDragged = true;
}
}

public function onDragRelease():void
{
m_isDragged = false;
m_mouseOffset.x = 0;
m_mouseOffset.y = 0;
}

If you are only dragging on thing at a time you'll only need one instances of offset. Although adding it to every draggable object isn't a massive overhead.
Free cake whippings every day at #flixel on irc.freenode.net.

NateTheGreatt

  • Member
  • **
  • Posts: 83
  • Karma: +0/-0
  • smell the sound
    • View Profile
    • n8bit
To keep the offset just use a point storing the distance between the mouse and the object when it's clicked on and then add it back to the position whilst you are dragging it around.

Psuedo code ahead:-
(I've probably screwed up the +/- signs for working out the offset distances)
Code: [Select]
var m_mouseOffset:FlxPoint = new FlxPoint()
var m_isDragged:Boolean

private function onDragInit ():void
{
m_mouseOffset.x = mouse.x - this.x;
m_mouseOffset.y = mouse.y - this.y;
}

public function onDrag()
{
if (m_isDragged)
{
x = mouse.x + mouse_offset.x;
y = mouse.y + mouse_offset.y;
}
else
{
onDragInit()
m_isDragged = true;
}
}

public function onDragRelease():void
{
m_isDragged = false;
m_mouseOffset.x = 0;
m_mouseOffset.y = 0;
}

If you are only dragging on thing at a time you'll only need one instances of offset. Although adding it to every draggable object isn't a massive overhead.

I tried doing exactly that a little earlier. For some odd reason it wouldn't drag the box at all when I added the offset :C. I guess I'll have to tinker with it
"A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away."
-Antoine de Saint-Exupery