سؤال

My project is a large map that can be panned around containing "info spots" that can be clicked. For now I use four large images, each spans 5000x5000 pixels (so total map size is 20'000x20'000 pixel). On my AMD Phenom 9950 Quad-Core with 8GB RAM and an NVIDIA GeForce 610 this takes a certain while to load while it's quite fast afterwards when panning the image. I tried tiling it up but there's no visible enhancement in loading speed as the image still has to be loaded completely before it's separated into tiles.

The only way to have some real improvement on speed and memory usage would be, to only load those parts of the map image that are actually shown. Does PyGame offer any way of doing so? I'm thinking of a "theoretical" tile map which contains the needed x and y values of each tile (I group them a little, less to compute each frame) and a theoretical image information (like: which image and which position therein). Only when a tile comes near the visible part of the screen, its image information is loaded, otherwise it remains a number and string value.

Would this make any sense? Is there any way to achieve this?

هل كانت مفيدة؟

المحلول 2

After reading @lukevp 's reply, I was interested and tried this:

http://imgur.com/Q1N2UtU

Go get this image and create a folder named 'test_data'. Now place this image, code outside of test_data folder and run. The output would be cropped figures named as per their order (It's a bit off on the edges as the image is 1920 * 1080). You can try it with your custom size tho. Also note that I am on ubuntu so take care to appropriate paths.

OUTPUT: http://imgur.com/2v4ucGI Final link: http://imgur.com/a/GHc9l

import pygame, os
pygame.init()

original_image = pygame.image.load('test_pic.jpg')

x_max = 1920
y_max = 1080

current_x = 0
current_y = 0

count = 1

begin_surf = pygame.Surface((x_max,y_max), flags = pygame.SRCALPHA)
begin_surf.blit(original_image,(0,0))

cropped_surf =  pygame.Surface((100,100),flags=pygame.SRCALPHA)

while current_y + 100 < y_max:

    while current_x + 100 < x_max:
    cropped_surf.blit(begin_surf, (0,0), (current_x, current_y,100,100))
    pygame.image.save(cropped_surf, os.path.join("test_data", str(count) + '.jpg'))

    current_x += 100

    count += 1

    current_x = 0

    current_y += 100

Would now actually be working to load those images and span them as he said.

نصائح أخرى

The only way to accomplish this with Pygame would be to break the images themselves into smaller squares (say 250x250), and then, as the user pans, just get the current topleft x,y coordinates, as well as the screen size, and load any tiles that fit into that screen or around the buffer edge into memory, and clear out any others that are outside that range. The math will be fairly straightforward unless you add support for rotation and/or zooming. I would name the tiles after their location as a multiple of the square size (for example the tile at 500, 500 would be named 2-2.png). This will make it very trivial to generate the tile name that you need to load at each location - take the current x/y coordinates, integer divide by 250, subtract the buffer tile amount, and then loop by your screen width integer divided by 250 plus 1 plus the buffer tile amount for each row. Do that loop for each column.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top