Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
Broadcast messages for custom events : how to? — Gideros Forum

Broadcast messages for custom events : how to?

MellsMells Guru
edited May 2012 in General questions
Hi community,

I am opening this thread to get some help (my previous thread was getting cluttered).

Do you know why isn't friend catching the message sent by enemy and how would you solve that?
-- main.lua
 
local mainGroup = Sprite.new()
stage:addChild(mainGroup)
 
-- ENEMY
local enemy = Enemy.new()
mainGroup:addChild(enemy)
enemy:setPosition(100, 50)
enemy:setColorTransform(1, 0, 0, 1)
 
-- FRIEND
local friend = Friend.new()
mainGroup:addChild(friend)
friend:setPosition(100, 600)
friend:setColorTransform(0, 1, 0, 1)
 
-- INTERACTIONS
-- ******************[ I want the friend to listen to the event ]*************************
friend:addEventListener("enemyIsClose", friend.enemyAlertFunction, friend)
-- ************************************************************************************
 
enemy:isClose()
-- classes.lua
 
-- CHAR
Char = Core.class(Shape)
function Char:init()		
	self:setFillStyle(Shape.SOLID, 0xFFFFFF)  
	self:beginPath()
	self:moveTo(0, 0)
	self:lineTo(500, 0)
	self:lineTo(500, 500)
	self:lineTo(0, 500)	
	self:closePath()
	self:endPath()	
end
 
-- ENEMY
Enemy = Core.class(Char)
function Enemy:isClose()
	local flag = true
	if (flag) then
		closerEvent = Event.new("enemyIsClose")   --with the specific keyword for the event.
		self:dispatchEvent(closerEvent)
		print ("Send message to Friend : Enemy is close")
	end
end
 
-- FRIEND
Friend = Core.class(Char)
function Friend:enemyAlertFunction(event)
    print("Get message from Enemy : Enemy is close!")
end
I can get "Send message to Friend : Enemy is close" to be printed but not "Get message from Enemy : Enemy is close!"

Why isn't friend catching the message sent by enemy?

Thank you for your help :)
twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps

