pygame-create multiple different instances of sprites [duplicate] - copy

I'm having trouble with getting new sprites to be added. I'm looking for something along the lines of:
def duplicate(sprites):
for d in sprites:
if d.energy >= d.max_energy * 0.9:
d.energy = d.energy / 2
new_d = d.duplicate()
so if 1 sprite had its 'energy' above 90% of its 'max_energy', its energy would be cut in half and now there would be a second sprite that was identical to the first. I'm not sure how to pull that off though.

In general, you need to implement the duplicate method and construct a new instance of the Sprite object in the method.
Another solution is to use the Python copy module. deepcopy can create a deep copy of an object. Unfortunately this cannot be used for pygame.sprite.Sprite objects, as theimage attribute is a pygame.Surface, which cannot be copied deeply. Therefore, a deepcopy of a Sprite will cause an error.
Unless you have nor any other attribute that needs to be copied deeply, you can make a shallow copy of the Sprite. The rect attribute is a pygame.Rect object. The copy of the Sprite needs its own rectangle, so you have to generate a new rectangle instance. Fortunately a pygame.Rect object can be copied by pygame.Rect.copy:
import copy
new_d = copy.copy(d)
new_d.rect = d.rect.copy()

Related

How to programmatically assign a random sprite to game object?

I have a function that generates a game object on screen every 100 frames:
var trash : Transform ;
function Update()
{
if(count == 1)
{
Instantiate(trash,new Vector3(UnityEngine.Random.Range(-3f,3f),UnityEngine.Random.Range(-3f,3f),UnityEngine.Random.Range(-3f,3f)), Quaternion.identity);
}
else if(count == 100)
{
count = 0;
}
}
Now, I want each of those generated objects to pick a random sprite from my assets. I thought about making a sprite array and picking from that, but I'm not sure how to go about doing so or how to assign the sprite to the object.
Anu help would be much appreciated!
I know it's late, but I just did it for myself, so I'm sharing.
Basically - put your assets in a folder and choose randomly from them to assign to the object you're duplicating.
Create a Resources folder under Assets.
Create another sub-folder for your relevant sprite assets, under Resources, lets call it CookiesImages.
Create your prefab object, and locate it under Assets/Prefabs/Resources (this is the object that you want to duplicate multiple times with different assets).
Create a script for this prefab object.
Create a static Object array (will hold the sprites).
In your Awake() method, init this Object array by loading all the resources from your assets folder:
if (objectsArray == null)
{
objectsArray= Resources.LoadAll("CookiesImages", typeof(Sprite));
}
In the Start() method, get a random index 0 --> objectsArray.Length and call Instantiate to create a sprite to assign to your prefab object.
this.GetComponent<SpriteRenderer>().sprite = Instantiate(objectsArray[index]) as Sprite;
At the beginning, I tried assigning them to an array variable from the unity UI, but I realized that in the way I described it's much more flexible.
Well, you can generate an array of sprites of the length of your choosing with:
Sprite[] _sprites = new Sprite[quantity desired]
Then using the resources folder and the Resources.Load method (found here: http://docs.unity3d.com/ScriptReference/Resources.Load.html), you could load all your sprites into the array one after the other. Then using your random number generator, you can access sprites at random from it.
Still probably not the best way of doing it, but I would imagine it is considerably better and easier to maintain than the prefab method, but different situations call for different approaches.

Creating a class to run a single action on multiple sprites

I'm trying to rotate numerous sprites (about 48 different ones) around an arbitrary point (using this article: http://indiedevstories.com/2012/08/14/custom-cocos2d-action-rotating-sprite-around-arbitrary-point/ ) and I managed to create the custom category for it, but it only works on a single sprite. I've looked around on the site and tried to use runAction:[action copy] but it makes the copies rotating points crazy numbers for some reason. Then I tried to create a method for the actions and just call the method, but I keep getting errors for that as well. I've tried so many different solutions but no luck.
So my question is, is there a way I can create another class that holds all of my sprites, and then run a single method to run an action on all of the sprites of the class?
Assuming you have an array called spriteArray containing all sprites you wish to rotate, it's as simple as:
for(CCSprite *sprite in spriteArray)
{
CCRotateAroundBy *rotateAround = [CCRotateAroundBy actionWithDuration:1.0 angle:90 rotationPoint:screenCenter];
[sprite runAction:rotateAround];
}

Box2D and wrapping worlds

I really stuck at implementing wrapping world with Box2D. I want to create game object appearing from left when it hides to the right and vice versa and the same for top-down.
My idea is to use object wich contains NSArray with 9 elements for superposition matrix (it's a quantum state when object exists at different locations at the same time, isn't it?).
Every element must contain the body. It covers all situations and has a more clear logic for me. For example, if my object doesn't touch any edges it holds only one "center" body (4th element). If it touches right edge i add "left-warped" body to 3rd element.
The main problem is creating body without adding to the world. First i must just add it to the array and then safely proccess adding outside of
world->Step();
For example… In collision logic (pseudocode)
[self.bodies addObjectAtIndex:index] = [self masterBody];
where
-(b2Body*)masterBody;
returns a template (master copy) for object body. But i can't write this method because there is only one
world->CreateBody(&bodyDef);
method and i must use it to create fixtures.
I can create separately only definition of the body, but full creation (with fixtures) can't be made without adding it to the world. But adding to the world msut be processed outside physics step.
Any ideas? Use separate world for storing template bodies of every game object?

Subclassing a sprite in cocos2d

A few days ago, I started working with cocos2d. I really like the framework. I would like to create a game with cocos2d and have a probably simple question...
I am making a game with 4 characters, which all have similar characteristics, but have some different attributes like "type" and "points". I'd like to subclass the sprites into one class which handles all their logic, drawing, and animation.
My question though, is how do I call the sprite class with say, a "type" parameter of 1, 2, 3, or 4 and then have the class draw the correct sprite into my scene with all of it's individual logic?
Thanks!
You should have an Enemy class that contains properties of specific enemies and that are not type specific (like position, current health, a CCSprite instance?) and an EnemyType class that contains properties that are shared among all enemies of a specific type (max health, max speed, size, sprite filename). You should load your enemy types prior to loading the level, than instantiate each enemy using the appropriate type in the constructor.
For example if your enemy element in the level file looks like this
<enemy><type>spider</type>...more properties...</enemy>
The code (pseudo) would do something like
EnemyType *enemyType = nil;
if (typeElement.value == "spider")
{
enemyType = spiderType;
}
Enemy *newEnemy = [Enemy enemyWithType:enemyType];
Also the Enemy class should contain the CCSprite that represents it, not subclass it. An enemy is not a sprite, so unless I'm missing something, as i see it, an enemy should not inherit from a sprite. I'd read about when to contain and when to inherit.
EDIT:
Another nice post to read that seems very relevant and could communicate a few other things probably better than me.
Anyway, my intention was not to make you think you should just rethink your entire design. What i'm proposing is "better" MVC-wise, but it doesn't mean it's better for your game. If you spend all your time on "design correctness" you'll never get a game done, especially if you're just learning the cocos2d framework, i was actually making a learning project not too long ago and Steve McConnel himself would come over and slap me if he saw it.
If you're working on a game alone and it's a small project go ahead and subclass away if it's going to be more manageable to you, everything, including "design correctness" needs to be properly quantified (except maybe usage of "goto" statements :) ).
polymorphism in this way can be done a couple of different ways, some better than others.
1) you could try to just override the init or node method and set up your object there.
+(CCSprite *)node
{
MySprite * returnSprite = [super node];
returnSprite.hat = #"fedora";
returnSprite.hatImage = [CCSprite spriteWithImage:...];
}
2) use reflection (psuedocode)
-(void)drawingMethodHere
{
[self.hat drawAtPoint:somePoint];
}
then override -(CCNode *)hat to reflect the type.
you may have to do some combination of them, but plan a little before you start, you will end up saving a lot of time.
You should subclass CCNode instead of subclassing CCSprite.
I think your problem is quite easy. Just create a base class called Character, which has the common logic, properties etc etc. Then you create 4 other classes like, enemy, player and so on and subclass from Character base. Note the character base should be subclassing CCNode.
Now you override the logic to fit your needs in the specific class. Now you will be able to use polymorphism, which is good.
For your sprite I would say create an instance variable of the CCSprite type and then create methods to initialize with an image. Then you will just add that sprite as a child when initializing the object.

