Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
One touch changing all objects of the same type — Gideros Forum

One touch changing all objects of the same type

ricvieiraricvieira Member
edited October 2013 in General questions
Hi all, Im new to gideros, been trying it out, Im doing a test where I create several sprites of the type ghost in main:
for i = 1, 10 do
	ghost = ghost.new(i)		
	self:addChild(ghost)
	end
Now when I touch one of the sprites, it changes a global variable in ghost class to all the ghost type objects in the onMouseDown function in ghost, heres the ghost class:
ghost = gideros.class(Sprite)
 
striked = false
 
local frameList = {
	getImgBase().."ghost_1.png",
	getImgBase().."ghost_2.png"
	}
 
function ghost:init(id)
print("init id: ", id)
	self.id = id
 
	strikedImg = Bitmap.new(Texture.new(getImgBase().."rip-32x32.png"))
 
	-- create a Bitmap for each frame
	self.frames = {}
	for i = 1, #frameList do
		self.frames[i] = Bitmap.new(Texture.new(frameList[i]))
	end
 
	self.nframes = #frameList
 
	-- add first Bitmap as a child
	self.frame = 1
	self:addChild(self.frames[1])
 
	-- subframe is used to adjust the speed of animation
	self.subframe = 0
 
 
	-- set initial position
	self:setPosition(getAppWidth() , math.random(800) + 40)
	self:setScale(2)
 
 
print("Position X : Y: ", self:getPosition())
	-- set the speed of the bird
	self.speedy = math.random(-500, 500) / 1000
	self.speedx = math.random(2000, 4000) / 1000
 
	self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)	
 
	self:addEventListener(Event.MOUSE_DOWN, self.onMouseDown, self)
end
 
function ghost:onEnterFrame()
	self.subframe = self.subframe + 1	
 
	if not striked then
	-- for every 10 frames, we remove the old frame and add the new frame as a child
	if self.subframe > 10 then
 
		self:removeChild(self.frames[self.frame])
 
		self.frame = self.frame + 1
		if self.frame > self.nframes then
			self.frame = 1
		end
 
		self:addChild(self.frames[self.frame])
 
		self.subframe = 0
	end
	end
 
	-- get the current position
 
	local x,y = self:getPosition()
 
 
 
	-- change the position according to the speed
	x = x - self.speedx
	y = y + self.speedy
 
	-- if the bird is out of the screen, set new speed and position
	if x < -100 then 
		self.speedy = math.random(-500, 500) / 1000
		self.speedx = math.random(2000, 4000) / 1000
		x = getAppWidth() 
		y = math.random(800) + 40
	end
 
	-- set the new position
	self:setPosition(x, y)
end
 
 
function ghost:onMouseDown(event)
 
    if self:hitTestPoint(event.x, event.y) then
	print("ID: ", self.id, " :Striked: ", striked)
		if  not striked then
		striked = true	
        print("## Position: ", self:getPosition());
		self.speedx = 0
		self.speedy = 0
		self:removeChild(self.frames[self.frame])
		self:addChild(strikedImg)	
		end	
    end
end
this test is based on the bird example, so most of the code is from there
Can someone explain to me whats going on, please?

