Determing FPS within another FPS .. How? - Printable Version +- QB64 Phoenix Edition (https://staging.qb64phoenix.com) +-- Forum: QB64 Rising (https://staging.qb64phoenix.com/forumdisplay.php?fid=1) +--- Forum: Code and Stuff (https://staging.qb64phoenix.com/forumdisplay.php?fid=3) +---- Forum: Help Me! (https://staging.qb64phoenix.com/forumdisplay.php?fid=10) +---- Thread: Determing FPS within another FPS .. How? (/showthread.php?tid=1107) |
Determing FPS within another FPS .. How? - TerryRitchie - 11-11-2022 I'm finishing up a Pac-Man clone. The game runs at 60 frames per second just like the original. During game play the speed of both Pac-Man and the ghosts are modified by level events and by advancing to higher levels. The speed of these objects is adjusted in 5% increments resulting in a loss of 3 frames per second per 5% loss: 100% = 60FPS (the fastest any object travels) 95% = 57FPS (60 * .95) 90% = 54FPS (60 * .9) 85% = 51FPS (60 * .85) ... ... 40% = 24FPS (60 * .4) (the slowest any object travels - ghost in the tunnel on level 1) The usual way I adjust speeds in games is to use MOD and skip frames when the outcome is 0 (zero): IF Frames MOD 20 THEN ... (every 20th frame will be skipped resulting in 95% or 57FPS) IF Frames MOD 10 THEN ... (every 10th frame will be skipped resulting in 90% or 54FPS) IF Frames MOD 5 THEN ... (every 5th frame will be skipped resulting in 80% or 48FPS) .. .. Etc. This can also be done in reverse for lower frame rates: IF Frames MOD 20 = 0 THEN ... (all but three frames will be skipped resulting in 3FPS) IF Frames MOD 10 = 0 THEN ... (all but six frames will be skipped resulting in 6FPS) .. .. And so on My problem is that neither of these methods will yield 85%(51FPS), 60%(36FPS), 55%(33FPS), 45% (27FPS), and 40%(24FPS) all of which I need. There must be a simple formula I am overlooking to use within a 60FPS loop: Object.FPS = 24 Frame = 0 DO _LIMIT 60 Frame = Frame + 1 ( If Object.FPS multiplied by some magical number= current frame then draw it ... formula here) LOOP I know I could set up individual frame counters for every object and skip, say, every 9th frame to achieve 85%. However, the original Pac-Man arcade machine had 16K of ROM and 2K of RAM and I can't imagine this was the procedure used with such limited space. I also realize that I could simply use single precision numbers for x,y and add the percentage ( x! = x! + .85 : 85% for instance ) to get the desired outcome, but again, using single precision values in that era would have been a no-no given the speed over head. How did those early programmers do this with Integers? Is there a formula I'm overlooking? Help me Obi-Wan math wizards, you are my only hope. I've stared at this for far too long now. My brain hurts. RE: Determing FPS within another FPS .. How? - SMcNeill - 11-11-2022 Why not use _LIMIT to set the FPS and then calculate position/graphic based on it? Mouth_Open = X times per second or Limit / x Mouth_Closed = Not Opened Move = x pixels per second or Limit / X Mouth should open 5 times per second? On limit 30, it's open starting at 0, 6, 12, 18, 24 on your loop counter, for 3 loop count, for example. RE: Determing FPS within another FPS .. How? - bplus - 11-11-2022 I think of speed as pixels per frame something moves over the screen: speed = SQR(dx^2 + dy^2) if you want a formula dx = speed * cos(HeadingInRadians) dy = speed * sin(HeadingInRadians) ' more formulas If fastest thing moves 5 pixels per frame then for 85% of it is .85 * 5 = 4.25 for speed and so on... If the heading is up or down it's all dy. Likewise if only left or right it's all dx. RE: Determing FPS within another FPS .. How? - TerryRitchie - 11-11-2022 (11-11-2022, 11:06 PM)SMcNeill Wrote: Why not use _LIMIT to set the FPS and then calculate position/graphic based on it? Yes, I could do that. That's another good method I can add to the two I pointed out above. I'm trying to find the system the original programmers used. This web site contains "The Pacman Dossier": https://www.gamedeveloper.com/design/the-pac-man-dossier If you scroll down about a quarter of the way you'll see a diagram of the PacMan and Ghost speeds and when they are to occur. The "Norm Dots" and "Fright Dots" columns can be ignored, they are simply the result of skipping one frame every time Pacman eats a pellet. Each of these speeds come out to an equal FPS when you multiply 60 by the percentage. There must be a simple algorithm I'm overlooking that relates to this. I found the original source code to Pacman (Z80 ASM) but oh lord, I have not dabbled in Assembler in years, and never in Z80, only x86. I suppose if a resident math wizard doesn't come to my rescue I could always wade through the thousands of lines of ASM code to see if I can glimpse the inner workings. Ugh. RE: Determing FPS within another FPS .. How? - TerryRitchie - 11-11-2022 (11-11-2022, 11:36 PM)bplus Wrote: I think of speed as pixels per frame something moves over the screen: speed = SQR(dx^2 + dy^2) if you want a formula Sure, sure. I use those same formulas for a lot of my vector work. This is similar to the approach I mentioned using single precision values. Completely doable. I'm hoping to find the way the original programmers did it. My goal, if it's attainable, is to have the ghosts move in the exact same patterns as the arcade machine so established patterns of play will work. I'm very close. A pattern I know *almost* works. I just need to get these timings exact. I'll add an option to the game that seeds the RND generator so established patterns won't work either creating a whole new experience. That Pac-Man Dossier I mentioned above has darn near everything one needs to clone the game perfectly, except for the method of FPS adjustment. RE: Determing FPS within another FPS .. How? - Pete - 11-12-2022 A completely different method is using an inner timer... For your 51 FPS example: Code: (Select All) z2 = TIMER Pete RE: Determing FPS within another FPS .. How? - TerryRitchie - 11-12-2022 (11-12-2022, 12:15 AM)Pete Wrote: A completely different method is using an inner timer... Hmmm.. Interesting. My son saw me working on the code this afternoon and suggested something similar. He said the way the Nintendo worked was that sprites had two pixel layers. The outer pixel layer was a one to one relationship with the pixels on screen. The inner pixel count was used to move the sprite using smaller steps that would not show up on screen. Your approach seems to be along this line. RE: Determing FPS within another FPS .. How? - LEM - 11-12-2022 For 85%, what if you do: IF (2*frames) MOD 18 THEN ... Would that work? RE: Determing FPS within another FPS .. How? - SMcNeill - 11-12-2022 (11-12-2022, 01:47 AM)TerryRitchie Wrote:(11-12-2022, 12:15 AM)Pete Wrote: A completely different method is using an inner timer... Seems like a count## = count## + 51 / 60 would work as well. Just move the sprite on every integer increase of count. 0 -- move 0.8 -- don't move 1.6 -- move 2.4 -- move 3.2 -- move 4.0 -- move 4.8 -- don't move (For example, depending on whatever 51/ 60 actually works out to be.) RE: Determing FPS within another FPS .. How? - Pete - 11-12-2022 (11-12-2022, 01:53 AM)LEM Wrote: For 85%, what if you do: I was thinking in similar terms, along the lines of work I did with greatest common factors. With the one of 85% I came out with 2.5. Dang, not an integer, right? Well whogas? Let's try that mulitpiled to the frames MOD 20... Pretty close to 85%! Input 2.5,20 Code: (Select All) DO +1 to LEM. I think he's on to something. Pete |