I am new to programming this question might sound very simple.
I have created a object as a module called box
box = {}
m={}
m.random = math.random
function box:new(x,y)
box.on=false
local box = display.newRect(0,0,100,100)
box:setFillColor(m.random(120,200),m.random(120,200),m.random(120,200))
box.x = x
box.y = y
box.type = "box"
return box
end
return box
in my main.lua I want to create as many boxes and ,like an adventure game how can I switch two of the boxes position,example I click on one of them,then it is selected,and simply I click on the other one and they change position with each other.
Thanks in advance
I don't know Corona, but the general logic for what you're doing is this:
Add an event handler which allows you to detect when a box is clicked.
Add some way of tracking the selected box.
When a box is clicked:
if no box is yet selected, select the current box
if another box was previously selected, swap with the current box
if the already-selected box was clicked, ignore (or toggle off selected)
General idea (not sure if this is valid Corona event handling, but should get you close):
box = {}
m={}
m.random = math.random
-- track the currently selected box
local selected = nil
function box:new(x,y)
box.on=false
local box = display.newRect(0,0,100,100)
box:setFillColor(m.random(120,200),m.random(120,200),m.random(120,200))
box.x = x
box.y = y
box.type = "box"
function box:touch(event)
if not selected then
-- nothing is selected yet; select this box
selected = self
-- TODO: change this box in some way to visually indicate that it's selected
elseif selected == self then
-- we were clicked on a second time; we should probably clear the selection
selected = nil
-- TODO: remove visual indication of selection
else
-- swap positions with the previous selected box, then clear the selection
self.x, self.y, selected.x, selected.y
= selected.x, selected.y, self.x, self.y
selected = nil
end
end
return box
end
Related
I'm super frustrated with this.
first for you to understand my code - My goal here is for the user to get randomly selected word appear to them in a way that every letter sits inside of a box.
Then if the user clicks on a button called "Pick a word", another word will be selected and the correct number of boxes will appear.
I have an array of words like this:
var word_group_1 = ["abolsh", "absorbent", "betrayal", "frutish", "commensurate", "eonfident", "zite"]
I'm using this function to select a random word from that array then splice it.. works perfectly:
function random_word_genereator() {
random = randomNumber(0, word_group_1.length);
//putting the chosen word from array in the chosen word variable
chosen_word = word_group_1[random]
//after we used the chosen word were removing it from the away
word_group_1.splice(random, 1)
//splitting the chosen word into an array
chosen_word_letters_arry = chosen_word.split("")
}
in a button click of "pick a word"- I'm creating 5 instances of a Movieclip I have in my library (just a blue box to put text in it) with text in at like this:
function create_boxes(e)
{
//to know which word has been displayed to the user//
old_word=chosen_word
random_word_genereator()
for (i=0;i<chosen_word.length;i++){
cell_boxes = new lib.cell_box();
stage.addChild(cell_boxes)
cell_boxes.name="cell_box"+i;
cell_boxes.x=(xlocation * i) + 50
cell_boxes.y = 80;
output = new createjs.Text();
cell_boxes.addChild(output)
output.text=chosen_word_letters_arry[i]
}
everything works fine on the first click As You Can View Here.
The word being selected and displayed on the stage
my problem is when I'm clicking Again on the button "pick a word"
its not deleting the correct number of boxes.
I'm putting visible false to the boxes which holds the "Old word" (the one I need to delete)
but As you can se here After I click again its getting messed up.
sometimes its's working, switches from 12 letter word, to a 4 one.
but it should be luck. I'm dying to get this to WORK! its for my school project.
Please help me!
Easy answer that will plug and play into your code:
js
...
//to know wichh word has been displayed to the user//
old_word=chosen_word
random_word_genereator()
for (i = 0; i < stage.numChildren; i++) // Loop through all children of the stage
if (stage.getChildAt(i) is lib.cell_box) // Checks if the child is a lib.cell_box
stage.removeChildAt(i--); // Removes child from stage and decrements i
for (i=0;i<chosen_word.length;i++){
...
Original answer (cleaner code, some restructuring):
It's best to break this kind of logic down into steps.
var boxes:MovieClip = new MovieClip();
boxes.y = 80;
addChild(boxes);
...
function createBoxes(word:String):void {
// Remove boxes first
while (boxes.numChildren > 0)
boxes.removeChildAt(0);
// Add boxes
for each(var c:String in word.split("")) {
var box:Box = new Box(c);
box.x = boxes.width + 50;
boxes.addChild(box);
}
}
Then set the text inside a Box class.
I have this script in a brick:
local giver = 1
function onClicked()
game.Players.[I NEED THE PLAYER NAME HERE].leaderstats.Clicks.Value = game.Players.[I NEED THE PLAYER NAME HERE].leaderstats.Clicks.Value + giver
end
script.Parent.ClickDetector.MouseClick:connect(onClicked)
Now I need to somehow get the player's name that clicked it and put it where I need to.
The ClickDetectors's MouseClick event have the "Clicking Player" as parameter, so you can do it like this:
local giver = 1
function onClicked(Player)
Player.leaderstats.Clicks.Value = Player.leaderstats.Clicks.Value + giver
end
script.Parent.ClickDetector.MouseClick:connect(onClicked)
However, this requires the FilteringEnabled to be set to false (not recomended).
To solve this, make a LocalScript in the brick with the code:
script.Parent.ClickDetector.MouseClick:connect(function(Player)
game.ReplicatedStorage:WaitForChild("BrickClick"):InvokeServer(script.Parent)
end)
And in a Script placed in the ServerScriptService put:
local Listener = game.ReplicatedStorage:FindFirstChild("BrickClick")
if Listener == nil then
Listener = Instance.new("RemoteFunction")
Listener.Name = "BrickClick"
Listener.Parent = game.ReplicatedStorage
end
function Listener.OnServerInvoke(Player,Brick)
Player.leaderstats.Clicks.Value = Player.leaderstats.Clicks.Value + 1
end
I won't point you to the wiki page for further reading, even thought it contains a bit of what you need, it contains too little information.
The ClickDetector's MouseClick info, the guide about FilteringEnabled and the guide about RemoteFunctions are better.
Try this!
script.Parent.MouseClick:Connect(function(Player)
-- Kill The Player
-- The parameter is referring to game.Players So if you want to do a kill button use .Character
Player.Character:BreakJoints()
-- Change The Color To Red (Other details)
script.Parent.Parent.BrickColor = BrickColor.new("Really red")
script.Parent.MaxActivationDistance = 0
-- Wait 4 Secs
wait(5)
-- Change The Color To Green
script.Parent.Parent.BrickColor = BrickColor.new("Lime green")
script.Parent.MaxActivationDistance = 50
end)
In this particular code, I have 3 boxes that currently show up on the screen. The boxes in the center of the screen are the ones I want to have treated as the characters. The box on the top of the screen randomly generates an image of one of the characters, in this case the red box or the blue box. For example, if at the top the red box was selected as the randomly generated image, I would want the player to tap the red box that would be treated as a character. If the person tapped the correct box as a result of the box on the top, I would want the box at the top to change again, therefore creating a cycle between the characters and the box at the top. If the player taps the wrong box, I would want the game to end. What am I doing wrong, and more importantly how can I fix it? Here is my code:
local imageFiles = {"bluebox.png", "redbox.png"}
local imageFile = imageFiles[math.random(2)]
local randomImage = display.newImage(imageFile, 40, 40)
local button1 = display.newImage("redbox.png")
button1.x = centerX
button1.y = centerY
group:insert(button1)
local button2 = display.newImage("bluebox.png")
button2.x = centerX
button2.y = centerY - 100
group:insert(button2)
local function randomize(event)
if button2 == randomImage then
(insert code here)
end
end
local function generate(event)
if button2 ~= imageFile then
storyboard.gotoScene ("restartEasy")
elseif button2 == imageFile then
(insert code here)
end
end
button1:addEventListener("tap", randomize)
button2:addEventListener("tap", generate)
if button2 ~= imageFile then
elseif button2 == imageFile then
You're comparing images with strings. This will never work. But let's ignore that for now.
While I'm not familiar with Corona, I believe randomImage will never equal either button1 or button2 because it's a separate image (with independent coordinates and/or dimensions).
I'd replace your random selection code (the first three lines) with the following lines right after the second call to group:insert():
local one_or_two = math.random(2)
local endGameButton, shuffleButton
if one_or_two == 1 the
endGameButton, shuffleButton = button1, button2
else
endGameButton, shuffleButton = button2, button1
end
At the end I'd replace your two addEventListener lines with:
shuffleButton:addEventListener("tap", randomize)
endGameButton:addEventListener("tap", generate)
And then I'd remove all the conditions (if buttonX == whatever) from your functions because they are no longer needed.
In other words: instead of testing which button is the random one every time something is clicked (as you're doing now), we assign each button a meaning.
Ok so in order to have the top button correspond with the characters, I needed to use the png files of the images as opposed to using a variable defined by those png images. in this case instead of using
if button2 = randomimage
use
if imageFile = "nameofimagefile.png"
To simplify my problem:
I have the following loop:
local arguments =
{
{ text="foo", x=0, y=0, font=native.systemFont, size=32 },
{ text="bar", x=0, y=0, font=native.systemFont, size=32 }
}
for _,item in ipairs( arguments ) do
local text = display.newText( item.text, item.x, item.y, item.font, item.size )
text:setFillColor( 1 ) -- white
text.x = 50 + 50 * i
text.y = 100
i = i + 1
text:addEventListener( "touch", onTouch )
end
The function onTouch is defined previously and it responds by allowing the user to drag the object around the screen.
The function works fine. However, I would like to be able to access the text of the object the user clicks in from within the onTouch function. For example, if a user clicks on text that contains the string "foo", I would be able to access this string and work with it. Is this possible? I am using Corona Starter (the free one) in case that is relevant.
Thanks in advance.
In short:
Yes, it is possible you should simply declare a variable with a string on the object as such:
text.string = "foo"
And then in your onTouch function you can reach it through
event.target.string
I am doing my first game in Corona SDK and I've been stuck for a while. I am trying to move two display objects, every object has a position property, after every move I update the position property, the problem is if I click again the object it don't show me the updated position.
I created my objects this way:
while count<=16 do
button[count] = display.newImage(count..".png")
button[count].position = count
count = count+1
end
And in my touch handler listener I want to move object 1 and 2:
local c = 1
while c <= 2 do
--HERE I DO THE MOVEMENT, THIS WORKS
transition.to( button[c], { time=200, delta=true, x=100 } )
--HERE I CHANGE THE POSITION
button[c].position = 1000
c = c+1
end
Then if I click again any of the 2 objects the position property was not updated! Thank you!