Gideros GTween Event Listener - gideros

I'm trying a GTween example from the following link
Gideros GTween with Easing
The example doesn't work out of the box, so I dug into the source code of GTween and added the following lines to my example in order to allow event dispatching.
local tween = GTween.new(jewel, 2, animProperties, gtweenProperties)
tween.suppressEvents = false -- New Line #1
tween.dispatchEvents = true -- New Line #2
tween:addEventListener('complete', function()
stage:removeChild(jewel)
jewel = nil
end)
However, the app crashes. I tried commenting the following line in gtween.lua
self:dispatchEvent(Event.new(name))
and the app doesn't crash, however the callbacks aren't invoked (obviously, why would it?)
This is the stack trace from the app.
gtween.lua:445: attempt to call method 'dispatchEvent' (a boolean value)
stack traceback:
gtween.lua:445: in function 'dispatchEvt'
gtween.lua:255: in function 'setPosition'
gtween.lua:86: in function <gtween.lua:74>
Any pointers would be greatly appreciated. Thanks.
PS: I'm not sure if this is a bug on Gideros.

i just tried with the latest gideros' gtween (note that it is edited 10 days ago), and use this sample (i took the sample from your link and add sprite definition, also include a image file in project) and it works(the callback is called) :
local animate = {}
animate.y = 100
animate.x = 100
animate.alpha = 0.5
animate.scaleX = 0.5
animate.scaleY = 0.5
animate.rotation = math.random(0, 360)
local properties = {}
properties.delay = 0
properties.ease = easing.inElastic
properties.dispatchEvents = true
local sprite = Bitmap.new(Texture.new("box.png")) -- ADD THIS
stage:addChild(sprite) -- ADD THIS
local tween = GTween.new(sprite, 10, animate, properties)
tween:addEventListener("complete", function()
stage:removeChild(sprite)
sprite = nil
end)

Related

Attempt to call a Instance value

This error keeps popping up in output, and I'm not sure what I am doing wrong.
Here's the code:
function bullet() --function giving me errors
bullet = Instance.new("Part") --instance
bullet.Size = Vector3.new(1,1,1)
bullet.Position = script.Parent.Position
bullet.Parent = workspace
bullet.Velocity = script.Parent.CFrame.LookVector * 90
bullet.CanCollide = false
--dont think making the script disable then enable after a certain time will work
end
script.Parent.Parent.Activated:Connect(function() --the script is in the handle of the tool
bullet() -- where the error is
--weird thing is, i have made functions like "explode()" that worked just like this and did not have any errors
--pretty sure this is a roblox problem, but i am not sure
--someone help
end)
the error: "Workspace.Tool.Handle.Script:12: attempt to call a Instance value"
--pretty sure this is a roblox problem, but i am not sure
Not the cause is your code.
You define a global function named bullet
function bullet()
-- more code
end
The first thing you do in that function is
bullet = Instance.new("Part")
Doing that you assign the return value of Instance.new("Part") to bullet.
Let's call function bullet the first time bullet()
Now the function is executed and bullet becomes an Instance. It is not a function anymore.
If we now call bullet a second time we get the error
"Workspace.Tool.Handle.Script:12: attempt to call a Instance value"
So bullet basically overwrites itself so it can not be called a second time.
Just use different names to avoid this. Then you should think about the scope. If you want to create a new bullet every time you call bullet you need to make the Intance value local as you would otherwise overwrite the same global bullet every time you call the function.
Try something like
function SpawnBullet() --function giving me errors
local bullet = Instance.new("Part") --instance
bullet.Size = Vector3.new(1,1,1)
bullet.Position = script.Parent.Position
bullet.Parent = workspace
bullet.Velocity = script.Parent.CFrame.LookVector * 90
bullet.CanCollide = false
return bullet
end
script.Parent.Parent.Activated:Connect(function()
SpawnBullet()
end)
Try naming the bullet variable inside the bullet function something besides bullet or change the name of the function
Did you try changing the name of the function or the variable? Maybe that's the problem.
Try:
function CreateBullet() --function giving me errors
bullet = Instance.new("Part") --instance
bullet.Size = Vector3.new(1,1,1)
bullet.Position = script.Parent.Position
bullet.Parent = workspace
bullet.Velocity = script.Parent.CFrame.LookVector * 90
bullet.CanCollide = false
end
script.Parent.Parent.Activated:Connect(function()
CreateBullet()
end)
I'm sorry if it didn't work or if I wasn't helpful.

