This site requires JavaScript, please enable it in your browser!
Greenfoot back
Entity1037
Entity1037 wrote ...

2014/7/21

Help on a game engine that uses frame skip please?

Entity1037 Entity1037

2014/7/21

#
So I'm trying to make an engine that uses frame skip so the entire game doesn't slow to a halt when it's at not 60fps, but I don't really have an idea on how to start making one (I know the concept of it, but I'm not sure how to translate that to code). My mind just goes blank... Could someone give me some help with some examples? I would really appreciate it!
davmac davmac

2014/7/21

#
If you want to maintain a consistent speed even when drawing at ~60 fps isn't possible, then you need to basically calculate where things should be depending on how much time has passed since the last act(). In the simplest case you assign speed as a unit of distance over real time (rather than distance per frame). Then each time your actors move you calculate how much time has passed since they last moved (used System.getCurrentTimeMillis() and subtract the previously measured time) and multiply that by the speed to get the distance to move.
Entity1037 Entity1037

2014/7/21

#
I know that. The problem is that I can't seem to figure out how to write the code. My mind just goes blank... Like how do you detect collisions if the actors aren't moving into the correct areas properly? I don't get it...
davmac davmac

2014/7/21

#
Well as always, break it down into smaller and smaller steps until you can write code for each step. To be honest in this case I'm not sure where your difficulty lies. Something like this should be sufficient:
long currentTime = System.currentTimeMillis();
long timePassed = currentTime - prevTime;
if (prevTime == 0) {
  timePassed = 0; // if we don't have a prevTime value, assume no time has passed
}
move (speed * (float) timePassed / 1000); // assuming speed is pixels per second
prevTime = currentTime; // prevTime must be declared as an instance variable
Entity1037 Entity1037

2014/7/21

#
My difficulty lies in how this would work with hit detection. If the actor is moving 100 px/sec, and another is too at a perpendicular trajectory to it to where they should collide, and there is horrible lag, couldn't they both pass each other and not detect a collision because they moved too fast in a single frame to notice each other, sense neither of them were in either's detection range any given cycle?
davmac davmac

2014/7/21

#
couldn't they both pass each other and not detect a collision because they moved too fast in a single frame to notice each other
Yes, they could. If you really want to deal with that properly, it gets rather complicated. Frankly, it's not usually worth worrying about. To solve it you need to to model edges of the actor as a 3d surface (the 3rd dimension being time) and see if it intersects any edge of the other actor (also modelled as a 3d surface). That's some fairly complicated math.
Entity1037 Entity1037

2014/7/21

#
Ohh, that makes sense. Although yeah, that would be fairly complicated to pull off... Well thank you!
davmac davmac

2014/7/21

#
Putting it another way, you have two actors, A and B. Each has 4 edges, A1..4 and B1..4, defined by four vertexes (corners). Take each corner of A and each edge of B; that's three points. Each of these points has a location which is a function of time, that is, each point has a formula which looks something like: Px(t) = Pox + Dx * t Py(t) = Poy + Dy * t (This is pseudo-code, of course, not Java). Remember there are three sets of each (and Pox, Poy, Dx and Dy are different for each point). Let's call them (Cax, Cay) (being the corner of A) and (Eb1x, Eb1y) and (Eb2x, Eb2y) (these last two are the edge of B). Now, you want to find if at any time (t) the corner intersects the edge. That's a simultaneous equation. You can first simplify the edge to a gradient line and offset: Mb(t) = (Eb1y(t) - Eb2y(t)) / (Eb1x(t) - Eb2x(t)); // gradient is "rise over run" O(t) = Eb1x(t) * Mb(t) + Eb1y(t); // You have to deal with (Eb1x(t) - Eb2x(t)) == 0 as a special case to avoid division by 0 // I leave that as an exercise :) Now, the point (Cax, Cay) intersects the edge if at some point in time t it lies on the line defined by Mb(t) and O(t), and furthermore it is between the two edge points at that time. You check first whether it is on the line. That is, you want to find if: Cay(t) = Cax(t) * Mb(t) + O(t) ... for any t. Re-arrange that as: Cax(t) * Mb(t) + O(t) - Cay(t) = 0 Because all the functions depend only on t, you can now find for what t value(s) this is true (I'll leave it as an exercise). If any of those t values are between 0 and N, where N is the amount of time passed, then the corner intersects the line (but not necessarily the edge, since it might not intersect between the two corner points, but possibly at a point outside the actor bounds). So you must check in each case whether the intersection occurs between the corner points or not. Now, you have to do this for every edge and every corner in both actors. If you have more than two actors involved, you must do this between each corner and edge of every actor, which quickly becomes inefficient as the number of actors increases. You then need to devise some sort of pruning mechanism, but that's far too complicated to discuss here. I'm sure you see by now how difficult the problem is :) But if you do want to discuss further, feel free. I will help as much as I can.
Entity1037 Entity1037

2014/7/21

#
Awesome! This is pretty interesting actually. Thanks for the help!
You need to login to post a reply.