Retina display tilemap collision detection in cocos2d iphone - cocos2d-iphone

I have created two different tilemaps for simple display and retina display.
Simple display collision detection is proper. When I test it on retina display map display properly but collision detection is not proper.
Can anyone help me please.

Here I check for collisions using this function then it runs well in both displays.
- (CGPoint)tileCoordForPosition:(CGPoint)position
{
CGFloat scale = [[UIScreen mainScreen] scale];
NSLog(#"%f",map1.tileSize.height);
int y = ((map1.mapSize.height * map1.tileSize.height) - position.y*scale) / map1.tileSize.height+(map1.position.y *scale/map1.tileSize.height);
int x =-((map1.position.x *scale) / map1.tileSize.width)+(MainCharacter.position.x*scale/map1.tileSize.width);
return ccp(x, y);
}

Related

SDL2 Mass Rendering of Textures faster than rendering across different loops?

I'm making a game in SDL2, and I have a glow image that's rendered behind bullets and particles. The unoptimized version renders the glow image in the bullets iterations and particle iterations. The optimized version simply renders the glow image all at once (at the recorded glow locations). This is kind of strange, and I'd like to know of any other solutions than mass rendering the glow image (it looks strange since it's not rendered at the correct point in the game loop). This is an example of the unoptimized version:
for (Particle &particle: particles){
if (particle.update(renderer)){
new_particles.push_back(particle);
// glow
glow_rect.x = particle.x;
glow_rect.y = particle.y;
glow_rect.w = particle.width * 2;
glow_rect.h = particle.height * 2;
SDL_SetTextureAlphaMod(glow_vignette, particle.alpha);
centerRect(glow_rect);
camera.renderCopy(renderer, glow_vignette, NULL, &glow_rect);
}
}
whereas in the optimized version (rendering all glows at once):
// show glows
for (auto [rect, alpha]: glow_locs){
SDL_SetTextureAlphaMod(glow_vignette, alpha);
camera.renderCopy(renderer, glow_vignette, NULL, &rect);
}

Collision detection between layers

I have a few layers, which holds CCSprites .
I have a main CCScene that is adding these layers at the start.
I have to check collision between sprites from different layers .
I know how to check a simple collision with CGRectContains , my problem is , that i need some kind of a class that holds all the sprites positions from all layers ,and to check each tick for collision.
Question: what is the right way to create such a class,that save/check sprites from all layers on the scene ?
THanks .
If you don't care about empty space, then you can just set self.contentSize for every layer. You can do it like this:
CGRect rect = CGRectNull;
for (CCNode *node in self.children) {
rect = CGRectUnion(rect, node.boundingBox);
}
self.contentSize = rect.size;
But if you care about empty space, then you need to use something like this:
// put it somewhere outside class implementation
static inline BOOL CCLayerIntersectsCCLayer(CCLayer l1, CCLayer l2) {
for (CCNode *n1 in l1.children) {
for (CCNode *n2 in l2.children) {
CGRect r1 = n1.boundingBox;
CGRect r2 = n2.boundingBox;
r1.origin = [l1.parent convertToNodeSpace:r1.origin];
r2.origin = [l2.parent convertToNodeSpace:r2.origin];
if (CGRectIntersectsCGRect(r1, r2)) {
return YES;
}
}
}
return NO;
}
But you must understand, that all sprites (even circles) are actually rectangles. So if you need very precise collision detection, then you should use box2d in your project. If you are interesting in this, here are some links to read:
Box2d
Intro to Box2D with Cocos2D 2.X Tutorial: Bouncing Balls
Box2D Tutorial for iOS: How To Use Box2D For Just Collision Detection with Cocos2D iPhone

Window resizing and scaling images / Redeclaring back buffer size / C++ / DIRECTX 9.0

