Cocos2D - Collision detection getTileGIDAt - cocos2d-iphone

I been stuck on this issue for a few days now. I am hoping you guys can help me. I am creating a simple game following this tutorial: http://discuss.cocos2d-x.org/t/tutorial-series-use-the-cocos2d-x-3-0-game-engine-write-a-tile-map-game-part02/12991
and I got stuck on the collision detection part. The method getTileGIDAt() is ALWAYS returning 0, most likely I have found out that this is a Tiled related problem (maybe the tiles are not there, etc), but the problem is that the tiles are completely fine. Everything runs and loads smoothly, with this exception.
Thanks!
here is the code:
void HelloWorld::setPlayerPosition(Point position)
{
Point tileCoord = this->tileCoordForPosition(position);
int tileGid = _blockage->getTileGIDAt(tileCoord);
if (tileGid) {
auto properties = _tileMap->getPropertiesForGID(tileGid).asValueMap();
if (!properties.empty()) {
auto collision = properties["Blockage"].asString();
if ("True" == collision) {
return;
}
}
}
_player->setPosition(position);
}

I would try this tutorial and see how your code matches. I guess the main thing is to check that you have Tiled setup correctly for the different layers.
http://www.raywenderlich.com/29458/how-to-make-a-tile-based-game-with-cocos2d-2-x

Related

UE4 - How do I get actors of an array to follow the previous actor like in Snake?

I am new to C++ and even newer to UE4.
I am trying to create a Snake game but I am having trouble getting the body segments of the snake to move like they should in Snake. Like a train of actors. How do I get the body to move like a train/snake in the Snake game?
I've made a gif to try and show the problem (sorry if it is too small).Snake segment movement problem
The green actor is the Snake's head and the yellow actors are the segments that spawn (currently when I press space bar).
I can post code snipets if that helps?
The github repo is here: https://github.com/joeyisplaying/SnakeGame/tree/dev-branch/Source/SnakeGame
SOLVED! For anyone having this problem, I managed to find a really simple solution in a video on YouTube for this. My code now looks like this:
void ASnake::UpdateTailSegmentLoc()
{
if(!TailSegment)
{
return;
}
if(TailSegment)
{
for (int32 i = 0; i < TailSegmentArray.Num(); i++)
{
const FVector CurrentSectionLoc = TailSegmentArray[i]->GetActorLocation();
TailSegmentArray[i]->SetActorLocation(PreviousTailSegmentLoc);
PreviousTailSegmentLoc = CurrentSectionLoc;
}
}
}
The tick looks like this now:
// Called every frame
void ASnake::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
PreviousTailSegmentLoc = SnakeHead->GetComponentLocation();
if(!MovementDirection.IsZero())
{
const FVector NewLocation = SnakeHead->GetRelativeLocation() + (MovementDirection * DeltaTime * SnakeHeadSpeed);
SnakeHead->SetRelativeLocation(NewLocation);
UpdateTailSegmentLoc();
}
}
The YouTube video is here: https://www.youtube.com/watch?v=x8s86k6JUl8

cocos2d - Sprite doesn't show properly

I am using cocos2dx v3.11.1 with c++ to create simple game for iOS platform. But I run into strange issue with sprite movement.
Definition of main objects looks like that:
Sprite *logoBackSprite;
SpriteFrameCache *cache;
SpriteBatchNode *batchNode;
I create sprite from the plist like that:
cache = SpriteFrameCache::getInstance();
cache->addSpriteFramesWithFile("game_sprites1.plist");
batchNode = SpriteBatchNode::create("game_sprites1.png");
addChild(batchNode);
logoBackSprite = Sprite::createWithSpriteFrameName(fileName);
logoBackSprite->setPosition(Vec2(centerPoint.x-4, centerPoint.y + 200-43));
addChild(logoBackSprite, 0);
After that I call function which must perform simple moving animation for sprite. Code of this function looks like that:
void MainMenuScene::playMenuAnimations() {
float startDelay = 0.0f;
auto windowSize = Director::getInstance()->getVisibleSize();
Point centerPoint = Vec2(windowSize.width/2, windowSize.height/2);
logoBackSprite->stopAllActions();
logoBackSprite->setOpacity(0);
logoBackSprite->runAction(Sequence::create(DelayTime::create(startDelay + 0.5 + 0.75),
FadeTo::create(0.5f, 255),
nullptr));
}
But when I run application - nothing happens. Could you point me what I am making wrong? Thank you.
EDIT After few hours of experiments, I have noticed, that runAction method of sprite objects doesn't work. For example, I have created vector of sprite frames and I want to run animation. When I run application I can see this sprite, but animation still does not work. Maybe, I missed smth important?
EDIT2
Today I have noticed that any action works prefect on previous scene.
Issue solved. Problem was in bad configuration of scene where I want to run animations.
I should override onEnter() and onExit() methods. In onEnter() method of scene I call
Layer::onEnter();
Also in scene class I create init() method like that:
bool MainMenuScene::init() {
if ( !Layer::init() )
{
return false;
}
return true;
}
And animation runs perfectly!

