how to make objects appear from one side when I rotate them in iOS ? (code + gif ) inside - objective-c

how to make objects appear from (one side only), when I rotate them in iOS ?
What I want to happen, (as you can see i can add another face to my UITableview cell)
What is happening, i can't even add another face since the previous one is showing up again
The Code I'm using
func animate()
{
var id = CATransform3DIdentity
id.m34 = -1.0 / 1000
var transformAnim = CAKeyframeAnimation(keyPath:"transform")
transformAnim.values = [
NSValue(CATransform3D: CATransform3DRotate(id, 0 * CGFloat(-M_PI_2), 0, 1.0, 0)),
NSValue(CATransform3D: CATransform3DRotate(id, 1 * CGFloat(-M_PI_2), 0, 1.0, 0)),
NSValue(CATransform3D: CATransform3DRotate(id, 0 * CGFloat(-M_PI_2), 0, 1.0, 0))
]
transformAnim.keyTimes = [0, 0.5, 1.0]
transformAnim.duration = 0.7
self.imageViewLogo.layoutIfNeeded()
self.imageViewLogo.layer.addAnimation(transformAnim, forKey: "transform")
}
If you know a feature called [force 2 sided] in 3ds max for example, I want it turned of here, but it seems that iOS has no feature like this.
This is an advanced question, I wish an expert answers me.
Thanks.
EDIT
if you are still not sure what I'm asking, I mean this :
how to make an object to show only from one side when i rotate it ?

That is a standard flip transition. Take a look at the UIView method +transitionFromView:toView:duration:options:completion:, specifically the UIViewAnimationOptionTransitionFlipFromLeft and UIViewAnimationOptionTransitionFlipFromRight settings.
There is also a view controller transition if you want to do a flip transition to a different view controller.
If you want to build this animation yourself it's much more work.
What you have to do is create 2 separate animations, one for the front face and one for the back face:
First, you animate the front face rotating to 90 degrees, at which point it disappears because you are viewing it edge-on. At that point you add your back half view/layer, but facing the other way. Then in the second animation you rotate the new view 90 degrees, which leaves it flat and face-up. It's possible to get a seamless animation that gives you exactly the effect you want, but it's difficult, fussy code to write.

the solution was a simple statement that I never heard of before
imageViewLogo.layer.doubleSided = false
from apple's website :-
A Boolean indicating whether the layer displays its content when
facing away from the viewer. Animatable.

Related

libgdx camera position using viewport

