director error in corona - coronasdk

settings.lua
local lang_table = {
{image = display.newImage("en.png"), x = 600, y = 400, lang = "1033", i = 1},
{image = display.newImage("fr.png"), x = 600, y = 400, lang = "fr", i = 2},
{image = display.newImage("dk.png"), x = 600, y = 400, lang = "dk", i = 3},
{image = display.newImage("ge.png"), x = 600, y = 400, lang = "ge", i = 4} }
local function changelanguage (event)
if event.phase == "ended" then
lang_table[event.target.i].image.isVisible = false
if event.target.i == 4 then
lang_table[1].image.isVisible = true
_G.value = event.target.lang
director:changeScene("settings")
else
lang_table[event.target.i+1].image.isVisible = true
_G.value = lang_table[event.target.i+1].lang
director:changeScene("settings")
end
end
return true
end
for i = 1,#lang_table do
local img_display = lang_table[i].image
img_display.x = lang_table[i].x
img_display.y = lang_table[i].y
img_display.i = lang_table[i].i
img_display.lang = lang_table[i].lang
if _G.value ~= lang_table[i].lang then
img_display.isVisible = false
end
img_display:addEventListener("touch", changelanguage)
langGroup:insert(img_display)
end
When I touch the image,changelanguage function is being invoked.In that function there is
director:changeScene
but this is not working.Basically,what I want is that whenever there is touch event to the image I want the same lua file to be called.But this is not happening.Then What I did was changed the function "changelanguage" to
_G.t =1
local function changelanguage (event)
if event.phase == "ended" then
lang_table[event.target.i].image.isVisible = false
if event.target.i == 7 then
lang_table[1].image.isVisible = true
_G.value = event.target.lang
director:changeScene("settings")
else
lang_table[event.target.i+1].image.isVisible = true
_G.value = lang_table[event.target.i+1].lang
if _G.t ==1 then
director:changeScene("..\settings")
_G.t = _G.t+1
elseif _G.t ==2 then
director:changeScene("..\..\settings")
end
end
end
return true
end
Now, it is working.But I dont know why is this happening.Can anyone suggest me why is this happening.Cant I use the same director:changeScene("settings") to change the scene again and again on touch event.

I tried using the empty scene to switch right back another scene to restart it.
At first it didn't work at all, I had to display a button in the empty scene, and attach a function to it, so that when the user presses it , it switches back to the old scene, which would restart it.
However, further Googling the problem, I found out that the Director class v. 1.3 and above, can reload the scene that you are in by simply calling it using the director:changeScene("") function!
(Read about it here:
http://rauberlabs.blogspot.com/2011/07/director-class-13.html )
So if you are in settings.lua, and you want to reload it, just include director:changeScene("settings") in the same settings.lua (as you did the first time).
of course remember to update the director.lua to the latest version.
I guess you can still download it from here:
https://bitbucket.org/ricardorauber/corona/downloads

You cannot use Director to change to a scene you are already in, eg, calling director:changeScene("settings") from within settings.lua, no.
You can do this in Storyboard, however. (It may be worth considering a switch if this is something you will be doing a lot of, alternatively you could make a file such as reset.lua and write functions within there to effectively reload any scene you liked simply by changing to reset and back to the previous scene again.)

Related

Text is not a valid member of Frame - how do I fix that?

It gives me an error when I execute it "Text is not a valid member of Frame". It's a slider script.
--SLIDER:
local SliderFrame = script.Parent.WalkSpeedSlider
local UIS = game:GetService("UserInputService")
local WalkSpeedSlider = script.Parent.WalkSpeedSlider
local SliderFrame = WalkSpeedSlider.SliderFrame
local Slider = SliderFrame.Slider
local WalkspeedReset = SliderFrame.Reset
local WalkspeedDragging = false
local WalkSpeedDisplay = SliderFrame.WalkSpeedNum
Slider.MouseButton1Down:Connect(function()
WalkspeedDragging = true
end)
UIS.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
WalkspeedDragging = false
end
end)
UIS.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement then
if WalkspeedDragging == true then
local MouseL = UIS:GetMouseLocation()
local RelativePos = MouseL-SliderFrame.AbsolutePosition
local percent = math.clamp(RelativePos.X/SliderFrame.AbsoluteSize.X,0,1)
Slider.Position = UDim2.new(percent,0,0,0)
game.Players.LocalPlayer.Character:FindFirstChildWhichIsA("Humanoid").WalkSpeed = math.round(percent*120)
WalkSpeedDisplay.Text = math.round(game.StarterPlayer.CharacterWalkSpeed)
end
end
end)
I was trying to make a slider which I succeeded, but I wanted my textbox which is WalkSpeedDisplay to be able to change to the speed that I put with the slider, but WalkSpeedDisplay.Text gives me an error "Text is not a valid member of Frame" and I don't know why.
Frames don't have a property known as text. If you want to add text to a frame, insert a text label in the frame and customize it to how you want.
I may be wrong about this, it would be helpful to see all the children and parents of the frame.
Also you probably shouldn't use a variable name two times, such as you did with SliderFrame.

