I'm working on a game which should have a constant height(480.0)
and because so I wrote that code below..
what's wrong with it is that I have sprite sheets power of 2s
for sd here're normal images, for hd - double size and for iPad retina - 4 times bigger;
so in this case when I draw my sprites from scene images are not correctly drawn..
And I guess that's because CCSpriteFrame is using CC_ContentScaleFactor() to calculate frame of a image and it cut's wrong frame..
does anybody has any idea how to solve it? :?
CCSize designResolutionSize = CCSize(320,480);
CCDirector* pDirector = CCDirector::sharedDirector();
CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();
pDirector->setOpenGLView(pEGLView);
pEGLView->setDesignResolutionSize(designResolutionSize.width,
designResolutionSize.height,
kResolutionFixedHeight);
CCSize size = CCEGLView::sharedOpenGLView()->getFrameSize();
std::vector<std::string> res;
if(size.width >= 2048 || size.height >= 2048){
res.push_back("ipadhd");
}
else if(size.width >= 960 || size.height >= 960){
res.push_back("hd");
}
else {
res.push_back("sd");
}
CCFileUtils::sharedFileUtils()->setSearchPaths(res);
CCDirector::sharedDirector()->setContentScaleFactor(size.height / designResolutionSize.height);
Thanks, George..
Related
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) );
I'm using Cocos2D 2.1 and this app is planned to be iPad only retina and non-retina. When I use spriteWithFile, and specify the filename without the -hd suffix, Cocos2D finds the image with the -hd suffix and uses it, but it displays in standard definition, meaning it doesn't scale down so it's displaying as a retina image.
In my delegate's - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method, I have the following:
CCGLView *glView = [CCGLView viewWithFrame:[window_ bounds]
pixelFormat:kEAGLColorFormatRGBA8
depthFormat:GL_DEPTH24_STENCIL8_OES
preserveBackbuffer:NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];
[glView setMultipleTouchEnabled:YES];
director_ = (CCDirectorIOS*) [CCDirector sharedDirector];
[director_ setDisplayStats:YES];
[director_ setAnimationInterval:1.0/60];
// attach the openglView to the director
[director_ setView:glView];
// 2D projection
[director_ setProjection:kCCDirectorProjection2D];
[director_ enableRetinaDisplay:YES];
// // Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
if( ! [director_ enableRetinaDisplay:NO] )
CCLOG(#"Retina Display Not supported");
// If the 1st suffix is not found and if fallback is enabled then fallback suffixes are going to searched. If none is found, it will try with the name without suffix.
CCFileUtils *sharedFileUtils = [CCFileUtils sharedFileUtils];
[sharedFileUtils setEnableFallbackSuffixes:NO]; // Default: NO. No fallback suffixes are going to be used
[sharedFileUtils setiPadRetinaDisplaySuffix:#"-hd"];
glView.opaque = NO;
glClearColor(0.0f,0.0f,0.0f,0.0f);
//glClear(GL_COLOR_BUFFER_BIT);
// Assume that PVR images have premultiplied alpha
[CCTexture2D PVRImagesHavePremultipliedAlpha:YES];
When I add the sprite using spriteWithFile (instead of using a sprite sheet because it's only one image) I have the following code:
movingTileGroup.handleSprite1 = [CCSprite spriteWithFile:#"draggableTileGroupHandle.png"];
movingTileGroup.handleSprite1.position = ccp(x,y);
[self.theMap addChild:movingTileGroup.handleSprite1 z:13];
Update: I see when -(BOOL) enableRetinaDisplay:(BOOL)enabled is called, none of the if statements return true. Could it have to do with a scale factor setting?
-(BOOL) enableRetinaDisplay:(BOOL)enabled
{
NSLog(#"enableRetinaDisplay called");
// Already enabled ?
if( enabled && __ccContentScaleFactor == 2 ){
NSLog(#"enabled && __ccContentScaleFactor == 2 ");
return YES;
}
// Already disabled
if( ! enabled && __ccContentScaleFactor == 1 ){
NSLog(#"! enabled && __ccContentScaleFactor == 1 ");
return YES;
}
// setContentScaleFactor is not supported
if (! [__view respondsToSelector:#selector(setContentScaleFactor:)]){
NSLog(#"setContentScaleFactor is not supported");
return NO;
}
// SD device
if ([[UIScreen mainScreen] scale] == 1.0){
NSLog(#"SD device");
return NO;
}
float newScale = enabled ? 2 : 1;
[self setContentScaleFactor:newScale];
// Load Hi-Res FPS label
[[CCFileUtils sharedFileUtils] buildSearchResolutionsOrder];
[self createStatsLabel];
return YES;
}
I am assuming you are using Spritebuilder to generate sprites , if that is so you need to specify the default size of the image in the spritebuilder software, this can be done by clicking on the image which is showing the problem and then on the left sidebar or panel select the image size as "default" and it will automatically scale to the required size...
If this doesn't solves your problem, Do let me know... regards...
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.
EDIT
Adjusted all the algorithms posted. It's now working NEARLY flawlessly. It's just the left-most 9 tiles that it fails on (A picture is at the bottom). It selects the completely wrong tile in most cases when hovering one of those nine.
EDIT2 I'm almost certain now that the problem is due to errors when screenX or screenY are negative, so it's probably down to using math.abs on tilePixelX/Y, but it can't just be that, otherwise the results wouldn't be so far off (Although it could well be contributing)
I'm making an isometric game, and right now I'm working on the map rendering engine. In theory it should be fairly simple but I just can't get the tile coords from the mouse position.
My tiles are 64 wide and 32 tall. An image is shown below:
My map displays fairly perfectly:
The actual problem is explained at the top.
Here's the code I'm using right now:
int screenX = sf::Mouse::getPosition(window).x - 250;
int screenY = sf::Mouse::getPosition(window).y - 250;
int tilex = floor((screenY / 32) + (screenX / 64));
int tiley = floor((screenY / 32) - (screenX / 64));
int tilePixelX = abs(screenX % 64); // I believe part of the problem
int tilePixelY = abs(screenY % 32); // is absoluting these. Not all though.
sf::Color mCol = mouseMap.getPixel(tilePixelX, tilePixelY);
if (mCol.r == 20)
tilex -= 1;
else if (mCol.r == 40)
tiley -= 1;
else if (mCol.r == 60)
tilex += 1;
else if (mCol.r == 80)
tiley += 1;
I'm now using a mousemap which is working fantastic however as said above it's still failing on the left-most nine tiles in the diamond (When you hover them it selects a seemingly random around 4-5 tiles away, or no tile at all (I'm guessing out of bounds of the map):
That also shows the problem tiles highlighted in red.
This is what the map looks like, to give you an idea of how my rendering engine works. Note that transparent pixels are considered empty, and black pixels are considered walls (Which I did not render for the example picture above, so none of the tiles displayed on the picture above are 0th-column or 0-th row, nor are they the last row.
My mouse map is definitely correct due to most of the map working but here it is anyway:
Edit:
I've packaged the necessary files and DLLs into a zip file so you can run it and see for yourself what is going on:
https://dl.dropbox.com/u/37019412/Broken.zip
Drawing formula is:
(x - y) * 32 + 250, (x + y) * 16 + 250
Where before coma is X and after is Y and inside x and y are the tile coordinates.
Looking at the tutorial, it seems you need to subtract 256 (224 plus half the width) from the mouse coordinate. Tell us if that works!
And please don't dynamically allocate a new sprite each time you draw one just to delete it in the same method! Ok, I'll try to refrain from making further comments on your code. ;)
In the end it was due to a lot of rounding errors.
if (screenX < 0 || tilePixelX < 0)
tilePixelX = 64 - abs(tilePixelX);
if (screenY < 0 || tilePixelY < 0)
tilePixelY = 32 - abs(tilePixelY);
if (tilePixelX >= 64)
tilePixelX = 63;
if (tilePixelY >= 32)
tilePixelY = 31;
if (screenX < 0 || screenY < 0)
{
tilex--;
tiley++;
}
Sorted it out, even if it was a little bit of an ugly hack in places.
so I am working on a game, following a tutorial online. Currently I have some FPS built into the system, and a simple animation which uses pieces of a sprite like such:
if( frameCount > 12 )
frameCount = 0;
//hero frames
SDL_Rect clip[ 13 ];
clip[ 0 ].x = 0;
clip[ 0 ].y = 0;
clip[ 0 ].w = 44;
clip[ 0 ].h = 39;
clip[ 1 ].x = 51;
clip[ 1 ].y = 0;
clip[ 1 ].w = 44;
clip[ 1 ].h = 39;
clip[ 2 ].x = 102;
clip[ 2 ].y = 0;
clip[ 2 ].w = 44;
clip[ 2 ].h = 39;
...
...
SDL_BlitSurface( hero, &clip[ frameCount ], destination, &offset );
frameCount++;
Now this works just fine, and each iteration of the while loop will cause it to play the next frame in the animation (This animation is part of a character class by the way).
The problem I am facing is the speed of the animation. It takes place at the current FPS of the game, which is 60. I want to be able to control the speed of the player animation separately, so I can slow it down to a reasonable speed.
Does anyone have any suggestions on how I could go about doing this?
note: There are 13 frames all together.
You have separate your refresh rate (60 fps) from your animation rate. The best solution, in my opinion, is to tie your animation rate to the real time clock. In SDL, you can do this with the SDL_Ticks() function, which you can use to measure time in millisecond resolution.
As an example, consider this example (not working code, just a sketch):
void init() {
animationRate = 12;
animationLength = 13;
startTime = SDL_Ticks();
}
void drawSprite() {
int frameToDraw = ((SDL_Ticks() - startTime) * animationRate / 1000) % animationLength;
SDL_BlitSurface( hero, &clip[ frameToDraw ], destination, &offset );
}
In case it isn't clear, the frameToDraw variable is computed by calculating how much time passed since the animation started to play. You multiply that by the animation rate and you get how many absolute frames at the animation rate have passed. You then apply the modulo operator to reduce this number to the range of your animation length and that gives you the frame you need to draw at that time.
If your refresh rate is slower than your animation rate your sprite will skip frames to keep up with the requested animation rate. If the refresh rate is faster then the same frame will be drawn repeatedly until the time to display the next frame comes.
I hope this helps.
What Miguel has written works great. Another method you can use is, to use a timer, set it to fire at a certain frequency and in that frequency, increment your sprite index.
Note that you should always make your rendering and logic separate.