Cocos2d sprite file finding - iphone

I am looking for a way to find the filename of the CGSprite variable, then use it in an IF statement. Like this:
if(target.spritefilename?? == #"Car1.png")
{
target = [CCSprite spriteWithFile:#"Car1_dead.png" rect:CGRectMake(0, 0, 37, 76)];
}

I am not sure why you want to do this. But as far as I am guessing your purpose I would like to suggest an alternative and proper way to identify your different sprites.
There is a "userData" property in the sprite (inherited from parent) which you can use to store your custom data. So when you create your sprites you should also assign the identified to the userData property.
Like in your case when you first create your "target" sprite, you can then set, "target.userData = "
Later you can check if target.userData is equal to your required file name.
This is the proper way to store custom data in your sprites.
I hope it helps.

if([target.spritefilename isEqualtoString:#"Car1.png"])
is what i guess you are looking for.

You can use isEqualtoString for string comparison.
if([target.spritefilename isEqualtoString:#"Car1.png"])
For NSString.

store the sprite names in an array and check the current sprite name matches the name in an array.
if([image_array containsObject:#"car.png"])
{
NSLog(#"Image Found");
}
Hope this helps!!!

If([sprite.userData hasPrefix#"Car1"])
...

if([(NSString*)sprite.userData hasPrefix#"Car1"])
...

If the purpose of this to just identifying the sprite you can simply do it by using tag property of sprite.
Like set a taf for sprite while initialing or creating the sprite as
CCSprite *spr1=[CCSprite spriteWithFile:#"1.png"];
spr1.tag=1;
CCSprite *spr2=[CCSprite spriteWithFile:#"2.png"];
spr2.tag=2;
and while getting the sprite on particular event use to get tag value as
if([(CCSprite*)tagetSprite tag]==1)
{
}
else if([(CCSprite*)tagetSprite tag]==2)
{
}

Related

Unity how to set a prefab property trought an array

Could you please help me to write the right syntax? I am stuck with the following code:
GameObject cube = (GameObject)Instantiate(cube_prefab, new Vector3(x, y, 0), Quaternion.identity, transform);
cube.GetComponentInChildren<TextMeshPro>.text = "test" **// WORKS FINE**
Take into account that inside my prefab i have more TextMeshPro, so my question is: how can I get to the second object if i can't access trought an array ? sounds weird for me
cube.transform.GetChild(0).GetComponent<TextMeshPro>().text = "AAA" // DOESN'T WORK
Thanks in advance
The GetChild(int) method is a method of transform. In your example, you're calling GetChild(0) from the GameObject instead. So the fix in your example would use the transform property of your "cube", find the child, then get the component of the child item:
GameObject cube = (GameObject)Instantiate(cube_prefab, new Vector3(x, y, 0), Quaternion.identity, transform);
cube.GetComponentInChildren<TextMeshPro>.text = "test" **// WORKS FINE**
cube.transform.GetChild(0).GetComponent<TextMeshPro>.text = "test"
Here's the Unity docs for GetChild(int).
If you wanted to iterate over the next level of children for your game object, you could do this:
var t = cube.transform;
var childCount = t.childCount;
for ( int i = 0; i < childCount; i++ )
{
if ( t.GetChild(i).TryGetComponent<TextMeshPro> ( out var tmp ) )
{
tmp.text = $"TextMeshPro found on child {i}";
}
}
Be aware, that this will only iterate over the direct children of "cube", not the children of those children. You would have to check the child count of each child to check further down the family tree.
Sorry if I sound like I'm preaching, but it seems you just try to guess what the syntax is, without knowing what it each thing really does, and it won't do you any good. You should look into methods with generics (especially how to call them) and try to write code meaningfully instead of throwing brackets here and there, and expect things to happen.
With that out of the way, let's look at your issue.
The name 'GetChild' does not exist in the current context, because your cube is of GameObject type, which indeed doesn't have a GetChild method. The component that does have it is Transform. You should call it like: cube.transform.GetChild(0)...
If you fix that, the next issue is that GetChild method doesn't use generics (<Type>) and even if it did, first you provide should provide a type in angle brackets, and then write regular brackets () to indicate method call. What you probably wanted is to first get child, and then to get a component in it: cube.transform.GetChild(0).GetComponent<TextMeshPro>().text = "test";
In cube.GetComponentInChildren<TextMeshPro>.GetChild(0).text you miss brackets: cube.GetComponentInChildren<TextMeshPro>().GetChild(0).text. Morover, the TextMeshPro doesn't have a GetChild method, you must have confused ordering of your method calls.
In cube.GetComponentInChildren<TextMeshPro>[0] you try to use syntax as if you were using arrays, while GetComponentInChildren is just a method, not a property that is an array.
To answer your question shortly: use yourGameObject.transform.GetChild(childIndex).GetComponent<TextMeshPro>().text transform.GetChild() to navigate down to your desired gameObject and only then call GetComponent (remember brackets!) to get to your text property.
the right syntax was
cube.transform.GetChild(0).gameObject.GetComponent().text = "test"
cube.transform.GetChild(1).gameObject.GetComponent().text = "test"

How to find all Cube game Object in the scene?

I'm looking for a way to find all CubeGameObject in the scene. I'm trying to do this :
Cube[] ballsUp = FindObjectsOfType (typeof(Cube)) as Cube[];
But cube isn't a game object type apparently.
I think i need to use something related to PrimitiveType but can figure out what and how to use it...
Thanks
Your Cube is of primitive type. And Primitive type objects are not possible to find using FindObjectsOfType.
There are many ways to solve the above problem. The easiest is by using tags.
When you instantiate your cube object you can use tag "Cube".
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.tag = "Cube";
Then you can get all the cube objects in scene with cube tags using
GameObject[] arrayofcubes = GameObject.FindGameObjectsWithTag("Cube");
This will give all the array of GameObject cubes in the scene.
FindObjectsOfType can be used to find gameobjects with attached classed and not primitive types.
Another way to proceed is finding all objects with MeshFilters and Searching for the Desired primitive name in the mesh filter arrays
string[] meshNames = new string[5] {"Cube", "Sphere", "Capsule", "Cylinder", "Plane"};
MeshFilter[] allMeshFilters = FindObjectsOfType(typeof(MeshFilter)) as MeshFilter[];
foreach(MeshFilter thisMeshFilter in allMeshFilters)
{
foreach(string primName in meshNames)
{
if (primName == thisMeshFilter.sharedMesh.name)
{
Debug.Log("Found a primitive of type: " + primName);
}
}
}
Geeting all the Object by their primitive type (C#)
You could try using a script. Let's say your GameObjects have a script MyScript, then you could FindObjectsofType GameObject and GetComponent Myscript.
Hope this helps. Although, I know it's not the answer you want, it's definitely an idea worth trying as a last resort :)
You could try this. If you are using the cube primitive of unity the mesh should be called "Cube" and while running "Cube Instance".
var gameOjects = GameObject.FindObjectsOfType<GameObject>();
foreach (var gameOject in gameOjects)
{
var meshFilter = gameOject.GetComponent<MeshFilter>();
if (meshFilter != null && meshFilter.mesh.name == "Cube Instance")
Debug.Log(gameOject.name);
}
tough this isn't very elegant or robust.
A more appropriate way would be to tag all cubes and get them by "FindGameObjectsWithTag"
Then recommended way from Unity of doing this is to create a tag and then use GameObject.FindGameObjectsWithTag to find all of them. GameObject.FindGameObjectsWithTag returns array of objects in this tag.
For example, create a tag called "cubeTags" then go to each cube and change the tag to cubeTags. When you want to find all the cubes, you can just do:
GameObject[] cubes = GameObject.FindGameObjectsWithTag ("cubeTags");
Cube[] ballsUp = new Cube[cubes.Length];
for(int i=0; i<cubes.Length; i++){
ballsUp = cubes[i].GetComponent<Cube>();
}

SpriteKit - How do I check if a certain set of coordinates are inside an SKShapeNode?

In my game, I'm trying to determine what points to dole out depending on where an arrow hits a target. I've got the physics and collisions worked out and I've decided to draw several nested circular SKShapeNodes to represent the different rings of the target.
I'm just having issues working out the logic involved in checking if the contact point coordinates are in one of the circle nodes...
Is it even possible?
The easiest solution specific to Sprite Kit is to use the SKPhysicsWorld method bodyAtPoint:, assuming all of the SKShapeNode also have an appropriate SKPhysicsBody.
For example:
SKPhysicsBody* body = [self.scene.physicsWorld bodyAtPoint:CGPointMake(100, 200)];
if (body != nil)
{
// your cat content here ...
}
If there could be overlapping bodies at the same point you can enumerate them with enumerateBodiesAtPoint:usingBlock:
You can also compare the SKShapeNode's path with your CGPoint.
SKShapeNode node; // let there be your node
CGPoint point; // let there be your point
if (CGPathContainsPoint(node.path, NULL, point, NO)) {
// yepp, that point is inside of that shape
}

CCSpriteBatchNode and CCArray, finding inactive objects

For a simple game, I have 4 different platforms (all on one spritesheet). I initially add 5 of each to a CCSpriteBatchNode, and set them all as not visible. When I set my platforms I want to take a platform of a certain type from my CCSpriteBatchNode and change it to make it visible and position it.
I am having trouble finding platforms of a specific type that aren't visible. Or vice-versa?
I know you can use [batchnode getchildbytag:tag] but as far as I know that only returns one sprite. Is there any way I can put pointers to each platform of a specific type into an array, so that I can iterate through the array and find all the not visible sprites?
Thanks!
As suggested by Drama, you will have no choice than to 'iterate' the children. As for identifying which sprite corresponds to which platform, a few ways exist. A simple one would be to use the 'tag' property of the sprite -- assuming you do not use it for any other purpose.
// some constants
static int _tagForIcyPlatform = 101;
static int _tagForRedHotPlatform = 102;
... etc
// where you create the platforms
CCSptiteBatchNode *platforms= [CCSpriteBatchNode batchNodeWithFile:#"mapItems_playObjects.pvr.gz"];
CCSprite *sp = [CCSprite striteWithSpriteFrameName:#"platform_icy.png"];
sp.tag = _tagForIcyPlatform;
[platforms addChild:sp];
sp = [CCSprite striteWithSpriteFrameName:#"platform_redHot.png"];
sp.tag = _tagForRedNotPlatform;
[platforms addChild:sp];
// ... etc
// where you want to change properties of
-(void) setVisibilityOf:(int) aPlatformTag to:(BOOL) aVisibility {
for (CCNode *child in platforms.children) {
if (child.tag != aPlatformTag) continue;
child.visible = aVisibility;
}
}
once again, this works if you are not using tags of platform's children for another purpose. If you need the tags for some other purpose, consider using an NSMutableArray in the class, one per platform type, and store in that array the pointer to your sprites of the appropriate type.
There's not a super straightforward way to do that. You'll need to iterate through the children and inspect each child individually.
For coding efficiency, consider adding a category to CCSpriteBatchNode that performs this function for you. That way you can easily replicate it as needed.

enum in Singleton cocos2d

What do you recommend me if I have two layers (which are added to a parallaxNode) and on each layers I've added sprites which I want to restrict the order that the player won't be able to remove sprite5 until it removes first the previous ones: sprite1, sprite2, sprite3 and sprite4 and so one.
I'm using Juan's example for dynamically touch detection
What will be the dynamical option for this?
UPDATE:
if([sprite tag] == tag_collection_1 && [sprite GetCanTrack]) {
//Set others to NO & call remove sprite method
[[TSprite FindByTag:tag_collection_number] SetCanTrack:NO];
[self removeSpriteMethod:touchLocation];
} else if ([sprite tag] == tag_collection_number && [sprite GetCanTrack]) {
// and so on
}
Use a fifo stack implementation. If you want to remove the sprite, you first check if it's at the bottom of the stack and when you do remove it, you pop it from the stack as well. Practically you will have an NSMutableArray and look at the first item if the object is in that position before you remove it. If you have added 1,2,3,4,5 in that order and want only to be able to remove them in the same order you check if the object you are trying to remove is at index 0 in the array first.