Creating pointer Attributes in cocos2d iPhone

I am working on a game. There are balls that fall from the top of the screen, and the player has to catch them, as the are caught they stack ontop of one another. I have a method that creates each new ball and adds it to an Array that i use to move the sprites. Problem is that the after they collide I need them to stop moving, since the array is called on to move them they all move. And if i try to make them stop they all stop. So I was hoping to create a pointer attribute if ther is such a think, for example "sprite.position" I need a new attribute that i can check like a boolean. I was hoping to create a attribute like sprite.hasCollided and if it returns YES then the ball should no longer move. Is this possible or is there a better way to do it?
Thanks
Tanner
I would suggest you create a ball object. And add the boolean as as part of the object.
CCNodes (and, by inheritence, CCSprites) have a userData property, which is a void*. You can use this to relate a custom object to a cocos2d object. Keep in mind if you use the userData option, you will, in most cases, need to allocate any memory when you create/assign the sprite, and release it when you are done.
int* myInt = (int*)malloc(sizeof(int));
*myInt = 0;
sprite.userData = myInt;
//some time later, when you are done with the sprite
free(sprite.userData);
As an improvement on the userData property, you can do what xuanweng suggests and create a ball object containing various game-related properties for the balls, and assign an instance of this to each of your ball CCSprites using the method above.