CoronaSDK Touch Events

Currently creating a game with Corona SDK is it possible to have an image and when it is clicked it displays 3 images and once one them 3 images are clicked the score increases by 1. Also Im only a beginner at coding , this is a new language to me. Thanks.
local CButton = display.newImage("+5.jpg" , 100 , 600)
CButton.alpha = 0.5
CButton.name = "CButton"
local CButtonLabel = display.newText( { text = "", x = 0, y = 0, fontSize = 28 } )
CButtonLabel:setTextColor( 0 ) ; CButtonLabel.x = 100 ; CButtonLabel.y = 45
local function touchCListener( event )
local object = event.target
print( event.target.name.." TOUCH on the '"..event.phase.."' Phase!" )
local ChordCOne = display.newImage("+5.jpg", 900,300)
local ChordCTwo = display.newImage("+5.jpg", 1000,300)
local ChordCThree = display.newImage("+5.jpg", 1100,300)
end
--add "touch" listener -- LABEL IS FOR TESTING!
CButton:addEventListener( "touch", touchCListener)
ChordCOne:addEventListener( "touch", updateScore)
CButtonLabel.text = "touch"
Yes, new DisplayObjects can be created in a listener function and listeners can be added to those objects as well.
In your code, you have not added the DisplayObjects created in your listener to any GroupObject (such as scene.view), which will give unexpected results.
Since the variables pointing to the newly created DisplayObjects (ChordCOne, etc.) are local to the function where they are instantiated, you cannot call addEventListener() on them outside the function. You should add the listener when they are created.
Also, the updateScore() listener function isn't defined anywhere. Make sure updateScore is not nil when and wherever you give it as an argument to addEventListener().

Coroutine problems

so I'm trying to make a basic GUI animation system in ROBLOX, using individual frames and a loop to put them into an imagelabel.
This is the function:
local playAnimation = coroutine.create(function(anim,pos,tank)
while true do
local animBase = sp.AnimBase:Clone()
animBase.Parent = tank
animBase.Visible = true
animBase.Position = pos -- line that causes the error mentioned below.
local frame = 1
for i = 0, animations[anim]["FrameNum"] do
frame = frame + 1
animBase.Image = animations[anim]["Frames"][frame]
NewWait(.1) --this right here, the wait, interfears with the yield.
if frame >= animations[anim]["FrameNum"] then
pos,anim,tank = coroutine.yield()
break
end
end
animBase:Destroy()
end
end)
There are two main problems with this:
every time it runs, I get this error:
20:41:01.934 - Players.Player1.PlayerGui.ScreenGui.Gui-MAIN:65: bad argument #3 to 'Position' (UDim2 expected, got number)
Although this error doesn't seem to do anything. (eg. stop the script completely)
The line causing the error is marked with a comment.
I've made sure that pos is correct. I even tried printing it before setting it, it prints the correct thing which is:
{0,120},{0,65}
The other main problem is that I can't resume it after using it once. It can run this line multiple times fine:
coroutine.resume(playAnimation,"Cannon Fire",UDim2.new(0,120,0,68-25),tank.Frame)
but it won't run:
if tank2:FindFirstChild("Ammo") and isTouching(ammoFrame,tank2:GetChildren()[3]) then
local lastAmmoPos = ammoFrame.Position
ammoFrame:Destroy()
coroutine.resume(playAnimation,"Explosion",lastAmmoPos-UDim2.new(0,25-(ammoTypes[type]["Size"].X.Offset)/2,0,25),tank.Frame)
tank2:GetChildren()[3]:Destroy()
end
Yes, the if statement is working fine. ammoFrame is destroyed and so is the third child of tank2. The coroutine just won't resume.
Fixed by removing the coroutine completely and wrapping the for loop inside a spawn function.
local playAnimation = function(anim,pos,tank)
local animBase = sp.AnimBase:Clone()
animBase.Parent = tank
animBase.Visible = true
animBase.Position = pos
local frame = 1
spawn(function()
for i = 0, animations[anim]["FrameNum"] do
frame = frame + 1
animBase.Image = animations[anim]["Frames"][frame]
wait(.1) --this right here, the wait, interfears with the yield.
if frame >= animations[anim]["FrameNum"] then
break
end
end
animBase:Destroy()
end)
end

