Issues with adding an array of sprites to the screen in cocos2d? - arrays

for my game in cocos2d, I'm trying to add an array of sprites to the screen that constantly move to the left. When I add the method to my update method, it doesn't work as expected. I first set up a batch node.
- (void)setupBatchNode
{
_batchNode = [CCSpriteBatchNode batchNodeWithFile:#"berries-hd.pvr.ccz"];
[self addChild:_batchNode z:-1];
[[CCSpriteFrameCache sharedSpriteFrameCache]
addSpriteFramesWithFile:#"berries-hd.plist"];
}
-(void)updatePinkBerries:(ccTime)dt
{
CGSize winSize = [CCDirector sharedDirector].winSize; // Is it time to spawn a pink berry?
double curTime = CACurrentMediaTime();
if (curTime > _nextPinkBerrySpawn)
{
// Figure out the next time to spawn an asteroid
float randSecs = randomValueBetween(0.20, 1.0); _nextPinkBerrySpawn = randSecs + curTime;
// Figure out a random Y value to spawn at
float randY = randomValueBetween(0.0, winSize.height);
// Figure out a random amount of time to move from right to left
float randDuration = randomValueBetween(2.0, 10.0);
// Create a new berry sprite
CCSprite *pinkBerry = [CCSprite spriteWithSpriteFrameName:#"testt.png"];
[_batchNode addChild:pinkBerry];
// Set its position to be offscreen to the right
pinkBerry.position = ccp(winSize.width + pinkBerry.contentSize.width/2, randY);
// Move it offscreen to the left, and when it's done, call removeNode
[pinkBerry runAction:
[CCSequence actions:
[CCMoveBy actionWithDuration:randDuration position:ccp(-winSize.width- pinkBerry.contentSize.width, 0)],
[CCCallFuncN actionWithTarget:self selector:#selector(removeNode:)], nil]];
}
}

Related

Form design via Region property in winform getting removed

I have customized winform-design using region property as follows,
Region = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(0, 0, varPassedInConstructor * 9, Height, 10, 10));
And here calling winform through following code in a new thread
new Thread(new ThreadStart(() => {
toast toast = new toast(message);
toast.Show(nativeWindow);
toast.Refresh();
Thread.Sleep(3000);
while (toast.Opacity > 0)
{
toast.Opacity -= 0.04;
Thread.Sleep(100);
}
toast.Close();
toast.Dispose();
})).Start();
Everything goes well, form is displayed properly initially, but before closing all of sudden, changes applied via Region gets disappeared and form appears like the one that is at design time.
Image one, When initially form displayed,
Image two, just before form is getting closed,
I tried lots of diff thing, I am not getting what exactly problem is, so all help will be appreciated.
Finally, I got the fix, instead of using CreateRoundRectRgn from GDI32 used a GraphicsPath approach as follows,
private void SetRegion()
{
var GP = RoundedRect(this.ClientRectangle, 5);
this.Region = new Region(GP);
}
And here is code for RoundRect function (Credit goes to https://stackoverflow.com/a/33853557/3531672),
public static GraphicsPath RoundedRect(Rectangle bounds, int radius)
{
int diameter = radius * 2;
Size size = new Size(diameter, diameter);
Rectangle arc = new Rectangle(bounds.Location, size);
GraphicsPath path = new GraphicsPath();
if (radius == 0)
{
path.AddRectangle(bounds);
return path;
}
// top left arc
path.AddArc(arc, 180, 90);
// top right arc
arc.X = bounds.Right - diameter;
path.AddArc(arc, 270, 90);
// bottom right arc
arc.Y = bounds.Bottom - diameter;
path.AddArc(arc, 0, 90);
// bottom left arc
arc.X = bounds.Left;
path.AddArc(arc, 90, 90);
path.CloseFigure();
return path;
}
then in constructor simply had set size of form itself and called SetRegion defined above,
this.Width = toastMessage.Length * 9;
SetRegion();
Please note additionally, I would recommend to override OnSizeChanged and simply call SetRegion in it.

Reuse texture SDL

I'm making my first SDL2 game, I have a texture where I draw my game but after each rendering the texture is blanked, I need to have my original texture unmodified.
I have easily made this with surface but it was too slow.
I draw random artefacts on this texture that disappears with the time, I use SDL_RenderFill to shade the texture.
Anyone know how to do this ?
EDIT: Here's the code of the texture rendering
int gv_render(void) // This is called every 10ms
{
gv_lock;
int nexttimeout;
// Clear the screen
SDL_SetRenderTarget(renderer,NULL);
SDL_SetRenderDrawColor(renderer,0,0,0,255);
SDL_SetRenderDrawBlendMode(renderer,SDL_BLENDMODE_NONE);
SDL_RenderClear(renderer);
// Render view specific stuff
SDL_SetRenderTarget(renderer,gv_screen); // gv_screen is my screen texture
switch (player_view) { // I have multiple views
case pvsound:nexttimeout=wave_render();break; // <- THE 2ND FUNCTION \/
};
SDL_RenderPresent(renderer);
// Final screen rendering
SDL_SetRenderTarget(renderer,NULL);
SDL_RenderCopy(renderer,gv_screen,NULL,NULL);
gv_unlock;
return nexttimeout;
};
int wave_render(void) // I (will) have multiple view modes
{
game_wave *currwave = firstwave; // First wave is the first element of a linked list
game_wave *prevwave = firstwave;
map_block* block;
map_block* oldblock;
gv_lock;
// Load the old texture
SDL_RenderCopy(renderer,gv_screen,NULL,NULL);
SDL_SetRenderDrawBlendMode(renderer,SDL_BLENDMODE_BLEND);
// Dark the screen
SDL_SetRenderDrawColor(renderer,0,0,0,8);
SDL_RenderFillRect(renderer,NULL);
SDL_SetRenderDrawBlendMode(renderer,SDL_BLENDMODE_NONE);
// Now I travel my list
while (currwave) {
// Apply block info
/* skipped non graphics */
// Draw the wave point
uint8_t light; // Wave have a strong that decrease with time
if (currwave->strong>=1.0)
light = 255; // Over 1 it don't decrease
else light = currwave->strong*255; // Now they aren't fully white
SDL_SetRenderDrawColor(renderer,light,light,light,255);
SDL_RenderDrawPoint(renderer, currwave->xpos,currwave->ypos);
// Switch to next wave
prevwave = currwave; // There also code is the skipped part
currwave = currwave->next;
};
SDL_RenderPresent(renderer);
gv_unlock;
return 10;
};
```
This seem to be complicated, as say #david C. Rankin the SDL renderer is faster than surface but more or less write-only (SDL_RenderReadPixels and SDL_UpdateTexture could do the job in non realtime case).
I have changed my method, I use a linked list of pixels coordinates with entry points in a 256 items array.
My source code is now :
struct game_wave_point {
struct game_wave_point *next;
int x;
int y;
};typedef struct game_wave_point game_wave_point;
game_wave_point* graph_waves[256] = {NULL,NULL,...};
wave_render(void)
{
game_wave *currwave = firstwave;
// Perform the darkening
int i;
uint8_t light;
for (i=1;i<=255;i++)
graph_waves[i-1] = graph_waves[i];
graph_waves[255] = NULL;
// Remove unvisible point
game_wave_point* newpoint;
while (graph_waves[0]) {
newpoint = graph_waves[0];
graph_waves[0] = newpoint->next;
free(newpoint);
};
// Wave heartbeat...
while (currwave) {
/* blablabla */
// Add the drawing point
newpoint = malloc(sizeof(game_wave_point));
newpoint->next = graph_waves[light];
newpoint->x = currwave->xpos*pixelsperblock;
newpoint->y = currwave->ypos*pixelsperblock;
if ((newpoint->x<0)|(newpoint->y<0))
free(newpoint);
else graph_waves[light] = newpoint;
/* blablabla */
};
// Now perform the drawing
for (i=1;i<=255;i++) {
newpoint = graph_waves[i];
SDL_SetRenderDrawColor(renderer,i,i,i,255);
SDL_GetRenderDrawColor(renderer,&light,NULL,NULL,NULL);
while (newpoint) {
SDL_RenderDrawPoint(renderer,newpoint->x,newpoint->y);
newpoint = newpoint->next;
};
};
return 10;
};
This work well on my computer (progressive slow appear in a case that I will never reach).
Next optimization maybe performed with Linux mremap(2) and similar, this will allow creating a simple array that work with SDL_RenderDrawPoints without slowness of realloc() on big array.

Trouble displaying player Vector lives on stage

Hey everyone so I am having some trouble displaying the player Vector lives in a Array added to the stage. When I first start my game the lives are added correctly and when an enemy hits the player they are removed correctly but when I added a store where you can purchase an extra life I am getting a bug to where the vector lives are added to the stage but they dont remove when an enemy hits the player and they just are there.
in the constructor I have nLives = 2;
addPlayerLivesToStage();
Here is the addPlayerLivesToStage(); function as well as the removePlayerLives();
private function addPlayerLivesToStage():void
{
var startPoint:Point = new Point((stage.stageWidth / 2) + 240, (stage.stageHeight / 2) - 180);
var xSpacing:Number = 30;
lives = new Vector.<Sprite>();
for (var i:int = 0; i < nLives; i++)
{
var playerLives:mcPlayerLives = new mcPlayerLives();
playerLives.x = startPoint.x + (xSpacing * i);
playerLives.y = startPoint.y;
addChild(playerLives);
lives.push(playerLives);
//aPlayerLivesArray.push(playerLives);
}
}
private function removePlayerLive():void
{
//Remove live from screen
removeChild(lives[lives.length - 1]);
lives[lives.length - 1] = null;
lives.splice(lives.length - 1, 1);
}
Now in my games ENTER.FRAME Loop I have the function purchaseExtraLifeFunc(); that controls the Purchase and is supposed to add 1 life to the stage.
Like So:
private function purchaseExtraLifeFunc():void
{
if (nCoins >= 5 && purchaseItem)
{
trace("purchase life");
//remove coins from cost of purchase
nCoins -= 5;
updatecoinsTextScore();
//add extra life
nLives += 1;
addPlayerLivesToStage();
}
else
{
purchaseItem = false;
}
}
as you can say I add 1 Live and call the addPlayerLivesToStage function.
THis is not working correctly and I'm all out of ideas if anyone could help me with this I would really aprreciate it
I can see a few logic problems that could be the cause.
It looks like your addPlayerLivesToStage method ignores the fact that it could have been called before, and there could already be lives Sprites added to the stage. You then overwrite the lives Vector with a new Vector. So you don't have access to the previously added Sprites anymore.
I bet if you made the lives Sprites slightly transparent, you would see them stack over each other as you purchase more lives. Or to test, you could store a number that you increment every time you add a lives Sprite in your loop. And set the Y of the new sprite to this number. That way you would see all the Sprites you are adding.
To fix this, you want to remove all the lives Sprites at the beginning of your addPlayerLivesToStage function, because you are recreating them later in that function anyway.
EDIT*
The problem is still that the Sprites are not being cleaned up between addPlayerLivesToStage calls.
It is easier if you first use a container Spirte to hold all you life sprites. So add a private property to your class:
private var livesContainer:Sprite;
Then in you constructor, just set it up:
livesContainer = new Sprite();
livesContainer.x = (stage.stageWidth / 2) + 240;
livesContainer.y = (stage.stageHeight / 2) - 180;
addChild(livesContainer);
The you can just add all the lives into this container.
I modified your addPlayerLivesToStage function to remove any left over life sprites at the end, and cleaned up the adding, so it does not add a life that is already added.
private function addPlayerLivesToStage():void
{
var xSpacing:Number = 30;
// Add new life sprites if we need to.
for (var i:int = lives.length; i < nLives; i++)
{
var playerLives:mcPlayerLives = new mcPlayerLives();
playerLives.x = xSpacing * i;
livesContainer.addChild(playerLives);
lives.push(playerLives);
}
// Remove any life Sprites that are left over from last time.
for (var j:int = lives.length - 1; j > nLives; j--)
{
var life:Sprite = lives[j]
livesContainer.removeChild(life);
lives.splice(j, 1);
}
}

opengl failing to draw mesh

SOLVED: I'm not really sure how though... thanks for all your help guys.
I tried glDisable(GL_CULL_FACE); but the mesh is still not visible.
Basically I'm trying to draw a mesh (made from verts, normals, and texture coords) in OpenGL, using a display list. The mesh is on .obj format (exported from 3ds max 2013)
The problem is that the mesh is not visible.
To draw the display list I'm just using glCallLists (list, 1);
I have verified that I can draw things to the screen by drawing a point in the center of the screen and that works fine.
Could it be possible that the camera is positioned inside the mesh? If so is there an OpenGL state that I could enable to allow me to see the inside of a set of verts?
I know that the data I have is all valid, verified by printing each vert, normal and texture coord to a file before adding it to the display list, it looks valid.
I have dont no glTranslatef or anything like that, my projection matrix is setup like this:
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (45.0, (float)1024/(float)768, -9999, 9999);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
If you want to have a look at the .obj file, here it is: http://pastebin.com/PpG3vG5e
This is how I create the display list:
list = glGenLists (1);
glNewList (list, GL_COMPILE);
glBegin (GL_TRIANGLES);
for (i = 0; i < data.face_count; i++)
{
// first vert
normal[0][0] = (float)data.vertex_normal_list[data.face_list[i]->normal_index[0]]->e[0];
normal[0][1] = (float)data.vertex_normal_list[data.face_list[i]->normal_index[0]]->e[1];
normal[0][2] = (float)data.vertex_normal_list[data.face_list[i]->normal_index[0]]->e[2];
tex[0][0] = (float)data.vertex_texture_list[data.face_list[i]->texture_index[0]]->e[0];
tex[0][1] = (float)data.vertex_texture_list[data.face_list[i]->texture_index[0]]->e[1];
tex[0][2] = (float)data.vertex_texture_list[data.face_list[i]->texture_index[0]]->e[2];
vert[0][0] = (float)data.vertex_list[data.face_list[i]->vertex_index[0]]->e[0];
vert[0][1] = (float)data.vertex_list[data.face_list[i]->vertex_index[0]]->e[1];
vert[0][2] = (float)data.vertex_list[data.face_list[i]->vertex_index[0]]->e[2];
// second vert
normal[1][0] = (float)data.vertex_normal_list[data.face_list[i]->normal_index[1]]->e[0];
normal[1][1] = (float)data.vertex_normal_list[data.face_list[i]->normal_index[1]]->e[1];
normal[1][2] = (float)data.vertex_normal_list[data.face_list[i]->normal_index[1]]->e[2];
tex[1][0] = (float)data.vertex_texture_list[data.face_list[i]->texture_index[1]]->e[0];
tex[1][1] = (float)data.vertex_texture_list[data.face_list[i]->texture_index[1]]->e[1];
tex[1][2] = (float)data.vertex_texture_list[data.face_list[i]->texture_index[1]]->e[2];
vert[1][0] = (float)data.vertex_list[data.face_list[i]->vertex_index[1]]->e[0];
vert[1][1] = (float)data.vertex_list[data.face_list[i]->vertex_index[1]]->e[1];
vert[1][2] = (float)data.vertex_list[data.face_list[i]->vertex_index[1]]->e[2];
// third vert
normal[2][0] = (float)data.vertex_normal_list[data.face_list[i]->normal_index[2]]->e[0];
normal[2][1] = (float)data.vertex_normal_list[data.face_list[i]->normal_index[2]]->e[1];
normal[2][2] = (float)data.vertex_normal_list[data.face_list[i]->normal_index[2]]->e[2];
tex[2][0] = (float)data.vertex_texture_list[data.face_list[i]->texture_index[2]]->e[0];
tex[2][1] = (float)data.vertex_texture_list[data.face_list[i]->texture_index[2]]->e[1];
tex[2][2] = (float)data.vertex_texture_list[data.face_list[i]->texture_index[2]]->e[2];
vert[2][0] = (float)data.vertex_list[data.face_list[i]->vertex_index[2]]->e[0];
vert[2][1] = (float)data.vertex_list[data.face_list[i]->vertex_index[2]]->e[1];
vert[2][2] = (float)data.vertex_list[data.face_list[i]->vertex_index[2]]->e[2];
for (j = 0; j < 3; j++)
{
glNormal3f (normal[j][0], normal[j][1], normal[j][2]);
glTexCoord3f (tex[j][0], tex[j][1], tex[j][2]);
glVertex3f (vert[j][0], vert[j][1], vert[j][2]);
}
}
glEnd ();
glEndList ();
EDIT:
I've tried things like:
glTranslatef (0, 0, 5);
glCallList (mesh);
glTranslatef (0, 0, 0);
but they don't work either :(
EDIT:
#datenwolf
Here is the code I use to draw it:
Draw_Begin ();
Mdl_Draw (list, 0.0f, 0.0f, 0.0f);
Draw_End ();
This
gluPerspective (45.0, (float)1024/(float)768, -9999, 9999);
is wrong. In a perspective projection both the near and the far plane distance must be of the same sign, i.e. both positive or both negative. Also the absolute value of the near plane must be smaller than the absolute value of the far plane. And the near plane distance must be nonzero. In mathematical notation:
sgn(near) = sgn(far) ^ 0 < |near| < |far|
Usually both near and far are chosen positive. Also as a rule of thumb the near clipping plane should be chosen as fer away as possible. The far plane can be placed at infinity (exploting some of the properties of homogenous matrices), but usually is placed as close as possible to max out depth buffer resolution.

How to move an object in XNA so that it does not jiggle?

i want to know how can i move a object that it dont jiggle in XNA?
my code just decrease the Y position by 1 in each update call. but this looks very ugly because it jiggle, how to fix this?
Vector2 Speed = new Vector2(0,100); // Pixels x Second
Vector2 Position = ScreenCenter;
public void Update(GameTime gametime)
{
float Seconds = (float) gametime.Elapsed.TotalSeconds;
Position += Speed * Seconds;
}

Resources