SpriteKit displaying variable number - objective-c

What is the best way to display some value (that changes as the game runs) on the screen in iPhone SpriteKit? The only way I can think of is SKLabelNode, but it's probably not meant to be used like this and also I can't find any way to measure its width, which makes me unable to position it correctly (I want it to be in the bottom right corner). Thanks in advance :).
#Edit
My attempt at doing this:
SKLabelNode *someLabel = [SKLabelNode labelNodeWithFontNamed:#"Chalkduster"];
someLabel.text = some_string;
someLabel.fontSize = 30;
someLabel.fontColor = [SKColor blackColor];
someLabel.position = CGPointMake(some_int, 15);
[self addChild:someLabel];
The values of some_string and some_int change as the game runs, so someLabel is removed, someLabel.text and someLabel.position are re-assigned, and the label is added again. Yes, I am aware that this is a bad way to do this...

Unfortunately, SKLabelNode is your simplest bet, it's just not the most robust tool.
You just want to update its text and its position when you need to. Your code is correct, and if you want to get its actual size, then you would get the width of its frame.
update text:
someLabel.text = theNewText;
update position:
someLabel.position = theNewPosition;
get relative width
float widthOfLabelFrame = someLabel.frame.size.width;
additional alignment settings that might help (vertical baseline is the default):
someLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeRight;
someLabel.verticalAlignmentMode = SKLabelVerticalAlignmentModeBaseline;

Related

Changing the color of NSProgressIndicator?

What is the best way to change the color of NSProgressIndicator, is there an easier way than just to subclass it and then draw the whole component by myself?
Basically what I want to do is to have a similar component but with the ability to change the color of the bar.
I tried to google this but all the questions were quite outdated and didn't really concern the 10.10 OS X version that I am working on. Also checked cocoa controls and did only find 1 component that was for outdated OS X version.
You can use Quartz filters (e.g. hue adjust) for this directly in Interface Builder. This works better than expected.
It's in the Effects Inspector. Under "Content Filters" you can add "Hue Adjust"
Use "CIFalseColor" filter to get white color and more.
let colorFilter = CIFilter(name: "CIFalseColor")!
colorFilter.setDefaults()
colorFilter.setValue(color1, forKey: "inputColor0")
colorFilter.setValue(color2, forKey: "inputColor1")
proggressBar?.contentFilters = [colorFilter]
To change color of NSProgressIndicator use setControlTint: method. If you want to set custom color you have to draw such control manually. However, you should use the system color to keep this kind of control consistent across the system.
For Swift the method name is controlTint.
progressIndicator = NSProgressIndicator(frame: .......
progressIndicator.controlTint = .blueControlTint
you can use proggressBar.appearance = NSAppearance(named: .vibrantLight) // this is light or vibrantDark for "black" indictor
Based on Paxos' answer on the Interface builder, this is how I was able to do it programmatically:
let progress = NSProgressIndicator()
progress.contentFilters = [CIFilter(name: "CIHueAdjust", parameters: ["inputAngle": 4])!]
This would turn the bar green. I got this from looking at the Main.storyboard diff:
<progressIndicator maxValue="100" doubleValue="50" style="bar" translatesAutoresizingMaskIntoConstraints="NO" id="NIr-vo-obX">
<rect key="frame" x="3" y="22" width="210" height="20"/>
+ <contentFilters>
+ <ciFilter name="CIHueAdjust">
+ <configuration>
+ <real key="inputAngle" value="4"/>
+ <null key="inputImage"/>
+ </configuration>
+ </ciFilter>
+ </contentFilters>
</progressIndicator>
I was trying to change de Hue as seen in most answers, but I was getting a lot of issues to get the right specific color I wanted.
What did worked for me, and seems to be the most direct way to get a specific color, was using the CIColorMonochrome filter, where You can set any RGB color you want:
let myCustomColor: CIColor(red: 10, green: 10, blue: 10)
if let colorMonochrome = CIFilter(name: "CIColorMonochrome", parameters: [kCIInputColorKey: myCustomColor]) {
progressIndicator.contentFilters.append(colorMonochrome)
}
Based on the answer from KamyFC I found out that CIColor was required for the filter named "CIFalseColor".
Here is the Objective-C solution to make the progress bar whatever NSColor, in this example orange.
Don't forget to add #import Quartz; to your file.
// Create color:
CIColor *color = [[CIColor alloc] initWithColor:[NSColor orangeColor]];
// Create filter:
CIFilter *colorFilter = [CIFilter filterWithName:#"CIFalseColor"
withInputParameters:#{#"inputColor0" : color,
#"inputColor1" : color}];
// Assign to bar:
_progressBar.contentFilters = #[colorFilter];

THREE.js rotating camera around an object using orbit path

I am struggling in solving this problem.
On my scene, I have a camera which looks at the center of mass of an object. I have a some buttons that enable to set camera position on particular view (front view, back view,...) along a invisible sphere that surroung the object (constant radius).
When I click on the button, i would like the camera to move from its start position to the end position along the sphere surface. When camera moves I would like it to keep fixing center of mass of the object.
Has anyone have a clue on how to achieve this?
Thanks for help!
If you are happy/prefer to use basic trigonometry then in your initialisation section you could do this:
var cameraAngle = 0;
var orbitRange = 100;
var orbitSpeed = 2 * Math.PI/180;
var desiredAngle = 90 * Math.PI/180;
...
camera.position.set(orbitRange,0,0);
camera.lookAt(myObject.position);
Then in your render/animate section you could do this:
if (cameraAngle == desiredAngle) { orbitSpeed = 0; }
else {
cameraAngle += orbitSpeed;
camera.position.x = Math.cos(cameraAngle) * orbitRange;
camera.position.y = Math.sin(cameraAngle) * orbitRange;
}
Of course, your buttons would modify what the desiredAngle was (0°, 90°, 180° or 270° presumably), you need to rotate around the correct plane (I am rotating around the XY plane above), and you can play with the orbitRange and orbitSpeed until you hare happy.
You can also modify orbitSpeed as it moves along the orbit path, speeding up and slowing down at various cameraAngles for a smoother ride. This process is called 'tweening' and you could search on 'tween' or 'tweening' if you want to know more. I think Three.js has tweening support but have never looked into it.
Oh, also remember to set your camera's far property to be greater than orbitRadius or you will only see the front half of your object and, depending on what it is, that might look weird.

MKOverlayPathView Trouble enabling user to define pathWidth

Ok so I'm using Apples IOS Breadcrumb [Sample Code][1] .
I've a slider to the BreadcrumbViewController.xib called "lineWidth" and have a UIlabel which shows the value of the slider being changed called "sliderLabel". This I can do with relative ease.
Although now I want whatever number is in the sliderLabel to affect the CrumbPath lineWidth which at the moment is in CrumbPathView.m
{
CrumbPath *crumbs = (CrumbPath *)(self.overlay);
CGFloat lineWidth = MKRoadWidthAtZoomScale(zoomScale);
Now this can be changed to
CGFloat lineWidth = 200;
Or whatever.
so my question is how do I store the value of the sliderLabel located in the BreadcrumbViewController.xib (which is linked to the BreadcrumbViewController.h &.m) and retrieve the stored value (INT) in the CrumbPathView.m?
Im still learning so be nice.
Thank you in advance.

cocos2d progress bar

HI all,
i am developing a puzzle game in iPhone using cocos2d.I need a progress bar (like uiprogress bar) to show the game progress time.But i can't find any good example...
can anyone tell me the way???
well....i get a better solution...here is my code
CCProgressFromTo *to1 = [CCProgressFromTo actionWithDuration:levelTimeLimit from:100 to:0];
timeBar = [CCProgressTimer progressWithFile:#"Bar.png"];
timeBar.type = kCCProgressTimerTypeHorizontalBarLR;
[timeBar setPosition:ccp(384,84)];
[self addChild:timeBar];
[timeBar runAction:to1];
there is a class called CCProgressTimer in latest version of cocos2d..
thanks
You can use a CCSprite that you set the width of using
yourSprite.scaleX = 0.5 //This goes between 0.0 and 1.0.
You will have to calculate the required width, percentage and scaleX-factor manually but its pretty simple. I did my fiend hp bar implementation like this:
-(void)decreaseHp:(float)hpIn {
self.hp = self.hp-hpIn; //Decrease HP by specified amount.
float p = (self.hp*100)/self.maxHp; //Calculate new hp percentage.
self.hpBar.scaleX = p/100; //Convert percentage to a factor between 0 and 1.
}
self is the Fiend object and hpBar is a simple CCSprite with anchor ccp(0,0).
You you don't want you progress bar to stretch, but move instead, you will have to mask it with something and update its position instead of scaleX.

in core-plot, how do I get my axes to float?

I've tried setting isFloatingAxis to YES, but it just makes my axis disappear. My axis is set up as follows:
CPXYAxisSet *axisSetKin = (CPXYAxisSet *)kinematicsGraph.axisSet;
CPXYAxis *xKin = axisSetKin.xAxis;
[xKin setIsFloatingAxis:YES];
xKin.labelingPolicy = CPAxisLabelingPolicyAutomatic;
xKin.orthogonalCoordinateDecimal = CPDecimalFromString(#"0");
xKin.minorTicksPerInterval = 4;
xKin.preferredNumberOfMajorTicks = 9;
xKin.majorGridLineStyle = majorGridLineStyleKin;
xKin.minorGridLineStyle = minorGridLineStyleKin;
xKin.labelOffset = 10.0;
xKin.title = #"Lab Angle";
xKin.titleOffset = 30.0;
xKin.titleLocation = CPDecimalFromString(#"2.7");
Any ideas?
I too have been playing with the demo applications getting the plots to do what I need. Using CPTestApp-Iphone as a base I started playing with CPTestAppScatterPlotController.m
First I did:
y.isFloatingAxis = YES;
x.isFloatAxis = YES;
After hitting "Run" it seemed like the axis disappeared, but they are still there if you look closely. On the lefthand side and bottom of the screen the tick marks are there, just very hard to see.
To see the labels we need to add some extra padding. Notice towards the top of CPTestAppScatterPlotController.m we set some padding for the graph itself:
graph.paddingLeft = 10.0;
graph.paddingTop = 10.0;
graph.paddingRight = 10.0;
graph.paddingBottom = 10.0;
If we add:
graph.plotAreaFrame.paddingLeft = 30.0;
graph.plotAreaFrame.paddingBottom = 30.0;
One can get the labels to appear.
https://github.com/djw/core-plot/tree/9282845bddbb8c40ff314bbfa158beff797c91f7/examples
This states that the isFloatingAxis property has been removed from at least version 0.9.
I found issue 108 addresses this as well, and gives a place to see how CorePlot is handling the change: http://code.google.com/p/core-plot/issues/detail?id=108
It seems like the new way to float an axis is to set its constraints:
x.axisConstraints = [CPTConstraints constraintWithUpperOffset:132];
Ok, it looks like having constraints is the key. So I should have
CPConstraints y2Constraints = {CPConstraintFixed, CPConstraintFixed};
yKin.isFloatingAxis = YES;
yKin.constraints = y2Constraints;
in there as well. If you use CPConstraintNone instead, then the axis will actually move around as you resize the view that it's sitting in, to the point that it may appear to not be there at all when the program first starts. fixed keeps it in place. Now to figure out how to position it...
Oh, and another bit that's necessary to know: the axes, when set to float, can show up outside of the normal plot space. you can tweak exactly where by modifying the origin with, for example,
xKin.orthogonalCoordinateDecimal = CPDecimalFromString(#"0.5");
I'm not sure exactly what the units are for this, so you may have to play around with the numbers to find the one you want.
In the case that you want the axes to appear on the bottom and left side of the plot, and stay there, you have one more thing to do. Because you are setting the position to 0, using the .orthogonalCoordinateDecimal trick above, they will actually show up outside the plot space, and thus appear to have vanished. This was the case with my program when I first set setIsFloatingAxis:YES. To fix this, you have to add some padding to the plotAreaFrame. Note that this is different from the padding seen in the main section of CPTestApp, which goes [graph setPaddingLeft:0];
Instead, use graph.plotAreaFrame.paddingTop = 20.0; (or equivalently, [[graph plotAreaFrame] setPaddingTop: 20.0];
Full examples of that can be found in CPTestApp's AxisDemoController.m.
So I guess I kinda answered my own question here?