5
5
- Comment représenter dans le programme de la matière
6
6
"""
7
7
8
- from debug_pygame import show_point
8
+ from functools import reduce
9
9
from sys import setrecursionlimit
10
10
from threading import Thread
11
- from functools import reduce
12
11
13
12
import pygame
14
13
15
- from CONSTS import coordinate , OnLoadMapError , DEFAULT_DENSITY , MAX_THREAD_BY_CALC
14
+ from CONSTS import coordinate , OnLoadMapError , DEFAULT_DENSITY
15
+ from debug_pygame import get_point_from_idx
16
16
from utils import get_full_line , get_circle
17
17
18
18
setrecursionlimit (9000000 )
@@ -35,12 +35,15 @@ def gen_segmented_map(vectmap: list[list[coordinate]]) -> list[list[coordinate]]
35
35
36
36
37
37
def algo_peinture (segmap : list [list [coordinate ]], fmap : list [list [bool ]], centers : list [coordinate ],
38
- base : bool = False ):
38
+ dim : list [ int ], base : bool = False ):
39
39
def fill_neighbours (point : coordinate , segform : set [coordinate ]):
40
40
# print(segform)
41
41
fmap [point [0 ]][point [1 ]] = not base
42
42
for (x , y ) in [(1 , 0 ), (0 , 1 ), (- 1 , 0 ), (0 , - 1 )]:
43
- if (point not in segform ) and fmap [point [0 ] + x ][point [1 ] + y ] == base :
43
+ if (
44
+ 0 <= point [0 ] + x < dim [0 ] and 0 < point [1 ] + y <= dim [1 ] and
45
+ (point not in segform ) and fmap [point [0 ] + x ][point [1 ] + y ] == base
46
+ ):
44
47
fill_neighbours ((point [0 ] + x , point [1 ] + y ), segform )
45
48
46
49
# print(centers)
@@ -58,10 +61,11 @@ def __init__(self, mappath: str):
58
61
"""
59
62
self .map : list [list [bool ]] = [] # [x][y]
60
63
self .texture : list [int ] | None = None # Invalid texture is None - debug // list[int] is bytes to print img
61
- self .fond : pygame . Surface | None = None
64
+ self .fond : list [ int ] | None = None
62
65
self .dimensions : list [int ] = [0 , 0 ]
63
66
self .form_borders : list [list [coordinate ]] = []
64
-
67
+ self .reset_ONMAP_thread : Thread | None = None
68
+ self .px_update_list : list [int ] = []
65
69
# Step 1: Extract vectorial map
66
70
67
71
"""
@@ -154,7 +158,7 @@ def __init__(self, mappath: str):
154
158
else :
155
159
if sp [0 ] == "empty" :
156
160
print ("load fond" )
157
- self .fond = pygame .image .load (sp [1 ])
161
+ self .fond = list ( pygame .image .tobytes ( pygame . image . load (sp [1 ]), 'ARGB' ) )
158
162
elif sp [0 ] == "full" :
159
163
print ("load front" )
160
164
# pygame.image.tobytes returns [y] then [x]
@@ -167,6 +171,7 @@ def __init__(self, mappath: str):
167
171
# print(vectmap)
168
172
169
173
### INTERLUDE ###
174
+ self .TRUEMAP = [[True for y in range (self .dimensions [1 ])] for x in range (self .dimensions [0 ])]
170
175
Thread (group = None , target = self .__reset_ONMAP , name = None ).start ()
171
176
### ###
172
177
@@ -305,7 +310,7 @@ def __init__(self, mappath: str):
305
310
elif x not in Hdict [y ]:
306
311
self .map [x ][y ] = inside
307
312
308
- self .__filter_image (0 , len (self .texture ))
313
+ self .__filter_image (0 , len (self .texture ), arbitrary = True )
309
314
310
315
def clear_map (self ):
311
316
"""
@@ -328,15 +333,28 @@ def print_map(self, screen):
328
333
else :
329
334
screen .set_at ((x , y ), "black" )
330
335
331
- def blit_texture (self , screen ):
336
+ def blit_texture (self , screen , * , all_pxs : bool = False ):
332
337
"""
333
338
Affiche la map dans le screen
334
339
Utilise les textures internes
335
340
:param screen: Le screen qu'on doit blit dessus
336
341
"""
337
- screen .blit (self .fond , (0 , 0 ))
338
- screen .blit (pygame .image .frombytes (bytes (self .texture ), self .dimensions , 'ARGB' ), (0 , 0 ))
342
+ if all_pxs :
343
+ screen .blit (pygame .image .frombytes (bytes (self .fond ), self .dimensions , 'ARGB' ), (0 , 0 ))
344
+ screen .blit (pygame .image .frombytes (bytes (self .texture ), self .dimensions , 'ARGB' ), (0 , 0 ))
345
+ else :
346
+ while len (self .px_update_list ) > 0 :
347
+ self .update_px (self .px_update_list .pop (), screen )
348
+
349
+ def update_px (self , idx : int , screen ) -> None :
350
+ """
351
+ Blit the pixel given on screen
352
+ :param idx: Pixel index in self.texture (should point on Alpha channel)
353
+ :param screen: The screen to update
354
+ """
355
+ screen .set_at (get_point_from_idx (idx ), self .fond [idx + 1 :idx + 4 ])
339
356
357
+ # @get_time
340
358
def destroy_map (self , impact : coordinate , power : float ):
341
359
"""
342
360
Destoy the map using an impact point and the power of the weapon
@@ -357,50 +375,78 @@ def destroy_map(self, impact: coordinate, power: float):
357
375
# show_point(point, does_stop=False, one_pixel=True)
358
376
# show_point(impact, color=(0,0,255))
359
377
360
- algo_peinture (seg_circle , self .ONMAP , [impact ], base = True )
378
+ algo_peinture (seg_circle , self .ONMAP , [impact ], self . dimensions , base = True )
361
379
362
- self .map = [
363
- [ self . map [ x ][ y ] and self . ONMAP [ x ][ y ] for y in range (len (self .map [x ]))] for x in range ( len ( self . map ))
364
- ]
380
+ for x in range ( len ( self .map )):
381
+ for y in range (len (self .map [x ])):
382
+ self . map [ x ][ y ] = self . map [ x ][ y ] and self . ONMAP [ x ][ y ]
365
383
366
384
head = (xmini , ymini )
367
- queue = (xmaxi , ymaxi )
368
- starter = (head [0 ]+ head [1 ]* self .dimensions [0 ])* 4
369
- goal = (queue [0 ]+ queue [1 ]* self .dimensions [0 ])* 4
385
+ # queue = (xmaxi, ymaxi)
386
+ starter = (head [0 ] + head [1 ] * self .dimensions [0 ]) * 4
387
+ # goal = (queue[0] + queue[1] * self.dimensions[0]) * 4
370
388
# show_point(head, does_stop=False)
371
389
# show_point(queue)
372
390
391
+ while self .reset_ONMAP_thread :
392
+ pass
393
+
373
394
Thread (group = None , target = self .__reset_ONMAP , name = None ).start ()
395
+
374
396
# self.tt = 0
375
- parter = (goal - starter ) // MAX_THREAD_BY_CALC
376
- print (parter , goal , starter )
377
- for i in range (MAX_THREAD_BY_CALC ):
378
- Thread (group = None , target = self .__filter_image , name = None ,
379
- kwargs = {'_from' : starter + parter * i , '_to' : starter + parter * (i + 1 )}
380
- ).start ()
381
-
382
- def __filter_image (self , _from : int , _to : int ):
397
+ parter = (xmaxi - xmini ) * 4
398
+ # print(parter, goal, starter)
399
+ launch_dicts = [{'_from' : starter + self .dimensions [0 ] * i * 4 ,
400
+ '_to' : starter + parter + self .dimensions [0 ] * (i + 1 ) * 4 }
401
+ for i in range (ymaxi - ymini )]
402
+ Thread (group = None , target = self .__start_filter_image , name = None , args = launch_dicts ).start ()
403
+ # for dlign in launch_dicts:
404
+ # self.__filter_image(**dlign)
405
+
406
+ # @add_time_incache
407
+ def __start_filter_image (self , * launch_dict : dict [str , int ]) -> None :
408
+ for dict in launch_dict :
409
+ self .__filter_image (** dict )
410
+
411
+ def __filter_image (self , _from : int , _to : int , * , arbitrary : bool = False ) -> None :
383
412
"""
384
413
Filter the image to set alpha channel of hidden pixel to 0 and the other pixel to 1
385
414
:param _from: Start processing at px _from (included)
386
415
:param _to: Ends processing at px _to (excluded)
387
416
"""
388
- print ("go from" ,_from , "to" , _to )
417
+ # print("go from", _from, "to", _to)
389
418
# t1 = time()
390
419
# Make sure we are interacting with images
391
420
assert self .texture != None
421
+ if arbitrary :
422
+ for idx in range (_from , _to , 4 ): # Catch only alpha channels
423
+ # print((idx // 4) // self.dimensions[0], (idx // 4) // self.dimensions[1])
424
+ if self .map [(idx // 4 ) % self .dimensions [0 ]][(idx // 4 ) // self .dimensions [0 ]]:
425
+ self .texture [idx ] = 255
426
+ else :
427
+ self .texture [idx ] = 0
428
+ else :
429
+ for idx in range (_from , _to , 4 ): # Catch only alpha channels
430
+ if (
431
+ self .map [(idx // 4 ) % self .dimensions [0 ]][(idx // 4 ) // self .dimensions [0 ]]
432
+ and self .texture [idx ] != 255
433
+ ):
434
+ self .texture [idx ] = 255
435
+ self .px_update_list .append (idx )
436
+ elif (
437
+ not self .map [(idx // 4 ) % self .dimensions [0 ]][(idx // 4 ) // self .dimensions [0 ]]
438
+ and self .texture [idx ] != 0
439
+ ):
440
+ self .texture [idx ] = 0
441
+ self .px_update_list .append (idx )
392
442
393
- for idx in range (_from , _to , 4 ): # Catch only alpha channels
394
- # print((idx // 4) // self.dimensions[0], (idx // 4) // self.dimensions[1])
395
- if self .map [(idx // 4 ) % self .dimensions [0 ]][(idx // 4 ) // self .dimensions [0 ]]:
396
- self .texture [idx ] = 255
397
- else :
398
- self .texture [idx ] = 0
399
443
# t2 = time()
400
444
# self.tt += t2 - t1
401
445
402
446
def __reset_ONMAP (self ):
403
- self .ONMAP = [[True for y in range (self .dimensions [1 ])] for x in range (self .dimensions [0 ])]
447
+ self .reset_ONMAP_thread = True
448
+ self .ONMAP = self .TRUEMAP .copy ()
449
+ self .reset_ONMAP_thread = False
404
450
405
451
406
452
if __name__ == "__main__" :
0 commit comments