0

I have just finished my second Python game with pygame, but this time I'm facing a new problem. When I tried the game on another pc, the game speed was so fast, way faster than it was supposed to be, I tried to adjust the FPS but that didn't help. How could this be fixed and why is this even happening when I've already set all the settings like the moving speed and game FPS?

import pygame
from settings import Settings
import game_functions as gf
from ship import Ship
from pygame.sprite import Group
from game_stats import Stats
from animation import spriteSheet
from scoreboard import ScoreBoard
from button import Button

def run_game():

    pygame.init()

    icon = pygame.image.load('icons/icon.png')
    pygame.display.set_icon(icon)

    so_settings = Settings()

    screen = pygame.display.set_mode((so_settings.screen_width, so_settings.screen_height))

    pygame.display.set_caption('Space Vikers')

    last_tick = 0    

    ship = Ship(screen, so_settings)
    stats = Stats(so_settings, screen)


    bullets = Group()
    bullets_enemy = Group()
    enemies = Group()
    explosion = Group()

    exploAni = spriteSheet("animations/explosion.png", 5, 4)
    sb = ScoreBoard(so_settings, screen, stats, bullets, ship)
    btn = Button(screen)

    gf.start_background_music()

    clock = pygame.time.Clock()
    FPS = 120
    while True:
        clock.tick(FPS)

        while stats.main_menu:

            gf.move_bg(so_settings, screen, sb, stats, last_tick)
            btn.draw_button()
            pygame.display.flip()
            gf.check_event(screen, so_settings, ship, bullets, sb, stats, btn)

        if stats.game_active:
            gf.update_enemy_bullet(bullets_enemy, so_settings, screen)
            gf.update_bullet(bullets, so_settings, sb)
            gf.generate_enemy(so_settings, stats, last_tick, screen, ship, enemies, bullets_enemy, bullets, explosion, sb)
            gf.update(so_settings, screen, bullets, enemies, bullets_enemy, ship, exploAni, explosion, stats, sb)
            gf.move_bg(so_settings, screen, sb, stats, last_tick)
            gf.check_event(screen, so_settings, ship, bullets, sb, stats, btn)
        else:
            gf.move_bg(so_settings, screen, sb, stats, last_tick)
            gf.check_event(screen, so_settings, ship, bullets, sb, stats, btn)

run_game()
skrx
  • 19,980
  • 5
  • 34
  • 48
Dia Abujaber
  • 33
  • 1
  • 6
  • Possible duplicate of [Mario running across screen too fast in pygame](https://stackoverflow.com/questions/20134955/mario-running-across-screen-too-fast-in-pygame) – kabanus Apr 28 '18 at 10:53
  • @kabanus I don't think this qualifies as a duplicate. – Daniel Apr 28 '18 at 11:02
  • @Coal_ Doesn't the answer there address a pygame running in different speeds on different computers? – kabanus Apr 28 '18 at 11:04
  • @kabanus Yes, but the question you linked to is about a very specific example, and it's certainly not the only time this issue was brought up. – Daniel Apr 28 '18 at 11:08
  • 2
    @Coal_ as far as I can tell all pygames will be specific examples of this problem. A duplicate has to provide a good answer, not match the question word for word - it's meant to help, and that's why OP can dispute it. If you find a better dupe - by all means, link it. – kabanus Apr 28 '18 at 11:11
  • I have already tried that but it didn't fix my problem. however, I have just included my main code in the question description – Dia Abujaber Apr 28 '18 at 11:55
  • Possible duplicate of [In Pygame, normalizing game-speed across different fps values](https://stackoverflow.com/questions/13591949/in-pygame-normalizing-game-speed-across-different-fps-values) – skrx Apr 28 '18 at 17:30

1 Answers1

2

Your problem is that the slow computer is not capable of handling 120 fps. You can easly check that by including the following line in loop after the clock.tick statement:

print(clock.get_fps())

This will print the actually achieved FPS

There are to ways to fix this. First you could make all the movements speed depending on the return value of clock.tick:

dt = clock.tick()

And then somewhere in the movement scripts:

pos = pos+speed*dt # Just an example

This is what you should always to in the future.

If you don't want to rewrite your movement system, just lower the framerate:

FPS = 30
MegaIng
  • 7,361
  • 1
  • 22
  • 35
  • Yes, multiplying the speed by the delta time is often sufficient (in single-player games), but note that you've got a variable time step now and your game has become non-deterministic. That means you could get trouble with physics and with networking. It's usually recommended to use a fixed time step with variable rendering, but that's more difficult to implement (see http://gameprogrammingpatterns.com/game-loop.html). – skrx Apr 28 '18 at 17:31
  • 2
    Isn't this possibly going to give problems with, e.g., object collisions? If two objects are on a collision line, but the system is slow enough, won't that sometimes allow one object to go through the other (because the time passed will be high enough that the coordinates will be much bigger)? – ChatterOne Apr 30 '18 at 14:22
  • 1
    @ChatterOne, yes exactly. That's one reason why this solution shouldn't be used when physics is involved. I think my previous comment was too positive. The variable timestep really isn't a good solution except maybe for simple card or board games or point and click adventures in which you only want to adjust the animation speed. The solution with the fixed update timestep and variable rendering should usually be preferred (see http://gameprogrammingpatterns.com/game-loop.html). – skrx Apr 30 '18 at 16:34