A lua script on roblox that moves a model upwards?

I have a model called door
Inside I have a BoolValue named Open
I have a model called Top that has all of the door blocks named Work Mabey Comeon and Proboblynot
And I have Block that when touched is supposed to make Top move up
Directly inside door I have this script
door = script.Parent
open = door.Open
Top = door.Top
opener = 18
speed = 100
steps = speed
startl = Top.CFrame
function MoveDoorToCFrame(cfrm,dr)
dr.Work.CFrame = cfrm
dr.Mabey.CFrame = dr.Work.CFrame * CFrame.new(0,-7.2,0)
dr.Comeon.CFrame = dr.Work.CFrame * CFrame.new(0,10.8,0)
dr.Problynot.CFrame = dr.Work.CFrame * CFrame.new(0,10.8,0)
end
function Update()
if speed/steps < 0.5 then
calc = 1-math.cos(math.rad((-90/speed)*steps*2))
else
calc = 1+math.sin(math.rad((90/speed)*((speed/2)-steps)*2))
end
MoveDoorToCFrame(startl * CFrame.new(0,(calc/2)*opener,0),Top)
end
Update()
while true do
wait()
if not open.Value and steps < speed then
steps = steps + 1
Update()
elseif open.Value and steps > 0 then
steps = steps - 1
Update()
end
end
Inside the button that is supposed to activate on touch I have
script.Parent.Touched:connect(function()
script.Parent.Parent.Open.Value = not script.Parent.Parent.Open.Value
end)
script.Parent.Parent.Open.Changed:connect(Update)
Update()
If you know how to fix this it would be gladly appreciated.
Update November 2015:
Using PrimaryPart
Since writing this post, ROBLOX has changed a lot in regards to the API. To move a model like requested, you should set the PrimaryPart property of the model to a central part inside the model. This will act as the origin for the model's movements.
You can then use model:SetPrimaryPartCFrame(cframe) to set the CFrame of the model. You can also retrieve this property by using model:GetPrimaryPartCFrame(), although I believe that is just a shortcut method for model.PrimaryPart.CFrame.
In code, it would look like this:
-- Set PrimaryPart:
MODEL.PrimaryPart = MODEL.SomeCentralPart
...
-- CFrame movement:
local movement = CFrame.new(0, 10, 0)
-- Move the model:
MODEL:SetPrimaryPartCFrame(MODEL:GetPrimaryPartCFrame() * movement)
Option A: Use Model's methods
I think you are making this much more difficult than it needs to be. Whenever you run into an issue like this, be sure to check the current APIs provided. The ROBLOX Model object contains a nifty method called 'TranslateBy' which takes a Vector3 argument to translate the model.
Using MODEL:TranslateBy(Vector3) is similar to moving a model via CFrame, since it ignores collisions.
Another alternative is MODEL:MoveTo(Vector3) which moves a whole model to the given Vector3 world position. The downside to this is that it does collide.
One way to get the same MoveTo effect but without collisions can be done with the TranslateBy method:
MODEL:TranslateBy(Vector3Position - MODEL:GetModelCFrame().p)
Option B: Write a custom function to manipulate the model's CFrame
Another alternative would be to manipulate the whole model's CFrame entirely. To do this, you can write a clever function that will move a whole model relative to an 'origin' point. This is similar to moving shapes on a grid given their points and an origin, except in three dimensions. Using ROBLOX's built-in functions, this is much easier though.
A good way to do this would be to write a function that lets you actually assign a CFrame value to a whole model. Another way would be to allow a translation via CFrame too.
Here's an example:
function ModelCFrameAPI(model)
local parts = {} -- Hold all BasePart objects
local cf = {} -- API for CFrame manipulation
do
-- Recurse to get all parts:
local function Scan(parent)
for k,v in pairs(parent:GetChildren()) do
if (v:IsA("BasePart")) then
table.insert(parts, v)
end
Scan(v)
end
end
Scan(model)
end
-- Set the model's CFrame
-- NOTE: 'GetModelCFrame()' will return the model's CFrame
-- based on the given PrimaryPart. If no PrimaryPart is provided
-- (which by default is true), ROBLOX will try to determine
-- the center CFrame of the model and return that.
function cf:SetCFrame(cf)
local originInverse = model:GetModelCFrame():inverse()
for _,v in pairs(parts) do
v.CFrame = (cf * (originInverse * v.CFrame))
end
end
-- Translate the model's CFrame
function cf:TranslateCFrame(deltaCf)
local cf = (model:GetModelCFrame() * deltaCf)
self:SetCFrame(cf)
end
return cf
end
-- Usage:
local myModel = game.Workspace.SOME_MODEL
local myModelCF = ModelCFrameAPI(myModel)
-- Move to 10,10,10 and rotate Y-axis by 180 degrees:
myModelCF:SetCFrame(CFrame.new(10, 10, 10) * CFrame.Angles(0, math.pi, 0))
-- Translate by 30,0,-10 and rotate Y-axis by 90 degrees
myModelCF:TranslateCFrame(CFrame.new(30, 0, -10) * CFrame.Angles(0, math.pi/2, 0))
This might be hard.
You might want to look to free models for this one unless the people above get it to work.
I, however, do have a script to move a model:
game.Workspace.Model:MoveTo(Vector3.new(0,0,0))
Your code indeed needs fixing.
You should NOT use a never-ending loop to make your stuff work (unless that is the only way).
You should rather base actions on events.
Consider to use this:
Structure:
Door [Model]
DoorScript [Script]
Button [Part]
DoorOpen [BoolValue]
Top [Model]
Mabey [Part]
Comeon [Part]
Problynot [Part]
DoorScript:
local Model = script.Parent
local Door = Model.Top
local Button = Model.Button
local DoorOpen = Model.DoorOpen
local Offset = 0
local ToOffset = 100
local Direction = 1
local StepLength = 0.1
local Moving = false
function StartMoving()
if Moving then return end
Moving = true
while (DoorOpen.Value and Offset ~= ToOffset) or (not DoorOpen.Value and Offset ~= 0) do
local Change = Offset
Offset = math.max(0,math.min(ToOffset,Offset + StepLength * (DoorOpen.Value and 1 or -1)))
Change = Offset - Change
Top:TranslateBy(Vector3.new(0,Change,0))
wait()
end
Moving = false
end
StartMoving()
DoorOpen.Changed:connect(StartMoving)
local Debounce = false
Button.Touched:connect(function()
if Debounce then return end
Debounce = true
DoorOpen.Value = not DoorOpen.Value
wait(4)
Debounce = false
end)
You might want to adjust the speed tho.
This can be used to move models, try adding something like this into your code. It's more dynamic.
a = Workspace.Model
for i=0.1,40 do
for i,v in pairs(a:getChildren()) do
if v:IsA("Part") then
v.CFrame = CFrame.new(v.CFrame + Vector3.new(0,0.1,0))
else print("Not a part")
end
end
end

How do I reference an image that I have created in an table array in Corona (Lua)?

Apologies for the incredibly noob question, but I'm new to Lua, very very rusty at any code, stuck and can't find the solution!
I'm creating a series of random images on screen using:
for count = 1, 6 do
r = math.random ( 1, 5 )
mpart[count] = display.newImage ("mpart" .. r .. ".png")
mpart[count].y = 680
mpart[count].x = x
mpart[count].spawnednew = false
x = x + 170
mpart[count]:addEventListener ("touch", onTouch)
end
How do I know which object is being touched/moved in the function "onTouch", and how do I add a property to it, e.g.
mpart[1].spawnednew == true
Your onTouch function should have an event parameter passed in. The touched image can then be found by in event.target.
Well first off, lins is spot on about how to reference the touched object: the 'event' parameter of the listener function includes the value 'event.target'
As for adding new data to the touched object, that's as simple as 'event.target.moved = true' and now the object has data at object.moved

Resources