Comments

  • alexzhengalexzheng Guru
    edited May 2012
    the dispatcher and the register are not the same object in your code.

    try

    enemy:addEventListener("enemyIsClose", friend.enemyAlertFunction, friend)
  • @alexzheng that works well but in this case the friend is enemy dependent, right?
    If the enemy is killed -> The friend won't be reacting to any other enemy.

    I would like the friend to be able to listen to messages sent by any enemy, dynamically created.
    So I thought I want to add the listener to the friend, and he would act on himself (run function).

    So I don't want the enemy to act on the friend, I want the friend to listen and act.
    Do you know how to do it?
    Or maybe I'm mistaking the purpose of events and listeners?
    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
  • alexzhengalexzheng Guru
    edited May 2012
    You have to register the listener on each enemy you created.

    I know what exactly you want is a broadcast event if available.
  • So are you suggesting that currently I can't achieve what I want? (listeners on friend, not enemy)

    Broadcast events
    I have made a research and found one of your suggestions for custom events :
    Suggestion for custom events.

    The discussion happened on december 2011 and @atilim said :

    great idea. I've added this to the todo list.
    I'd be interested to know if this is achievable or if I have been looking for something that is not currently possible :)
    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
  • @Mr. Mells, you can send a broadcast event, but for that you will have to intercept and manage it yourself. You can have a list of all the bojects that you want to send the broadcast message to and then using a loop, invoke that event / dispatch that message to them.

    There are several ways to do that, even if you do not have dispatch events.
    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
  • MellsMells Guru
    edited May 2012
    @OZApps,
    but for that you will have to intercept and manage it yourself.
    I really can't grasp the concept well : how can I intercept a broadcast event except from the object that dispatches the event himself (in my case, enemy)?
    I don't undestand how objects communicate? I can see how enemy can order friend to act, but that's all.

    Please take a look at that image below :
    image

    Case 1. Enemy (A) tells Friend (B) to Fight -> Achievable and I know how to do it

    Case 2. Enemy (A) tells Friend (B) that he is close. Friend (B) then decides himself that he should fight -> It seems that it is not achievable from what I could understand from the people that commented on my threads.

    Case 3. A middle man (C) checks the distance constantly between objects (A and B) and then informs and giver orders to friend (B) "Enemy (A) is close, You should Fight!" -> Is it what you are suggesting?
    But in that case it seems that "middle man" is doing everything himself, and he is not "intercepting" events....

    ... right?
    Sorry for asking again something that probably looks evident, but I was thinking that the ability to set up Case 2 would be simple and achievable.
    I thought that Case 2 was exactly what the purpose of "listening" was.
    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
  • bowerandybowerandy Guru
    edited May 2012
    @Mells, I apologize that I don't have time at the moment to understand exactly your predicament but I did read that you were looking for some form of broadcast events.

    A couple of weeks back @atilim helped me out by posting the following recursive event dispatch idea:
    -- save original stopPropagation function
    Event.__stopPropagation = Event.stopPropagation
     
    -- reimplement stopPropagation
    function Event:stopPropagation()
    	self.__isPropagationStopped = true
    	self:__stopPropagation()
    end
     
    function Event:isPropagationStopped()
    	return not not self.__isPropagationStopped
    end
     
    local function recursiveDispatchEvent(sprite, event)
    	for i=sprite:getNumChildren(),1,-1 do
    		recursiveDispatchEvent(sprite:getChildAt(i), event)
    	end
    	if not event:isPropagationStopped() then
    		sprite:dispatchEvent(event)
    	end
    end
    Maybe you could use something like this to broadcast events to all objects on your stage. Bear in mind that, because this is in Lua, it will be significantly slower than the broadcast events implemented by the system and therefore may not be suitable if you have a lot of objects on the stage. Of course you could segregate your objects into layers and only recursively dispatch within a single layer.

    The original thread is here:
    http://www.giderosmobile.com/forum/discussion/comment/5755

    Again, I apologise if this is not relevant to what you're looking for.

    Best regards
  • MellsMells Guru
    edited May 2012
    @bowerandy first of all thank you for your help.
    It seems a bit complex for my level, I will need time to understand if this is relevant to my problem or not :)
    By the way, I really like your multistroke gesture recognition system that enhanced the great work provided by @ar2rsawseen.

    In the meantime, I hope I can get other people to suggest a solution.


    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
  • JaviJavi Member
    edited May 2012
    Hi @Mells, instead of using "mainGroup" to store a list of enemies and friends, I think the best solution is to have two lists: enemies and friends.

    Maybe something like this?
    CharactersList = Core.class()
    (...)
    function CharactersList:broadcastMessage(event)
      -- (send event to all characters in the list)
    end
    function CharactersList:getNearest(character)
      -- (return the character in the list nearest to character.position and the distance)
    end
    (...)
     
     
    enemies = CharactersList.new()
    enemies:add(enemy_x)
    (...)
     
     
    friends = CharactersList.new()
    friends:add(friend_x)
    (...)
     
     
    -- (...loop to control the characters...)
    local enemy, distance = enemies:getNearest(friend)
    -- or: local friend, distance = friends:getNearest(enemy)
    if distance < x then
      -- send a message only to "friend"
      local friend_event = Event.new("ENEMY_CLOSE")
      friend_event.enemy = enemy
      friend_event.distance = distance
      friend:dispatchEvent(friend_event)
     
      -- send a message only to "enemy"
      local enemy_event = Event.new("FRIEND_CLOSE")
      enemy_event.friend = friend
      enemy_event.distance = distance
      enemy:dispatchEvent(enemy_event)
    end
    if (...)
      -- send a message to all active enemies...
      enemies:broadcastMessage(Event.new("STOP_ALL"))
    if (...)
    (...)
  • Thank you @Javi, that was very helpful.
    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
Sign In or Register to comment.