I am rather experiences libgdx developer but I struggle with one issue for some time so I decided to ask here.
I use FillViewport, TiledMap, Scene2d and OrtographicCamera. I want the camera to follow my player instance but there are bounds defined (equal to mapsize). It means that camera will never ever leave outside of map, so when player comes to an end of the map camera stops following and he goes to the edge of the screen itself. Maybe sounds complicated but it's simple and I am sure that you know what I mean, it's used in every game.
I calculated 4 values:
minCameraX = camera.viewportWidth / 2;
minCameraY = camera.viewportHeight / 2;
maxCameraX = mapSize.x camera.viewportWidth / 2;
maxCameraY = mapSize.y - camera.viewportHeight / 2;
I removed not necessary stuff like unit conversion, camera.zoom etc. Then I set the camera position like this:
camera.position.set(Math.min(maxCameraX, Math.max(posX, minCameraX)), Math.min(maxCameraY, Math.max(posY, minCameraY)), 0);
(posX, posY is player position) which is basically setting camera to player position but if it's to high or too low it sets it to max or min defined before in right axis. (I also tries MathUtils.clamp() and it works the same.
Everything is perfect until now. Problem occures when aspect ratio changes. By default I use 1280x768 but my phone has 1280x720. Because of that bottom and top edges of the screen are cut off because of the way how FillViewport works. Because of that part of my map is cut off.
I tried to modify maximums and minimums, calculate differences in ratio and adding them to calculations, changing camera size, different viewports and some other stuff but without success.
Can you guys help?
Thanks
I tried solution of noone and Tenfour04 from comments above. Both are not perfect but I am satisified enough i guess:
noone:
camera.position.x = MathUtils.clamp(camera.position.x, screenWidth/2 + leftGutter, UnitConverter.toBox2dUnits(mapSize.x) - screenWidth/2 + rightGutter);
camera.position.y = MathUtils.clamp(camera.position.y, screenHeight/2 + bottomGutter, UnitConverter.toBox2dUnits(mapSize.y) - screenHeight/2 - topGutter);
It worked however only for small spectrum of resolutions. For strange resolutions where aspect ratio is much different than default one I've seen white stripes after border. It means that whole border was printer and some part of the world outside of border. I don't know why
Tenfour04:
I changed viewport to ExtendViewport. Nothing is cut off but in different aspect ratios I also can see world outside of borders.
Solution for both is to clear screen with same color as the border is and background of level separatly which gave satisfying effect in both cases.
It stil has some limitations. As border is part of the world (tiled blocks) it's ok when it has same color. In case border has different colors, rendering one color outside of borders won't be a solution.
Thanks noone and Tenfour04 and I am still opened for suggestions:)
Here are some screenshots:
https://www.dropbox.com/sh/00h947wkzo73zxa/AAADHehAF4WI8aJ8bu4YzB9Va?dl=0
Why don't you use FitViewport instead of FullViewport? That way it won't cut off your screen, right?
It is a little bit late, but I have a solution for you without compromises!
Here width and height are world size in pixels. I use this code with FillViewport and everything works excellent!
float playerX = player.getBody().getPosition().x*PPM;
float playerY = player.getBody().getPosition().y*PPM;
float visibleW = viewport.getWorldWidth()/2 + (float)viewport.getScreenX()/(float)viewport.getScreenWidth()*viewport.getWorldWidth();//half of world visible
float visibleH = viewport.getWorldHeight()/2 + (float)viewport.getScreenY()/(float)viewport.getScreenHeight()*viewport.getWorldHeight();
float cameraPosx=0;
float cameraPosy=0;
if(playerX<visibleW){
cameraPosx = visibleW;
}
else if(playerX>width-visibleW){
cameraPosx = width-visibleW;
}
else{
cameraPosx = playerX;
}
if(playerY<visibleH){
cameraPosy = visibleH;
}
else if(playerY>height-visibleH){
cameraPosy = height-visibleH;
}
else{
cameraPosy = playerY;
}
camera.position.set(cameraPosx,cameraPosy,0);
camera.update();

applyBlurWithRadius working on iPhone 6, not 6+ (UIImage+ImageEffects)

I'm using Apple's UIImage+ImageEffects category from WWDC (2013?)
This method works just fine on iPhone 6, but creates a really strange unblurred, oversaturated image on iPhone 6 Plus:
[self applyBlurWithRadius:60 tintColor:[UIColor colorWithWhite:1.0 alpha:0.3] saturationDeltaFactor:2.4 maskImage:nil];
iPhone 6 (proper):
iPhone 6 Plus (weird):
Any idea what's going on?
Update: I've determined through trial and error that setting the blurRadius to anything less than or equal to 50 shows up OK, so it's related to the radius. I'd still like to know what exactly is causing it to goof on the larger screen.
I know this question is old and the OP has since moved on, but I would like to explain why it's different on each phone... for future generations.
The iPhone6 and the iPhone6+ have different screen resolutions. Mainly, the iPhone6 is has a scale of 2.0, while the iPhone6+ has a scale of 3.0.
Why does this matter?
In the source code for applyBlurWithRadius in the source file UIImage+ImageEffects.m, you will find these lines:
CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale];
uint32_t radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5);
if (radius % 2 != 1) {
radius += 1; // force radius to be odd so that the three box-blur methodology works.
}
You can see that the inputRadius will be different based on what the scale of the screen is. So, on the iPhone6, this value will be 60*2 (end result for radius will be: 227), and on the iPhone6+ the value will be 60*3 (end result for radius will be 339). This will obviously produce the different results since they are different values.
As for why the color difference? I am pretty sure the radius shouldn't exceed 255 otherwise undefined results may occur (probably integer overflow, causing color components to wrap back to zero). Since the iPhone6+'s screen scale value pushes it above this value, you see weird results, but not on the iPhone6 since it's below that threshold.
You should be able to see the same weirdness happen on an iPhone6 by using the value of 90 for the blurRadius parameter.
Side note: You shouldn't need values above 30 for parameter blurRadius anyway -- the results won't be much different beyond that point.
Hope this helps you.

