Cocos2d-x Game screen not fit in iPhone 4 with iOS 7 - c++

I am new for Cocos2d-x, I found strange issue in my game we are testing in all simulator that working fine. also we are testing our game in iPhone 5 and iPad all thing working perfect but got an issue in only iPhone 4 device. there is game screen display small and there are show top and right side black area like following screenshot:
I check its all Default images size and resolution is correct as par apple guide line.
Can you please suggest me how to fix this issue. i can't figure it out is there any code related issue or something need to change in xcode.
Following is iPhone 5 screen shot:
Here is my appdelegate code:
bool AppDelegate::applicationDidFinishLaunching()
{
wrapper->authenticateLocalPlayer();
// initialize director
CCDirector *pDirector = CCDirector::sharedDirector();
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
// turn on display FPS
pDirector->setDisplayStats(false);
// set FPS. the default value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 / 60);
CCSize Size = CCDirector::sharedDirector()->getWinSize();
IPADX = Size.width/1024;
IPADY = Size.height/768;
if (Size.width==1024 || Size.width==2048){
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(1024, 768, kResolutionExactFit);
SCALEX = 1.0f;
SCALEY = 1.0f;
}
else
{
if (Size.width<568)
{
SCALEX = 960.0f/1024;
SCALEY = 640.0f/768;
}
else
{
SCALEX = 1136.0f/1024;
SCALEY = 640.0f/768;
}
}
// create a scene. it's an autorelease object
CCScene *pScene = HelloWorld::scene();
// run
pDirector->runWithScene(pScene);
return true;
}

Try this:
//set design resolution
Size designSize = Size(960, 640);
if (Size.width==1024 || Size.width==2048){
designSize = Size(1024, 768);
SCALEX = 1.0f;
SCALEY = 1.0f;
}
else
{
if (Size.width<568)
{
SCALEX = 960.0f/1024;
SCALEY = 640.0f/768;
}
else
{
SCALEX = 1136.0f/1024;
SCALEY = 640.0f/768;
designSize = Size(1136, 640);
}
}
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width, designSize.height, kResolutionExactFit);
CCEGLView::sharedOpenGLView()->setContentScaleFactor(MAX(768/designSize.height,1024/designSize.width) );

Related

Cocos2d-x smooth drawing

i'm developing freehand drawing game, and the drawing isn't very smooth , i used this code:
void Canvas::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *event) {
Canvas::drawEvenlySpacedSprites(touch->getLocation(),touch->getPreviousLocation());
}
void Canvas::drawEvenlySpacedSprites(Vec2 start, Vec2 end) {
// begin drawing to the render texture
_target->begin();
float distance = start.getDistance(end);
if (distance > 1) {
int d = (int)distance;
for (int i = 0; i < d; i++)
{
float difx = end.x - start.x;
float dify = end.y - start.y;
float delta = (float)i / distance;
Sprite * sprite = Sprite::create("brush3.png");
sprite->setColor(Color3B::BLUE);
sprite->setPosition(Vec2(start.x + (difx * delta), start.y + (dify * delta)));
sprite->visit();
}
}
// finish drawing and return context back to the screen
_target->end();
}
I'm working with cocos2d-x V3.3
Please help me to get smooth drawing
Thanks
As Nadarian says, you should not create a new Sprite each time you draw it.
Even though you cannot reuse same sprite, you can create sprite from same SpriteFrame.
First, you need to store SpriteFrame on some variable. Or, you can use SpriteFrameCache if you want.
I will show the code which will use SpriteFrame.
// create sprite
auto sprite = cocos2d::Sprite::create("brush3.png");
// get spriteframe from sprite
auto spriteframe = sprite->getSpriteFrame();
and on Canvas::drawEvenlySpacedSprites, create Sprite from the stored spriteframe.
Here is the example, change the this code
Sprite * sprite = Sprite::create("brush3.png");
to this code,
Sprite * sprite = Sprite::createWithSpriteFrame(spriteframe);
I've found this implementation, I hope it will helps you: http://build-failed.blogspot.it/2012/08/freehand-drawing-with-cocos2d-x-and.html

cocos2d-x undunderstand the image /screen /proportion, relative size between the opengl windows simulator and real device

