Checking if tile exists without Assertion Failure? - objective-c

[layer tileGIDAt:position]
If I give it a position outside the map, I get an Assertion Failure, which is just normal.
I need a way to know when a tile exists. Before running the above code so I don't get a an Assertion Failure and also to do other things in case the tile does not exist. But how can I? Is there not a method in the CCTMXLayer class to check that?

To test if a tile exists, test if the tile GID is 0. Before that you can test if the position is on the tilemap as such:
if (position.x < layer.size.width &&
position.y < layer.size.height &&
position.x >= 0 && position.y >= 0)
{
// position is within tilemap layer …
if ([layer tileGIDAt:position] != 0)
{
// tile at position exists …
}
}

Related

Hit detection implementation for Processing JS

I am having some trouble with programming hit detection in Processing.JS. I have tried to make a function that checks if something is touching an object and returns true and otherwise returns false. This is that here.
`Box.prototype.checkTouching = function(v){
if(v.position.x > this.position.x - this.width/2 && v.position <
this.position.x + this.width/2 && v.position.y > this.positon.y -
this.height/2 && v.position.y < this.position.y + this.height/2){
return true;
}else{
return false;
}
};`
I am implementing it by creating a new variable "b" in my draw function that holds the value the function returned then using an if statement to check if the value "b" is holding is true. Like so
var b = box3.checkTouching(mos);
if(b === true){
println("It works");
}
What should happen when the two objects touch is that a message saying "it works" gets printed in to the console. Unfortunately even when the object the function is running on is touching the object that is running it nothing happens. I have already checked to see if the logic works and it is valid so I know it has to be my implementation I just can not seem to find out what is wrong with my implementation. Can anyone tell what I am doing wrong? Full program here
You need to check whether the rectangles overlap. You'd do this by checking each side, like this:
if(rectOneRight > rectTwoLeft && rectOneLeft < rectTwoRight && rectOneBottom > rectTwoTop && rectOneTop < rectTwoBottom){
//collision
}
Shameless self-promotion: I've written a tutorial on collision detection in Processing (including rectangle-rectangle collision) available here.
To build on what Kevin posted, say I want to hover my mouse over a rectangle. processing has the built in variables mouseX, mouseY that return the coordinates of the mouse.
so I would check if the mouse X position was greater then the rect X pos, and less than the rect X pos + the rect width. the, do the same with the mouseY, rect Y and rect height
if (mouseX > rectXpos &&
mouseX < rectXpos + rectWidth &&
mouseY > rectYpos &&
mouseY < rectYpos + rectHeight) {
// the button is being hovered over
}

Obj-C Method calls super slow, lots more CPU usage?

