1

Hello HPMAN,

I would like to suggest an alternative way to update animations without the use of pointers in favor to use sprite numbers instead.

That means instead of using the pointer to update an animation like:

aSpriteSetAnim(&pointer_to_animation, 0); aSpriteSetPos(&pointer_to_animation, x_pos, y_pos); aSpriteAnimate(&pointer_to_animation);


I would like to use only the first sprite number of the animation (for the following example the first sprite number is 100):

aSpriteSetAnim(100, 0); aSpriteSetPos(100, x_pos, y_pos); aSpriteAnimate(100);

This would make using external functions much faster when updating multible similar animations because:

- then I would not need to pass over the pointers to the function
- it would save a lot of "if" statements
- the needed code would be shorter

Do you think you could add this option to the next DATlib update, please?
Or if not do you could please suggest a better way to update similar animations in external functions with pointers?


Here is an example:
===================

Lets assume I want to update 5 enemy animations in an external function in an external file (outside of main.c).
The enemy animations use the same base graphic and have the same size (3 sprites).
The graphics are already initialized in main.c and the sprite numbers are 100, 103, 106, 109 and 112.

In this way I would do it currently (with pointers):
main.c
aSpriteInit(&enemy_1, &enemy, 100,  17, 350, -250, 0, FLIP_NONE); 
aSpriteInit(&enemy_2, &enemy, 103,  17, 350, -250, 0, FLIP_NONE);
aSpriteInit(&enemy_3, &enemy, 106,  17, 350, -250, 0, FLIP_NONE);
aSpriteInit(&enemy_4, &enemy, 109,  17, 350, -250, 0, FLIP_NONE);
aSpriteInit(&enemy_5, &enemy, 112,  17, 350, -250, 0, FLIP_NONE);
palJobPut(17, enemy_Palettes.palCount, enemy_Palettes.data);
...
update_enemies(&enemy_1, &enemy_2, &enemy_3, &enemy_4, &enemy_5);
enemy.c
void update_enemies(aSprite *ani1, aSprite *ani2, aSprite *ani3, aSprite *ani4, aSprite *ani5)
{
	int i=0;

	for(i=0; i<5; i++) // maximal number of enemies is 5
	{
		if(enemy[i].state == ENEMY_IS_NOT_USED)
		{
			// set position to offscreen & update graphic
			if(i==0) {aSpriteSetAnim(ani1,0);  aSpriteSetPos(ani1, 350, -250); aSpriteAnimate(ani1);}
			if(i==1) {aSpriteSetAnim(ani2,0);  aSpriteSetPos(ani2, 350, -250); aSpriteAnimate(ani2);}
			if(i==2) {aSpriteSetAnim(ani3,0);  aSpriteSetPos(ani3, 350, -250); aSpriteAnimate(ani3);}
			if(i==3) {aSpriteSetAnim(ani4,0);  aSpriteSetPos(ani4, 350, -250); aSpriteAnimate(ani4);}
			if(i==4) {aSpriteSetAnim(ani5,0);  aSpriteSetPos(ani5, 350, -250); aSpriteAnimate(ani5);}
		}

		if(enemy[i].state == ENEMY_IS_ACTIVE)
		{
			// calculate new position
			enemy[i].x +=1;
			enemy[i].y +=1;

			// update graphic
			if(i==0) {aSpriteSetAnim(ani1,1); aSpriteSetPos(ani1, enemy[1].x, enemy[1].y); aSpriteAnimate(ani1);}
			if(i==1) {aSpriteSetAnim(ani2,1); aSpriteSetPos(ani2, enemy[2].x, enemy[2].y); aSpriteAnimate(ani2);}
			if(i==2) {aSpriteSetAnim(ani3,1); aSpriteSetPos(ani3, enemy[3].x, enemy[3].y); aSpriteAnimate(ani3);}
			if(i==3) {aSpriteSetAnim(ani4,1); aSpriteSetPos(ani4, enemy[4].x, enemy[4].y); aSpriteAnimate(ani4);}
			if(i==4) {aSpriteSetAnim(ani5,1); aSpriteSetPos(ani5, enemy[5].x, enemy[5].y); aSpriteAnimate(ani5);}
		}
	}
}

Here is an example how it could be if I could use sprite numbers to update the 5 enemy animations:
main.c
aSpriteInit(&enemy_1, &enemy, 100,  17, 350, -250, 0, FLIP_NONE); 
aSpriteInit(&enemy_2, &enemy, 103,  17, 350, -250, 0, FLIP_NONE);
aSpriteInit(&enemy_3, &enemy, 106,  17, 350, -250, 0, FLIP_NONE);
aSpriteInit(&enemy_4, &enemy, 109,  17, 350, -250, 0, FLIP_NONE);
aSpriteInit(&enemy_5, &enemy, 112,  17, 350, -250, 0, FLIP_NONE);
palJobPut(17, enemy_Palettes.palCount, enemy_Palettes.data);
...
update_enemies();
enemy.c
void update_enemies()
{
	int i=0;
	int first_sprite_number=100;  // number of the first sprite of a goup of similar enemies
	int sprites_used_per_enemy=3; // number of sprites needed for each enemy

	for(i=0; i<5; i++) // maximal number of enemies is 5
	{
		if(enemy[i].state == ENEMY_IS_NOT_USED)
		{
			// set position to offscreen & update graphic
			aSpriteSetAnim(first_sprite_number+(i*sprites_used_per_enemy),0); aSpriteSetPos(first_sprite_number+(i*sprites_used_per_enemy), 350, -250); aSpriteAnimate(first_sprite_number+(i*sprites_used_per_enemy));
		}

		if(enemy[i].state == ENEMY_IS_ACTIVE)
		{
			// calculate new position
			enemy[i].x +=1;
			enemy[i].y +=1;

			// update graphic
			aSpriteSetAnim(first_sprite_number+(i*sprites_used_per_enemy),1); aSpriteSetPos(first_sprite_number+(i*sprites_used_per_enemy), enemy[i].x, enemy[i].y); aSpriteAnimate(first_sprite_number+(i*sprites_used_per_enemy));
		}
	}
}

2

The functions need the aSprite handle information, can't relate a sprite # to information.

What you should do however is embed aSprite handler to your enemy type:
typedef struct enemy_type { aSprite as; //put it first short x; short y; short state; //etc... } enemy_type;
main.cshort x; short sprNum=100; enemy_type enemies[5]; //... for(x=0;x<5;x++) { aSpriteInit((aSprite*)&enemies[x], &enemy, sprNum, 17, 350, -250, 0, FLIP_NONE); sprNum+=3; } palJobPut(17, enemy_Palettes.palCount, enemy_Palettes.data); //... update_enemies();
enemy.cvoid update_enemies() { int i; for(i=0; i<5; i++) // maximal number of enemies is 5 { if(enemies[i].state == ENEMY_IS_NOT_USED) { // set position to offscreen & update graphic aSpriteSetAnim((aSprite*)&enemies[i],0); aSpriteSetPos((aSprite*)&enemies[i], 350, -250); } if(enemies[i].state == ENEMY_IS_ACTIVE) { // calculate new position enemies[i].x +=1; enemies[i].y +=1; // update graphic aSpriteSetAnim((aSprite*)&enemies[i],1); aSpriteSetPos((aSprite*)&enemies[i], enemies[i].x, enemies[i].y); } aSpriteAnimate((aSprite*)&enemies[i]); } }
You can further improve by using chained lists of used/unused ennemies etc etc... (because here we are reseting unused handles every loop)

3

Wow - thanks a lot for this code - I will try this out immediately enflamme

4

Your aSprite handler code works perfectly - thx again rotfl