after long and many hours of development only on the windows opengl simulator using visual studio 2012
every thing looked like it should be i tested on 480/320 screen size
CCSize screenSize = pEGLView->getFrameSize();
CCSize designSize = CCSize(320, 480);
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width, designSize.height, kResolutionShowAll);
if (screenSize.width > 640) {
CCFileUtils::sharedFileUtils()->addSearchPath("ipadhd");
pDirector->setContentScaleFactor(1280/designSize.width);
} else if (screenSize.width > 320) {
CCFileUtils::sharedFileUtils()->addSearchPath("ipad");
pDirector->setContentScaleFactor(640/designSize.width);
} else {
CCFileUtils::sharedFileUtils()->addSearchPath("iphone");
pDirector->setContentScaleFactor(320/designSize.width);
}
and with this function that loads the images
void GameLayer::loadImages()
{
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("sprites35.plist");
m_gameBatchNode = CCSpriteBatchNode::create("sprites.png",200);
this->addChild(m_gameBatchNode,2,kSSheet);
m_background = CCSprite::create("gride300_300.png");
m_background->setPosition(ccp(m_winSize.width/2,m_winSize.height/2));
this->addChild(m_background,kGrid);
}
when i first run the app in my device ( iPhone 5 )
all sizes of the images got 1/3 smaller and the position was all wrong .
my question is how can i develop on windows using the open GL simulator and still to see every thing right on my iPhone 5
UPDATE
i will give more info
for example i have background image that is 297 x 297 Pixels (1.00) in size
i place it like this :
m_background = CCSprite::create("gride300_300.png");
m_background->setPosition(ccp(m_winSize.width/2,m_winSize.height/2));
this->addChild(m_background,kGrid);
in the simulator it looks great . but when i see it in the iPhone it in the middle but very small . not like in the simulator
second example:
i place round gems with size : 35 x 35 Pixels (1.00) each to place in the middle also
one after the other they all look great in the simulator but when i see it in the iPhone they are again very small
and align to the bottom left of the screen ,
here is the code to place the gems :
void Gem::placeInGride()
{
CCSpriteBatchNode *spriteBatchNode = (CCSpriteBatchNode*) getGameController()->getGameLayer()->getChildByTag(kSSheet);
int gemSelect =(rand() % totalGemsAvailable) + 1;
GemType gemNum;
gemNum =(GemType)gemSelect;
setGemState(kGemNew);
char spritename[20];
sprintf(spritename,"gem%i_tranc.png",gemNum);
setImageName(spritename);
setGemType(gemNum);
char spriteid[20];
sprintf(spriteid,"gem_%i_%i",getRowNum(),getColNum());
std::string gemid(spriteid);
setGemId(spriteid);
mySprite = CCSprite::createWithSpriteFrameName(spritename);
mySprite->setOpacity(255);
spriteBatchNode->addChild(mySprite, 2);
CCSize sSize = mySprite->getContentSize();
setGemPosition(setPositionForGem(getRowNum(),getColNum(),sSize));
}
CCPoint Gem::setPositionForGem(int row,int col,const CCSize& gemSize)
{
float leftPadding = 30 ;
float rightPadding = 37.5 ;
float topPadding = 111.5;
float buttonPadding = 90;
float gemHight = gemSize.height;
float gemWidth = gemSize.width;
float x = (leftPadding+1) + ((gemWidth+2)*(col));
float y = (topPadding+1) + ((gemHight+2)*(row/*+1*/));
return ccp(x,y) ;
}
m attaching screen shots both from my iPhone and windows
iphone_screen.PNG
windos_screen.jpg
I think you have your parameters backward for
CCSize designSize = CCSize(320, 480);
should be
CCSize designSize = CCSize(480,320);
also have you tried using
CCSize winSize = CCDirector::sharedDirector()->getWinSize(); to verify the actual screen size being used for the device
then then providing scaled images from there like in this example that uses the iphone, ipad and ipadhd.

Box2D object speed

