Lua game app required transition of object with scaling factor - lua

I am working on a iOS Game Application (Race) which requires the background to have transition coming forward.
For the above requirement I have written a code where I have to make people feel as if the objects were coming from a far distance to nearby.
Hence I am using transition to do so where I increase their y position and scaling (both xScale and yScale). While doing so, the problem I am facing is when the objects seem to come closer with their size increasing (using scaling), the distance between the objects decreases from their actual distance because of scaling and it does not perfectly look as if the objects were coming from far behind.
Please let me know what is the best way to achieve what I trying to do or else if there is any available sample code having the functionality of car/bike racing.

transition.to ( object,{ time=500, alpha=1,x = (destination x coor),y = (destination y coor),width =(to scale x),height =( to scale y), onComplete=saltCellarOnComplete} )

Related

Wierd gaps appearing in between SKSpriteNode - swift

Note: I have tried this answer: Gap between SKSpriteNodes in SpriteKit collision detection
I am getting gaps in between my SKSpriteNodes, after 5 minutes of letting my game run. Here is my code to make the node:
let tileNode = SKSpriteNode(imageNamed: "world1Tile\(tileNumber).png")
tileNode.position.x = x
tileNode.position.y = y
tileNode.size.width = 128
tileNode.size.height = 128
tileNode.zPosition = 10
tileNode.physicsBody = SKPhysicsBody(rectangleOf: tileNode.size)
tileNode.physicsBody!.isDynamic = false
tileNode.physicsBody!.restitution = 0
tileNode.physicsBody!.allowsRotation = false
tileNode.name = "Tile"
row.append(tileNode)
When I remove the physics body, it is running fine. Here is are some images to show you what I mean:
This image has a physics body, and was taken after immediately after running the app.
This image was taken 5 minutes after running the app.
Why is this happening? I assume it has something to do with the physics body, because my app looks exactly like the first picture, even an hour after running the app if there is no physics body. What physics body property should I change to stop this from happening? Any help would be appreciated.
I had a similar issue not too long ago, where gaps were appearing between nodes that were tiled (although I didn't use physics). Based on this answer, I found that if you want perfect alignment between nodes, it is best to ensure that the positions of nodes as well as the nodes' width and height are whole numbers.
I would suggest to round-off the x and y values of the position of tileNode and see if it will make any difference .
I'm guessing there is no gap. you probably have 'showPhysics' to true in your gameviewcontroller, and the line appears as a gap to me.
compare position with and without the pb to verify.
I had similar problem where gaps between sprites started appearing after around 5 minutes of scrolling with constant speed (game with infinite scroll). I did not use physics and I even had all positions, widths, heights rounded to integer value. I was scrolling the camera and adding new sprites one right after another and everything was working fine except after around 5 minutes of that infinite scrolling gaps begin to appear just as in your case. I spent some time in looking for a solution and it turned out that the problem was that when positions of my objects were becoming big that is in my case X position in the scene was around 150000 then those gaps started to appear and also I noticed that this problem occurred only on devices which had to scale the scene. I was using aspect fill with default scene size for iPhone 6 resolution and those gaps only appeared on iPhone 5 but on iPhone 6 I did not notice them. I was able to fix that issue by subtracting some constant value from X position of all objects (including camera position) from time to time so that everything on the scene relatively did not change position to the camera and look the same but actually absolute positions were changed to keep them low. I guess that larger position values like 150000 and scene scaling cause some floating point rounding issue in SpriteKit and that is why gaps are then becoming visible.
So based on my experience if you have similar gaps I recommend using integer values for all positions, widths, heights and additionally keep values of objects positions of all objects low.
For future reference in case someone is still searching for this, here are my experiences:
If tiles have PhysicsBodies, they are prone to making gaps. A solution for me was making a blank SKNode as a child of the tile, and assigning the PhysicsBody to that.
If possible, make sure bit masks are set in a way that tiles can't collide with each other.
As stated in a previous answer, make sure all measurements are integers and rounded in a way that doesn't leave a one unit gap between them.
A related problem is also SpriteKit's PhysicsBody drifting. There are some threads about this (e.g. https://forums.developer.apple.com/thread/27057 ), and it seems to be abug. In my case, the problem was a combination of PhysicsBodies causing random small gaps, and the drifting making some of them larger. The steps above removed the small gaps. Unfortunately the only workaround for the drifting problem in my case was to only generate PhysicsBodies for nodes that are within a certain distance from the player and destroying them after they are left behind.
For future reference for anyone who needs, I found an different answer specific to my problem. As JohnV said, I may need to round of values when setting the position, but when running the code, I found out that I also need to do that when running SKActions.

iOS core motion drifts in cars, trains, flights

I get feedback from my users, that "from time to time" my Game-App has a bug were the ship gets completely uncontrollable. After investigating into this, it looks like the attitude, reported by CoreMotion drift away very fast (below a second) and it does that suddenly. You can play for up to five minutes, then it happens suddenly that the ship moves to one of the screen borders and does not move away from that point any more.
My question: Has anybody made the same experience with CoreMotion attitude and what are your ways or ideas to get control over this sudden, massive drifts?
The code I'm using to get the attitude in the update() of SpriteKit is:
if let motion = motionManager.deviceMotion {
let x = CGFloat(motion.attitude.yaw - basePosition.x)
let y = CGFloat(motion.attitude.roll - basePosition.y)
ship.physicsBody?.applyImpulse(CGVectorMake(X_SENSITITVITY * x, Y_SENSITITVITY * y))
}
where basePosition, X_SENSITITVITY, Y_SENSITITVITY are constant values in the game.
motionManager is defined by private var motionManager = CMMotionManager() at the top of the class.
As far as I understand the documentation, deviceMotion uses a combination of gravity and attitude measure to minimise the long term drift somehow.
Maybe also important to notice: When the Game runs in a silent environment without the vibrations of cars etc, it works perfectly fine.
I would like to have people to play my game whenever they need a rest - like on long train rides or flights - or kids in the backseat of the car.
I figured out the same drift problem. I compared the CMDeviceMotion's attitude with the CLLocation's magneticHeading. Therefor, I walked 10 times around a small table and put the device after every round on the exact same place.
I figured out, that the DeviceMotion's attitude drifts around 30 degrees every round. Thus, after 10 rounds the attitude is around 300 degrees off.
According to Apple's WWDC 2012 talk "Session 524: Understanding core motion" the used sensor fusion depends on the specified reference frame. Phil Adam mentions, that the sensor fusion algorithm also uses the magnetometer if the xArbitraryCorrected reference frame is specified. I did the same test with xArbitrary, xArbitraryCorrected and xMagneticNorth, but there is no difference. The compass's uncertainty is around 2 - 3 degree (with a heading filter of 1.0 degree).
Maybe it's a bug, I don't know. But I expected at least a difference between xArbitrary and xArbitraryCorrected.
ok, I've found a way to handle this. And as I see a number of views on this question there might be some interest in the answer and some people dealing with the same issue.
From my understanding, there're two things you can rely on:
The change of devices in motion. Specifically CMDeviceMotion.rotationRate
The attitude of a device towards earth. Specifically CMDeviceMotion.gravity
It looks like the first uses changes in current position by reading some kind of current forces. This is a current value and there's no need to sum up the values - and therefore no errors are summed up.
The second one (gravity) measures the current forces against earth. Again: current values, no sum up, no sum up of errors, no drift.
Anything else, especially CMDeviceMotion.attitude, takes measures and adds them up. Leading to adding up the small errors in each measure, leading to a drift in the result.
I've tried to use rotation rate and calculate the attitude myself by adding up. Well, Apple is not perfect in doing that, but way better then any of my solutions :-)
Talk is cheap. Where's the code? Here it is. This method is called during update() in SpriteKit (for every frame)
private func update(ship: SKSpriteNode) {
// Orientation can be landscape left or right
let orientation = UIApplication.sharedApplication().statusBarOrientation == UIInterfaceOrientation.LandscapeLeft ? -1.0 : 1.0
// Get rotation rate
let x = orientation*motionManager.deviceMotion.rotationRate.x
let y = orientation*motionManager.deviceMotion.rotationRate.y
// If user tilts device very slow it does not affect the ship
let xf = CGFloat(abs(x) >= X_RESPONSIVNESS ? X_SENSITITVITY*x : 0.0)
let yf = CGFloat(abs(y) >= Y_RESPONSIVNESS ? Y_SENSITITVITY*y : 0.0)
// Apply as impulse
ship.physicsBody?.applyImpulse(CGVectorMake(xf, yf))
}
As my game is more about "how does the user tilt the device to let me know where you want the ship go to" I simply used rotationRate to measure this and apply it as impulse. As an add-on you can rotate the device which means that what was a rotation towards the top of the screen is actually a rotation to the bottom after rotation. So I have to invert the impulse when the device is rotated.
You can now play the game in any direction. Landscape left, Landscape right, overhead, in a vibrating environment like cars or trains. It works like a charm. I'm even looking forward to a 2.5 hours flight next Saturday...

What is the right way to zoom the camera out from a scene view?

I have a scene where my gameplay happens. I'm looking for a way to slowly 'zoom-out' so more and more space becomes visible as the time passes. But I want the HUD and some other elements to stay the same size. It's like the mouse wheel functionality in top-down games.
I tried to do it with sticking everything into display groups and transitioning the xScale, yScale. It works visually of course but game functionality screws up. For example I have a spawner that spawns some objects, its graphics gets scaled but spawner still spawns the objects from its original position, not the new scaled position..
Do I need to keep track of every X, Y position I'm using during gameplay and transition them too? (Which is probably possible but too hard for me since I use a lot of touch events for aiming and path creating etc.) Or is there an easier way to achieve this? Please please say yes :P
I'm looking forward for your answers, thanks in advance! :)
The problem is you are scaling your image, but not your position coordinates.
You need to convert from 'original coordinates' to 'scaled coordinates'
If you scale your map size to half, you should scale the move amounts by half too.
You need to 'scale' your coordinates in the same amount your image is scaled.
For example lets assume your scale factor is 0.5, you have an image:
local scaleFactor = 0.5
image.xScale = scaleFactor
image.yScale = scaleFactor
Then you would need to scale your move amounts by this factor
thingThatIsMoved.x = thingThatIsMoved.x + (moveAmount * scaleFactor)
thingThatIsMoved.y = thingThatIsMoved.y + (moveAmount * scaleFactor)
I hope this helps, I am assuming you have a moveAmount variable and updating the position on the enterFrame() event.

Points coordinates in multiple screen CoronaSDK

I'm new to Corona SDK development and I'm looking around to get some documentations and see if this platform is goot to reach my goal.
Let's say that I have a background image in my screen (320X480 for example), and I want to move an object from one point to another. For example I want to move an object from 100,100 to 300,300. In this case, my object follow a line that almost covers the entire width of my screen. But what happens when I run the app on a different screen resolution? For example on a Ful HD screen, moving an object from 100 to 300 on the X axis, it just moves a little.
What I saw from Corona documentations is that multiple screen is supported by providing different image resolutions. But what happens when I have to go through screen coordinates? Do I have to check at runtime for the screen resolution and do all the Math operations to scale my points coordinates? Or is there anything else that I'm missing?
I ask you sorry if I missed something from the doc :(
Usually corona will do all such work for you, if you have added proper config.lua to your project. But I'm doing it in a different way for more precision and for my satisfaction:
In normal case:
-- Your object at point (100,100)
local myObject = display.newRect(0,0,50,50)
myObject.x = 100
myObject.y = 100
-- sample transition
transition.to(myObject,{time=1000,x=300,y=300})
What I'm doing:
-- Create a scale factor for X and Y
local _x = display.contentWidth/320
local _y = display.contentHeight/480
-- Multiply X values with '_x' and Y values with '_y', as below:
local myObject = display.newRect(0,0,50*_x,50*_y)
myObject.x = 100*_x
myObject.y = 100*_y
transition.to(myObject,{time=1000,x=300*_x,y=300*_y})
Note:
While trying the above code, you have to develop your code for iPhone simulator. Hence, I obtained local _x = display.contentWidth/320, where the division factor is the width of the simulator/screen that you are using to build your app. And in local _y = display.contentHeight/480, the division factor is the height of the simulator/screen.
Keep Coding................. :)
It scales it all for you. I'm not sure if it specifically mentions it in the documentation, probably.
I am also newer to Corona (since July) with no previous mobile experience. It has blown me away with what it can do.
Corona does all the work for you. You define your default screen resolution (320x480 for example) and in whatever resolution you want to move from 100 to 300 it will behave equally because corona will treat all screens resolutions as it was 320x480.

Cocos2D Realistic Gravity?

I have tried many different techniques of applying a realistic looking gravity feature in my game but have had no luck so far. I plan on offering a 100 point bounty on this for someone who can show me or (share) some code that applies gravity to a CCSprite in Cocos2D.
What I have done so far has just been ugly or unrealistic and I have asked in many different places on what the best approach is but I just have not found any good looking gravity techniques yet.
Anyway, can anyone offer some tips/ideas or their approach only applying gravity to a CCSprite in Cocos2D without using a physics engine?
Thanks!
A effective approach without having to explicitly use any physics engine is to step the velocity and position of your sprite manually in your update loop. This is essentially Euler Integration.
// define your gravity value
#define GRAVITY -0.1
// define a velocity variable in the header of your Game class/CCSprite Subclass (neater)
float velocity_y;
-(void) update: (ccTime) dt
{
// Step the y-velocity by your acceleration value (gravity value in this case)
velocity_y += GRAVITY *dt; // drop the dt if you don't want to use it
// Step the position values and update the sprite position accordingly
sprite.position.y += velocity_y* dt; // same here
}
In the code snippet above, I defined a velocity_y variable to keep track of my sprite's current velocity along the y-direction. Remember to initialize this value to 0 in your init method.
Next comes the crux of Euler. At every time step:
Advance your velocity by your acceleration (which is your gravity) multiplied by dt to find your new velocity.
Advance your position by your newly computed velocity value multiplied by dt to find your new position.
You can experiment whether using delta-time or not (see LearnCocos2D's excellent comment on the cons of using it) works for your game. While multiplying by delta-time allows your object motion to more accurately take into account varying framerates, as LearnCocos2d pointed out, it might be wise to avoid using it in a real-time game where system interrupts (new mail, low battery, ads pop-out) can occur and subsequently cause the game simulation to jump forward in an attempt to make up.
So if you are dropping the dt, remember to tweak (scale down) your GRAVITY value accordingly to retain the right feel, since this value is no longer multiplied by the value of delta-time (which is ~ 1/60).
Aditional Tip: To apply an impulse to move the sprite (say via a swipe), you can affect the velocities directly by changing the values of velocity_x (if you have this) and velocity_y.
I have used this approach in my games, and it works very well. hope it helps.
This isn't trivial matter, you should try to see other posts. I'm sure other poeple already had this issue. Try to look at :
How to simulate a gravity for one sprite in cocos2d without a physics engine?
Cocos2D Gravity?
Or try our good friend google :
http://www.gamedev.net/page/resources/ -> got to Math and Physics and then A Verlet based approach for 2D game physics
http://www.rodedev.com/tutorials/gamephysics/
In any case here are some tips :
Step 1, calculate the effective direction vectors
Step 2, calculate velocity
Step 3, project this velocity onto the two effective directions.
Step 4, generate an equal and opposite force for the two direction and call this the “response force”.

Resources