C++ / Windows 8 / Win api / DirectX 9.0
I am having real big issues with this:
https://github.com/jimmyt1988/TheGame/tree/master/TheGame
Problem is that I have defined some adjust coordinate functions. They are for when a window is resized and I need to offset all of my coordinates so that my mouse cooridnates are working out the correct collisions and also to scale and yet keep ratio locked for the images I am drawing to the screen.
For example, If I had a screen at 1920 x 1080 and then resized to 1376 x 768, I need to make sure that the bounding boxes for my objects (for when my mouse hovers over them) is adjusted on the mouse coordinates I use to use to check if the mouse was in the bounding box.
I found out that I originally had problems because when I resized my window, directX was automatically scaling everything.. and on top of that, I too was rescaling things, so they would get utterly screwed... I was told by someone that I need to re-declare my screen buffer width and height, which I have done keeping in mind there is a border to my window and also a menu at the top.
Can anyone see why... regardless of doing all this stuff, I am still getting the incorrect results.
If you manage to run my application: Pressing the 1 key will make the resolution 1920 x 1080, pressing the 2 key will make it 1376 x 768. The resize is entirely wrong: https://github.com/jimmyt1988/TheGame/blob/master/TheGame/D3DGraphics.cpp
float D3DGraphics::ResizeByPercentageChangeX( float point )
{
float lastScreenWidth = screen.GetOldWindowWidth();
float currentScreenWidth = screen.GetWindowWidth();
if( lastScreenWidth > currentScreenWidth + screen.GetWidthOffsetOfBorder() )
{
float percentageMoved = currentScreenWidth / lastScreenWidth;
point = point * percentageMoved;
}
return point;
}
float D3DGraphics::ResizeByPercentageChangeY( float point )
{
float lastScreenHeight = screen.GetOldWindowHeight();
float currentScreenHeight = screen.GetWindowHeight();
if( lastScreenHeight > currentScreenHeight + screen.GetHeightOffsetOfBorderAndMenu() )
{
float percentageMoved = currentScreenHeight / lastScreenHeight;
point = point * percentageMoved;
}
return point;
}
and yet if you put the return point above this block of code and just do nothing to it, it scales perfectly because of blooming directX regardless of this which is being called correctly (presparams are previously declared in the D3DGraphics construct and a reference held in the class its self:
void D3DGraphics::ResizeSequence()
{
presParams.BackBufferWidth = screen.GetWindowWidth() - screen.GetWidthOffsetOfBorder();
presParams.BackBufferHeight = screen.GetWindowHeight() - screen.GetHeightOffsetOfBorderAndMenu();
d3dDevice->Reset( &presParams );
}
This is the problem at hand:
Here is the code that makes this abomination of a rectangle:
void Game::ComposeFrame()
{
gfx.DrawRectangle( 50, 50, screen.GetWindowWidth() - screen.GetWidthOffsetOfBorder() - 100, screen.GetWindowHeight() - screen.GetHeightOffsetOfBorderAndMenu() - 100, 255, 0, 0 );
}
EDIT::::::::::::::::
I noticed that On MSDN it says:
Before calling the IDirect3DDevice9::Reset method for a device, an
application should release any explicit render targets, depth stencil
surfaces, additional swap chains, state blocks, and D3DPOOL_DEFAULT
resources associated with the device.
I have now released the vbuffer and reinstantiated it after the presparams and device are reset.
EDIT::::::::::::
I placed an HRESULT on my reset in which I now manage to trigger an error... But, well.. it doesn't really help me! : http://i.stack.imgur.com/lqQ5K.jpg
Basically, the issue was I was being a complete derp. I was putting into my rectangle the window width and then readjusting that size based on the oldwidth / newwidth.. well the new width was already the screen size... GRRRRRRR.

Can I make CCFollow follow more naturally?

I want to build a platform game with cocos2d/Box2D. I use CCFollow to follow the player sprite but CCFollow constantly puts it in the center of the screen. I want CCFollow to follow more naturally, like a human turning a camcorder with an acceptable lag, a small overshoot ...etc.
Here is a method of mine that didn't work: I attached (via a distance joint) a small physics body to the player that doesn't collide with anything, represented by a transparent sprite. I CCFollow'ed the transparent sprite. I was hoping this ghost body would act like a balloon attached to the player, hence a smooth shift in view. The problem is distance joint breaks with too heavy - too light objects. The balloon moves around randomly, and of course, it pulls the player back a little no matter how light it is.
What is a better way of following a moving sprite smoothly?
Try add this to CCActions in cocos2d libs.
-(void) step:(ccTime) dt
{
#define CLAMP(x,y,z) MIN(MAX(x,y),z)
CGPoint pos;
if(boundarySet)
{
// whole map fits inside a single screen, no need to modify the position - unless map boundaries are increased
if(boundaryFullyCovered) return;
CGPoint tempPos = ccpSub(halfScreenSize, followedNode_.position);
pos = ccp(CLAMP(tempPos.x,leftBoundary,rightBoundary), CLAMP(tempPos.y,bottomBoundary,topBoundary));
}
else {
// pos = ccpSub( halfScreenSize, followedNode_.position );
CCNode *n = (CCNode*)target_;
float s = n.scale;
pos = ccpSub( halfScreenSize, followedNode_.position );
pos.x *= s;
pos.y *= s;
}
CGPoint moveVect;
CGPoint oldPos = [target_ position];
double dist = ccpDistance(pos, oldPos);
if (dist > 1){
moveVect = ccpMult(ccpSub(pos,oldPos),0.05); //0.05 is the smooth constant.
oldPos = ccpAdd(oldPos, moveVect);
[target_ setPosition:oldPos];
}
#undef CLAMP
}
i get this from cocos2d forums.
Perhaps this http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:actions_ease can help you get an "acceleration" effect with CCFollow.

Trapping the mouse?

I'm using GLUT and developing a FPS game. I need a way to trap the mouse so that the camera continues to move because right now when the mouse position exceeds the monitor limit, there is no way to calculate change in X or change in Y. How can I 'trap' the mouse with GLUT?
Thanks
I'd recommend using a ready-made engine like OGRE 3D instead, but if you really want to reinvent the wheel, here's how...
In all cases I'm aware of, PC FPS games "trap" the pointer by registering a mouse motion callback, noting the relative motion, and then warping the pointer back to the center of the window.
Here's some code I wrote to add mouse input to a sample ping-pong table in an OpenGL with C++ course a year or two ago:
void resetPointer() {
glutWarpPointer(TABLE_X/2, TABLE_Y/2);
lastMousePos = TABLE_Y/2;
}
void mouseFunc(int sx, int sy) {
if (!started) { return; }
int vertMotion = lastMousePos - sy;
lastMousePos = sy;
player1.move(vertMotion);
// Keep the pointer from leaving the window.
if (fabs(TABLE_X/2 - sx) > 25 || fabs(TABLE_Y/2 - sy) > 25) {
resetPointer();
}
}
// This goes in with your "start new game" code if you want a menu
resetPointer();
glutSetCursor(GLUT_CURSOR_NONE);
glutPassiveMotionFunc(mouseFunc);
It only tracks vertical motion, but adding horizontal is trivial.