Comments

  • Hello, sorry I could not really understand, what exactly do you want to achieve, and what is happening that is not supposed to? :)
  • well, im creating several ghosts, and they move around the screen, and when i touch one, i change its image and it stops, but I want the rest of them to keep moving and keep with the original images in the framelist, to be touched also

    but whats happening is when i touch the first one, the "striked" boolean gets changed to all of them, so the animation in onEnterFrame() stops for all.

    I added this boolean, because without it, when I touched the first one, it changed the img, but if i touched it a second time, it would give an error, because the "self:removeChild(self.frames[self.frame])" is not a child anymore.

    basically Im wondering, how do I create several instances of one object (ghost in this case) and I can change each one state (booleans, or other wise) without affecting the rest of them
  • aha, then you could create self.striked property for each ghost to see if it was striked or not inside onMouseDown event
  • ok, its working now, what i did was, sending the strike has a parameter when creating the ghosts:
    function ghost:init(id, strike)
    and i set it 0:
    ghost = ghost.new(i, 0)
    so now it works, when i hit the 1st one, the others continue the animation, and i can hit those too

    only problem now, is that their getting removed when i hit the next one, they're just gone, one by one, i dont get it, since Im not removing them from the parent (scene)

    I would like to keep them all there, stopped, after i hit them. So I still dont get why or how they are connected, i create a new one each time:
    for i = 1, 10 do
    		ghost = ghost.new(i, 0)		
    		self:addChild(ghost)
    	end
  • ok, i think that the listener i add to ghost object:
    self:addEventListener(Event.MOUSE_DOWN, self.onMouseDown, self)
    is changing the state of all ghost objects created, when it should be only changing the one I touched, how can I set the listener to change only 1 instance of the object instead of all ?

    oh, and im sry about my english, its not my first language
  • dreiko65dreiko65 Member
    edited October 2013
    Delete your striked variable and in your init write self.sriked = false
    And in your mouse down whrite
    if self.striked == false then
    self.striked = true
    ...
    end
    Instead of
    if not striked then
    striked = true

  • @ricvieira,
    The best solution would be to make the Ghost a class by itself that creates and returns a new ghost, each ghost has it's own set of variables that tell you if it was stricken, it's other properties like x, y, size, (thinking more like PAC MAN type ghosts) the state, time to normalize, etc

    For an idea on how to do that, look at the Birds demo that comes with Gideros, the Birds class will give you an idea of how it can be done.

    Side-effect of this: the code looks small and more managable.
    twitter: @ozapps | http://www.oz-apps.com | http://howto.oz-apps.com | http://reviewme.oz-apps.com
    Author of Learn Lua for iOS Game Development from Apress ( http://www.apress.com/9781430246626 )
    Cool Vizify Profile at https://www.vizify.com/oz-apps
  • @dreiko65 already tried that, its the same result

    @OZApps Im using the birds demo code, this ghost class is the bird class with a few changes, the result is the same, everytime I touch 1 ghost/bird, it changes its image, but it gets removed everytime i click another ghost/bird

    but I got it to work, basically, the final image I want to set the ghost, I cant create it in the init :S I create the new bitmap in the onMouseDown, inside the if:
     function ghost:onMouseDown(event)
     
        if self:hitTestPoint(event.x, event.y) then
     
    		print("ID: ", self.id, " :Striked: ", self.striked)
    		if  self.striked == false then
    		strikedImg = Bitmap.new(Texture.new(getImgBase().."rip-32x32.png"))	
    		self.striked = true	
            print("## Position: ", self:getPosition());
    		self.speedx = 0
    		self.speedy = 0
     
     
    		self:addChild(strikedImg)
     
    		self:removeChild(self.frames[self.frame])	
     
    		end	
        end
    end
    tnx everyone :)

    Likes: ar2rsawseen

    +1 -1 (+1 / -0 )Share on Facebook
  • hi all, sry about the noobiness, just a quick question again, im really new to lua, if I do this:
    ghost = gideros.class(Sprite)
     
    striked = false
     
    function ghost:init(id)
     ..... --code here
    end
    the variable "striked" is not a variable of the class ghost right? its a global variable of my current scope ??

    to be a variable of the class, it needs to be created in the construtor(init) right? or can I do "ghost.striked = false" outside of init or any other function?

    again, sorry about the noob questions, my background is java, trying to understand lua and gideros

    tnx again
  • OZAppsOZApps Guru
    Accepted Answer
    @ricvieira,

    if you have a java background, then you should be fine to resolve this issue.

    when you use
    striked = false
    (BTW the english for the past tense of strike is not striked, but struck and the adjective stricken) you are setting this on the global variable called striked.

    However what you want (in Java terms) is something like
    me.striked = true
    if you still want to use the global variable rather than create a member variable for each object, then instead of making it true/false, just save the object to the variable
    striked = theObj
    then in the touch, check if the object that you clicked on is the same as the one you had touched (striked) earlier.

    Could you try in words to explain what exactly are you trying to do? What I understand is that you will have a couple of random ghosts on the screen and then you would tap them and replace them with the RIP graphic. if that is correct then (here's pseudo code)
    local arryGhosts = {}
    for i = 1, _numberGhosts do
       local ghost = newGhost() -- get a new ghost and the image is set to a random ghost
       local xR, yR = math.random(1, 100), math.random(1, 100) 
       ghost:setPosition(xR, yR) -- position them randomly on the screen
       ghost.struck = false -- initialise it as not striken
       arryGhosts[i] = ghost
    end
    In the touch function, you have the correct object
      if self.struck == false then
        --You need to either delete the image and replace it with the RIP
        -- or insert the RIP image and overlay it on this, what we are doing here
     
        local ripImage = Bitmap.new(Texture.new("rip.png"))
        self:insertChild(ripImage)
        self.struck = true
      end
    Hopefully this should work for you, you may have to position the images a little. If you have worked with other Lua game frameworks, then the point of difference here is that each Gideros Object is in itself a container, so you can add a child image to an existing image (Sprite) unlike others where you need to create a group and then add children to the group only.

    hope this helps you move ahead...
    twitter: @ozapps | http://www.oz-apps.com | http://howto.oz-apps.com | http://reviewme.oz-apps.com
    Author of Learn Lua for iOS Game Development from Apress ( http://www.apress.com/9781430246626 )
    Cool Vizify Profile at https://www.vizify.com/oz-apps
  • we also created an array to store the ghost, you can also check that if the object does not exist in the array, you do not have to add the rip image and when you do add the image (onTouch) remove that object from the array. If your app has scoring, you can check for the size of the table to know how many ghosts remain and how many were tapped.
    twitter: @ozapps | http://www.oz-apps.com | http://howto.oz-apps.com | http://reviewme.oz-apps.com
    Author of Learn Lua for iOS Game Development from Apress ( http://www.apress.com/9781430246626 )
    Cool Vizify Profile at https://www.vizify.com/oz-apps
  • tnx OZApps, that was exactly what I wanted to do, have a few random ghosts walking about and change the image when I clicked on them.

    tnx again :D
Sign In or Register to comment.