Here an example. I haven't finish it. Just let me know if this lag.
If this doesn't lag. Then something in your code is causing it.
If this doesn't lag. Then something in your code is causing it.
import pygame import random # Why make frameworks. For you can use it over and over. # Game Framework class Scene: def __init__(self, manager): self.manager = manager def on_draw(self, surface): pass def on_event(self, event): pass def on_update(self, delta, ticks): pass def on_quit(self): self.manager.engine.running = False class DisplayEngine: def __init__(self, manager, caption, width, height, fps, gamespeed, flags): # Basic pygame setup pygame.display.set_caption(caption) self.surface = pygame.display.set_mode((width, height), flags) self.rect = self.surface.get_rect() self.clock = pygame.time.Clock() self.gamespeed = gamespeed self.running = False self.delta = 0 self.ticks = 0 self.fps = fps self.scene = Scene(manager) self.next_scene = None def main_loop(self): self.running = True while self.running: if self.next_scene is not None: self.scene = self.next_scene self.next_scene = None # Only one event loop. for event in pygame.event.get(): if event.type == pygame.QUIT: self.scene.on_quit() else: self.scene.on_event(event) self.ticks = pygame.time.get_ticks() self.scene.on_draw(self.surface) self.scene.on_update(self.delta, self.ticks) # Only one pygame display (flip or update) pygame.display.flip() self.delta = self.clock.tick(self.fps) * 0.001 * self.gamespeed def set_scene(self, scene): self.next_scene = scene class GameManager: def __init__(self, caption="Pygame Window", width=800, height=600, fps=60, gamespeed=1, flags=0): pygame.init() self.engine = DisplayEngine(self, caption, width, height, fps, gamespeed, flags) self.images = ImageHandler() self.images.load_level_1() self.scenes = {} def add_scene(self, scene, name=""): if name == "": self.scenes[scene.__class__.__name__] = scene else: self.scenes[name] = scene def run(self): self.engine.main_loop() pygame.quit() # End Of Game Framework # Handle all images in one place. # You only want to load or create once. class ImageHandler: def load_level_1(self): self.ball = self.create_ball("skyblue", (12, 12)) self.paddle = self.create_paddle("gray60", (12, 38)) def create_ball(self, color, size): image = pygame.Surface(size, pygame.SRCALPHA) image.fill((0, 0, 0, 0)) rect = image.get_rect() pygame.draw.circle(image, color, rect.center, rect.centerx) return image def create_paddle(self, color, size): image = pygame.Surface(size) image.fill(color) return image class Entity(pygame.sprite.Sprite): def __init__(self, image, position, anchor): super().__init__() self.image = image self.rect = image.get_rect(**{anchor:position}) self.center = pygame.Vector2(self.rect.center) def move(self, x, y): self.center += (x, y) self.rect.center += self.center def set_position(self, x, y): self.center = pygame.Vector2(x, y) self.rect.center = self.center class EntityVector(pygame.sprite.Sprite): def __init__(self, vector, speed, image, position, anchor): super().__init__() self.image = image self.rect = image.get_rect(**{anchor:position}) self.center = pygame.Vector2(self.rect.center) self.vector = vector self.speed = speed def update(self, delta): self.center += delta * self.vector * self.speed self.rect.center = self.center class Counter: def __init__(self, ticks, interval): self.ticks = ticks + interval self.interval = interval self.count = 0 def elapsed(self, ticks): return ticks >= self.ticks def reset(self, ticks, interval=None): if interval: self.interval = interval self.ticks = ticks + self.interval def tick(self, ticks): if ticks >= self.ticks: self.ticks += self.interval return True return False def tick_count(self, ticks): self.count = 0 while ticks >= self.ticks: self.ticks += self.interval self.count += 1 return bool(self.count) class PenLabel(pygame.sprite.Sprite): def __init__(self, pen, text, position, anchor): super().__init__() self._pen = pen self.image = pen.render(text) self.rect = self.image.get_rect(**{anchor:position}) self._anchor = anchor def set_text(self, text): self.image = self._pen.render(text) position = getattr(self.rect, self._anchor) self.rect = self.image.get_rect() setattr(self.rect, self._anchor, position) class Pen: def __init__(self, font_name, size, color): self._font = pygame.font.Font(font_name, size) self._color = color def render(self, text): return self._font.render(text, 1, self._color) def write(self, text, position, anchor): return PenLabel(self, text, position, anchor) class PongIntro(Scene): def __init__(self, manager): super().__init__(manager) def on_draw(self, surface): surface.fill("black") def on_event(self, event): pass class PongGame(Scene): def __init__(self, manager): super().__init__(manager) mid = manager.engine.rect.centerx, 5 self.pen = Pen(None, 24, "white") self.fps_counter = Counter(manager.engine.ticks, 250) self.fps_image = self.pen.write("0", mid, "midtop") rect = manager.engine.rect gap = 30 self.player = Entity(manager.images.paddle, (gap, rect.centery), "midleft") right = rect.right - gap self.computer = Entity(manager.images.paddle, (right, rect.centery), "midright") vector = pygame.Vector2() self.vector_shot = (-45, 45), (135, 225) shot = random.choice(self.vector_shot) vector.from_polar((1, random.randint(shot[0], shot[1]))) self.ball = EntityVector(vector, 140, manager.images.ball, rect.center, "center") self.sprites = pygame.sprite.Group() self.sprites.add(self.fps_image, self.player, self.computer, self.ball) self.collible = pygame.sprite.Group() self.collible.add(self.player, self.computer) def ball_collide(self): area = self.manager.engine.rect clamp = self.ball.rect.clamp(area) change = False if clamp.x != self.ball.rect.x: self.ball.vector.x = -self.ball.vector.x change = True if clamp.y != self.ball.rect.y: self.ball.vector.y = -self.ball.vector.y change = True if change: self.ball.rect = clamp self.ball.center = clamp.center def on_draw(self, surface): surface.fill("navy") self.sprites.draw(surface) def on_event(self, event): if event.type == pygame.MOUSEMOTION: self.player.set_position(self.player.rect.centerx, event.pos[1]) def on_update(self, delta, ticks): if self.fps_counter.tick(ticks): self.fps_image.set_text(str(int(self.manager.engine.clock.get_fps()))) self.ball_collide() self.ball.update(delta) self.computer.rect.centery = self.ball.rect.centery collision = pygame.sprite.spritecollide(self.ball, self.collible, False) for sprite in collision: self.ball.speed += 2 if self.ball.rect.centerx > sprite.rect.centerx: self.ball.vector.x = abs(self.ball.vector.x) elif self.ball.rect.centerx < sprite.rect.centerx: self.ball.vector.x = -abs(self.ball.vector.x) if self.ball.rect.centery > sprite.rect.centery: self.ball.vector.y = abs(self.ball.vector.y) elif self.ball.rect.centery < sprite.rect.centery: self.ball.vector.y = -abs(self.ball.vector.y) if __name__ == "__main__": game = GameManager("Pong") pygame.mouse.set_visible(False) pong = PongGame(game) game.engine.set_scene(pong) game.run()
99 percent of computer problems exists between chair and keyboard.