Roblox: how to script VectorForce

I'm very new (2 days) to Roblox and Lua, so don't bite me too hard please.. =)
What I am trying to do is to script VectorForce for the Part I've also instanced from code.
In simulation Attachment and VectorForce did create, but without any expected effect.
Please, look at my script and tell me where do I need to dig.
local sandblock = script.Parent
local sandblock_health = 5
local function blockJump(object)
local jump_att = Instance.new("Attachment", object)
local jump_force = Instance.new("VectorForce", object)
jump_force.ApplyAtCenterOfMass = true
jump_force.Attachment0 = jump_att
jump_force.RelativeTo = Enum.ActuatorRelativeTo.World
jump_force.Force = Vector3.new(10,1000,-10)
jump_force.Enabled = true
-- here: what is the difference between Enabled and Active?
--jump_force.Active = true
end
local function onTouch(object)
--print("К блоку прикоснулся "..object.Name)
if object.Name == "Handle" then
sandblock_health = sandblock_health - 1
print(sandblock_health)
if sandblock_health < 1 then
local sandblock_drop1 = Instance.new("Part", workspace)
sandblock_drop1.Size = Vector3.new(2,2,2)
sandblock_drop1.Position = sandblock.Position + Vector3.new(0,5,-1)
blockJump(sandblock_drop1)
sandblock_drop1.Material = "Metal"
sandblock_drop1.BrickColor = BrickColor.new("Gold")
sandblock_drop1.Name = "Gold"
print("Вы добыли "..sandblock_drop1.Name)
sandblock:Destroy()
end
end
end
sandblock.Touched:Connect(onTouch)
Solved it.
The product of workspace's gravity and part's mass is much higher than 1000 in my Force vector.
Code below works as expected:
jump_force.Force = Vector3.new(10, game.Workspace.Gravity * object.Mass * 1.35, -10)
jump_force.Enabled = true
wait(0.4)
jump_force.Enabled = false
It seems like the issue is that when you made the onTouch function, you had a parameter: object. However when you called the function on a player touching the part, you put no parameter: sandblock.Touched:Connect(onTouch). To fix this, do: sandblock.Touched:Connect(onTouch(<object_parameter>))

Corona Sdk - Is there a way to call and group:insert() an object from another lua file?