I have a little issue with my game. In my main game scene I create a Player object from a class, like this:
player = [Player spriteWithFile:#"Icon-Small#2x.png"];
player.position = ccp(100.0f, 180.0f);
[player createBox2dObject:world];
Below is the main chunk of my small Player class that creates the body and the fixture so I can use it in a box2d world.
b2BodyDef playerBodyDef;
playerBodyDef.type = b2_dynamicBody;
playerBodyDef.position.Set(self.position.x/PTM_RATIO, self.position.y/PTM_RATIO);
playerBodyDef.userData = self;
playerBodyDef.fixedRotation = true;
playerBodyDef.linearDamping = 4.0;
body = world->CreateBody(&playerBodyDef);
b2CircleShape circleShape;
circleShape.m_radius = 0.7;
b2FixtureDef fixtureDef;
fixtureDef.shape = &circleShape;
fixtureDef.density = 1.0f;
fixtureDef.friction = 1.0f;
fixtureDef.restitution = 1.0f;
body->CreateFixture(&fixtureDef);
The result of this code is a Box2d object with Icon-Small#2x.png over it. When I move a joystick, a Box2D impulse is applied and the player moves. Simple enough, right?
In non-retina displays, this works fine. However, when I switch to Retina in the simulator, Icon-Small#2x.png is created a little higher and farther to the right, not over the Box2D circle. Then, gravity is applied and they both fall down to the platform. Icon-Small#2x.png falls twice as fast. When I move the joystick, the Box2D circle moves, but Icon-Small#2x.png moves twice as fast and the camera follows it, soon leaving the circle off the screen. I doubt this issue has really anything to do with the code I have here, I feel like its a scaling issue hidden somewhere in my game. Does anyone have suggestions?
Edit:
I move the sprite with:
[player moveRight];
This is moveRight in the player class:
-(void) moveRight {
b2Vec2 impulse = b2Vec2(2.0f, 0.0f);
body->ApplyLinearImpulse(impulse, body->GetWorldCenter());
}
Shouldn't be any issue here, right?
Edit (again):
Here's my update: method-
- (void) update:(ccTime)dt {
int32 velocityIterations = 8;
int32 positionIterations = 1;
world->Step(dt, velocityIterations, positionIterations);
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext()) {
if (b->GetUserData() != NULL) {
CCSprite *myActor = (CCSprite*)b->GetUserData();
myActor.position = CGPointMake( b->GetPosition().x *PTM_RATIO,
b->GetPosition().y * PTM_RATIO);
myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
b2Vec2 pos = [player body]->GetPosition();
CGPoint newPos = ccp(-1 * pos.x * PTM_RATIO + 50, self.position.y * PTM_RATIO);
[self setPosition:newPos];
}
I have a feeling that the issue is somewhere in here. I've tried changing PTM_RATIO around, but it doesn't affect the speed. Any ideas?
Edit: see comment below, almost have this figured out
You problem probably stems from the fact you are using a #2x image... Read, http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:how_to_develop_retinadisplay_games_in_cocos2d
There it states:
WARNING: It is NOT recommend to use the ”#2x” suffix. Apple treats those images in a special way which might cause bugs in your cocos2d application.
So to solve your problem read through the information on using png files with the -hd suffix.
For the comment:
Do you have some code that looks something like...
world->Step(dt, 10, 10);
for(b2Body *b = world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData() != NULL) {
CCSprite *sprite = (CCSprite *)b->GetUserData();
sprite.position = ccp(b->GetPosition().x * PTM_RATIO,b->GetPosition().y * PTM_RATIO);
}
}
See how the code loops through all the box2d bodies in the word and sets the position of the sprite that is associated with the box2d body?

Tilemap platform collision detection with Cocos2d

I'm getting my feet wet with game development by working on a platformer using Cocos2d for iPhone. I'm struggling a bit in getting collision detection running so that my character will have his jump action cancelled when he hits a platform.
I'm using a technique from this tutorial where I create a separate layer of "meta tiles". The problem is that collision detection does not occur until the character sprite is well within the collidable tile, not on top of it.
I'm using the code below to determine the tile coordinate based on my character sprite's current position:
- (CGPoint) tileCoordForPosition: (CGPoint) position {
int x = position.x / tileMap.tileSize.width;
int y = ((tileMap.mapSize.height * tileMap.tileSize.height) - position.y) / tileMap.tileSize.height;
return ccp(x, y);
}
I tried various techniques, even trying to figure out what tile was below my character using this code:
- (void) update: (ccTime) dt {
BOOL isCollision = NO;
if (firstRun) {
oldY = player.position.y;
firstRun = NO;
}
CGPoint oneTileDown = ccp(player.position.x, player.position.y / 2);
CGPoint tileCoord = [gameplayLayer tileCoordForPosition:oneTileDown];
int tileGid = [gameplayLayer.meta tileGIDAt:tileCoord];
if (tileGid) {
NSDictionary* tileProperties = [gameplayLayer.tileMap propertiesForGID:tileGid];
if (tileProperties) {
NSString* collision = [tileProperties valueForKey:#"Collidable"];
if (collision && [collision compare:#"True"] == NSOrderedSame) {
//CCLOG(#"Collision Below");
isCollision = YES;
if (player.characterState == kStateFalling) {
[player stopAllActions];
}
}
}
}
if (oldY < player.position.y) {
CCLOG(#"Character is jumping");
player.characterState = kStateJumping;
}
else if (oldY > player.position.y) {
CCLOG(#"Character is falling");
player.characterState = kStateFalling;
}
oldY = player.position.y;
}
But the same problem happens: my character jumps, lands inside of the collision tile and is stopped instead of landing on top of the tile.
Is there a better way of checking for collision in a tilemap?
I have the solution to this issue.
In the method (CGPoint) tileCoordForPosition: (CGPoint) position you have to write the following:
int x = position.x / tileMap.tileSize.width;
int y = ((tileMap.mapSize.height * tileMap.tileSize.height + player.contenSize().height / 2) - position.y) / tileMap.tileSize.height;
return ccp(x, y);
player is a sprite from which you have to add half its height.
What you need to do is use CGRectContainRect to check if the player sprite's bounding box is intersecting with and of the tiles where it shouldn't.

Box2d + CoCos2d: Moving an Object automatically to simulate computer movement in a game

I am working on a hockey game and I am implementing Single Player mode. I am trying to move the "computer's" paddle in offense mode (move towards the ball). I am using CoCos2d and Box2d. I am moving the paddle using MouseJoints. The problem is the Paddle doesnt move at all!
tick is called in init method
[self schedule:#selector(tick:)];
...
- (void)tick:(ccTime) dt
{
_world->Step(dt, 10, 10);
CCSprite *computer_paddle;
CCSprite *ball;
b2Body *computer_paddle_b2Body;
float32 direction;
b2Vec2 velocity;
for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData() != NULL) {
CCSprite *sprite = (CCSprite *)b->GetUserData();
if (sprite.tag == 1) { //ball
ball = sprite;
static int maxSpeed = 10;
velocity = b->GetLinearVelocity();
float32 speed = velocity.Length();
direction = velocity.y;
if (speed > maxSpeed) {
b->SetLinearDamping(0.5);
} else if (speed < maxSpeed) {
b->SetLinearDamping(0.0);
}
}
if (sprite.tag == 3){ // paddle
computer_paddle = sprite;
computer_paddle_b2Body = b;
}
// update sprite position
sprite.position = ccp(b->GetPosition().x * PTM_RATIO,b->GetPosition().y * PTM_RATIO);
sprite.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
// update the computer paddle in single player moving it towards the ball using MouseJoint
//move towards the ball
b2Vec2 b2Position = b2Vec2(ball.position.x/PTM_RATIO,ball.position.y/PTM_RATIO);
b2MouseJointDef md1;
md1.bodyA = _groundBody;
md1.bodyB = computer_paddle_b2Body;
md1.target = b2Position;
md1.collideConnected = true;
md1.maxForce = 9999.0 * computer_paddle_b2Body->GetMass();
_mouseJoint = (b2MouseJoint *)_world->CreateJoint(&md1);
computer_paddle_b2Body->SetAwake(true);
Check whether:
a) the body is sleeping
b) the body is a static body
If it is sleeping and you have no other bodies, disable sleeping entirely. Otherwise disable sleeping of the body: body->SetSleepingAllowed(NO)
Note: this is according to Box2D 2.2.1 API Reference which isn't the default in cocos2d 1.0 yet, so the function may be different in your Box2D version.
Also check that your body is dynamic by looking up the b2BodyDef's type member and, if necessary, set it to be dynamic (see the b2BodyType enumeration). I'm not sure what the default is, it should be dynamic but this may depend on the Box2D version.