Any ImageSprite.Touched

Hi everyone!
There are 50 imagesprite in the program. When I group them, I can adjust the height (width. etc.) in a cycle, for example. But how can I query the touch of a group member? Do each member need a separate “Touched” command? I can’t use “when anyimage.touched” because “Component” is just a meaningless string.
Joseph

Usually you define global lists for separate sprite types
like bullets, targets, etc depending on their intended use.

In your Any Sprite Touched Event, you can apply an is-in-list test to the component,
to determine if it is a bullet or a target, etc.
(edit)

1 Like

No common “Touched” command indicating which sprite is affected?

In the Blocks Editor there is a separate Any Component section, or
look in the Right Click menu of a Sprite.TouchDown Event for the Make Generic option.

I tried but the return “component” is a meaningless font, not the component name

This is an example of Generic component events, using Buttons instead of Sprites.
Same idea.

You need to keep a map of component names or numbers. Example:

I think what Tetrimino wants to do is have the name of the Sprite returned, but the Block returns the underlying system record:

SpriteTouched

So for example the above Block, when the User touches the Sprite Component named “ImageSprite3”, returns something like: com.google.apinventor.components.runtime.imagesprite@440a1988

…which is no doubt correct but not developer friendly :grin:

Edit: This of course means that the developer cannot inject the next action as he can with the individual Sprite Touched Block:

IndiviualSpriteTouchedBlock

So, really, the Generic Block is not delivering what one would intuitively expect.

Err. I think this comes down to a misunderstanding of how the any component event handlers work. The component variable in the handler is exactly what it is, it is a reference to the component instance. It’s not a component name. When you try to turn it into a string, it gives you an internal Java representation of the component (fully qualified class name + memory location of the object). Why exactly would you need the component name versus manipulating the component directly since you’ve already got it? For example, if you want to change the image of the sprite, you can use the set ImageSprite.Image of component … to … block to change its image. You plug the component parameter into the component input on the block and a text element representing the new image into the to input.

If you haven’t already, you may want to take a look at Don’t Repeat Yourself (DRY) with Any Component Blocks, which includes an example of manipulating Ball components in a snow globe app. It’s not ImageSprites, but it’s close enough that you may be able to adapt it to your code depending on what you’re trying to do.

What if, on touch of Sprite 3, I want to do something to Sprites 2 and 4?

you could have all components in a list and find the corresponding component in that list...
Taifun


Trying to push the limits! Snippets, Tutorials and Extensions from Pura Vida Apps by Taifun.

That works with other, regular components…got an example with Sprites?
I still feel the Generic Sprite Blocks should deliver in the same way as the individual Blocks.

Just use the regular event handler of Sprite3 in this case
Taifun

…but that is the point Taifun - in Tetrimino’s App, there are 50 sprites!

Someone still doesn’t understand the problem. If I have a game with 20X50 fields, at 1000 sprites then I cannot write a procedure for every sprite. If the sprites are in the list, why is “component” not the number of the sprite in the list? This is how the DEPLHI programming language works. The string you just returned cannot be used for anything !!!
“Component” should be the component name or serial number in the list! Don’t com.google.apinventor.components.runtime.imagesprite@440a1988
So useless and unnecessary!

Why don’t you use this?

2 Likes

You are absolutely wrong about that being useless. May be it feels useless to you because you don't know how to use it. @ewpatton explained how it works and makes total sense for ALL of the cases in which you need to identify a component generically.
You just have to find the way to translate or convert that basic piece of information into what you need for your particular case, like I showed you in the previous post.

1 Like

Also, out of curiosity, what are you going to do with the component name? You can’t use its name for referencing it anywhere!

Perhaps a peek at a game that separates out its underlying
object model from the user view might help you see
how to set up your app.

In the following app, how many Sprites or Balls do you see?

1 Like

I’m inclined to say that if you’ve got 1000 of anything in App Inventor then you may want to consider switching to another tool. App Inventor isn’t really well equipped to deal with scale because we don’t have a good mechanism to reference components by their name or any other way that doesn’t require some work by the developer. The typical way you would do something involving many components would be to put them into a list like @Italo demonstrated. Of course, this means you will end up with a list that’s 1000 items long (or 20 lists of 50 items, etc.). Components are objects, so you can do lookups using them such as by using the lookup in pairs block, or by comparing component references using the = (logical equal) block.

Taking @ChrisWard’s example, I originally thought as @Taifun suggested where I would just implement the specific handler. If you wanted to leverage generic handlers, you can also compare against specific components like so:

blocks (32)

However, if you’re looking to generalize that–say for a given ImageSprite n you want to access ImageSprite n-1 and n+1, then you’d want to do something like:

We also had a paper recently where we discussed some of these generalizability issues and ways they could be addressed that may be an interesting read for some, although we haven’t decided on what the final implementation should look like:

2 Likes