Am a flash game developer at present I started writing games for iphone using cocos 2d engine, I have implemented separate Axis theorem for collision detection which works perfect. All the polygons are drawn as follows in openGl.
Now am trying to apply gravity to this 16x16 box after many search I found this tutorial http://www.seinia.com/tutorials/Bounce/ and implemented the same in objective C.
The problem am having is after the square comes to rest it keeps bouncing up/down in fractions. I tried a lot to fix this but I couldn't control that tiny movement.I never had such problem in flash but here the floating value is affecting the square position a lot.
Please let me know what is the write way to handle such issue , any reference URL would be helpful. Appriciated your help.Thanks!
0,16 16,16
------------
| |
| |
| |
| |
------------
0,0 16,0
Objective C code
if (square.points[0].y <= 0.1f) {
velocity.vy *= -bounce;
[square restInPeace:[Vector2D createVectorWithComponentX:velocity.vx Y:8.0f]];
// landed
if (fabs(velocity.vy) < 0.9f) {
velocity.vy = 0.0f;
[square restInPeace:[Vector2D createVectorWithComponentX:velocity.vx Y:8.0f]];
isLanded = YES;
}
}
Translate the object
-(void) translateVelocity:(Vector2D*)velocity
{
// The center as well as all of the vertices need to be
// accommodated.
center.x += velocity.vx;
center.y += velocity.vy;
for(int i=0; i < count; i++)
{
points[i].x += velocity.vx;
points[i].y += velocity.vy;
////NSLog(#"velocity %f %f",points[i].x , points[i].y);
}
}
When using a bounce algorithm, it is usually recommended to implement a slight imperfection to make sure that this event does not happen. You could also largen the range of what is accepted as "Landed", but remember to make sure that you then stick the object to the floor to make sure there are no visual artifacts.
By the imperfection I mean :
velocity.vy *= (-bounce + 0.01f);
For example. This should make your object always come to a halt.
Related
I am making a game based on the game AZ on the website Y8, and I am having problems with tile collisions.
the player moves basically by giving it speed when up is pressed, then rotating left or right.
direction = image_angle;
if(keyForward)
{
speed = 2;
}
else speed = 0;
// rotate
if(keyRotateLeft)
{
image_angle = image_angle + 5;
}
if(keyRotateRight)
{
image_angle = image_angle - 5;
}
then I said when the player collides with the tile speed = 0. But the player gets stuck and can't move anymore. is there a better way to do this.
A simple approach would be as following:
Attempt to rotate
Check if you are now stuck in a wall
If you are, undo the rotation.
A more advanced approach would be to attempt pushing the player out of solids while rotating.
Alternatively, you may be able to get away with giving the player a circular mask and not rotating the actual mask (using a user-defined variable instead of image_angle).
I have a method that I use to render little map using tiles, but when I finish rendering and I want to make a translation changing "transY" variable using different method nothing happens, so I must call RenderTesture() again to make it. How can I do this withot unnecessary rendering because it can slow down application when I use larger number of tiles?
void RenderTexture ()
{
MakeCurrent ();
GL.Clear((int)All.ColorBufferBit | (int)All.DepthBufferBit);
GL.MatrixMode(All.Modelview);
GL.LoadIdentity();
GL.Translate(-transX, transY, -10);
for (int i = 0; i < tileRows; i++)
{
for (int j = 0; j < tileColumns; j++)
{
GL.BindTexture(All.Texture2D, textureIds [i*tileColumns + j]);
GL.EnableClientState(All.VertexArray);
GL.EnableClientState(All.TextureCoordArray);
GL.PushMatrix ();
GL.Translate(j*2, -i*2, 0);
GL.VertexPointer(3, All.Float, 0, frontV);
GL.TexCoordPointer(2, All.Float, 0, frontT);
GL.DrawArrays (All.TriangleFan, 0, 4);
GL.PopMatrix ();
}
}
GL.DisableClientState(All.VertexArray);
GL.DisableClientState(All.TextureCoordArray);
SwapBuffers ();
}
If anybody have advice for me, I'll be very grateful!
Thanks in advance!
The bottleneck lies, most likely, in the amount of state changes (GL.BindTexture) and the amount of draw calls you are making (GL.DrawArrays). In general, you should draw as much as possible in a single draw call.
The simplest approach wold be to use a "texture atlas":
combine all your tile textures into a single large texture (this is the "texture atlas")
combine all your tile vertices into a single vertex array
call GL.BindTexture once to bind the texture atlas
call GL.DrawArrays once to render all tiles
So how do you render different tile textures? Simple: you change the vertex texture coordinates to point to the correct tile inside the texture atlas.
A single 1024x1024 can hold 256 distinct 64x64 tiles. Depending on the amount of distinct tiles in your game, you might have to use multiple texture atlases. Moreover, depending on the size of your map, you might wish to split it into "regions" with separate vertex arrays for each (you don't want to render 1 million tiles every frame if your monitor can only display 1000 tiles.)
On its own, this will give a measurable performance boost. Once this is working, you can get a second large boost by storing your vertex arrays on the GPU via Vertex Buffer Objects (VBOs).
Thank you very much!
The "Texture atlas" strategy can be very good idea. I've implemented that last night and it looks like rendering is getting speed. I've reduce loading of NxM tiles using separate textures, by loading one big NxM tiles bitmap using single texture and I've implemented method to change vertex array (in regard to new bitmap dimensions - NxM)
public void UpdateFrontVertex(int rowNumber, int columnsNumber)
{
for (int i = 0; i < 12; i++) {
if (i % 3 == 0)
frontVertex [i] = defaultFrontVertex[i] * rowNumber; // x-axis
else if (i % 3 == 1)
frontVertex [i] = defaultFrontVertex[i] * columnsNumber; // y-axis
else if (i % 3 == 2)
frontVertex [i] = defaultFrontVertex[i]; // z-axis
}
}
After that, I've got my map!!!
I still cannot compare performances before that implementation and now because I have to make changes for panning and zooming functionalities to work with that new rendering strategy.
For example, I've used
//zoom in
transY = (transY * 2 + 1);
transX = (transX * 2 + 1);
//zoom out
transX = ((transX - 1) / 2);
transY = ((transY - 1) / 2);
for zooming calculations to figure out which tile is my central tile, and after that to load all rounding tiles.
Thank you again for great help, I'll proceed now with panning and zooming implementation.
I am developing a game using iOS SpriteKit. I am trying to make an object in this game that will pull things towards it and the force will get greater as objects come closer to it, think of a magnet or a black hole. I've been having a difficult time figuring out what properties to change to get this nodes physicsBody to attract other nodes as they pass by.
In iOS 8 and OS X 10.10, SpriteKit has SKFieldNode for creating forces that apply to bodies in an area. This is great for things like buoyancy, area-specific gravity, and "magnets".
Watch out, though — the magneticField you get from that class is probably not what you want for the kind of "magnets" gameplay you might be looking for. A magnetic field behaves as per real-world physics at the micro level... that is, it deflects moving, charged bodies. What we usually think of as magnets — the kind that stick to your fridge, pick up junked cars, or make a hoverboard fly — is a higher-level effect of that force.
If you want a field that just attracts anything (or some specific things) nearby, a radialGravityField is what you're really after. (To attract only specific things, use the categoryBitMask on the field and the fieldBitMask on the bodies it should/shouldn't interact with.)
If you want a field that attracts different things more or less strongly, or attracts some things and repels others, the electricField is a good choice. You can use the charge property of physics bodies to make them attracted or repelled (negative or positive values) or more or less strongly affected (greater or less absolute value) by the field.
Prior to iOS 8 & OS X 10.10, SpriteKit's physics simulation doesn't include such kinds of force.
That doesn't keep you from simulating it yourself, though. In your scene's update: method you can find the distances between bodies, calculate a force on each proportional to that distance (and to whatever strength of magnetic field you're simulating), and apply forces to each body.
yes you can create magnetic force in sprite kit
-(void)didSimulatePhysics
{
[self updateCoin];
}
-(void) updateCoin
{
[self enumerateChildNodesWithName:#"coin" usingBlock:^(SKNode *node, BOOL *stop) {
CGPoint position;
position=node.position;
//move coin right to left
position.x -= 10;
node.position = position;
//apply the magnetic force between hero and coin
[self applyMagnetForce:coin];
if (node.position.x <- 100)
[node removeFromParent];
}];
}
-(void)applyMagnetForce:(sprite*)node
{
if( gameViewController.globalStoreClass.magnetStatus)
{
//if hero under area of magnetic force
if(node.position.x<400)
{
node.physicsBody.allowsRotation=FALSE;
///just for fun
node.physicsBody.linearDamping=10;
node.physicsBody.angularVelocity=10*10;
//where _gameHero is magnet fulling object
[node.physicsBody applyForce:CGVectorMake((10*10)*(_gameHero.position.x- node.position.x),(10*10)*(_gameHero.position.y-node.position.y)) atPoint:CGPointMake(_gameHero.position.x,_gameHero.position.y)];
}
}
}
remember both hero and coin body need be dynamic
Well seems like now you can since Apple introduced SKFieldNode in iOS 8.
Well you use the following code snippets to do what you're looking for, but it doesn't have attraction and repulsion properties
Body code:
let node = SKSpriteNode(imageNamed: "vortex")
node.name = "vortex"
node.position = position
node.run(SKAction.repeatForever(SKAction.rotate(byAngle: CGFloat.pi, duration: 1)))
node.physicsBody = SKPhysicsBody(circleOfRadius: node.size.width / 2)
node.physicsBody?.isDynamic = false
node.physicsBody?.categoryBitMask = CollisionTypes.vortex.rawValue
node.physicsBody?.contactTestBitMask = CollisionTypes.player.rawValue
node.physicsBody?.collisionBitMask = 0
addChild(node)
Upon contact with the that blackhole body:
func playerCollided(with node: SKNode) {
if node.name == "vortex" {
player.physicsBody?.isDynamic = false
isGameOver = true
score -= 1
let move = SKAction.move(to: node.position, duration: 0.25)
let scale = SKAction.scale(to: 0.0001, duration: 0.25)
let remove = SKAction.removeFromParent()
let sequence = SKAction.sequence([move, scale, remove])
player.run(sequence) { [unowned self] in
self.createPlayer()
self.isGameOver = false
}
}
I am stuck with a problem that is how to recognize some patterns in image.
the image is the image of paper which is pure white and the patterns are in four corners are in black.
I want to recognize the black patterns on the image?
I surf a lot on the net and found that the opencv as a answer. but there is nothing provided that describe how to use opencv in order to achieve the required feature.
Please help me with some coding point of view or provide some link which I should follow or any name of any open source library which I should use to achieve this feature.
The image for pattern is below:-
The image consist of pure white background and four black patterns in the corner.I need to recognize these black patterns in the all four corners all then process the image.One corner shown in oval to highlight it.
Any suggestions will be highly appreciated.
Thanks in advance!
I really don't understand your problem - if you say:
The image is the image of paper which is pure white and the patterns
are in four corners are in black.
Then what's the problem to mask only these four contours from image? After doing mask with 4 squares with length 40 pixels I got this:
To remove small areas you can use morphological operations. I got this:
And just draw them (optional) on input image. Here's result:
To implement this algorithm I use OpenCV library. I'm 100% sure that it works on IOS - OpenCV team finally published IOS version. So if you say:
I tried running the OpenCV-iOS link but the project does not run, it
is showing errors.
Then we can't help you with that because we are not telepathists to see your problem. Just small suggestion - try to google your problem. I'm 99% sure that it should help.
And lest I forget - here's c++ code:
Mat src = imread("input.png"), tmp;
//convert image to 1bit
cvtColor(src, tmp, CV_BGR2GRAY);
threshold(tmp, tmp, 200, 255, THRESH_OTSU);
//do masking
#define DELTA 40
for (size_t i=0; i<tmp.rows; i++)
{
for (size_t j=0; j<tmp.cols; j++)
{
if(!((i < DELTA && j < DELTA)
|| (i < DELTA && j > tmp.cols - DELTA)
|| (i > tmp.rows - DELTA && j < DELTA)
|| (i > tmp.rows - DELTA && j > tmp.cols - DELTA)))
{
//set color to black
tmp.at<uchar>(i, j) = 255;
}
}
}
bitwise_not(tmp,tmp);
//erosion and dilatation:
Mat element = getStructuringElement(MORPH_RECT, Size(2, 2), Point(1, 1));
erode(tmp, tmp, element);
dilate(tmp, tmp, element);
//(Optional) find contours and draw them:
vector<Vec4i> hierarchy;
vector<vector<Point2i> > contours;
findContours(tmp, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
for (size_t i=0; i<contours.size(); i++)
{
drawContours(src, contours, i, Scalar(0, 0, 255), 1);
}
Maybe this question is helpful for you, especially the link to the Tennis Ball Recognizing Tutorial seems to be pretty much what you are looking for.
Regarding how to use OpenCV on iOS you might want to take a look at OpenCV-iOS and Computer Vision with iOS.
Ok, I haven't found it anywhere. What should I do if i want to draw with core graphics per pixel? Like… I want to draw a line to pixels (45,61) and than (46,63) instead of drawing to point (23,31) or something like that. So what should I do in this case?
Should I use something like:
CGContextAddLineToPoint(context,22.5,30.5);
CGContextAddLineToPoint(context,23,31.5);
Or there is some better way?
I know about contentScaleFactor but should I use it as (when plotting some function for example):
for(int x=bounds.origin.x; x<=bounds.origin.x+bounds.size.width*[self contentScaleFactor]; i++)
CGContextAddLineToPoint(context,x/[self contentScaleFactor],y(x/[self contentScaleFactor]));
I know that the example code is not superb, but I think you'll get the idea.
I'll be vey thankful for help because I'm a bit confused with all this scale factor stuff.
Sounds like you are doing the Assignment3 from the iOS uTunes Stanford Course? :)
I think you are on the right track, as my implementation looks very similar:
for(int x=self.bounds.origin.x; x<=self.bounds.origin.x + (self.bounds.size.width * self.contentScaleFactor); x++) {
// get the scaled X Value to ask dataSource
CGFloat axeX = (x/self.contentScaleFactor - self.origin.x) / self.scale;
// using axeX here for testing, which draws a x=y graph
// replace axeX with the dataSource Y-Point calculation
CGFloat axeY = -1 * ((axeX * self.scale) + self.origin.y);
if (x == self.bounds.origin.x) {
CGContextMoveToPoint(context, x/self.contentScaleFactor, axeY);
} else {
CGContextAddLineToPoint(context, x/self.contentScaleFactor, axeY);
}
}
Tested on iOS-Sim iPhone4 (contentScaleFactor 1.0) + iPhone4S Device (contentScaleFactor 2.0).
Would be happy about possible improvements from other readers, because I am still learning.