SpriteKit Animation Physics - animation

is there a way to apply skphysics to a animated character? Okay I have my player play an animation when I move it around the screen and below is it's animation code but for some reason when I want to apply physics to my animation, I get an error saying wrong data type.
Sending 'SKSpriteNode *_strong' to parameter of incompatible type 'CGRect' (aka 'struct CGRect')
NO Reputation and I can't answer my own question so I posted here.
actually never mind I had to add this _Player.frame and I am hoping this is right and is putting physics on my character. However, please correct me if I am wrong. thanks.
- (void) Player {
_Player = [SKSpriteNode spriteNodeWithImageNamed:#"bird"];
_Player.xScale = 0.88;
_Player.yScale = 0.88;
_Player.position = CGPointMake(100, 100);
[self addChild:_Player];
// 1
NSMutableArray *PlayerCh = [NSMutableArray arrayWithCapacity:2];
// 2
for (int i = 1; i < 2; i++) {
NSString *mytextureName = [NSString stringWithFormat:#"bird%d", i];
SKTexture *ItsTexture = [SKTexture textureWithImageNamed:mytextureName];
[PlayerCh addObject:ItsTexture];
}
// 3
for (int i = 2; i > 1; i--) {
NSString *mytextureName = [NSString stringWithFormat:#"bird%d", i];
SKTexture *ItsTexture = [SKTexture textureWithImageNamed:mytextureName];
[PlayerCh addObject:ItsTexture];
}
// 4
_PlayerAnimation = [SKAction animateWithTextures:PlayerCh timePerFrame:0.1];
// SKPHYSICS FOR PLAYER
SKPhysicsBody *MYPLAYER = [SKPhysicsBody bodyWithCircleOfRadius:_Player]; // I get a error here.
}

Of course this program has to crash when it runs
[SKPhysicsBody bodyWithCircleOfRadius:_Player] expects a float not an SKPriteNode, what you probably want to do is change this line of code to the following:
SKPhysicsBody *MYPLAYER = [SKPhysicsBody bodyWithCircleOfRadius:_Player.size.width/2];

Related

Unexpected behavior when working with PhysicsBodies in SpriteKit

I´ve got some issues with the physics bodies in this exercise.
when the dot(snake) is moving very fast, it "squeezes" itself through the physics bodies of the bricks. Can someone help, please?
snake:
self.physicsBody.categoryBitMask = snakeCategory;
self.physicsBody.collisionBitMask = lineCategory | brickCollissionCategory;
self.physicsBody.contactTestBitMask = brickContactCategory;
self.physicsBody.usesPreciseCollisionDetection = YES;
self.physicsBody.allowsRotation = NO;
self.physicsBody.dynamic = YES;
self.physicsBody.restitution = 0;
self.physicsBody.affectedByGravity = NO;
bricks:
self.physicsBody.categoryBitMask = brickCollissionCategory;
self.physicsBody.collisionBitMask = snakeCategory;
self.physicsBody.dynamic = NO;
self.physicsBody.affectedByGravity = NO;
self.physicsBody.usesPreciseCollisionDetection = YES;
self.physicsBody.restitution = 0;

xcode " use of undeclared identifier "

#import "MainScene.h"
static const CGFloat _scrollSpeed = 80.f;
#implementation MainScene {
CCSprite *_hero;
CCPhysicsNode *_physicsNode;
CCNode *_ground1;
CCNode *_ground2;
NSArray *_grounds;
}
- (void)didLoadFromCCB {
_grounds = #[_ground1, _ground2];
}
- (void)update:(CCTime)delta {
_hero.position = ccp(_hero.position.x + delta * _scrollSpeed, _hero.position.y);
_physicsNode.position = ccp(_physicsNode.position.x - (_scrollSpeed *delta), _physicsNode.position.y);
// loop the ground
for (CCNode *ground in _grounds) {
// get the world position of the ground
CGPoint groundWorldPosition = [_physicsNode convertToWorldSpace:ground.position];
// get the screen position of the ground
CGPoint groundScreenPosition = [self convertToNodeSpace:groundWorldPosition];
// if the left corner is one complete width off the screen, move it to the right
if (groundScreenPosition.x <= (-1 * ground.contentSize.width)) {
ground.position = ccp(ground.position.x + 2 * ground.contentSize.width, ground.position.y);
}
}
}
#end
And in this line
if (groundScreenPosition.x <= (-1 * ground.contentSize.width)) {
I have this 2 issues
Expected expression
Use of undeclared identifier 'lt'
thats my problem
plis help me, I really need it before possible
Wherever you copied your code from, it percent-escaped a less than sign, so it put in < instead of <. So just replace the < with <.

Truncate the last line of multi-line NSTextField

I'm trying to create a text field similar to Finder's file labels. I would like the last (second) line to be truncated in the middle.
I started with a multi-line NSTextField.
However, calling [self.cell setLineBreakMode:NSLineBreakByTruncatingMiddle]; results in a the text field showing only a single truncated line (no line breaks anymore).
Here is what it looks like in Finder:
If you want to wrap text like finder labels, using two labels doesn't do you any good since you need to know what the maximum breakable amount of text is on the first line. Plus, if you're building something that will display a lot of items two labels will overburden the GUI needlessly.
Set your NSTextField.cell like this:
[captionLabel.cell setLineBreakMode: NSLineBreakByCharWrapping];
Then find the code for "NS(Attributed)String+Geometrics" (Google it, it's out there). You must #import "NS(Attributed)String+Geometrics.h"
to measure text. It monkey patches NSString and NSAttributedString
I include the following code to wrap text exactly how Finder does in its captions. Using one label below the icon it assumes that, like Finder, there will be two lines of caption.
First this is how you will call the following code in your code:
NSString *caption = self.textInput.stringValue;
CGFloat w = self.captionLabel.bounds.size.width;
NSString *wrappedCaption = [self wrappedCaptionText:self.captionLabel.font caption:caption width:w];
self.captionLabel.stringValue = wrappedCaption ? [self middleTruncatedCaption:wrappedCaption withFont:self.captionLabel.font width:w] : caption;
Now for the main code:
#define SINGLE_LINE_HEIGHT 21
/*
This is the way finder captions work -
1) see if the string needs wrapping at all
2) if so find the maximum amount that will fit on the first line of the caption
3) See if there is a (word)break character somewhere between the maximum that would fit on the first line and the begining of the string
4) If there is a break character (working backwards) on the first line- insert a line break then return a string so that the truncation function can trunc the second line
*/
-(NSString *) wrappedCaptionText:(NSFont*) aFont caption:(NSString*)caption width:(CGFloat)captionWidth
{
NSString *wrappedCaption = nil;
//get the width for the text as if it was in a single line
CGFloat widthOfText = [caption widthForHeight:SINGLE_LINE_HEIGHT font:aFont];
//1) nothing to wrap
if ( widthOfText <= captionWidth )
return nil;
//2) find the maximum amount that fits on the first line
NSRange firstLineRange = [self getMaximumLengthOfFirstLineWithFont:aFont caption:caption width:captionWidth];
//3) find the first breakable character on the first line looking backwards
NSCharacterSet *notAlphaNums = [NSCharacterSet alphanumericCharacterSet].invertedSet;
NSCharacterSet *whites = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSRange range = [caption rangeOfCharacterFromSet:notAlphaNums options:NSBackwardsSearch range:firstLineRange];
NSUInteger splitPos;
if ( (range.length == 0) || (range.location < firstLineRange.length * 2 / 3) ) {
// no break found or break is too (less than two thirds) far to the start of the text
splitPos = firstLineRange.length;
} else {
splitPos = range.location+range.length;
}
//4) put a line break at the logical end of the first line
wrappedCaption = [NSString stringWithFormat:#"%#\n%#",
[[caption substringToIndex:splitPos] stringByTrimmingCharactersInSet:whites],
[[caption substringFromIndex:splitPos] stringByTrimmingCharactersInSet:whites]];
return wrappedCaption;
}
/*
Binary search is great..but when we split the caption in half, we dont have far to go usually
Depends on the average length of text you are trying to wrap filenames are not usually that long
compared to the captions that hold them...
*/
-(NSRange) getMaximumLengthOfFirstLineWithFont:(NSFont *)aFont caption:(NSString*)caption width:(CGFloat)captionWidth
{
BOOL fits = NO;
NSString *firstLine = nil;
NSRange range;
range.length = caption.length /2;
range.location = 0;
NSUInteger lastFailedLength = caption.length;
NSUInteger lastSuccessLength = 0;
int testCount = 0;
NSUInteger initialLength = range.length;
NSUInteger actualDistance = 0;
while (!fits) {
firstLine = [caption substringWithRange:range];
fits = [firstLine widthForHeight:SINGLE_LINE_HEIGHT font:aFont] < captionWidth;
testCount++;
if ( !fits ) {
lastFailedLength = range.length;
range.length-= (lastFailedLength - lastSuccessLength) == 1? 1 : (lastFailedLength - lastSuccessLength)/2;
continue;
} else {
if ( range.length == lastFailedLength -1 ) {
actualDistance = range.length - initialLength;
#ifdef DEBUG
NSLog(#"# of tests:%d actualDistance:%lu iteration better? %#", testCount, (unsigned long)actualDistance, testCount > actualDistance ? #"YES" :#"NO");
#endif
break;
} else {
lastSuccessLength = range.length;
range.length += (lastFailedLength-range.length) / 2;
fits = NO;
continue;
}
}
}
return range;
}
-(NSString *)middleTruncatedCaption:(NSString*)aCaption withFont:(NSFont*)aFont width:(CGFloat)captionWidth
{
NSArray *components = [aCaption componentsSeparatedByString:#"\n"];
NSString *secondLine = [components objectAtIndex:1];
NSString *newCaption = aCaption;
CGFloat widthOfText = [secondLine widthForHeight:SINGLE_LINE_HEIGHT font:aFont];
if ( widthOfText > captionWidth ) {
//ignore the fact that the length might be an odd/even number "..." will always truncate at least one character
int middleChar = ((int)secondLine.length-1) / 2;
NSString *newSecondLine = nil;
NSString *leftSide = secondLine;
NSString *rightSide = secondLine;
for (int i=1; i <= middleChar; i++) {
leftSide = [secondLine substringToIndex:middleChar-i];
rightSide = [secondLine substringFromIndex:middleChar+i];
newSecondLine = [NSString stringWithFormat:#"%#…%#", leftSide, rightSide];
widthOfText = [newSecondLine widthForHeight:SINGLE_LINE_HEIGHT font:aFont];
if ( widthOfText <= captionWidth ) {
newCaption = [NSString stringWithFormat:#"%#\n%#", [components objectAtIndex:0], newSecondLine];
break;
}
}
}
return newCaption;
}
Cheers!
PS Tested in prototype works great probably has bugs...find them
I suspect there are two labels there. The top one contains the first 20 characters of a file name, and the second contains any overflow, truncated.
The length of the first label is probably restricted based on the user's font settings.

EXC_BAD_ACCESS error in Xcode

I really need you guy HELP , I run my program in Xcode and its successful but later,
Its show me this error: **Thread 1: Program received signal :"EXC_BAD_ACCESS" on my program line that I have **bold below :
- (NSString *) ocrImage: (UIImage *) uiImage
{
CGSize imageSize = [uiImage size];
double bytes_per_line = CGImageGetBytesPerRow([uiImage CGImage]);
double bytes_per_pixel = CGImageGetBitsPerPixel([uiImage CGImage]) / 8.0;
CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider([uiImage CGImage]));
const UInt8 *imageData = CFDataGetBytePtr(data);
// this could take a while. maybe needs to happen asynchronously.
**char* text = tess->TesseractRect(imageData,(int)bytes_per_pixel,(int)bytes_per_line, 0, 0,(int) imageSize.height,(int) imageSize.width);**
// Do something useful with the text!
NSLog(#"Converted text: %#",[NSString stringWithCString:text encoding:NSUTF8StringEncoding]);
return [NSString stringWithCString:text encoding:NSUTF8StringEncoding];
}
Thank you guy .
make sure that imageData is not NULL here. That's the most common cause of what you're seeing. You should reconsider your title to something more related to your problem, and focus on the stacktrace and all the variables you are passing to TesseractRect().
The other major likelihood is that tess (whatever that is) is a bad pointer, or that is not part of the correct C++ class (I assume this is Objective-C++; you're not clear on any of that).
- (NSString *)readAndProcessImage:(UIImage *)uiImage
{
CGSize imageSize = [uiImage size];
int bytes_per_line = (int)CGImageGetBytesPerRow([uiImage CGImage]);
int bytes_per_pixel = (int)CGImageGetBitsPerPixel([uiImage CGImage]) / 8.0;
CFDataRef data =
CGDataProviderCopyData(CGImageGetDataProvider([uiImage CGImage]));
const UInt8 *imageData = CFDataGetBytePtr(data);
// this could take a while. maybe needs to happen asynchronously?
char *text = tess.TesseractRect(imageData, bytes_per_pixel, bytes_per_line, 0,
0, imageSize.width, imageSize.height);
NSString *textStr = [NSString stringWithUTF8String:text];
delete[] text;
CFRelease(data);
return textStr;
}

Avoid translating standard menus items in XCode project

I have an XCode project, with the XIB interface files built using Interface Builder. I'm building localized XIB files by using ibtool to extract strings, translating them, and using ibtool again to build localized XIB files.
However, doing this means I have to translate all items in the application menus, including those that are completely standard (File, Save, Open, Minimize, etc.). Is there a way to avoid that?
i've developed a solution to this problem.
https://www.corecode.io/index_opensource.html
look for "Translator", it will translate your MainMenu.strings file into a dozen languages with the standard Apple translations for the standard menu item strings.
if you find some strings or languages missing that Aapple has included in their base apps, please send a patch over.
So, apparently no way around this.
I have been looking for a similar solution for a while and I found this resource
http://www.bdunagan.com/2009/03/15/ibtool-localization-made-easy/
It quotes toward the end of the article:
ibtool will look through MainMenu.xib for every user-visible string and insert that string with an associated ObjectID into MainMenu.strings, essentially a dictionary of strings keyed by ObjectID. Even better, the tool sorts them by ObjectID, so versioned .strings files are nicely diff’able. I can easily see what strings are added, removed, or just changed. Let me repeat this because it’s so incredibly handy: .strings files diff well! Of course, these .strings files are unicode, so they are not grep’able. Below is an example of the output for a string:
Go ahead and take a look I really hope it helps you as much as it helped me!
Translator by https://github.com/core-code/MiscApps/blob/master/Translator/Translator/MainMenuTranslations.plist
is cool but if you do not want to deal with 30 MainMenu.string files in your build (I personally don't) - you can just add MainMenuTranslations.plist to your resources (230KB uncompressed is tiny) and do it on the fly like this:
- (void) processMenu: (NSString*) app {
NSDictionary* d = [self loadMenuTranslations: app];
NSMenu* mm = NSApplication.sharedApplication.mainMenu;
for (int i = 0; i < mm.numberOfItems; i++) {
NSMenuItem* mi = [mm itemAtIndex: i];
mi.title = [self translateMenu: mi.title withDictionary: d];
NSMenu* sm = [[mm itemAtIndex: i] submenu];
sm.title = [self translateMenu: sm.title withDictionary: d];
for (int j = 0; j < sm.numberOfItems; j++) {
NSMenuItem* mi = [sm itemAtIndex: j];
mi.title = [self translateMenu: mi.title withDictionary: d];
}
}
}
- (NSString*) translateMenu: (NSString*) key withDictionary: (NSDictionary*) dictionary {
for (NSString* lang in dictionary) {
NSDictionary* translation = dictionary[lang];
NSString* t = translation[key];
if (t != null) {
return t;
}
}
return key;
}
- (NSDictionary*) loadMenuTranslations: (NSString*) app {
NSArray* langs = [NSUserDefaults.standardUserDefaults objectForKey: #"AppleLanguages"];
NSURL* url = [NSBundle.mainBundle URLForResource:#"MainMenuTranslations.plist" withExtension: null];
NSMutableDictionary* r = NSMutableDictionary.new;
NSDictionary* translations = [NSDictionary dictionaryWithContentsOfURL: url];
for (NSString* lang in langs) {
NSString* locale = [NSString stringWithFormat:#"%#.lproj", lang];
NSDictionary* translation = translations[locale];
NSMutableDictionary* d = [NSMutableDictionary.alloc initWithCapacity: translations.count * 3 / 2];
for (NSString* k in translation) {
NSString* v = translation[k];
NSString* key = k;
if ([k indexOf: #"APPLICATIONNAME"] >= 0) {
key = [k stringByReplacingOccurrencesOfString: #"APPLICATIONNAME" withString: app];
}
if ([v indexOf: #"APPLICATIONNAME"] >= 0) {
v = [v stringByReplacingOccurrencesOfString: #"APPLICATIONNAME" withString: app];
}
d[key] = v;
}
if (d.count > 0) {
r[lang] = d;
}
}
return r;
}
just call it from
- (void) applicationDidFinishLaunching: (NSNotification*) n {
// ...
[self processMenu: #"<your app name>"];
}
I wish there is a UniversalTranslation.plist somewhere (which could be probably collected automatically via creative use of translate.google.com)

Resources