remove a sprite in cocos2d-x

I am new to cocos2d-x.I am developing a game in xcode using cocos2d-x.
In my game, i have sprite animation(man) and moving obstacles and coins. I making collision with sprite animation & coins. When i get 10 coins, i am adding a life(adding a sprite for life).
My question is when collision is happening between sprite animation(man) & obstacles, life should decrease(i mean life sprite should remove) but it is not removed.
I am using the following code.
if(coincount%10==0)
{
lifecount=lifecount+1;
}
if(lifecount==1)
{
life = CCSprite::create("life.png");
life->setPosition( ccp(winwsize/2, winhsize/1.08) );
this->addChild(life, 5);
}
else if(lifecount==2)
{
life1 = CCSprite::create("life.png");
life1->setPosition( ccp(winwsize/1.8, winhsize/1.08) );
this->addChild(life1, 5);
}
else if (lifecount==3)
{
life2 = CCSprite::create("life.png");
life2->setPosition( ccp(winwsize/1.6, winhsize/1.08) );
this->addChild(life2, 5);
}
if (manRect.intersectsRect(obs5Rect))
{
if(lifecount>=1)
{
lifecount=lifecount-1;
this->scheduleOnce(schedule_selector(PlayScene::remove),0.5f);
}
void PlayScene::remove()
{
if(lifecount==0)
{
this->removeChild(life, true);
}
else if(lifecount==1)
{
this->removeChild(life1, true);
}
else if(lifecount==2)
{
this->removeChild(life2, true);
}
But sprite is not removing, when obstacle collide with sprite animation(man).
Please anyone could help me to find the solution. Thanks.
First setTag on Sprite like:
Sprite->setTag(111);
removeChildByTag(111);
OR
Sprite->removeFromParent();
I think your best bet is to do:
life1->setTag(99); // i made up the 99
and then when you want to remove it use removeChildByTag(99);
It seems that the problem is in your remove function. You create sprites life, life1, life2 when lifeCount is 1, 2 or 3 respectively. But in your remove method, you check if lifeCount is 0, 1 or 2. If it were 3, none of the sprites would be removed, as none of the conditions are met. Also you do not deacrease lifeCount anywhere.
Solution :
Either add --lifecount; at the beginning of remove(), or change your conditions appropriately and decrease the counter at the end.
Suggestions :
If I may suggest an improvemt to your code : you should keep your life sprites in an array, so that when you decide to add the possibility to have more lives it will be much easier.
Let me know if anything is not clear.

How do I create a more efficient portrait gallery using Cocos2d?

I'm building an app that has gallery of portraits (like a museum) and my character(s) walk past them from left-to-right-to-left. My portrait (images) are all 2048x2048. I haven't reduced their size yet because I want to make sure they can be used for the iPad version. I know their large size is an issue because it crashes when I try to load all of them at once (and it takes a long time to launch even with only 10 images).
That being said, my real issue is trying to create an efficient method for adding/removing them (sprites) as needed. I came up with something that works but it is clearly not the best way to do this.
I am hoping someone can suggest a more efficient approach.
Here is my code. You can assume another method takes care of loading the images into a mutable array called framedSprites (except I can only load 10 at a time because of the size/crashing). The following method (checkPosition) is called every time the screen position changes (via a TouchMoved swipe). As I see it, I will have to create similar statements for each image/portrait in the array (very inefficient and time consuming)...
-(void)checkPosition {
CGSize winSize = [CCDirector sharedDirector].winSize;
for (CCSprite *sprite in framedSprites) {
if (sprite.tag == 2) {
if ((sprite.position.x > 2000.0f)&&(sprite.position.x < 2010.0f)) {
CCSprite *portrait = (CCSprite *)[_backgroundNode getChildByTag:0];
if (portrait.tag == 0) {
NSLog(#"Removing a Portrait Left 2 Places From This One");
[_backgroundNode removeChildByTag:0 cleanup:YES];
}
}
if ((sprite.position.x > 1980.0f)&&(sprite.position.x < 1990.0f)) {
CCSprite *portrait = (CCSprite *)[_backgroundNode getChildByTag:0];
if (portrait == nil) {
CCSprite * framedSprite = (CCSprite *)[framedSprites objectAtIndex:0];
NSLog(#"Adding a Portrait Left, 2 Places From This One");
framedSprite.position = ccp(600,winSize.height/2); //figuring these positions is also not efficient and time consuming
[_backgroundNode addChild:framedSprite z:0 parallaxRatio:ccp(0.4f,0.5f) positionOffset:framedSprite.position];
}
}
}
}
}
You should only need to have 3 images loaded at any one time to allow scrolling in either direction (assuming you're not also allowing movement in the y direction). The one on display, one either side as a buffer and then lazy load and replace as needed.
If you don't need to see the entire image at once you could also consider cutting it into tiles using a free tool like Tilen (http://itunes.apple.com/gb/app/tilen/id409199185?mt=12) and then loading the tiles as required.

collision of a platformer (like mario bros) not working

i've been sitting here for hours now trying to figure out how collision could work for a platformer.. after doing a lot of research i found something useful in the internet.. but it doesn't work yet :/
my character seems to jump one time.. and then gets stuck a short distance above the ground
This is the function where i load my platforms from txt (by calling setupworld)
in my txt i define xstart (where the platform starts) xend (end of platform) ystart (bottom of platform) 2 unnused variables and the texture filter (0-4 atm)
each platform is then created by repeating 2x2 tiles in x direction
numblocks= number of platforms (sry for the bad variable name ^^)
number of blocks is calculated by taking the end coordinate of the platform - start coordinate and dividing by 2.0 (my platforms always have coordinates dividable by 2.. like.. 0 - 16.. or.. 8 - 16.. )
as u see.. the structure block is where all the data is saved to in setupworld() and it has nothing to do with the number of tiles displayed.. sry again for my weird names
GLvoid BuildLists()
{
texture[0]=LoadPNG("data/grass.png");
texture[1]=LoadPNG("data/gnd.png");
texture[2]=LoadPNG("data/pilz_test.png");
texture[3]=LoadPNG("data/rockwall.png");
texture[4]=LoadPNG("data/crate.png");
setupworld();
quad[0]=glGenLists(numblocks);
for(int loop=0;loop<numblocks;loop++)
{
GLfloat xstart,xend,ystart,u,v,u2,v2;
xstart=block.data[loop].xstart;
xend=block.data[loop].xend;
ystart=block.data[loop].ystart;
//u=block.data[loop].u;
//v=block.data[loop].v;
GLuint filter=block.data[loop].filter;
GLfloat blocks=(xend-xstart)/2.0f;
u=0.0f;
v=0.0f;
u2=1.0f*blocks;
v2=1.0f;
glNewList(quad[loop],GL_COMPILE);
glBindTexture(GL_TEXTURE_2D, texture[filter]);
// Start Drawing Quads
for(int y=0;y<blocks;y++)
{
glBegin(GL_QUADS);
glTexCoord2f(u,v);
glVertex3f(xstart,ystart,-1.0f);
glTexCoord2f(u2,v);
glVertex3f(xstart+((y+1)*2.0f),ystart,-1.0f);
glTexCoord2f(u2,v2);
glVertex3f(xstart+((y+1)*2.0f),ystart+2.0f,-1.0f);
glTexCoord2f(u,v2);
glVertex3f(xstart,ystart+2.0f,-1.0f);
glEnd();
}
glEndList();
quad[loop+1]=quad[loop]+1;
}
}
This is where the key actions are processed..
DetectCollision() calls my function where i (try to) check for collisions
ymovement
ypos2=ypos; is just to remind the last position for repositioning
i jump until i reach 5.0f or a collision in y-direction is detected.. then locky turns TRUE; the else is to let my character get back to ground (cause no gravity) even when the player keeps w pressed
the same thing happens when w is not pressed.. and locky is being reset
xmovement
i add to (or subtract from) xpos for movement
as long as the character doesn't reach the border or a collision appears it should do the normal movement
if (active) // Program Active?
{
if (keys[VK_ESCAPE])
{
done=TRUE;
glDeleteTextures(1,&texture[0]);
glDeleteTextures(1,&texture[2]);
glDeleteTextures(1,&texture[1]);
}
if (keys['W'])
{
if(!locky)
{
DetectCollision();
ypos2=ypos;
ypos=ypos+0.2f;
if(ypos>=5.0f)
{
locky=!locky;
}
if(collisiony)
{
ypos=ypos2;
locky=!locky;
}
}
else
{
if(ypos>0.0f && !collisiony)
{
ypos=ypos-0.2f;
}
}
}
if (!keys['W'])
{
locky=!locky;
if(ypos>0.0f && !collisiony)
{
ypos=ypos-0.2f;
}
}
if (keys['A'])
{
if(xpos>0.0f && !collisionx)
{
xpos=xpos-0.2f;
}
}
if (keys['D'])
{
if(xpos< 50.0f && !collisionx)
{
xpos=xpos+0.2f;
xcam=xcam-0.1f;
}
}
glLoadIdentity();
glTranslatef(0,-7.0f,-25.0f);
DrawWorld(); //draws my platforms by calling the display lists compiled in build lists
DrawChar(); //draws the character
SwapBuffers(hDC);
}
Finally the code where i check for collisions
inPlatformx for checking x
is my character between left and right side of the platform being checked
-> function returns TRUE and is written into collisionx
inPlatformy for checking y
same for inPlatformy
bool inPlatformx(float xpos, BLOCK block, int i){
return xpos > block.data[i].xstart &&
xpos < block.data[i].xend;}
bool inPlatformy(float ypos, BLOCK block, int i){
return ypos > block.data[i].ystart &&
ypos < (block.data[i].ystart+0.2);
}
GLvoid DetectCollision(){
for(int i=0; i<numblocks;i++)
{
collisionx=inPlatformx(xpos,block,i);
collisiony=inPlatformy(ypos,block,i);
}
}
finally a screenshot
http://www.grenzlandzocker.de/test.png
I hope u can help me.. either fix my code or give me some tips on collisions.. since it's my first game with opengl :s
if u need any more detail or infos please ask ^^
and thanks in advance !
if (keys['W'])
{
//DetectCollision();
if(!locky)
{
ypos2=ypos;
ypos=ypos+0.2f;
if(ypos>=5.0f)
{
locky=!locky;
}
if(collisiony)
{
ypos=ypos2;
locky=!locky;
}
}
else
{
if(ypos>0.0f)
{
ypos=ypos-0.2f;
}
}
}
if (!keys['W'])
{
locky=!locky;
if(ypos>0.0f && !collisiony)
{
ypos=ypos-0.2f;
}
}
if (keys['A'])
{
//DetectCollision();
if(xpos>0.0f && !collisionx)
{
xpos2=xpos;
xpos=xpos-0.2f;
}
if(collisionx)
{
xpos=xpos2;
}
}
if (keys['D'])
{
//DetectCollision();
if(xpos< 50.0f && !collisionx)
{
xpos2=xpos;
xpos=xpos+0.2f;
xcam=xcam-0.1f;
}
if(collisionx)
{
xpos=xpos2;
}
}
THANKS :)
well i just edited the code for x movement and collision.. so it works properly.. (despite the flickering (but idc atm :) ).. i'm wondering why jumping doesn't work at all anymore.. it's just increasing till i'm stuck.. can't even get up once anymore :/
i put my detectCollision() in front of they key section.. which works for x AND y now (hopefully)..
and i also edited something in DetectCollision()
i had ystart+0.2 instead of ystart+2.0 which is the correct coordinate for the platforms top
but looks like it just got worse at y
i'm still totally confused..
oh and talking about those predefined api's and stuff.. since somebody first showed me some things with glut i tried to make the next step and initialize everything myself.. i guess detection is much easier using predefined stuff.. but i want to learn it and not just get one game to work :)
if u have any more suggestions for my code i would be really grateful.. and if u know any good books for starters till advanced lvl i would really appreciate
and yes.. i know.. display lists are deprecated since opengl 3.0 ^^
Unless I am not following your code correcty, once you reach the apex of your jump and set your locky to !locky, you start hitting your else statement, which never checks for collision. IF you are moving in the x or -x direction, you likely want to be doing this as the ground may not be in the same place as your origin of the jump.
Additionally, your locky check is checking if the ypos >= 5.0f , which will immediately be the case if you are already on some part of your game world above the 5.0 mark. You likely want this to be a variable such as limitY = ypos + 5.0f; and then check if ypos >= limitY, so it works regardless of origin.
As for the issue you are seeing now, it should be easy to debug and look at the current value of your y coordinate and see if there is anything obvious (such as not executing a final ypos -= 0.2f ) which is cause for you floating slightly above the ground after a jump. (I don't see an obvious error in the way you are doing your code, although I would not have designed it in the way you are doing it yourself.)
If you are developing this for Windows you may want to look into XNA development, which makes collision detection and resolution a lot easier.
Are you initializing locky to true or false? because all the code i can see inverts the state of locky, so depending on how the input is processed, your locky value is flipping every loop or possibly being set out of sync with your expectations.
I would recommend setting locky to true and false explicitly in the code you've shown, rather than using locky=!locky, it's clearer about the state of the system.