As stated in the title I would like to not only call an object from an external Lua file, but I would also like to group:insert() this object into my Menu page with the properties given to it in the external lua file. Is this possible and/or efficient? I would just really like to make sure data isn't repeated through out my project.
EDIT
Here's my code so far:
The group:insert() function is throwing me an error stating it was expecting a table and that I might have been trying to call a function in which case i should use ":" instead of "."
This is menu.lua:
local storyboard = require( "storyboard" )
local scene = storyboard.newScene()
local widget = require "widget"
local m = require ("myData")
local menuFunction = require("menuFunction")
local menuSwipe
-- =======================
-- menuSwipe()
-- =======================
menuSwipe = function(self, event)
local phase = event.phase
local touchID = event.id
if(phase == "began") then
elseif(phase == "moved") then
elseif(phase == "ended" or phase == "cancelled") then
if(m.menuActivator > 0) then
menuDown(m.invisiBar, event)
else
--m.layerInfo = layers
transition.to( menuFunction.menuBar, { x = menuFunction.menuBar.x, y = 0, time = 200 } )
--transition.to( layers, { x = menuFunction.menuBar.x, y = h, time = 100 } )
m.invisiBar = display.newRect( 0,0,w,25,6)
m.invisiBar.alpha = 0
m.menuActivator = 1
end
end
end
-- ++++++++++++++++++++++
-- menuDown()
-- ++++++++++++++++++++++
function menuDown(self, event)
local phase = event.phase
local touchID = event.id
if(phase == "began") then
elseif(phase == "moved") then
elseif(phase == "ended" or phase == "cancelled") then
if(m.menuActivator == 1) then
transition.to( menuFunction.menuBar, { x = m.menuInfo.x, y = h*.964, time = 200 } )
--transition.to( group, { x = 0, y = 0, time = 10 } )
m.menuActivator = 0
end
end
end
function scene:createScene( event )
local group = self.view
group:insert( menuFunction.menuBar ) -- *** ERROR occurs here
end
function scene:enterScene( event )
local group = self.view
end
function scene:exitScene( event )
local group = self.view
end
function scene:destroyScene( event )
local group = self.view
end
scene:addEventListener( "createScene", scene )
scene:addEventListener( "enterScene", scene )
scene:addEventListener( "exitScene", scene )
scene:addEventListener( "destroyScene", scene )
return scene
This is menuFunction.lua:
local m = require("myData")
local menu = require ("menu")
local w = display.contentWidth
local h = display.contentHeight
local menuFunction = {}
--menuBar
menuFunction.menuBar = display.newImage( "images/menuBar1.png")
menuFunction.menuBar.x = w*(1/2)
menuFunction.menuBar.y = h*1.465
menuFunction.menuBar.height = h
menuFunction.menuBar:setReferencePoint(display.TopLeftReferencePoint)
menuFunction.menuBar.touch = menu.menuSwipe
menuFunction.menuBar:addEventListener("touch", menuFunction.menuBar)
return menuFunction
This is the exact error message:
ERROR: table expected. If this is a function call, you might have used '.' instead of ':'
message**
Does this happen every time this code is called, or does it by any chance work the first time and then crashes? In your case, code could work the first time you enter the scene, but the second time you do, it may crash [if you remove scenes in between].
When you do a 'require' of a file, its contents are executed and returned value is saved in the global packages table. When you require the same file again, the returned value is taken from the global packages table instead, the code is not executed again.
So if you by any chance require this file in one spot of your app, and then call :removeSelf() and nil the reference of the menuBar, the display object will be removed and its reference will cease to exist, and calling the require again, will not recreate the object. Fully removing a scene will also remove the display objects.
So what you wanted to achieve is very sensible [contrary to what #Schollii says], but your "module" should allow creation of multiple objects if you want to get rid of them during runtime.
I'm not going to correct your code, just a simple example of how you can achieve this:
-- menu.lua
local menuCreator = {}
menuCreator.newMenu = function(params)
local menu = display.newGroup()
-- create your menu here
return menu
end
return menuCreator
Now anytime you do:
local menuCreator = require("menu.lua")
you will be able to call:
local menu = menuCreator.newMenu(someParams)
and get yourself a nice new menu wherever you need.
If it's not shown all the time on screen, it may be better to create a new one whenever you need it, and then remove it from the memory.
There are several issues with this, and none of them seem related to your error but fixing them will either also fix the error or make the cause of the error more obvious. Please fix following and update:
Although Lua allows it, don't use circular includes, where A includes B which includes A. Instead have menu require menuFunction and then call a creation function in menuFuntion:
-- menuFunction.lua
local m = require("myData")
-- require("menu") -- BAD! :)
local w = display.contentWidth
local h = display.contentHeight
local menuBar = display.newImage( "images/menuBar1.png")
menuBar.x = w*(1/2)
menuBar.y = h*1.465
menuBar.height = h
menuBar:setReferencePoint(display.TopLeftReferencePoint)
local menuFunction = { menuBar = menuBar }
function createMenuBar(menuSwipe)
menuFunction.menuBar.touch = menuSwipe
menuFunction.menuBar:addEventListener("touch", menuFunction.menuBar)
return menuFunction
end
-- menu.lua
function createScene(event)
local mf = require('menuFunction')
mfFunction = mf.createMenuBar(menuSwipe)
group:insert(menuFunction.menuBar)
end
Secondly out of the four calls to group:insert() the first 3 refer to objects that are not shown in the code and don't see relevant to problem, they should be removed or if you think relevant, comment why their code now shown, or show their code.

How do touch functions trigger correctly when used in a scroll group (corona)?

