Python Forum
[PyGame] Tiling large images
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] Tiling large images
#1
Hello,

Is it faster for pygame to draw a huge image if it is chopped up into smaller tiles?

Currently they are just circles, but I would like to have star and planet images in my space game be large.. very large. Pygame hates large images, would it draw things faster if they are cut into a bunch of smaller images?

I'm sure I can get an image to draw out onto a grid of smaller surfaces, but is it worthy time, or is there another method for very big images? Similarly, would drawing enormous circles showing planet orbits or will I later have to figure out how to calculate the visible sections only (or does pygame do that itself)?

Many thanks.
Reply
#2
I use to write test scripts for my games. Write two seperate test scripts for your two scenerios and time them. Go with the smaller time.
BashBedlam likes this post
Recommended Tutorials:
Reply
#3
Here is where I am so far. I went with a function that takes an image, chops it up, and returns a dictionary. It runs, but nothing shows up. A lot of this was pretty new to me, so if you see obvious errors, please let me know. This is just where I got to so far.

def make_tiled_image(game, image, tilesize):
    rect = image.get_rect()
    x, y = 0, 0
    image_dict = {}

    for x in range(0, rect.width, tilesize):
        for y in range(0, rect.height, tilesize):
            tile = pg.Surface((tilesize, tilesize), pg.SRCALPHA)
            tile.blit(image, (-x, -y))
            image_dict.update({(x, y) : tile})

    return image_dict

########################


    for o in self.local_objects:
        if o == self.star_system.star:
              for pos, image in o.image_dict.items():
                   self.screen.blit(image, vec(pos) + o.pos - self.camera.pos)
Reply
#4
Tiling is use for memory saving. So you can have really large map. With low memory usage. Because you are using the same images over and over. It also gives faster load times.

Why do you think pygame hate large images ?
What size are you talking about ?

Drawing a lot images will slow things down.
Doing a lot work in main loop will slow thing down.

Example of big image.
import random
import pygame

class QuickRun:
    def __init__(self, caption, size, flags=0):
        pygame.display.set_caption(caption)
        self.main_surface = pygame.display.set_mode(size, flags)
        self.rect = self.main_surface.get_rect()
        self.clock = pygame.time.Clock()
        self.running = False
        self.gamespeed = 1
        self.delta = 0
        self.ticks = 0
        self.fps = 60

        self.startup(100)

    def startup(self, size):
        self.fps_tick = 0
        self.fps_image = None
        self.fps_interval = 250
        self.font = pygame.font.Font(None, 24)
        self.pos = [0, 0]
        self.speed = 1000
        self.big_surface = pygame.Surface((10000, 10000), pygame.SRCALPHA)

        for x in range(0, 10000, size):
            for y in range(0, 10000, size):
                r, g, b = 0, 0, 0
                while r + g + b < 60:
                    r = random.randint(0, 255)
                    g = random.randint(0, 255)
                    b = random.randint(0, 255)
                    if r + g + b < 60:
                        continue
                    else:
                        pygame.draw.rect(self.big_surface, (r, g, b), (x, y, size, size))

    def on_draw(self, surface):
        rect = pygame.Rect(self.pos, self.rect.size)
        self.main_surface.blit(self.big_surface, (0, 0), rect)
        if self.fps_image:
            self.main_surface.blit(self.fps_image, (5, 5))

    def on_event(self, event):
        if event.type == pygame.QUIT:
            self.running = False

    def on_update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_RIGHT]:
            self.pos[0] += self.delta * self.speed

        if keys[pygame.K_LEFT]:
            self.pos[0] -= self.delta * self.speed

        if keys[pygame.K_UP]:
            self.pos[1] -= self.delta * self.speed

        if keys[pygame.K_DOWN]:
            self.pos[1] += self.delta * self.speed

        if self.ticks > self.fps_tick:
            self.fps_tick = self.ticks + self.fps_interval
            self.fps_image = self.font.render(str(self.clock.get_fps()), 1, "lightblue")

    def main_loop(self):
        self.running = True
        while self.running:
            for event in pygame.event.get():
                self.on_event(event)

            self.ticks = pygame.time.get_ticks()
            self.main_surface.fill("black")
            self.on_draw(self.main_surface)
            self.on_update()
            pygame.display.flip()
            self.delta = self.clock.tick(self.fps) * 0.001

pygame.init()
window = QuickRun("BigImage", (800, 600))
window.main_loop()
pygame.quit()
metulburr likes this post
99 percent of computer problems exists between chair and keyboard.
Reply
#5
(Jul-15-2022, 12:47 AM)Windspar Wrote: Tiling is use for memory saving. So you can have really large map. With low memory usage. Because you are using the same images over and over. It also gives faster load times.

Why do you think pygame hate large images ?
What size are you talking about ?

Drawing a lot images will slow things down.
Doing a lot work in main loop will slow thing down.


I know that old NES games used to use meta sprites because of memory limitation, so I thought that might help with performance (or at least something I wanted to ask about here)

As far as large images in pygame, I just picked that up somewhere. Who knows. But I do know that when my game launches, if it picks a large star (pygame surface(800x800) with a circle drawn onto it) to spawn, there is noticeable slowdown when it is on screen vs when it makes a small star. The only difference is literally the size.

Now, there is lots of stuff also going on at the time, a player, a bunch of enemies, a tiled background of stars, a minimap and far to many bullets flying, so I clearly need to trim back in places, but I hoped that there was a way to optimize my large planet and star sprites in some way.
Reply
#6
First make sure you only load image once.
Second convert your loaded images. Otherwise it will do this every frame.
Third you can handle more images with sprite class and group class. Last test I did on my computer. It was almost 1000 more. Before frame rate drops.
metulburr likes this post
99 percent of computer problems exists between chair and keyboard.
Reply
#7
If you are using any pygame.draw commands. It better to draw them to surfaces. Then you just blit the surface. Otherwise draw commands can do a lot of calculation. That will slow things down.
metulburr and XavierPlatinum like this post
99 percent of computer problems exists between chair and keyboard.
Reply
#8
(Jul-18-2022, 09:02 AM)Windspar Wrote: If you are using any pygame.draw commands. It better to draw them to surfaces. Then you just blit the surface. Otherwise draw commands can do a lot of calculation. That will slow things down.

Good to know! I'll change how my mini map gets drawn. That will save a bunch of cycles. Thankyou.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020