Variable Jump Height

I have been having great difficulty creating a jumping system whereby the user can tap the jump button for a small jump and hold it down for a higher jump.
I stumbled upon this topic:
https://gamedev.stackexchange.com/questions/13277/variable-height-jumping-in-side-scrollers
Which greatly helped me develop the following code:
PlayerMovementTimer = [NSTimer scheduledTimerWithTimeInterval:0.005 target:self selector:#selector(movePlayer) userInfo:nil repeats:YES];
[JumpButton addTarget:self action:#selector(jumpPlayer:) forControlEvents:UIControlEventTouchDown];
[JumpButton addTarget:self action:#selector(stopJump:) forControlEvents:UIControlEventTouchCancel | UIControlEventTouchUpInside | UIControlEventTouchDragExit];
- (void)movePlayer
{
CGFloat playerY = Player.center.y + PlayerYV;
if(playerY > 264) {
PlayerYV = 0;
playerY = 264;
}
if(playerY < 264) {
PlayerYV += 0.048f - PlayerYD;
}
if(HoldingJump && PlayerYV < 0 && PlayerYD + 0.0018f < 0.048f) {
PlayerYD += 0.0018f;
}
Player.center = CGPointMake(Player.center.x + PlayerXV, playerY);
}
- (IBAction)jumpPlayer:(id)sender
{
if(Player.center.y == 264) {
PlayerYD = 0;
PlayerYV = -2.25;
HoldingJump = true;
}
}
- (IBAction)stopJump:(id)sender
{
HoldingJump = false;
}
The code seems to work (some of the values need a bit of fine tuning but I haven't gotten round to that yet). The only problem is that the movement appears to be slightly jerky (even on the real device) and that when the player is at the top of the jump they accelerate really slowly and no values I put seem to be able to get the jump to look smooth like on Mario games.
Please take a look at the code and see if I am missing something obvious, or if there is a more efficient method of controlling movement than an NSTimer calling a void function. Also, is setting a UIImageView's position to a float value bad?
Thanks.
So there are quite a few things wrong here. First, yes, you should never be setting the origin of an ImageView or any other UI element to a coordinate position that is a fractional pixel. This causes sub-pixelling which will blur your image. To avoid this, all CGFloats should be rounded to the nearest whole number using roundf() or other similar rounding functions.
Another issue I can see is that you're setting Player.center. I hope for your sake that Player is not an ImageView cause you're going to be making your life harder. As mentioned above, when the origin of a frame is not set to a CGFloat that is a round number, you'll get sub-pixelling. When you use the center property, you can easily cause yourself to get on a bad origin value. For example, if I have a 11 by 11 image and set it's center to (11,11), the origin will get set to (5.5,5.5) and will cause sub-pixelling. Easy ways to avoid this is just do the math to place the origin correctly and make sure to round the CGFloats that you feed into it (or use CGRectIntegral on the frame before you set it).
A third issue here is that the timer is being called 0.005 seconds. Let's assume you want this game to run with 60 FPS. 60 FPS translates to about 0.0167 seconds. The timer is calling the method three times more often then it would need to even if you wanted 60 FPS and additionally, calling this method so often could be causing some of your jerky motion.
Now in terms of getting a "Mario" like jump, what you really need to do is look at getting a dedicated physics engine since if you're using the code above, you don't appear to have one. What a physics engine would do is it would apply a constant "gravity" which will help make the player jumps look and act more realistically. You would, when a player presses a button, apply an impulse up on the player character. The use of impulses would also simplify your work as you could apply impulses in different ways depending on how long they hold the button, etc. The code above is simply trying to get around this problem instead of addressing the real issue of you not having a physics engine.
Go investigate cocos2D and Box2D as a possible physics engine you could use. There are a wealth of resources on cocos2D+Box2D and there is a developer who even has made a tutorial on using cocos2D to create a Super Mario clone that should give you some basic understanding of how physics engines work: http://www.raywenderlich.com/15230/how-to-make-a-platform-game-like-super-mario-brothers-part-1

How to correctly paint a huge image

I'm fairly new to wxWidgets so please bear with me. Let's say I have a 10Kx10K image and my wxScrolledWindow has a size of 640x480. I load the whole image into a wxBitmap which I use in my paint function.
Now in my OnPaint function I just say
wxPaintDC dc(this);
dc.DrawBitmap(_Bitmap, 0, 0 );
This somewhat works for the first few paints but soon the Window content is out order and artifacts appear. This happens very fast when I move a scroll bar back and forth very quickly.
I use the latest wxWidgets on a Windows 7 machine.
So, how can I improve my painting code?
Many thanks,
Christian
Using a 10000x10000 wxBitmap is a bad idea on its own, it may simply fail to be created on an older system (that's 400MiB of video RAM!). Drawing it entirely is sheer madness.
I don't know where does your data come from but in a typical case of e.g. a map to be shown on screen, you should break it into tiles, convert the tiles that are currently visible on screen to wxBitmap (or several of them) and draw only those.
Then you may optimize your drawing by using double buffering (which is relatively useless under Windows 7 that double buffers everything on its own) and otherwise, but you should be using a reasonably-sized backing store bitmap.
This sounds like something that might be helped by using double buffering.
The first thing to start trying is to replace wxPaintDC with wxBufferedPaintDC
For more suggestions, here is a wiki article on the subject: http://wiki.wxwidgets.org/Flicker-Free_Drawing
As Ravenspoint kindly pointed out, there is an article on wxWidgets' wiki. So according to that article two things need to happen. First override the EVT_ERASE_BACKGROUND with an empty function.
void Canvas::EraseBackground( wxEraseEvent& WXUNUSED(event))
{
}
And second to implement a basic double buffering scheme. Here is how I did it.
void Canvas::OnPaint(wxPaintEvent& WXUNUSED(event))
{
int x, y;
GetViewStart(&x, &y);
wxRect Client_Area = GetClientRect();
int width = Client_Area.width;
int height = Client_Area.height;
wxBitmap Current = _Bitmap.GetSubBitmap(wxRect( x * 10, y * 10, width, height ));
wxPaintDC dc(this);
dc.DrawBitmap(Current, 0, 0, false );
}
My scroll rate for both x and y is set to 10. That's why I multiply the view start coordinates.
Any more insight is very welcome.
Thanks,
Christian

Rotate UITableViewCell inside a rotated UITableView

Rather than implementing a clunky, potentially bug-ridden custom table, I went with the much simpler rotate table option. The problem comes in when I decide that, rather than initializing rotated contents, I want to rotate the cell itself and cut down on the amount of code in complex cells.
The following lines are immediately after cell configuration.
This causes every cell to rotate 90° on load, regardless of orientation:
cell.transform =
(CGAffineTransform)CGAffineTransformRotate(cell.transform, (M_PI / 2.0));
cellRotated = YES;
And this option only rotates the first cell once, but preserves the rotation:
if (!cellRotated) {
cell.transform =
(CGAffineTransform)CGAffineTransformRotate(cell.transform, (M_PI / 2.0));
cellRotated = YES;
}
Can cell orientation be tracked with an existing function (or set thereof)?
I can't find anything about this with Google. There are related questions, but mostly about tables and Portrait/Landscape UI orientations, so the counter-rotation implementation is quite a bit different.
EDIT
If I move cellRotated = YES to viewDidAppear: every cell except one gets rotated. (And then cell reuse makes it so that, in this case, every sixth cell is left alone.)
1-5 is good, 6 is bad, 7-11 is good, 12 is bad, etc (and then it changes in a perfectly logical but entirely unwanted pattern when I hit the end of the table)
Halfway there or a step back, I don't know, but that's what I have now.
If rotation is the only transform you do then why don't you just do this,
cell.transform = CGAffineTransformMakeRotation(M_PI/2.0);
and then,
if ( !CGAffineTransformIsIdentity (cell.transform) ) {
// Rotated.
}