Yeah, PEBs idea on using eventhandler is pretty good.
And yes, If you use MoveLayer, then that is by default a slow method as its purpose is to move the layer using Hollywoods own move function thing, more like a script command. Showlayer simply shows it on that exact spot you want.
I remembered one time I did the same, although bit differently, copy-pasting the relevant parts of code here so you can look if you are interested.
This is actually meant to be moving Group of Layers, like Layers attached together.
Here is first the LayerGroup code:
Code: Select all
LayerGroup = { Groups = {} }
Function LayerGroup:New()
Local d = {}
SetMetaTable(d, self)
self.__index = self
Return(d)
EndFunction
Function LayerGroup:CreateGroup(GroupID, LayerID) /* is the first Layer, upon which rest will be relative to */
self.Groups[GroupID] = {}
self.Groups[GroupID][1] = LayerID
Local t = GetLayerStyle(layerID)
userdata = { originalposition = { x = t.x, y = t.y, w = t.width, h = t.height } }
SetObjectData(#LAYER, LayerID, "userdata", userdata)
EndFunction
Function LayerGroup:DeleteGroup(GroupID)
self.groups[GroupID] = Nil
EndFunction
Function LayerGroup:AddLayer(GroupID, ...) /* Each ... is LayerID to be added to the specified group */
Local base_t = GetLayerStyle(LayerGroup.groups[GroupID][1]) /*Baselayers current stylesettings */
Local userdata = GetObjectData(#LAYER, LayerGroup.groups[GroupID][1], "userdata")
Local t_orig = userdata.originalposition
Local origwidthmultiplier = t_orig.w / base_t.width
Local origheightmultiplier = t_orig.h / base_t.height
For Local n = 0 To arg.n-1
Local t = GetLayerStyle(arg[n])
Local userdata = {
originaldata = { x = (t.x - base_t.x) * origwidthmultiplier, y = (t.y - base_t.y) * origheightmultiplier, w = t.width * origwidthmultiplier, h = t.height * Origheightmultiplier },
lastposition = { x = t.x, y = t.y, w = t.width, h = t.height }
}
SetObjectData(#LAYER, arg[n], "userdata", userdata)
InsertItem(self.Groups[GroupID], arg[n])
Next
EndFunction
Function LayerGroup:RemoveLayer(GroupID, ...) /* each ... is LayerID to be removed from specified Group */
For Local n = 0 To arg.n-1
Local found = -1
ForEach(self.Groups[GroupID], Function (Index, LayerID)
If arg[n] = LayerID Then found = Index
EndFunction)
If found <> -1 Then RemoveItem(self.Groups[GroupID], found)
Next
EndFunction
Function LayerGroup:ShowGroup(GroupID, Positiontable)
Local baselayer = self.groups[GroupID][1]
Local userdata = GetObjectData(#LAYER, baselayer, "userdata")
baseorig = userdata.originalposition
Local t = GetLayerStyle(baselayer) /* Can use GetLayerStyle instead of userdata, because baselayer is always on round() pixels. */
Local new_x = t.x
Local new_y = t.y
Local new_w = t.width
Local new_h = t.height
If HaveItem(Positiontable, "x") Then new_x = Positiontable.x
If HaveItem(Positiontable, "y") Then new_y = Positiontable.y
If HaveItem(Positiontable, "w") Then new_w = Positiontable.w
If HaveItem(Positiontable, "h") Then new_h = Positiontable.h
SetLayerStyle(baselayer, { x = new_x, y = new_y, width = new_w, height = new_h } )
widthmultiplier = new_w / baseorig.w
heightmultiplier = new_h / baseorig.h
Local changedpositionlist = {}
ForEach(self.groups[GroupID], Function (index, layerID)
If layerID <> baselayer
Local t = GetLayerStyle(LayerID)
Local userdata = GetObjectData(#LAYER, layerID, "userdata")
Local lastposition = userdata.lastposition
If t.x <> lastposition.x Or t.y <> lastposition.y Or t.width <> lastposition.w Or t.height <> lastposition.h Then InsertItem(changedpositionlist, layerID)
EndIf
EndFunction)
ForEach(changedpositionlist, Function (index, layerID)
LayerGroup:RemoveLayer(GroupID, layerID)
LayerGroup:AddLayer(GroupID, layerID)
EndFunction)
ForEach(self.groups[GroupID], Function (index, layerID)
If layerID <> baselayer
Local userdata = GetObjectData(#LAYER, layerID, "userdata")
Local orig_t = userdata.originaldata
Local xpos = new_x + ( orig_t.x * widthmultiplier )
Local ypos = new_y + ( orig_t.y * heightmultiplier )
Local wpos = orig_t.w * widthmultiplier
Local hpos = orig_t.h * heightmultiplier
SetLayerStyle(LayerID, { x = xpos, y = ypos, width = wpos, height = hpos} )
Local temp = GetLayerStyle(LayerID)
Local lastposition = { x = temp.x, y = temp.y, w = temp.width, h = temp.height }
userdata.lastposition = lastposition
SetObjectData(#LAYER, layerID, "userdata", userdata)
EndIf
EndFunction)
EndFunction
Function LayerGroup:LayerGroupToFront(GroupID)
Local baselayer = self.groups[GroupID][1]
SetLayerZPos(baselayer, 0)
ForEach(self.groups[GroupID], Function (index, layerID)
If layerID <> baselayer Then SetLayerZPos(layerID, 0)
EndFunction)
EndFunction
Using it works following:
First you use LayerGroup:CreateGroup(GroupID, LayerID), here you need to give name to your new group (there can be several existing at same time) and also the first layer which will work as the main layer. Meaning that all future layers attached after, will be in relative positions to this first one. THat if first one is at position 100, 100, and second one is at position 300, 300, that means that from now on, the second layer will always be displayed on position +200, +200 relative to first one.
Example: LayerGroup:CreateGroup("mygroup1", "MyLayer1")
after this you add more layers using:
LayerGroup:AddLayer(GroupName, ...) In this Groupname is a group name already existing, as example the one you just created previous step. Then add as many layers you like to that group.
example: LayerGroup:AddLayer("mygroup1", "mylayer2", "mylayer3", "mylayer4")
Now you would have 4 different layers in that group.
To display these layers somehwere, just use:
LayerGroup:ShowGroup(Groupname, positiontable) - in here groupname the name of the group you wish to show, as example "mygroup1" positiontable is a table that can contain 4 different variables, x, y, width, height. If one of these is not defined, it will use the current one (which is most likely the case with width and height), if defined, will use these new ones. Remember that width and height are based upon the first layers width and height. So if original widht and height were 100, 100, then by using 200, 200, you would be doubling all layers size in that group and their relative distance to first layer.
as example: LayerGroup("MyGroup1", {x=500, y=800})
As to the actual Layer movement thing, here is the moving part from one code of mine that is using this layergroup to do the actual moving:
Code: Select all
Function GameBoard.Board(msg)
Switch msg.action
Case "OnMouseDown":
gameboard.movingboard_x = MouseX()
gameboard.movingboard_y = MouseY()
Local id = SetInterval(Nil, gameboard.move, 1)
t_interval["movinggameboard"] = id
EndSwitch
EndFunction
Function GameBoard.Move()
If IsLeftMouse() = False
If HaveItem(t_interval, "movinggameboard") = True /* Might be better to move it at beginning of function and return if false */
ClearInterval(t_interval["movinggameboard"])
t_interval["movinggameboard"] = Nil
EndIf
EndIf
Local xmovement = MouseX() - gameboard.movingboard_x
Local ymovement = MouseY() - gameboard.movingboard_y
gameboard.movingboard_x = MouseX()
gameboard.movingboard_y = MouseY()
gameboard.x = gameboard.x + xmovement
gameboard.y = gameboard.y + ymovement
LayerGroup:ShowGroup("GameBoard", { x = gameboard.x, y = gameboard.y, w=gameboard.w, h = gameboard.h } )
/*SetLayerStyle("gameboard", {x = gameboard.x, y = gameboard.y})*/
EndFunction
This is actually using my own t_interval function, but I guess it is easy enough to figure out what it is doing, it is adding an interval to be played, just using this t_interval to have more control about intervals, like being able to name them.
edit: Forgot to mention still, so that width and height in that grouplayer were so that I could shrink or expand some layergroups. Like when some button is not active, they can shrunk like windows programs to that bottom bar, when being the active buttons to choose from, i could expand them in front of the screen begging for attention.