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.
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 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.
So me and my partner are trying to make a pong game that's player vs. computer, but we just couldn't figure out how to make the computer lose.
We already have the basic stuff done and it works fine but the computer just never loses. And we also tried slow down the computer peddle using sleep, but whenever the paddle moves slow, the ball also moves slow.
any advice would help!
Thanks
And we also tried slow down the
computer peddle using sleep, but
whenever the paddle moves slow, the
ball also moves slow.
You need to make it slower by moving it a shorter distance each time it moves.
In the original Pong game, the paddle was perfectly in sync with the ball, that is whenever the ball went down a line, the paddle did too. Obviously, that would make the game unwinnable so the solution used by the developers was to skip an update cycle every few cycles.
In layman's terms, on every frame, you adjust the paddle's location to follow the ball, except on the fifth, tenth, fifteenth, etc. By doing that, your paddle will seem to follw the ball nicely, but with some kind of delayed reaction.
I assume that the computer never loses because it "knows" where the ball is going to go. In that case, why can't you make it go to the wrong place some percentage of the time?
As well, if you just wanted to slow it down, rather than sleeping, you could intersperse "moves" of "don't go anywhere" along with the movement towards what it thinks is the right place to be. So instead of "down 1, down 1, down 1", you could have "down 1, down 0, down 0, down 1, down 0, down 0..." or something along those lines.
I think there is a game site for problems like this https://gamedev.stackexchange.com/. But my answer would be to try and cycle the top speed of the AI bat. And to make the bat short sited. (Only respond to the ball position once it is in its half.)
Computer must make mistakes to lose. The catch is, the mistake must be realistic. If the mistakes seems too artificial, the human player loses interest after a while. The human must believe the cause of the mistake is his good play.
The computer may occacionally react late. I mean, freezes when the human hit the ball. This may especially happen if the human hit the ball with the edges.
Intentional going slow would be unrealistic. But sometimes the computer may go a little bit slower while defending a ball that would bounce.
The computer may plain react to wrong side (for example, go up instead of down) when the ball hit with the middle of the bat.
The computer may wait a ball at the wrong place (off by 1), especially if the ball would bounce.
When you use Sleep the whole program stop for some milliseconds.
Do you have a game loop ? If so, try decreasing the translation amount, and do not forget to normalize
the acceleration vector.
cpuPadlle.Position += amount * acceleration;
Where :
amount in [0..1]
acceleration is a 2d
vector
How can I program hourglass behavior (similar like on picture) for my game?
Should I make something like gravitation and process each grain of sand?
What about digital hourglass (like on this clocks)?
Wasting effort on a "proper" simulation for grains of sand for the sake of an in-game hourglass is serious over-engineering.
Get an artist to produce a high-quality animation and either render it as a series of static images or as a movie.
Seriously, don't simulate the sand.
Tangentially, you can model falling sand with cellular automata. I'd not considered using it for an hourglass simulation, but in principle it might work quite nicely, and be a fun project.
Looking at your digital hourglass -- either the grains move in set patterns, or it might use something like this CA.
Modelling it is making a rod for your own back, you'd be better off just drawing the frames by hand and playing them back.
But -- if maths is your thing you could:
work out the volume of sand in the top.
define a rate of volume flow through the neck (keep this arbitrary as you'll want to tweak it).
at any given time you can use the flow rate to work out how much sand has left the top.
if you know the shape of the top vessel you can work out the current height of sand given the current volume of sand.
if you know the shape of the bottom vessel you can work out the current height of sand given the volume of sand that's flowed through the neck.
I will play devil's advocate here and assume you actually want to simulate sand in your game not just create a simple hour glass loading indicator (as people have said it would be a waste of effort).
So I go back to my initial comment. What kind of resolution are you looking for?
Chances are you don't need to simulate each granule of sand. So keep it simple and leave the physics out of it and just simulate the effect.
For example, off the top of my head you can use 3 simple rules:
Gravity: If the pixel below a "sand pixel" is empty shift that column down.
Cave In: If there is a empty space between two columns of "sand pixels" fill it in if the space below it is not empty (ie. not falling)
Pile Up: if there is empty space beside a column of "sand pixels" spread it out if the space below it is not empty.
These are just some example of rules that might work. The point is to experiment to come up with a simulation that will give the desired effect. Typically it is less work and processor intensive than modeling the physics.
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.