On PC, my game compiles fine and runs properly, but as soon as I build it for Android I get this weird error code:
bad argument #1 to 'random' (interval is empty)
The line of code this error code comes from is:
local word = wordsList[math.random(#wordsList)]
The whole code Segement:
local lineCount = 1
local wordsList = {}
local wordAccepted = true
local file = io.open( system.pathForFile( "words.txt", system.ResourceDirectory ), "r" ) --Open the words file from the resource folder
for line in file:lines() do
if #line > 1 and #line <= 10 then
for i = 1,#line do
if string.byte(line,i)<65 or string.byte(line,i)>90 and string.byte(line,i)<97 or string.byte(line,i)>122 then
wordAccepted = false
end
end
if wordAccepted == true then
print ("accepted "..line)
wordsList[lineCount]=string.upper(line)
lineCount = lineCount + 1
else
print("rejected "..line)
end
end
end
io.close( file )
file = nil
local word = wordsList[math.random(#wordsList)]
The error message bad argument #1 to 'random' (interval is empty) means that you are trying to pass zero to math.random().
In other words, your wordsList array is empty.
Related
I am newbie on Matlab, and i am trying to plot the data from the txt file written by an android application ( https://play.google.com/store/apps/details?id=com.lul.accelerometer&hl=it)
I cleaned the file and i have only the 4 columns with values separated by the " "
X Y Z time_from_previous_sample(ms)
e.g.
-1.413 6.572 6.975 0
-1.2 6.505 7.229 5
-1.047 6.341 7.26 5
-1.024 6.305 7.295 5
-1.154 6.318 7.247 5
-1.118 6.444 7.104 5
-1.049 6.225 7.173 5
-1.098 6.063 6.939 5
-0.769 6.53 6.903 5
fileID = fopen ('provamatlav.txt');
C = textscan (fileID, '%s %s %s %s');
fclose (fileID);
>> celldisp (C)`
After importing the data i created three new variables
X = C {1};
Y = C {2};
Z= C {3}
The error occur when i try to convert the cell array X into an ordinary array
xx = cell2mat('X')
the error is the following
Cell contents reference from a non-cell array object.
Error in cell2mat (line 36)
if isnumeric(c{1}) || ischar(c{1}) || islogical(c{1}) || isstruct(c{1})
Analyzing the code:
% Copyright 1984-2010 The MathWorks, Inc.
% Error out if there is no input argument
if nargin==0
error(message('MATLAB:cell2mat:NoInputs'));
end
% short circuit for simplest case
elements = numel(c);
if elements == 0
m = [];
return
end
if elements == 1
if isnumeric(c{1}) || ischar(c{1}) || islogical(c{1}) || isstruct(c{1})
m = c{1};
return
end
end
% Error out if cell array contains mixed data types
cellclass = class(c{1});
ciscellclass = cellfun('isclass',c,cellclass);
if ~all(ciscellclass(:))
error(message('MATLAB:cell2mat:MixedDataTypes'));
end
What did i do wrong?
After solved this, what would be the next step to plot the X Y Z data in the same window, but in separate graphs?
Thank you so much!
When using cell2mat, you do not need to use quotes when giving the input argument. The quotes are the reason for the error you got. Generally speaking, you would call it like so:
xx = cell2mat(X)
But you will run into a different error with this in your code, because the cell elements in your case are strings (cell2mat expects numerical values as the output). So you need to convert them to numerical format, e.g. by using this:
xx=cellfun(#str2num,X)
Please try the code line above. It worked ok in my small test case.
I have two scenes: the game.lua file and a restart.lua file. Once the game.lua file ends it transfers to the restart screen. On the restart screen I have 'your current score:' and 'your highscore:' along with the values. However, the values don't update themselves after each subsequent restart. The highscore won't update until I restart the app and the current score won't reset to zero until I restart the app.
So for example: i)Say my current highscore is 21. I play the game once and achieve a new highscore: 23. My current score goes to 23 but my highscore is still 21 (until I restart the app).
ii)I play again(without restarting the app) and get a score of 5. The restart screen still shows 23 as my current score.
So basically once I play the game once, all scores are stuck.
In the app I am using the ego module to save highscore(as that would have to be permanent) and have my current score set as global.
Here is the code in my game scene:
highscore = loadFile("score.txt")--the ego module loads this file for me
score = 0--kept global to use in restart screen
local scoreText = display.newText(score,W,0)--create text
sceneGroup:insert(scoreText)
local function checkForFile()
if highscore == "empty" then
highscore = 0--gives highscore number if file is empty
saveFile("score.txt", highscore)--saves new highscore
end
end
checkForFile()
local function onObjectTouch(event)
if(event.phase == "began") then
score = score+1--increment score on touch
scoreText.text = score
if score>tonumber(highscore) then
saveFile("score.txt",score)--if new highscore, save score as highscore
end
vertical = -150--set ball's velocity
ball:setLinearVelocity(0,vertical)
print(ball.x .. " " .. event.x)
end
end
Runtime:addEventListener("touch", onObjectTouch)
And here is the code in my restart scene
------------highScore Text----------------
myscore = loadFile("score.txt")--load highscore file
local highscoretext = display.newText( "Your high score:"..myscore, 0, 0, native.systemFontBold, 20 )
highscoretext:setFillColor(1.00, .502, .165)
--center the title
highscoretext.x, highscoretext.y = display.contentWidth/2, 200
--insert into scenegroup
sceneGroup:insert( highscoretext )
--------------yourscore----------------
local yourscoretext = display.newText( "Your score:"..score, 0, 0, native.systemFontBold, 20 )
yourscoretext:setFillColor(1.00, .502, .165)
--center the title
yourscoretext.x, yourscoretext.y = display.contentWidth/2, 230
--insert into scenegroup
sceneGroup:insert( yourscoretext )
Your code seems a little bit confusing because you are using score, highscore and myscore but lets try and fix this. I will explain the three methods briefly but we will only try out two of them:
Global Score and High Score variables
Game.lua file
Pass paremeters between the scenes
1. Global Score and High Score variables
This is the method that you are using now and I would not recommend to use global variables if you don't need to so let's skip this method and check out the other two.
2. Game.lua file
In this method we will use a designated game.lua file that will store all the data. Please read this blog post from Corona on how Modular Classes works in Lua:
https://coronalabs.com/blog/2011/09/29/tutorial-modular-classes-in-corona/
We will not use meta tables in this example but we'll create a game.lua file that we can call from any other lua or scene file in our Corona project. This will enable us to save the Score and High Score in only one place and also be able to save and load the High Score very easily. So let's create the game.lua file:
local game = {}
-- File path to the score file
local score_file_path = system.pathForFile( "score.txt", system.DocumentsDirectory )
local current_score = 0
local high_score = 0
-----------------------------
-- PRIVATE FUNCTIONS
-----------------------------
local function setHighScore()
if current_score > high_score then
high_score = current_score
end
end
local function saveHighScore()
-- Open the file handle
local file, errorString = io.open( score_file_path, "w" )
if not file then
-- Error occurred; output the cause
print( "File error: " .. errorString )
else
-- Write data to file
file:write( high_score )
-- Close the file handle
io.close( file )
print("High score saved!")
end
file = nil
end
local function loadHighScore()
-- Open the file handle
local file, errorString = io.open( score_file_path, "r" )
if not file then
-- Error occurred; output the cause
print( "File error: " .. errorString )
else
-- Read data from file
local contents = file:read( "*a" )
-- Set game.high_score as the content of the file
high_score = tonumber( contents )
print( "Loaded High Score: ", high_score )
-- Close the file handle
io.close( file )
end
file = nil
end
-----------------------------
-- PUBLIC FUNCTIONS
-----------------------------
function game.new()
end
-- *** NOTE ***
-- save() and load() doesn't check if the file exists!
function game.save()
saveHighScore()
end
function game.load()
loadHighScore()
end
function game.setScore( val )
current_score = val
setHighScore()
end
function game.addToScore( val )
current_score = current_score + val
print("Current score", current_score)
setHighScore()
end
function game.returnScore()
return current_score
end
function game.returnHighScore()
return high_score
end
return game
In your scene file call game.lua like this (at the top of the scene):
local game = require( "game" )
and you'll be able to call the different game methods when needed like this:
game.load()
print("Current Score: ", game.returnScore())
print("High Score: ", game.returnHighScore())
game.setScore( game.returnHighScore() + 5 )
game.save()
The code snippet above:
Loads the High Score from the file
Print out the Current Score
Print out the High Score
Sets the Current Score to the current High Score + 5
Saves the High Score back to the file
Because we set the Current Score to High Score + 5 we will see that change when we restart the Corona Simulator.
3. Pass paremeters between the scenes
When you are switching scene using composer.gotoScene you can also add parameters like this:
local options =
{
effect = "fade",
time = 400,
params =
{
score = 125
}
}
composer.gotoScene( "my_scene", options )
and access them like this in the called scene:
function scene:create( event )
local sceneGroup = self.view
print("scene:create(): Score: ", event.params.score )
end
-- "scene:show()"
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
print("scene:show(): Score: ", event.params.score )
end
Documentation about this method: https://coronalabs.com/blog/2012/04/27/scene-overlays-and-parameter-passing/
I want to be able to pass the value from a stepper widget in corona into a json file. So far I've got my stepper to display and increment and decrement and display the current value on screen. I've written a function to save the value to a file as json, but i'm having trouble calling that function. I want to be able to have other setting on screen which have their values save to json. Here the code I have to save the setting:
local function saveSettings (e)
-- body
print("testtesttest")
if (file) then
local content = file:read("*a")
else
settings = {}
settings.houses = StepperNo
file = io.open(path, "w")
local json_setting = json.encode(settings)
file:write(json_setting)
io.close(file)
end
end
and then the code to display the stepper:
local StepperNo = 1
local displayNoOfHouses = display.newText("Number of houses: "..StepperNo,180,135, native.systemFontBold,16)
local function onStepperPress( e )
if ("increment" == e.phase) then
StepperNo = StepperNo + 1
elseif ("decrement") == e.phase then
StepperNo = StepperNo - 1
end
displayNoOfHouses.text = "Number of houses: "..StepperNo
end
local HouseStepper = widget.newStepper {left = 100, top = 100, minimumValue = 0, maximumValue = 9, onPress = onStepperPress}
I dont know how to call the savesetting function after the stepper is pressed. I think I might have done this incorrectly or may be missing something obvious, I am very new to Lua...
There is a very simple to implement table saver and loader presented in this tutorial:
http://coronalabs.com/blog/2014/10/14/tutorial-saving-and-loading-lua-tables-with-json/
It uses JSON to encode a Lua table to save and when needed, read the JSON back in and decode it to a Lua table.
This function reads a file line by line and sets global variables to the values read accordingly. However, the problem is that this code works on the simulator 100% fine however once compiled and run on the android device it stops working. Through the use of displaying text I have located the error to be on the line of code: "mapObject[i].x = sum". The attribute .x is of type real and I've already confirmed that sum, numerator and denominator are all numerical data types. The app crashes on the first run through of the loop containing "mapObject[i].x = sum" so i = 1. 1 is within range of the array. Any help is appreciated, I just can't get my head around this. Here is the function code:
-- Read map from file
local function loadmap(mapnum)
local tempstring
local numerator
local denominator
local sum
local i
local path = system.pathForFile( "maps/map" .. mapnum .. ".txt", system.ResourceDirectory)
--Open the file
local fh = io.open( path, "r" )
if fh then
-- read the lines of data systematically.
mapName = fh:read( "*l" )
mapNPCS = fh:read( "*l" )
mapSpawnTimer = tonumber(fh:read( "*l" ))
mapSpawnMax = tonumber(fh:read( "*l" ))
mapSpawnMaxLocations = tonumber(fh:read( "*l" ))
mapObjectMax = tonumber(fh:read( "*l" ))
for i = 1, mapObjectMax do
tempstring = fh:read( "*l" )
mapObject[i] = display.newImage("graphics/" .. tempstring .. ".png")
-- Fractional mapping for all screen sizes
denominator = tonumber(fh:read( "*l" ))
numerator = tonumber(fh:read( "*l" ))
sum = (display.contentWidth / denominator) * numerator
mapObject[i].x = sum
denominator = tonumber(fh:read( "*l" ))
numerator = tonumber(fh:read( "*l" ))
sum = (display.contentHeight / denominator) * numerator
mapObject[i].y = sum
mapObject[i].myName = "object"
physics.addBody(mapObject[i], "kinematic", {density = 10.0, friction = 0.0})
end
for i = 1, mapSpawnMaxLocations do
mapSpawnX[i] = tonumber(fh:read( "*l" ))
mapSpawnY[i] = tonumber(fh:read( "*l" ))
end
io.close( fh )
end
end
here is the global variables that come with the code:
-- Map Data Variables
local mapName
local mapNPCS
local mapSpawnTimer
local mapSpawnMax
local mapSpawnMaxLocations
local mapObjectMax
local mapObject = {}
local mapSpawnX = {}
local mapSpawnY = {}
-- Map Npc Spawning
local mapNPC = {}
local maxMapNPCS = 30
local npcsSpawned
local spawnTimer = 0
Some things to try on physical device:
If you use sum = display.contentWidth does it work?
How about sum = 100?
Could it be that the denominator is 0? (although that shouldn't cause a crash, just an error)
Try replacing mapObject[i].x = sum by mapObject[i].x = 100, does it still crash?
could it be that mapObject[i] is not a valid display object, say if the path in mapObject[i] = display.newImage("graphics/" .. tempstring .. ".png") is not valid or if tempstring is empty? (although you'd think display.newImage('graphics/.png') should not cause any trouble)
I'm going to guess that:
mapObject[i] = display.newImage("graphics/" .. tempstring .. ".png")
is producing a file name that's invalid on the device. Device's are case sensitive, where as the simulator is not.
hey i am new to the Corona sdk world i want to learn how to spawn some objects and make them move across the screen i try everything and it never work i read the forum on spawning the right way and try it but still end up with a error in my code help this is my code
local mRandom = math.random
local mAbs = math.abs
local objects = {"rocket02" ,"rocket01","coin01"}
local function spawnObject()
local objIdx = mRandom(#objects)
local objName = objects[objIdx]
local object = display.newImage("image/object_"..objName..".png")
object.x = mRandom (screenLeft +30,screenRight-30)
object.y = screenTop
if objIdx < 4 then
object.type = "food"
else
object.type = "other"
end
end
Also can some one tell me how to make it move across the screen
Please help Thanks
here's the media file for you to take a look at
I'll show you a method. For that, I have rewritten your code as follows:
local mRandom = math.random
local objects = {"rocket02" ,"rocket01","coin01"}
local objectTag = 0
local object = {}
local function spawnObject()
objectTag = objectTag + 1
local objIdx = mRandom(#objects)
local objName = objects[objIdx]
object[objectTag] = display.newImage(objName..".png") -- see the difference here
object[objectTag].x = 30+mRandom(320)
object[objectTag].y = 200
object[objectTag].name = objectTag
print(objectTag)
end
timer.performWithDelay(1,spawnObject,3)
Here I've used a timer for displaying the object. You can also use for loop for the same purpose.
Here you can call any object with tag as object[objectTag].
For your information:
display.newImage(objName..".png")
--[[ will display object named rocket02.png or rocket01.png or coin01.png
placed in the same folder where your main.lua resides --]]
And
display.newImage("image/object_"..objName..".png")
--[[ will display object named object_rocket02.png or object_rocket01.png
or object_coin01.png placed in a folder named 'image'. And the folder
'image' should reside in the same folder where your main.lua is. --]]
And for moving your object from top to bottom, you can use:
either
function moveDown()
object[objectTag].y = object[objectTag].y + 10
--replace 'objectTag' in above line with desired number (ir., 1 or 2 or 3)
end
timer.performWithDelay(100,moveDown,-1)
or
transition.to(object[objectTag],{time=1000,y=480})
--[[ replace 'objectTag' in above line with desired number (ir., 1 or 2 or 3)
eg: transition.to(object[1],{time=1000,y=480}) --]]
Keep coding.............. :)