With the current complexity of scripting, and my abilities, i have hit a dead end with working out how to create a sliding door in the Popular MMO, "Roblox".
I have analyzed the script automatically, and manually, and have not found any errors.
Here it is below:
local Part = workspace.Part
local newPos = Part.Position + Vector3.new(-61.866, 8.551, -97.181)
local Time = 5
local Increment = 0.5
local Debounce = false
local Diff = newPos - Part.Position
local Mag = Diff.magnitude
local Direction = CFrame.new(Part.Position, newPos).lookVector
function MovePart()
if Debounce then return end
Debounce = true
for n = 0, Mag, Increment do
Part.CFrame = Part.CFrame + (Direction * Increment)
wait( (Time/Mag) * Increment )
end
Debounce = false
end
workspace.Button.ClickDetector.MouseClick:connect(MovePart)
When i have inserted a Button with a Clickdetector inside, and tried to click the button, no results have been shown- not even an error! I am stuck, and require assistance. It would be much appreciated.
Hmmm, works for me.
Is it already at (-61.866, 8.551, -97.181)?
Is there another "Part" or "Button"?
Is it not anchored and something in the way?
Alternate solution:
Put the button, part, and the following script together in a model.
local Part = script.Parent.Part
local Button = script.Parent.Button
Part.Anchored = true
local Direction = Part.CFrame.lookVector
local Mag = Part.Size.Z
local Time = 5
local Increment = 0.5 -- Smaller will make smoother 'movement'
local Debounce = false
function MovePart()
if Debounce then return end
Debounce = true
for n = 0, Mag, Increment do
Part.CFrame = Part.CFrame + (Direction * Increment)
wait(Time/(Mag * Increment))
end
for n = 0, Mag, Increment do
Part.CFrame = Part.CFrame + (Direction * -Increment) -- so that it moves back
wait(Time/(Mag * Increment))
end
Debounce = false
end
clickD = Button.ClickDetector or Instance.new("ClickDetector",Button)
clickD.MouseClick:connect(MovePart)
Hope that helps.
all you have to do is place a part in the workspace, rename it "Button" and insert a clickDetector into the part.
Related
I've tried switching from Vector3 to CFrame and it still hasn't been working. The best I've gotten is the part appearing like 10 feat in the air, this is what I have so far.
local Dog = game:GetService("ReplicatedStorage"):WaitForChild("PetTesting")
local RunService = game:GetService("RunService")
local tweenService = game:GetService("TweenService")
local Petfollow = game:GetService("ReplicatedStorage"):WaitForChild("PetFollow")
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(char)
wait(1)
local dc = Dog:Clone()
dc.Name = "Pet"
dc.Parent = char
local offsetCframe = CFrame.new(0, 0, 0)
dc.CFrame = char:WaitForChild("HumanoidRootPart").CFrame + offsetCframe
dc.Anchored = true
dc.CanCollide = false
dc.Transparency = 0
end)
end)
You can use a bit of CFrame manipulation as described in https://developer.roblox.com/en-us/api-reference/datatype/CFrame. I am not sure if this is the right way of doing this, so please reply if this is incorrect.
local offset = Vector3.new(0, 0, 10)
local newCFrame = humanoidRootPart.CFrame * offset
I have a table full of enemies and simple want them to move across the screen via gameLoop, however for some reason nothing seems to work. Its probably an easy fix but I have tried to fix it but am getting nowhere. Anyone know whats up?
gameLoop Function
local i
for i = 1, #enemies do--.numChildren,1, -1 do
local blocks = enemies[i]
if blocks ~= nil and blocks.x ~= nil then
enemyRate = 2.0 + (0.1 * wave)
transition.to( blocks, { time=1500, x=300} )
end
end
The Spawn Function
function spawnEnemy()
local spawnData = { -- Easily store spawns in a table to make it easier to add new enemies later
{name = "Blue", seq = "blueRect", frame = 3, imgSheet = imageSheetRectangle, seqData = sequenceDataRectangle},
{name = "Red", seq = "blueCross", frame = 1, imgSheet = imageSheetCross, seqData = sequenceDataCross},
{name = "Green", seq = "blueCirc", frame = 2, imgSheet = imageSheetCircle, seqData = sequenceDataCircle}
}
local xPos = display.contentWidth - 150
local r = math.random(1, #spawnData)
local sd = spawnData[r] -- get the spawn data for this enemy
local s = display.newSprite(sd.imgSheet, sd.seqData)
s.name = sd.name
physics.addBody(s, { isSensor = true })
s:setSequence(sd.seq)
s:setFrame(sd.frame)
s.y = display.contentHeight - 400
s.x = xPos
enemies[#enemies+1] = s
enemyGroup:insert(s)
In this related answer: transition.to( ) doesn't work within a function and with a Runtime:addEventListener( "enterFrame", method) listener in Corona / Lua you can see a similar issue as I stated above. You are creating an animation right as one is starting - making it seem as though it is not moving. As I suggested above, if it suits your game, begin the transition when you spawn the object; not every gameloop.
I have just started to learn LUA in school, but i cannot find many helpful tutorials o the internet to aid in my learning. I have made a simple game (which doesn't work yet, i realize that) and a main menu. However, when i try to start the app, it gives me this error:
/Users/jordanmcbride/Desktop/Lua Projects/Tapinator/main.lua:47: attempt to index global 'showCredits' (a nil value)
stack traceback:
/Users/jordanmcbride/Desktop/Lua Projects/Tapinator/main.lua:47: in main chunk
[Finished in 9.4s]
I have looked the error, and I cannot seem to understand how to fix it. The other questions have said something about returning the function returning a nil value, and that I should add a return statement to the end, but that doesn't work either.
Here is the code # line 47.
function showCredits.touch(e)
playButton.isVisible = false
creditsButton.isVisible = false
creditsView = display.newImage('credits.png', 0, display.contentHeight)
lastY = name.y
transition.to(name, {time = 300, y = display.contentHeight * 0.5 - title.height - 25})
transition.to(creditsView, {time = 300, y = display.contentHeight * 0.5 + creditsView.height, onComplete = function() creditsView:addEventListener('tap', hideCredits) end})
end
Here is my full code, in case the problem lies elsewhere:
display.setStatusBar(display.HiddenStatusBar)
radius = 40
smallTime = 200
bigTime = 800
score = 0
scoreInc = 2000
--HomePage
local name
local playButton
local creditsButton
local homePage
--Credits
local creditsPage
--Sounds
local circleSpawn = audio.loadSound( "circle_spawn.wav" )
local circleTap = audio.loadSound( "circle_tap.wav" )
function Main()
name = display.newImage('title.png', display.contentWidth / 2, 53)
name:scale( .5, .5 )
playButton = display.newImage('playButton.png', display.contentWidth / 2, 245)
playButton:scale( .5, .5 )
creditsButton = display.newImage('creditsButton.png', display.contentWidth / 2, 305)
creditsButton:scale( .5, .5 )
homePage = display.newGroup(name, playButton, creditsButton)
startButtonListeners('add')
end
function showCredits.touch(e)
playButton.isVisible = false
creditsButton.isVisible = false
creditsView = display.newImage('credits.png', 0, display.contentHeight)
lastY = name.y
transition.to(name, {time = 300, y = display.contentHeight * 0.5 - title.height - 25})
transition.to(creditsView, {time = 300, y = display.contentHeight * 0.5 + creditsView.height, onComplete = function() creditsView:addEventListener('tap', hideCredits) end})
end
function hideCredits.touch(e)
transition.to(creditsView, {time = 300, y = display.contentHeight, onComplete = function() creditsButton.isVisible = true playButton.isVisible = true creditsView:removeEventListener('tap', hideCredits) display.remove(creditsView) creditsView = nil end})
transition.to(name, {time = 300, y = lastY});
end
function startButtonListeners(action)
if(action == 'add') then
playButton:addEventListener('touch', playGame)
creditsButton:addEventListener('touch', showCredits)
else
playButton:removeEventListener('touch', playGame)
creditsButton:removeEventListener('touch', showCredits)
end
end
Main()
printScore = display.newText("Score: " .. tostring(score), display.contentWidth-80, 40, native.systemFontBold, 20)
-- A function that creates random circles
function generateCircle ()
-- Creates a new circle between 0 (the left most bounds) and the width of the display (being the content width), and also
-- 0 (the upper most bounds) and the height of the display (being the content height). The radius of the circle is 'radius'
x = math.random(radius, display.contentWidth-radius)
y = math.random(80, display.contentHeight)
score = score + scoreInc
myCircle = display.newCircle( x, y, radius )
myCircle:setFillColor( math.random(), math.random(), math.random() )
delayTime = math.random(smallTime, bigTime)
score = score + scoreInc
printScore.text = "Score:"..tostring(scores)
local spawnChannel = audio.play( circleSpawn )
timer.performWithDelay( delayTime, generateCircle )
end
generateCircle()
function myCircle:touch( event )
local tapChannel = audio.play( circleTap )
myCircle:removeSelf()
end
myCircle:addEventListener( "touch", myCircle )
The answer by greatwolf will work. But just a tip from my experience. One way I like to create functions is to try to define the name of the function first near the top of the lua file. Then I will define the function later on in the file. Something like this:
--function preallocation
local onPlayTap
local onSoundOnTap
local onSoundOffTap
local onCreditsTap
local onHelpTap
---------------------------------------------------------------------------------
-- Custom Function Definitions
---------------------------------------------------------------------------------
--Called when Sound On Button is tapped, turn off sound
onSoundOnTap = function(event)
end
--Called when Sound Off Button is tapped, turn on sound
onSoundOffTap = function(event)
end
--Called when Credits button is tapped, shows credits
onCreditsTap = function(event)
end
--Called when Help button is tapped, shows help
onHelpTap = function(event)
end
--Callback to Play button. Moves scene to Level Picker Scene
onPlayTap = function(event)
end
What this does is allow each function to be called by any other function in the file. If you do it the way you are doing it by adding the function name before the function like so:
local showCredits = {}
function showCredits.touch(e)
end
local hideCredits = {}
function hideCredits.touch(e)
end
your showCredit function will not be able to call the hideCredits function below it because the hideCredits variable has not been defined yet when the showCredit function was defined. Although this may not effect your current game, in future apps or games, you may need to call functions inside of other functions. To make this work properly, predefine all your function variables first, then define all your function afterwards. Hope this helps.
I am new to corona and I am trying to make multiple objects get moving, and selectively make them rotate one at a time. I should be able to select any one object by tapping on it, and then by clicking a button, it should rotate by X degree (for each click). I have the following code working for one object. But stuck on getting the setup for multiple moving objects. I apologize if it is basic.
local Button = display.newRect(200,200, 10, 40)
local obj = display.newRect(50,50, 10, 40)
local SPEED = 1
local function move(event)
obj.x = obj.x + math.cos(math.rad(obj.rotation)) * SPEED
obj.y = obj.y + math.sin(math.rad(obj.rotation)) * SPEED
end
local function rotate(event)
obj.rotation = obj.rotation + 45
end
Runtime:addEventListener("enterFrame", move)
Button:addEventListener("tap", rotate)
Just update your code to have a "selected" object, like this:
local selectedObject = nil
local Button = display.newRect(200,200, 10, 40)
local obj = display.newRect(50,50, 10, 40)
local SPEED = 1
local function select(event)
selectedObject = event.target
end
local function move(event)
obj.x = obj.x + math.cos(math.rad(obj.rotation)) * SPEED
obj.y = obj.y + math.sin(math.rad(obj.rotation)) * SPEED
end
local function rotate(event)
if selectedObject then
selectedObject.rotation = selectedObject.rotation + 45
end
end
obj:addEventListener("tap", select)
Runtime:addEventListener("enterFrame", move)
Button:addEventListener("tap", rotate)
I've read the other topics related to this subject and cannot make sense of them in the sense of my code. In the code below, I cannot get the make other word buttons into the table. I can generate the words but they will not go into the table. The previous function with the correct word works fine. What am I doing wrong? Do I have problems elsewhere in the code?
--main text
local content = require "content"
--chooses a random number according to the maximum number available in the table
local defaultWidth = 1024
local defaultHeight = 768
local displayWidth = display.viewableContentWidth
local displayHeight = display.viewableContentHeight
local yMargin = 20
local centerX = defaultWidth/2;
local centerY = defaultHeight/2;
local xAdjust = (defaultWidth - display.viewableContentWidth)/2
local yAdjust = (defaultHeight - display.viewableContentHeight)/2
local rnd = math.random
local maxSightwords = 3
local currQuestion = 0
local playOrder
local letterButtons
local wrongGraphic
local correctButton
--local wordButtons
function getRandomOrder(amount)
local order ={}
local i
local temp
local temp1
for n = 1,amount do
order[n] = n
end
for i=0,9 do
for temp = 1,amount do
n = math.random(1, amount)
temp1 = order[temp]
order[temp] = order[n]
order[n] = temp1
end
end
return order
end
-- assign random order for words
playOrder = getRandomOrder(#content)
function nextQuestion()
-- update question number index
currQuestion = currQuestion+1
if currQuestion > #playOrder then
currQuestion = 1
end
local questionNumber = playOrder[currQuestion]
print("Question# "..currQuestion)
print("id "..content[questionNumber].id)
-- make word buttons
wordButtons = {}
-- make word button for correct word
local word = content[playOrder[currQuestion]].word
table.insert(wordButtons, newWordButton(word))
correctButton = wordButtons[1].graphics
local buttonWidth = 150
print ("correct: "..word)
print (#wordButtons)
---[[
-- ****make other word buttons***
local otherWords = getRandomWords(content.word)
--print (otherWords)
for i=1, maxSightwords-1 do
table.insert(wordButtons, otherWords)
end
--]]
print (#wordButtons)
-- position letter buttons and add touch event listener
local randomWordOrder = getRandomOrder(#wordButtons)
local buttonSpacing = buttonWidth * 1.5
local buttonsWidth = (#wordButtons * buttonWidth) + ((#wordButtons-1) * (buttonSpacing/4))
local buttonsX = centerX - (buttonWidth)
for i=1, #wordButtons do
local button = wordButtons[i].graphics
button.y = centerY
button.x = buttonsX + (buttonSpacing * (randomWordOrder[i]-1))
button:addEventListener("touch", onWordTouch)
--local randomDelay = transitionDuration + (math.random(1,10) * 10)
--transition.from(button, {time = 500, delay = randomDelay, y = defaultHeight + button.height})
end
end
function clearQuestion()
-- remove wrongGraphic if present
if wrongGraphic then
wrongGraphic:removeSelf()
wrongGraphic = nil
end
-- remove all word buttons
for i=1,#wordButtons do
wordButtons[i].graphics:removeSelf()
wordButtons[i].graphics = nil
end
end
function onWordTouch(event)
local t = event.target
if "ended" == event.phase then
if t == correctButton then
onCorrect()
else
onIncorrect(t)
end
end
end
function onIncorrect(incorrectButton)
media.playSound("sounds/splat.wav")
wrongGraphic = display.newImageRect("images/graphics/wrong.png", 137, 136)
wrongGraphic.x = incorrectButton.x + incorrectButton.width/2
wrongGraphic.y = incorrectButton.y + incorrectButton.height/2
transition.to(incorrectButton, {time=100, delay=500, alpha=0})
transition.to(wrongGraphic, {time=200, delay=500, alpha=0, onComplete=wrongCompleteListener})
local wrongCompleteListener = function(obj)
obj:removeSelf()
obj = nil
incorrectButton:removeSelf()
incorrectButton = nil
end
end
function onCorrect()
-- play correct sound then display word
media.playSound("sounds/correct.mp3", playWord)
-- remove the letter buttons
clearQuestion()
-- disable the home button until new screen is shown
homeEnabled = false
end
function newWordButton(word)
local wordGraphic = display.newImageRect("images/words/"..word..".png", 150, 75)
local wordButton = {}
wordButton.graphics = display.newGroup()
wordButton.graphics:insert(wordGraphic)
wordButton.word = word
return wordButton
end
function getRandomWords ()
local wordGraphic = display.newGroup ()
for i=1,maxSightwords-1 do
--remove a word from content using a random index #
--Since the index will be between 1 and the number of words in content
--and each time through the loop a word is removed, you can be sure
--You will get 3 different words without repeats.
local next_word = table.remove(content, math.random(#content))
--next_word is a table with 'word' and 'id' fields so you can make the text display object from next_word.word
local wordText = display.newImageRect("images/words/"..next_word.id..".png", 150, 75)
wordText.x = display.contentWidth/2
wordText.y = display.contentHeight/2 - 100
wordGraphic:insert(wordText)
print (next_word.id)
end
end
nextQuestion ()
I think your problem is that you are resetting the wordButton = {} again in function newWordButton. You already made the table in function nextQuestion(), so by calling it again in the newWordButton function is reseting the entire table.
Take a look at this links:
http://www.coronalabs.com/blog/2011/06/21/understanding-lua-tables-in-corona-sdk/
http://docs.coronalabs.com/api/library/table/insert.html
I'm pretty sure the function should look like this:
function newWordButton(word)
local wordGraphic = display.newImageRect("images/words/"..word..".png", 150, 75)
wordButton.graphics = display.newGroup()
wordButton.graphics:insert(wordGraphic)
wordButton.word = word
return wordButton
end