I'm writing a pong game and I have a ball class that has velocity x, y, positions and all that stuff that every frame is updated by calling #ball.update, this moves the ball forward by its x_vel and Y_vel etc. My question is Should my collision code be in the loop or in the update method of the ball class? Or should it all be in the loop and the ball should not have any control of its position?
The collision detection should not be done in you ball class because it would require the knowledge of all other objects in your game.
Imagine a shooter with many objects and think about what happens if each object would try to calculate the collision on it's own.
There should be a dedicated class that cares about collision detection. This class is notified if any of its supervised objects changed its position. Then it checks for collision and notifies all abjects (not only 2 :) that have a collsion.
Have fun... :)
A Ball class like you described is indeed a good idea. That way you can replicate it if, like in some "breakout" games, you ever want to spawn two or more balls -- or if you want to re-use that code in another game. You can also have a Paddle class with similar X,Y coordinates (or derive both Ball and Paddle from a "ScreenObject" class if they turn out to share many such similar members). Paddle can read a shared variable that gets updated by a thread/event receiving user input.
Simple collisions, such as against walls, can be done in your Ball class based on globally accessible values like the screen dimension extents. Your Update routine can simply reverse one velocity component when that particular wall is hit. You can define and set a delegate/callback in the Ball class to play a sound when the ball bounces. Similarly, Paddle's Update can check the screen size so you can't move the paddle off-screen.
Like TottiW recommended, collision between objects is best done in a parent "manager" class that owns all the objects or has access to their X,Y members or bounding boxes. This is good object-oriented design. Ball and Paddle shouldn't have access to each other's X,Y positions! ...but the manager does. It can also eliminate redundant collision checks. If object A checks to collide with object B, B shouldn't have to subsequently check for collision with A. So really all your manager class needs to do is, for each Paddle, check each Ball's position. This can be further simplified since a Paddle might only move in one direction, say horizontally, at a fixed Y position. Thus your first check can immediately eliminate any Ball.Y < Paddle.Y, for simplistic example (depending on Y's direction).
For games with lots of objects, you don't want to collison-detect every one, just the nearest ones. In that case, the "manager" becomes more of a "scene manager" which keeps linked lists of objects in both X and Y directions. As objects move past other objects, they exchange pointers in the lists, so the lists always stay sorted. That way, for any given object, we know the objects immediately to the left/right/above/below, so we need only do collision checks against those... saving lots of time and making your game run with maximum speed. Maybe you're not to this point, though!
Good luck and like the others have said, have fun with it!
For pong simple matrix operations should be sufficient. A ball class is not needed if there is only one and you use it only for holding a tuple.
Related
I am making a version of the Atari game "Centipede" for my computer science class. I need help creating the collision for my code. I need to make it so when the bullets hit a part of the centipede, the game detects it and the part that got hit goes away.
This is a pretty broad question, but I'll try to help in a general sense.
You need to read up on collision detection.
First you probably want to break your centipede down into individual rectangles. For each rectangle, check whether it's colliding with the bullet.
You might consider point-rectangle collision detection, where you check whether the point is inside the rectangle. This will work if your bullet is a small point.
Or you might consider rectangle-rectangle collision detection, where you check whether two rectangles are overlapping. Use this if your bullets are larger than a point. Even if your bullet is a circle, you can usually get away with this kind of collision detection.
Please try something, and if you get stuck, then please post a MCVE that demonstrates where you're stuck. Good luck.
A simple implementation would be as follows:
1. Designate an array that represents the pixel positions of the centipede
2. Designate another array that represents the pixel positions of the bullet
3. Update each array's values based on the sampling rate of your game and check to see if there is any overlap. (Ideally have this as a separate thread)
4.Any overlap is indicative of a collision, so have some sort of collision handler function, which deletes the part of the centipede hit, that is triggered anytime an overlap event occurs.
I have a game that requires the player to roll two die. As this is a multiplayer game, the way I currently do this is have 6 animations (1 for each die's outcome). When the player clicks a button, it sends a request to my server code. My server code determines the die's outcome and sends the results to the client. The client then plays the corresponding animations.
This works ok, but has some issues. For instance, if the server sends back two of the same values (two 6's, for example) then the animations don't work correctly. As both animations are the same, they overlay each other, and it looks like only one die was rolled.
Is there a better way to do this? Instead of animations, using "real" dice? If that's the case, I always need to be sure to "pre-determine" the outcome of the dice roll, on the server. I also need to make sure the dice don't fall off the table or jostle any of the other player pieces on the board.
thanks for any ideas.
The server only needs to care about the value result, not running physics calculations.
Set up 12 different rolling animations:
Six for the first die
Six for the second die
Each one should always end with the same modeled face pointing upwards (the starting position isn't relevant, only the ending position). For the latter steps you'll probably want to adjust the model's UV coordinates to use a very tall or very wide texture (or just a slice of a square one). So not like this but rather all in a line 1-2-3-4-5-6.
The next step is picking a random animation to play. You've already got code to run a given animation, just set it to pick randomly instead of based on the die-roll-value from the server:
int animNum = Mathf.Floor(Random.Next()*6);
Finally, the fun bit. Adjusting the texture so that the desired face shows when the animation is done. I'm going to assume that you arrange your faces along the top edge of your square texture. Material.SetTextureOffset().
int showFace = Mathf.Floor(Random.Next()*6); //this value should come from the server
die.renderer.material.SetTextureOffset(1f/6 * showFace,0);
This will set the texture offset such that the desired face will show on top. You'll even be able to see it changing in the inspector. Because of the UVs being arranged such that each face uses the next chunk over and because textures will wrap around when reaching the edge (unless the texture is set to Clamp in its import settings: you don't want this here).
Note that this will cause a new material instance to be instantiated (which is not very performant). If you want to avoid this, you'll have to use a material property block instead.
You could simulate the physics on the server, keep track of the positions and the orientations of the dice for the duration of the animation, and then send the data over to the client. I understand it's a lot of data for something so simple, but that's one way you can get the rolls to appear realistic and synced between all clients.
If only Unity's physics was deterministic that would be a whole lot easier.
I have recently asked a question here about programming a game so it will be efficient and won't lag.
I have made a game that lags like hell. I suspect that the way that I programmed it's game-loop, could be the source of the problem.
I want to describe to you in general the situation in my game, and then present my way of programming it's game loop.
It's a game for two players. Each player controls a tank. Each tank can shoot missiles. Each tank can collect 'gifts' from the field.
Each missile of tank1 can collide with tank2, and each missile of tank2 can collide with tank1.
Each missile can collide with a boundary of the screen.
Each tank can collide with the other tank.
Each tank can collide with 'gifts'.
All missiles constantly move.
Tanks move when specific buttons on the keyboard are pushed.
My game loop (Each stage is inside a method called from the game loop):
Loop through all the missiles on the screen, and update their location (move them).
Loop through all of tank1's missiles, and for every one check if collides with tank2.
Loop through all of tank2's missiles, and for every one check if collide with tank1.
Loop through all the missiles on the screen, and check if collide with screen boundaries.
Check if specific keys are pressed on the keyboard. If so, move tanks.
Check if the two tanks collide.
Loop through all of the 4 'gifts' on the screen, and check if they touch a tank.
Questions:
This game-loop is probably inefficient. How inefficient is it? A little, or a lot?
How can I improve the game loop and/or the way it's methods work? How can I achieve the same thing, more efficiently?
How likely is it for a game-loop to be the main cause for poor performance level? How common is it in games for this to be the source of the problem?
Appreciate your help.
I wouldn't necessarily say it's inefficient since you're just giving us the general idea of what might be done in several other games. It sounds like all you're doing is moving objects and checking for collisions, which I'm assuming uses AABB collision detecting. Nothing really expensive here. Of course it has room for improvement. See #2.
You're probably getting input more than once, so what you could do is get the input at the beginning of each frame and store it in some way. I don't know what form of input you're using, but if you're using a keyboard for example, you'd get and store the state of the WASD keys and check those states when handling tank input.
The most notable optimization you could make is you loop through every missile 3 times. The first time is to move them, the second to check their collisions, and the third time to check if they are outside the screen. In one loop, you can move them, check if they're outside of the screen, and then check if they collide with the opposing tank. I recommend doing it in this order, because if the bullet does happen to move outside the screen you can avoid doing an unnecessary collision check.
Finally, you only have to check if the two tanks collide when they move, and you only have to do it once. If you need it so something happens for every frame the two tanks are on top of each other, you can store the state of the collision and you only need to update it again when one tank moves.
It really depends. You're probably locking the frame rate by sleeping, so you could be sleeping for too long. Try to remove your method of frame rate limiting and seeing what happens.
I am making a game and i have come across a hard part to implement into code. My game is a tile-bases platformer with lots of enemies chasing you. basically, in theory, I want my enemies to be able to, every frame/second/2 seconds, find the realistic, and shortest path to my player. I originally thought of A-star as a solution, but it leads the enemies to paths that defy gravity, which is not good. Also, multiple enemies will be using it every second to get the latest path, and then walk the first few tiles of it. So they will be discarding the rest of the path every second, and just following the first few tiles of it. I know this seems like a lot, to calculate a new path every second, all at the same time, if their is more than one enemy, but I don't know any other way to achieve what i want.
This is a picture of what I want:
Explanation: The green figure is the player, the red one is an enemy. the grey tiles are regular, open, nothing there tiles, the brown tiles being ones that you can stand on. And finally the highlighted yellow tiles represents the path that i want my enemy to be able to find, in order to realistically get to the player.
SO, the question is: What realistic path-finding algorithm can i use to acquire this? While keeping it fast?
EDIT*
I updated the picture to represent the most complicated map that their could be. this map represents what the player of my game actually sees, they just use WASD and can move around and they see themselves move through this 2d plat-former view. Their will be different types of enemies, all with different speeds and jump heights. but all will have enough jump height and speed to make the jumps in this map, and maneuver through it. The maps are generated by simply reading an XML file that has the level data in it. the data is then parsed and different types of tiles are placed in the tile holding sprite, acording to what the XML says. EX( XML node: (type="reg" graphic="grass2" x="5" y="7") and so the x and y are multiplied by the constant gridSize (like 30 or something) and they are placed down accordingly. The enemies get their frame-by-frame instruction from an AI class attached to them. This class is responsible for producing this path and return the first direction to the enemy, this should only happen every second or so, so that the enemies don't follow a old, wrong path. Please let me know if you understand my concept, and you have some thought/ideas or maybe even the answer that i'm looking for.
ALSO: the physics in this game is separate from the pathfinding, they work just fine, using a AABB vs AABB concept (the player and enemies also being AABBs).
The trick with using A* here is how you link tiles together to form available paths. Take for example the first gap the red player would need to cross. The 'link' to the next platform (aka brown tile to the left) is actually a jump action, not a move action. Additionally, it's up to you to determine how the nodes connect together; I'd add a heavy penalty when moving from a gray tile over a brown tile to a gray tile with nothing underneath just for starters (without discouraging jumps that open a shortcut).
There are two routes I see personally: running a quick prediction of how far the player can jump and where they'd jump and adjusting how the algorithm determines node adjacency or accept the path and determine when parts of the path "hang" in the air (no brown tile immediately below) and animate the enemy 'jumping' to the next part of the path. The trick is handling things when the enemy may pass through brown tiles in the even the path isn't a parabola.
I am not versed in either solution; just something I've thought about.
You need to give us the most complicated case of map, player and enemy behaviour (including jumping up and across speed) that you are going to either automatically create or manually create so we can give relevant advice. The given map is so simple, put the map in an 2-dimensional array and then the initial player location as an element of that map and then first test whether lower number column on the same row is occupied by brown if not put player there and repeat until false then same row higher column and so on to move enemy.
Update: from my reading of the stage generation- its sometime you create- not semi-random.
My suggestion is the enemy creates clones of itself with its same AI but invisible and each clone starts going in different direction jump up/left/right/jump diagonal right/left and every time it succeeds it creates a new clone- basically a genetic algorithm. From the map it seems an enemy never need to evaluate one path over another just one way fails to get closer to the player's initial position and other doesn't.
I'm running a simple sketch in an HTML5 canvas using Processing.js that creates "ball" objects which are just ellipses that have position, speed, and acceleration vectors as well as a diameter. In the draw function, I call on a function called applyPhysics() which loops over each ball in a hashmap and checks them against each other to see if their positions make them crash. If they do, their speed vectors are reversed.
Long story short, the number of calculations as it is now is (number of balls)^2 which ends up being a lot when I get to into the hundreds of balls. Using this sort of check slows down the sketch too much so I'm looking for ways to do smart collisions some other way.
Any suggestions? Using PGraphics somehow maybe?
I assume you're already simplifying the physics by treating the ellipses as if they were circles.
Other than that, check out quadtree collision detection:
http://gamedev.tutsplus.com/tutorials/implementation/quick-tip-use-quadtrees-to-detect-likely-collisions-in-2d-space/
I don't know your project, but if the balls have non-random forces applied to them (e.g. gravity) you might use predictive analytics also.
If you grid the space and create a data structure that reflects this (e.g. an array of row objects each containing an array of column objects each containing an ArrayList of ball objects), you can just consider interactions within each cell (or also with neighbouring cells). You can reassign data location for balls that cross boundaries. You then have far fewer interactions.