How do I make a SKSpriteNode avoid another SKSpriteNode? - swift

I am working on an AI mode for a SpriteKit game I am making in Xcode. I have dynamic physics bodies which can be launched towards the AI. I want to make it so that when one of these bodies is within a certain radius of the AI, the AI tries to dodge it. I have started working through different routes and got decent results.
1st method (pseudocode): Check AI.position.x and AI.position.y and compare to incomingSprite.position.x and incomingSprite.position.y. Break this comparison into quadrants if both x and y are within radius. (i.e. incomingSprite is bottom left relative to AI, bottom right, etc). Based on this info move the AI's position to move away from it.
cons:
-lots of code and calculations in update function to account for multiple incoming sprites
-depending on dx and dy of incoming sprite, the AI often make illogical decision
2nd method (pseudocode): Calculate distance from AI to incomingSprite. Then check dx and dy of incomingSprite and set dx and dy to go in reverse direction of incomingSprite. This seems logical. I am a little rusty on reversing vectors to do this. I feel like this might be possibly a good idea though.
Is there a better method to accomplish this? Perhaps a force field on the magnet I could use to repel the AI at a certain strength so that if the incomingSprite is fast enough it will override and still collide anyway? Im concerned about memory as most of the AI logic is in the update function, which can cause big problems if I'm not careful.
Edit: I decided to use the electric field and gave the incoming sprites a positive charge so that they are repelled by the AI. This makes things accurate/lightweight and more interesting. If the incoming sprites are fast enough, they will break through the electric field and still collide with AI. This also gives room as an additional difficulty parameter in my game (the stronger the field, the harder it is to get the incoming sprites to collide with the AI).

Related

Raycasting Layermask vs RaycastAll

Hi I have a small question on how the raycasting with layermasks work vs using RaycastAll.
I am trying to project my rays from inside my object and layermask the rays to collide with the same layer as the original object, therefore i need to ignore the "hit" on the original object itself.
My question is: when Raycasting uses a layermask does it register a collision with other undesirable layers too and then simply ignore them, or does it not even register a collision with those layers in the first place? Would it be worse or equal on performance if I used RaycastAll to logically decide to respond to a layer or not vs somehow using strictly layermasks? Or is it not even an appreciable difference?
I know some posts say that "if you cast it from inside the object it wont collide with that object" but evidently it does.
Thanks
You can take a look at official Unity's physics preformance tutorial. To start with, Raycast is rather cheap operation but it's performance really depends on how you actually do Raycasting. For example, for one of your questions - RaycastAll is more expensive than doing Raycast on a separate layer, it's also mentioned in the link above. It's based on how actually physics work. Unity doesn't implement physics itself, instead it uses existing solutions (like PhysiX for 3d, and earlier it was Box2d for 2d physics).
Also the length of your ray actually influences Raycast's performance. The shorter ray you cast the better performance you get. The worst case is Raycasting to infinity. Another case is that Collider.Raycast is cheaper than Physics.Raycast.
It's no secret, that there is nothing more that some bunch of math equations behind physics in game development so you may thing in such things - the simplier equation you have, the better performance and time to complete you get. So Raycast can be treated as system of equations where you have the equation of the line (actual Raycast) and some number of equations, which describe some 2d/3d object in plane/space and the task is two calculate the points of intersection between your line (Ray) and other objects.
If you don't have complex physics in your game you may not see the difference between RaycastAll and Raycast with layermask, or shorter ray's length, but performance really differs.

SpriteKit Detect Ranges

I am making small/mid RTS game, I have the following need:
I want Enemy Players to Attack allies and vice versa when they are in each attack range.
My question is: what would be a better approach finding if enemy units are in attack range of allied or vice versa of course ?
What have I tried:
For now I tried to add SKNodes with SKPhysicsBodies for each unit Node.
I can see that FPS are going down when the contact happens... I guess it wasn't the best way to know detect whether enemies are in range.
I guess my alternative is to run some Nested Loop within Update method and check if there are enemy units within the Radius.
I am not sure if it is the best approach, however with this approach I may play with some parameters and maybe optimize the routine for my own needs.
I would like to know if there is some better alternatives.
Look into GamePlayKit,
It may have some things you want.
Otherwise I would just use the Euclidiean Distance Formula https://math.stackexchange.com/questions/139600/euclidean-manhattan-distance without the square root, and use this value based on squads, not individual troops. (So if a group of 4 soldiers is attacking an enemy of 5 soldiers, only 1 distance check is done).
The reason why you do not square root, is because you should know the squared allowable distance. If an enemy 10 pixels away attracts soldiers, then use 100.
The best way to treat your soldiers like squads, add them all to an SKNode (sub class to add better functionality), then you just need to compare those squad SKNodes
If you want to reduce the number of checks you make, consider turning your play area into a grid (Like a chess board). Since you know the size of your tiles, you could easily check to see if the units are close enough to warrant a distance check. E.G. You have a unit at a1, and an enemy at i9, then you know just by tile distance that the units are too far apart to attack each other

Making a unicycle with Box2D