Touch Functions in a Scroll Group
I am attempting to add touch event listeners to objects that are placed in a scroll group. The scroll part is working fine, but the "ended" part of the touch function never registers.
I have seen that others have had this problem, but their solutions never fixed my problem - I have not though seen any using tables. In my code below it implements the code that fixed other people's problems.
I have tried re-organizing everything in different orders but that did not seem to change anything.
local widget = require("widget")
local scrollView = widget.newScrollView
{
left = 100,
top = 200,
width = 900,
height = 500,
maskFile = "white.png"
scrollWidth = 2000,
scrollHeight = 400,
hideBackground = true,
friction = 0.9 --0 is slowest
}
scrollView.x = 0
scrollView.y = H/2 - scrollView.height/2
The scroll screen above works fine...
local page = {}
page[1] = {exists = true}
page[2] = {exists = true}
page[3] = {exists = true}
page[4] = {exists = true}
page[5] = {exists = true}
page[6] = {exists = true}
page[7] = {exists = true}
page[8] = {exists = true}
page[9] = {exists = false}
page[10] = {exists = false}
Above I created a table.
for i = 1,#page do
if page[i].exists == true then
page[i].img = display.newImage("images/"..myScene..i..".png") --makes the different page link images
else
page[i].img = display.newImage("images/coming.png")
end
page[i].img:setReferencePoint( display.CenterReferencePoint)
page[i].img.x = (W+(i*2*W))/9 - 2*W/8 + 50
page[i].img.y = scrollView.height/4+20
if i > #page/2 then
page[i].img.x = (W+((i-#page/2)*2*W))/9 - 2*W/8 + 50
page[i].img.y = page[i].img.y + scrollView.height/2-20
end
local img = page[i].img
I rename it as a local variable because touch functions do not like [ ]
scrollView:insert(img)
group:insert(scrollView)
function img:touch(e)
if e.phase == "began" then
display.getCurrentStage():setFocus( img )
img.isFocus = true
elseif e.phase == "moved" then
local dx = math.abs( e.x - e.xStart )
local dy = math.abs( e.y - e.yStart )
if dx > 10 or dy > 10 then
scrollView:takeFocus( event )
end
The above part is what supposedly fixes this problem for others..
It checks if the x- or y-transition is more than 10 put the focus to my scrollview
elseif e.phase == "ended" then --it never gets to this part...
if page[i].exists == true then
storyboard.gotoScene(myScene..i)
else
audio.play(soon)
end
end
end
img:addEventListener("touch")
end
In your img:touch(e) function, you need to add "return true" right before the last end ... like below. Also, you can remove the extra code in the function which is not necessary ( setFocus (img) and img.isFocus = true ). I've found that that code does not perform well on Android devices.
Use the code below instead and it should work.
function img:touch(e)
if e.phase == "began" then
-- do something here
elseif e.phase == "moved" then
local dx = math.abs( e.x - e.xStart )
local dy = math.abs( e.y - e.yStart )
if dx > 10 or dy > 10 then
scrollView:takeFocus( event )
end
elseif e.phase == "ended" then
if page[i].exists == true then
storyboard.gotoScene(myScene..i)
else
audio.play(soon)
end
end
return true
end

Corona SDK - Pop Up Window (with Director Class)

I am new to game development and I am trying to create a simply GUI framework for my current project. I am currently using the Director Class 1.4 for my scene management. I have got my project o change scenes, but now I want to create a pop up window. I just want the pop up window to show up over the current scene I'm on. Below is the code for my main.lua and menu.lua (my initial scene). If anyone could help me out, I would really appreciate it. Please try to be as specific as possible, because I am very new to Corona and programming in general.
main.lua
_W = display.contentWidth
_H = display.contentHeight
local director = require ("director");
local mainGroup = display.newGroup();
local function main()
mainGroup:insert(director.directorView);
director:changeScene("menu");
return true;
end
main();
menu.lua
module(..., package.seeall)
function new()
local localGroup = display.newGroup();
local bg = display.newImage("Images/background1.PNG");
local myText = display.newText("Merchant", 0, 0, native.systemFont, 24)
myText:setTextColor(255, 255, 255)
myText:setReferencePoint(display.CenterReferencePoint);
myText.x = _W/2; myText.y = _H/2;
local hero_btn = display.newImage("Images/weaponcraft.PNG", 25, 25);
hero_btn:setReferencePoint(display.BottomLeftReferencePoint);
hero_btn.x = 252; hero_btn.y = 475;
hero_btn.scene = "heroMain";
local craft_btn = display.newImage("Images/smithing.PNG", 25, 25);
craft_btn:setReferencePoint(display.BottomLeftReferencePoint);
craft_btn.x = 7; craft_btn.y = 475;
craft_btn.scene = "craftMain";
local inventory_btn = display.newImage("Images/inventory1.png");
inventory_btn:setReferencePoint(display.CenterReferencePoint);
inventory_btn.x = _W/2; inventory_btn.y = 430;
--inventory_btn.scene = "inventory";
function changeScene(e)
if(e.phase == "ended") then
director:changeScene(e.target.scene);
end
end
localGroup:insert(bg);
localGroup:insert(hero_btn);
localGroup:insert(craft_btn);
hero_btn:addEventListener("touch", changeScene);
craft_btn:addEventListener("touch", changeScene);
return localGroup;
end
You can use the native.showAlert function. This shows a popup dialog box.
Something like this:
local function onComplete( event )
local action = event.action
if "clicked" == event.action then
if 1 == event.index then
end
end
local alert = native.showAlert( "You are in scene1!", "Congratulations!", { "OK" }, onComplete )
This show a dialog box with a "You are in scene1!" title, "Congratulations!" subtitle, and a "OK" button that closes the dialog box when you click(or tap) it.
Put these code in the front of your scene, and change the native.showAlert properties to the words you want.
You can create your custom pop up and can handle it by your own I am putting the sample code.
--function to create a dialog to be shown on the game over
local function gameOverAlertScreen()
--Display item used in the popup screen
local alertBox , restartBtn, levelBtn, soundOnOffSwitch, quitOnOffSwitch, imageSheetSoundOnOff, imageSheetQuitOnOff
--initial constans used for positioning the display items
local startTX = -400
local startTY = halfH
local btnInitailY = halfH -50
local btnMargin = 10
--cancel the game pausse timer
if(gameTimer_main) then
timer.cancel(gameTimer_main)
gameTimer_main = nil
end
local optionSoundSheet =
{
-- The params below are required
width = 51,height = 51,numFrames = 2,-- The params below are optional; used for dynamic resolution support
sheetContentWidth = 102, -- width of original 1x size of entire sheet
sheetContentHeight = 51 -- height of original 1x size of entire sheet
}
local optionQuitSheet =
{
-- The params below are required
width = 51,height = 51,numFrames = 2,-- The params below are optional; used for dynamic resolution support
sheetContentWidth = 102, -- width of original 1x size of entire sheet
sheetContentHeight = 51 -- height of original 1x size of entire sheet
}
isFirstTime=true
--pauseScreen()
dialog=true
alertBox = display.newImage("image/popup_dialog.png")
alertBox.x = halfW; alertBox.y = halfH
alertBox:setReferencePoint(display.CenterReferencePoint)
--creating the restart button fot the popup dialog
restartBtn = widget.newButton{
defaultFile="image/replay_btn.png",overFile = "image/replay_btn_hover.png",
isEnable=true,onRelease = onReplayBtnGameOverRelease -- event listener function
}
restartBtn.x = halfW
restartBtn.y = btnInitailY
--creating the level button
levelBtn = widget.newButton{
defaultFile="image/menu.png",overFile = "image/menu_hover.png",
isEnable=true, onRelease = onLevelBtnGameOverRelease -- event listener function
}
levelBtn.x = halfW
levelBtn.y = restartBtn.y + restartBtn.height + btnMargin
--creating the sound on off switch
imageSheetSoundOnOff = graphics.newImageSheet( "image/sound.png", optionSoundSheet )
soundOnOffSwitch = widget.newSwitch
{
left = screenW * 0.18,top = screenH * 0.73, style = "checkbox", sheet = imageSheetSoundOnOff,
initialSwitchState = soundOn,frameOff = "2",frameOn = "1",onRelease = onSoundButtonClicked, onPress = onSoundButtonClicked,
}
--creating the quit on off switch
imageSheetQuitOnOff = graphics.newImageSheet( "image/vibration.png", optionQuitSheet )
quitOnOffSwitch = widget.newSwitch
{
left = screenW * 0.7,top = screenH * 0.735,style = "checkbox",sheet = imageSheetQuitOnOff,onPress = onViberationButtonClicked,
initialSwitchState = vibrationOn,frameOff = "2",frameOn = "1",
}
--soundOnOffSwitch:setState({ isOn = soundOn })
--quitOnOffSwitch:setState({ isOn = vibrationOn})
--create/position logo/title image on upper-half of the screen
local titleLogo = display.newImageRect( "image/gameover.png",144,30)
titleLogo:setReferencePoint( display.CenterReferencePoint )
titleLogo.x = halfW
titleLogo.y = btnInitailY - 65
if popupGameOverGroup == nil then
popupGameOverGroup = display.newGroup()
end
-- inserting the buttons and the alert dialog to the popup group
popupGameOverGroup:insert(alertBox)
popupGameOverGroup:insert(restartBtn)
popupGameOverGroup:insert(levelBtn)
popupGameOverGroup:insert(soundOnOffSwitch)
popupGameOverGroup:insert(quitOnOffSwitch)
popupGameOverGroup:insert(titleLogo)
transition.from(popupGameOverGroup, {time =1000,x=startTX,y=titleLogo.y,xScale = 1, yScale = 1,
transition = easing.inOutExpo})
localGroup:insert(popupGameOverGroup)
showAdd()
end

Resources