I'm doing pixel processing and when I call an empty Objective-C method, it uses 25% more CPU.
Furthermore another strange occurrence is if I have another Obj-C function call in that method that never gets called, it increases the CPU usage by an extra 10%.
Here's the code I'm calling:
- (void)addLeftCorner:(struct Position)p top:(BOOL)top {
if (top) {
[blackBorderLock lock];
[topLeftAllyMinionCorners addObject:[NSValue valueWithBytes:&p objCType:#encode(struct Position)]];
[blackBorderLock unlock];
} else {
[blackBorderLock lock];
[bottomLeftAllyMinionCorners addObject:[NSValue valueWithBytes:&p objCType:#encode(struct Position)]];
[blackBorderLock unlock];
}
}
- (void) processPixel:(uint8_t *)pixel x:(int)x y:(int)y{
//Assume multithreaded
if (pixel[0] == 0 && pixel[1] == 0 && pixel[2] == 0) {
//Check if top left border
if (x < imageData.imageWidth-1) {
if (y < imageData.imageHeight-1) { //Check for top left bar
//Check bottom right pixel
uint8_t *bottomRightPixel = pixel + (imageData.imageWidth + 1)*4;
if (bottomRightPixel[2] == 81 && bottomRightPixel[1] == 162 && bottomRightPixel[0] == 230) {
uint8_t *rightPixel = pixel + (1)*4;
if (rightPixel[0] == 0 && rightPixel[1] == 0 && rightPixel[2] == 0) {
uint8_t *bottomPixel = pixel + (imageData.imageWidth)*4;
if (bottomPixel[0] == 0 && bottomPixel[1] == 0 && bottomPixel[2] == 0) {
struct Position p;p.x=x;p.y=y;
[self addLeftCorner:p top:true];
}
}
}
}
if (y > 0) { //Check for bottom left bar
//Check top right pixel
uint8_t *topRightPixel = pixel + (-imageData.imageWidth + 1)*4;
if (topRightPixel[2] == 40 && topRightPixel[1] == 80 && topRightPixel[0] == 114) {
uint8_t *rightPixel = pixel + (1)*4;
if (rightPixel[0] == 0 && rightPixel[1] == 0 && rightPixel[2] == 0) {
uint8_t *topPixel = pixel - (imageData.imageWidth)*4;
if (topPixel[0] == 0 && topPixel[1] == 0 && topPixel[2] == 0) {
struct Position p;p.x=x;p.y=y;
[self addLeftCorner:p top:false];
}
}
}
}
}
}
}
In running this, the addLeftCorner never gets called yet if I comment it out, I get an extra 10% CPU usage. Also just calling the method processPixel takes 25% CPU usage alone.
Why is this? Is there a way to optimize it? I'd like to get that 35% CPU back.
TL;DR - You will want to investigate the use of NSObject -methodForSelector: as a means of avoiding Objective-C runtime overhead. Use this judiciously.
-
There's some terminology that comes from Smalltalk that is useful in keeping a mental model of what's really going on. We generally refer to invoking a method rather than calling a function in recognition that a dynamic language like Objective-C resolves function addresses at runtime, every time, in response to the kind of object that is the receiver of the message.
This dynamic dispatch is at the heart of the polymorphism of dynamic languages. And while the Objective-C runtime goes to almost superhuman lengths to make method invocation as efficient as possible, it will never ever be as efficient as a direct function call.
Most of the time, method invocation inefficiencies don't matter. The usually small loss of efficiency is swamped by human interaction with the application. But for computational kernels like image processing, the inefficiencies will become apparent.
By using NSObject -methodForSelector:, you can resolve the method into a function address once, and after that skip the runtime lookup. Study the documentation carefully. Make sure you understand what a SEL is and what an IMP is. Calling a method as a function requires two extra arguments, self and _cmd. Make sure you understand what they are and how they're used.
Most of all, make sure that profiling absolutely proves that bypassing the runtime like this is necessary. Based on your description of the problem, I'm not completely convinced you're seeing exactly what the issue is. But you're the one who knows your software best.
You'll be preventing the possibility of polymorphism of the objects you're using this method/function with, so it kind of sets this aspect of your design in concrete, without the usual flexibility of a dynamic language.

How to get multiple sprites to bounce off the bounds of a scene in Objective-C

I have a game I'm creating with sprite-kit with 25 sprites that are all children of one sprite node BOMNeutNode. At the beginning of the game I create 25 child nodes within the scene using a for-loop, and set them all moving in a random direction using physicsBody.velocity.
What I want to do is to get them to bounce off the bounds of the scene when they reach the edge. I assumed the code below would do the trick to begin with, but it only seems to work on 1 of the 25 nodes (for that one node it is working perfectly well). I'm thinking this must be due to where I have this code positioned in my GamePlayScene code. I thought it would be appropriate to put it in the update section of the game run loop. Maybe I have to set this rule in the node itself?
I also thought it might be that I need to identify ALL nodes named #"Neut" but I can't find the syntax to do this. Please let me know if you need more code than I have provided.
(void) update:(NSTimeInterval)currentTime {
BOMNeutNode *neut = (BOMNeutNode*)[self childNodeWithName:#"Neut"];
if (neut.position.y > self.frame.size.height-50) {
neut.physicsBody.velocity = CGVectorMake(0, -100);
} else if (neut.position.y < 50) {
neut.physicsBody.velocity = CGVectorMake(0, 100);
} else if (neut.position.x > self.frame.size.height-50) {
neut.physicsBody.velocity = CGVectorMake(-100, 0);
} else if (neut.position.x < 50) {
neut.physicsBody.velocity = CGVectorMake(100, 0);
}
}
Any suggestions would be greatly appreciated.
One easy way to do this is to add a SKPhysicsBody created with bodyWithEdgeLoopFromRect: to your SKScene. That way the physics engine can handle all the bouncing for you (with the correct angles and everything).
Typically you'd want to add it in your SKScene's didMoveToView: method. Something like:
- (void)didMoveToView:(SKView*)view {
// ... any other setup you might need ...
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:CGRectMake(50, 50, self.size.width - 100, self.size.hight - 100)];
}
If you go this route, that should take care of everything; you shouldn't need the code you currently have in your update: method.
The problem is that you have many nodes called Neut and its finding one of them and checking if its inside the frame, what you need to do is to find all nodes with that name and run the code on all of them
-(void)update:(NSTimeInterval)currentTime {
[self enumerateChildNodesWithName:#"Neut" usingBlock:^(SKNode *node, BOOL *stop) {
if (node.position.y > self.frame.size.height-50) {
node.physicsBody.velocity = CGVectorMake(0, -100);
} else if (node.position.y < 50) {
node.physicsBody.velocity = CGVectorMake(0, 100);
} else if (node.position.x > self.frame.size.height-50) {
node.physicsBody.velocity = CGVectorMake(-100, 0);
} else if (node.position.x < 50) {
node.physicsBody.velocity = CGVectorMake(100, 0);
}
}];
}

ios int to float comparison always evaluates to true

I am trying to compare a CGFloat to an integer value. Based on this value, execute a conditional... pretty standard. However, this will always be true for some reason. I even print out the values and they are clearly less than 800.... I have tried a bunch of different combinations, the most recent is shown below, I thought maybe it was comparing the size of float and the size of the int based purely on its binary values, so I tried this risky little cast operation... Any ideas?
CGPoint textViewPoint = [scroller convertPoint:[textView center] toView:(UIView *)self.view];
NSLog(#"the y coord is %f", textViewPoint.y);
int size = (int)textViewPoint.y;
NSLog(#"the yint %d", size);
//move the main view, so that the keyboard does not hide it.
//if (self.scroller.frame.origin.y >= 0 && textViewPoint.y > 800.0);
if(size > 800);
{
NSLog(#"moving up");
The problem is the ; at the end of the if(size > 800); line, not the int vs. float comparison. Remove it and all should be OK.
This is because this semicolon is interpreted as the body of your if statement, and that's this NO-OP statement that is executed when the condition is true. Then, the rest of your code next to this if empty body is outside of the if body so is executed whatever the condition value. That's exactly as if you had written:
if(size > 800)
{
}
{
NSLog(#"moving up");
}
Compiler Warning Tip
The compiler generally warns you about this mistake. Be sure that you have the "Empty Loop Bodies" warning activated in your project Build Settings (compiler flag -Wempty-body): this way the next time you do this mistake, you will have a warning about it and will know what is wrong and how to fix it.

point light illumination using Phong model

I wish to render a scene that contains one box and a point light source using the Phong illumination scheme. The following are the relevant code snippets for my calculation:
R3Rgb Phong(R3Scene *scene, R3Ray *ray, R3Intersection *intersection)
{
R3Rgb radiance;
if(intersection->hit == 0)
{
radiance = scene->background;
return radiance;
}
...
// obtain ambient term
... // this is zero for my test
// obtain emissive term
... // this is also zero for my test
// for each light in the scene, obtain calculate the diffuse and specular terms
R3Rgb intensity_diffuse(0,0,0,1);
R3Rgb intensity_specular(0,0,0,1);
for(unsigned int i = 0; i < scene->lights.size(); i++)
{
R3Light *light = scene->Light(i);
R3Rgb light_color = LightIntensity(scene->Light(i), intersection->position);
R3Vector light_vector = -LightDirection(scene->Light(i), intersection->position);
// check if the light is "behind" the surface normal
if(normal.Dot(light_vector)<=0)
continue;
// calculate diffuse reflection
if(!Kd.IsBlack())
intensity_diffuse += Kd*normal.Dot(light_vector)*light_color;
if(Ks.IsBlack())
continue;
// calculate specular reflection
... // this I believe to be irrelevant for the particular test I'm doing
}
radiance = intensity_diffuse;
return radiance;
}
R3Rgb LightIntensity(R3Light *light, R3Point position)
{
R3Rgb light_intensity;
double distance;
double denominator;
if(light->type != R3_DIRECTIONAL_LIGHT)
{
distance = (position-light->position).Length();
denominator = light->constant_attenuation +
(light->linear_attenuation*distance) +
(light->quadratic_attenuation*distance*distance);
}
switch(light->type)
{
...
case R3_POINT_LIGHT:
light_intensity = light->color/denominator;
break;
...
}
return light_intensity;
}
R3Vector LightDirection(R3Light *light, R3Point position)
{
R3Vector light_direction;
switch(light->type)
{
...
case R3_POINT_LIGHT:
light_direction = position - light->position;
break;
...
}
light_direction.Normalize();
return light_direction;
}
I believe that the error must be somewhere in either LightDirection(...) or LightIntensity(...) functions because when I run my code using a directional light source, I obtain the desired rendered image (thus this leads me to believe that the Phong illumination equation is correct). Also, in Phong(...), when I computed the intensity_diffuse and while debugging, I divided light_color by 10, I was obtaining a resulting image that looked more like what I need. Am I calculating the light_color correctly?
Thanks.
Turned out I had no error. The "final image" I was comparing my results to wasn't computed correctly.