I'm fairly new to Box2D and trying to figure out the best way to make a unicycle. The unicycle essentially is in two pieces, the wheel and the stem (with seat post etc). I've tried attaching the two with a revolute joint and using a motor for the wheel, which works well except that the stem is then subject to forces from the movement of the wheel. I want to be able to directly control the rotation of the stem (via the accelerometer on the iPhone), and have it unaffected by the movement of the wheel, except to maintain its position based on the position of the wheel.
What is the best way to do this? How do you control rotation of b2Body's? Should I be using a distance joint instead? Any help would be appreciated.
I see several routes, depending on your needs. Which way is preferable is up to you and your game.
1. Fix the stem's rotation
For the bodyDef for the stem set the fixedRotation-flag to true. This prevents any rotation of the stem (be it by forces from the motor joint, (de)acceleration or collisions.
Than you'd have to manually set the rotation each tick. This is easy if it's purely based on the iPhone's position. If you still want to calculate other factors into it, things might get from a bit more complicated (e.g. adding rotation if stem leans too far in one direction) to somewhat painful (have collisions affect the rotation).
2. Constantly apply balancing forces to the stem
Each tick read the stems angular velocity and apply countering forces to balance the stem.
While this would probably be more complicated to implement correctly (always find the right force to apply etc.) it may result in a more realistic behaviour as the fixed rotation obviously removes most reactions stem movement would have and how the stem itself is affected by the world.
3. Don't actually use a wheel
While your layout is the obvious choice for a unicycle (and seems to be a somewhat popular choice for all kind of characters) it might not be the best choice from a gameplay point of view.
Instead you could combine the stem and wheel fixtures in a single body (or attach them with a prismatic joint) and create all movement by applying forces to this body. A sensor at the bottom can inform you of ground contact to determine if movement forces are to be applied.
This way you'd get rid of all the forces a wheel creates (forces to the stem may not be the only unwelcome ones in gameplay) and still have it react to all external forces.

Chipmunk objects fall through floor at high velocities. Help?

I'm using Chipmunk cocos2d for what will ultimately be a sound-generation game where colliding particles make noise. But right now, I'm running into a problem: my particles keep falling through the floor!
In the example "bouncing ball" templates, the multiplier on the incoming accelerometer stream is fairly low (around 100.0f) but to get things to really react quickly I am cranking it up:
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)accel
{ space->gravity = cpvmult(cpv(accel.x, accel.y), 10000.0f); // originally 100.0f
}
I have found that this can be ameliorated by making dt really small, polling the accelerometer around 1/240 of a second.
Is this the best way? Is there another way to say to Chipmunk "look out, these things move fast"?
In general many physics engines have difficulty with collisions between quickly moving objects that are small relative to their velocities. I do not know the specifics of Chipmunk, but your issue implies that at certain time intervals a check is performed for intersecting objects. If the objects move quickly and are small, it is possible for the time interval where a collision is happening to be skipped.
The two easiest solutions are to use a smaller time interval, or somehow make one of the two objects larger. How are you representing the floor? If you can represent it as a thick rectangle, that should also reduce the problem.
The harder solution is to use a more complicated intersection algorithim, such as using bounding capsules to represent the area of space traversed by a sphere between two samples. If the API does not already support this, it is a pretty hefty amount of math and modification.

How would you keep a top view of a train on the tracks with the Box2D physics engine?

I think it would be fun to model a top view of a train following a track, traversing switches and so on, using a physics library like Box2D. What joints and motors would I need to make this work?
I'm curious about how to implement the forces needed to make the car follow a spline track so it can bump into other train cars, pedestrians, DeLoreans etc. Just saying "the car is now at spline(t)" for each time step would create excessive forces in the physics engine. If I understand correctly, you have to stick the car onto the track with one force, constrain its angle to tend towards parallel with the track with another (or stick the front and back of the car to the track with two forces), and create another force to propel the train forward. I'm looking for some details on how to accomplish these things.
I believe it would be easier without "real" physics, like the ball movement of games such as Luxor or Tumble Bugs. Meaning: let the train follow a spline which is defined by the tracks.
Using phyiscs is probably overkill to make a train follow a track and could lead to all kinds of undesired side-effects, including jerky motion, train derailing, train getting stuck on junctions, etc.
You could still join the individual wagons together using physic joints, however. Just make sure that only the locomotive gets acceleration forces, the rest of the train just follows or is pushed but stays on the spline.
Why are you worried about keeping it "on the tracks"? Where is it going to go? Gravity should keep it down, object intersection should keep it up, and so the only directions you need to worry about are forward and backwards. That's where a motor comes in, and you're done. The rest is decorations.
In response to edit of problem:
Siderails. And have the train long enough / rigid enough compared to its width that you can navigate crossings (make them closer to right angles to minimize the crossing problems.
A top-down view (i.e. seeing the train from the sky) doesn't really require a 2d physics engine - if I understand you correctly. In fact, it seems like it wouldn't really help with the problem (if you want a train simulation), but then maybe you just wanna try it out for fun. :)
However, what about putting something like a slider joint on the train and the cars, and a motor on the locomotive. The slider joint might need some special implementation; you probably want to run the train along a spline and not a segment of straight lines, right?
Some sort of ball joint would connect the cars together.
The implementation is not so toughand I was able to prototype something in a few hours that does the basic job. It will require a lot of work to make it run smoothly, but it's essentially just "siderails."
Being top-down you obviously first must turn off gravity in Box2D. Second, build a train. Treat train wheels like car wheels and it'll suddenly get a lot more simple. For tracks you have a few choices:
Create your own game object (not in the box2D world) that is a simple line the train will then "follow" (you can use motors on train wheels to "steer" towards the line). Then just overlay the line with some nice wide "rail" graphics and you have a nicely faked system. Tell the wheels to turn off if it strays too far from the line and presto, you have a derailment.
Create actual physical rails - outside rails (like siderails) that the trains "wheels" will bump into. They will have to have gentle curves in this instance, which could be very difficult given the limited resources you have (simulating a nice slow curve out of boxes in Box2D is rough on the processor)
Then just let your train go!