diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2e5195d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea + +__pycache__ \ No newline at end of file diff --git a/ButtonUI.py b/ButtonUI.py new file mode 100644 index 0000000..dcda1e4 --- /dev/null +++ b/ButtonUI.py @@ -0,0 +1,100 @@ +import os +from Widgets import * + + +def create_buttons(output, painting): + brush_water = MyButton(output, painting, os.path.join("Resources", "brush_water.png"), + 25, 33, 50, 60, + ButtonData('normal_button', 15, Colors.water), '水域', + ['*PAINT COLORS*', ' ', 'Current Size : '], Colors.coolred) + brush_neighborhood = MyButton(output, painting, os.path.join("Resources", "brush_neighborhood.png"), + 80, 33, 50, 60, + ButtonData('normal_button', 15, Colors.neighborhood), '街区', + ['*PAINT COLORS*', ' ', 'Current Size : '], Colors.coolred) + brush_culture = MyButton(output, painting, os.path.join("Resources", "brush_culture.png"), + 135, 33, 50, 60, + ButtonData('normal_button', 15, Colors.culture), '文化区', + ['*PAINT COLORS*', ' ', 'Current Size : '], Colors.coolred) + brush_vegetation = MyButton(output, painting, os.path.join("Resources", "brush_vegetation.png"), + 190, 33, 50, 60, + ButtonData('normal_button', 15, Colors.vegetation), '绿化区', + ['*PAINT COLORS*', ' ', 'Current Size : '], Colors.coolred) + + pencil_road0 = MyButton(output, painting, os.path.join("Resources", "pencil_road0.png"), 25, 95, 50, 60, + ButtonData('normal_button', 2, Colors.road_0), '小道', + ['*DRAW*', ' ', 'Current Size : '], Colors.carrot) + pencil_road1 = MyButton(output, painting, os.path.join("Resources", "pencil_road1.png"), 80, 95, 50, 60, + ButtonData('normal_button', 8, Colors.road_1), '公路', + ['*DRAW*', ' ', 'Current Size : '], Colors.carrot) + pencil_road2 = MyButton(output, painting, os.path.join("Resources", "pencil_road2.png"), 135, 95, 50, 60, + ButtonData('normal_button', 12, Colors.road_2), '高速公路', + ['*DRAW*', ' ', 'Current Size : '], Colors.carrot) + pencil_road3 = MyButton(output, painting, os.path.join("Resources", "pencil_road3.png"), 190, 95, 50, 60, + ButtonData('normal_button', 12, Colors.road_3), '在建道路与其它道路', + ['*DRAW*', ' ', 'Current Size : '], Colors.carrot) + # pencil_road1 = MyButton(output, painting, os.path.join("Resources", "pencil_road1.png"), 25, 150, 50, 60, + # ButtonData('normal_button', 2, Colors.road_0), 'Pencil', + # ['*DRAW*', ' ', 'Current Size : '], Colors.carrot) + + eraser = MyButton(output, painting, os.path.join("Resources", "eraser.png"), 30, 230, 50, 60, + ButtonData('function_button', None, None), 'Eraser', + ['*CLEARS SELECTED*', ' ', 'Current Size : '], Colors.coolblue) + rbin = MyButton(output, painting, os.path.join("Resources", "bin.png"), 135, 230, 50, 60, + ButtonData('function_button', None, None), 'Clear', + ['*CLEARS ALL*', ' ', 'Current Size : '], Colors.cloud) + bplus = MyButton(output, painting, os.path.join("Resources", "plus.png"), 31, 510, 35, 45, + ButtonData('function_button', None, None), 'Brush Size +', + ['**INCREASE SIZE**', 'Current Size : '], Colors.coolred) + bminus = MyButton(output, painting, os.path.join("Resources", "minus.png"), 200, 510, 35, 50, + ButtonData('function_button', None, None), 'Brush Size -', + ['**DECREASE SIZE**', 'Current Size : '], Colors.coolblue) + cplus = MyButton(output, painting, os.path.join("Resources", "plus.png"), 31, 450, 35, 45, + ButtonData('function_button', None, None), 'Darken Brush', + ['**INCREASE SIZE**', 'Current Size : '], Colors.coolred) + cminus = MyButton(output, painting, os.path.join("Resources", "minus.png"), 200, 450, 35, 50, + ButtonData('function_button', None, None), 'Lighten Brush', + ['**DECREASE SIZE**', 'Current Size : '], Colors.coolblue) + + buttons = [brush_water, brush_neighborhood, brush_culture, brush_vegetation, + pencil_road0, pencil_road1, pencil_road2, pencil_road3, + eraser, rbin, bplus, bminus, cplus, cminus] + + return buttons + + +def create_color_button(output, painting): + black_b = ColorButton(output, painting, Colors.black, 150, 330, 40, 50, + ButtonData('color_button', None, None), 'Black') + white_b = ColorButton(output, painting, Colors.white, 190, 330, 40, 50, + ButtonData('color_button', None, None), 'White') + red_b = ColorButton(output, painting, Colors.road_1, 50, 330, 20, 25, + ButtonData('color_button', None, None), 'Road_1') + cred_b = ColorButton(output, painting, Colors.coolred, 50, 350, 20, 25, + ButtonData('color_button', None, None), 'Red') + yellow_b = ColorButton(output, painting, Colors.yellow, 70, 330, 20, 25, + ButtonData('color_button', None, None), 'Yellow') + cyellow_b = ColorButton(output, painting, Colors.coolyellow, 70, 350, 20, 25, + ButtonData('color_button', None, None), 'Yellow') + blue_b = ColorButton(output, painting, Colors.blue, 90, 330, 20, 25, + ButtonData('color_button', None, None), 'Blue') + cblue_b = ColorButton(output, painting, Colors.coolblue, 90, 350, 20, 25, + ButtonData('color_button', None, None), 'Blue') + green_b = ColorButton(output, painting, Colors.green, 110, 330, 20, 25, + ButtonData('color_button', None, None), 'Green') + cgreen_b = ColorButton(output, painting, Colors.coolgreen, 110, 350, 20, 25, + ButtonData('color_button', None, None), 'Green') + skin_b = ColorButton(output, painting, (255, 160, 122), 50, 370, 20, 25, + ButtonData('color_button', None, None), 'Skin') + pink_b = ColorButton(output, painting, (255, 105, 180), 70, 370, 20, 25, + ButtonData('color_button', None, None), 'Yellow') + brown_b = ColorButton(output, painting, (139, 69, 19), 90, 370, 20, 25, + ButtonData('color_button', None, None), 'Blue') + grey_b = ColorButton(output, painting, Colors.red, 110, 370, 20, 25, + ButtonData('color_button', None, None), 'Red') + + color_buttons = [black_b, white_b, red_b, cred_b, + yellow_b, cyellow_b, blue_b, cblue_b, + green_b, cgreen_b, skin_b, pink_b, + brown_b, grey_b] + + return color_buttons diff --git a/Colors.py b/Colors.py new file mode 100644 index 0000000..11953bc --- /dev/null +++ b/Colors.py @@ -0,0 +1,52 @@ +class Colors: + coolgrey = (52, 73, 94) + pick = (103, 128, 159) + silver = (189, 195, 199) + spacecol = (70, 70, 70) + white = (255, 255, 255) + black = (0, 0, 0) + red = (255, 0, 0) + blue = (0, 0, 255) + green = (0, 255, 0) + coolred = (231, 76, 60) + darkred = (201, 46, 30) + + coolpurple = (142, 68, 173) + + coolblue = (52, 152, 219) + darkblue = (22, 122, 189) + + coolyellow = (244, 208, 63) + darkyellow = (214, 178, 33) + + hyperlapse = (103, 128, 159) + coolgreen = (27, 188, 155) + darkgreen = (16, 68, 40) + carrot = (230, 126, 34) + cloud = (236, 240, 241) + brown = (139, 69, 19) + yellow = (255, 255, 0) + + mountain = (244, 244, 244) + water = (178, 206, 254) + neighborhood = (210, 232, 245) + culture = (255, 130, 130) + vegetation = (180, 235, 175) + + road_0 = (255, 255, 255) + road_1 = (255, 240, 187) + road_2 = (255, 172, 77) + road_3 = (227, 227, 227) + + def __init__(self): + return + + +def tupadd(tup, howmuch): + listify = list(tup) + + for i in range(len(listify)): + if 0 < (listify[i] + howmuch) < 255: + listify[i] += howmuch + + return listify diff --git a/Colours.py b/Colours.py deleted file mode 100755 index 563d207..0000000 --- a/Colours.py +++ /dev/null @@ -1,38 +0,0 @@ -import pygame - -coolgrey = (52, 73, 94) -pick=(103, 128, 159) -silver = (189, 195, 199) -spacecol = (70,70,70) -white = (255,255,255) -black = (0,0,0) -red = (255,0,0) -blue = (0,0,255) -green = (0,255,0) -coolred = (231, 76, 60) -darkred = (201, 46, 30) - -coolpurple = (142, 68, 173) - -coolblue = (52, 152, 219) -darkblue = (22, 122, 189) - -coolyellow = (244, 208, 63) -darkyellow = (214 , 178 , 33) - -hyperlapse= (103, 128, 159) -coolgreen = (27, 188, 155) -darkgreen = (16,68,40) -carrot =(230, 126, 34) -cloud = (236, 240, 241) -brown = (139,69,19) -yellow = (255,255,0) - -def tupadd(tup,howmuch): - listify=list(tup) - - for i in range(len(listify)): - if 0<(listify[i]+howmuch)<255: - listify[i]+=howmuch - - return listify diff --git a/FileSystem.py b/FileSystem.py new file mode 100644 index 0000000..08d897d --- /dev/null +++ b/FileSystem.py @@ -0,0 +1,45 @@ +import os +import pygame + + +class FileSystem: + def __init__(self, start_name, input_dir, output_dir, output_name, blank=False): + self.start_name = start_name + self.input_dir = input_dir + self.output_dir = output_dir + self.output_name = output_name + self.blank = blank + + if self.blank: + self.file_names = [self.output_name] + self.idx = 0 + self.cur_img = None + else: + self.file_names = os.listdir(input_dir) + self.idx = self.file_names.index(start_name) + self.cur_img = None + self.read_cur() + return + + def read_cur(self): + if self.blank: + return self.cur_img + file_name = os.path.join(self.input_dir, self.file_names[self.idx]) + self.cur_img = pygame.image.load(file_name) + return + + def get_cur(self): + return self.cur_img + + def get_next(self): + if self.idx + 1 >= len(self.file_names): + return None + else: + self.idx += 1 + self.read_cur() + return self.get_cur() + + def save_img(self, canvas): + file_name = os.path.join(self.output_dir, self.file_names[self.idx]) + pygame.image.save(canvas, file_name) + return diff --git a/Functions.py b/Functions.py index 0efaaf3..0022cd9 100644 --- a/Functions.py +++ b/Functions.py @@ -1,22 +1,27 @@ -from Colours import * +import pygame +import math +from Colors import * -w_width = 1000 -w_height = 800 -def fullquit(): +def full_quit(): pygame.quit() quit() -def message_to_screen(window,msg,colour=cloud,x=0,y=0,fontsize=25,bold=False,italic = False ): - message_font = pygame.font.SysFont("Century Gothic",fontsize,bold,italic) - screen_text = message_font.render(msg,True,colour) - window.blit(screen_text,[x,y]) +def message_to_screen(window, msg, color=Colors.cloud, x=0, y=0, fontsize=20, bold=False, italic=False): + message_font = pygame.font.SysFont("SimHei", fontsize, bold, italic) + screen_text = message_font.render(msg, True, color) + window.blit(screen_text, [x, y]) + return - +def mouse_pos_distance(vec_a, vec_b): + return math.sqrt(math.pow(vec_a[0] - vec_b[0], 2) + math.pow(vec_a[1] - vec_b[1], 2)) - - - +def forward_a_step(vec_a, vec_b, v_size): + vec_diff = [vec_b[0] - vec_a[0], vec_b[1] - vec_a[1]] + vec_diff_m = math.sqrt(math.pow(vec_diff[0], 2) + math.pow(vec_diff[1], 2)) + 1e-20 + vec_diff_n = [vec_diff[0] / vec_diff_m, vec_diff[1] / vec_diff_m] + ret = [vec_a[0] + vec_diff_n[0] * v_size, vec_a[1] + vec_diff_n[1] * v_size] + return ret diff --git a/GameData.py b/GameData.py index 23dd002..1d52b0e 100755 --- a/GameData.py +++ b/GameData.py @@ -1,18 +1,45 @@ import pygame import math -from Colours import * +from Colors import * from Functions import * +class BaseGame: + def __init__(self): + pygame.init() -pygame.init() + # Window + self.window_width = 960 + self.window_height = 700 + self.window_size = (self.window_width, self.window_height) + self.window = pygame.display.set_mode(self.window_size) # pygame.NOFRAME -window_size = window_width , window_height = 1000,800 -window = pygame.display.set_mode(window_size)#, pygame.NOFRAME ) + # Game info + pygame.display.set_caption("Map Painter") -pygame.display.set_caption("Project MAN") + self.clock = pygame.time.Clock() + self.FPS = 1000 + self.font = pygame.font.SysFont("Century Gothic", 25) -clock = pygame.time.Clock() -FPS = 1000 + # Border + self.border_width = 10 -font = pygame.font.SysFont( "Century Gothic" , 25 ) + # Toolbar + self.toolbar_x = self.border_width + self.toolbar_y = self.border_width + self.toolbar_w = 250 + self.toolbar_h = self.window_height - 2 * self.border_width + + # Canvas + self.canvas_x = self.border_width + self.toolbar_w + self.border_width + self.canvas_y = self.border_width + self.canvas_w = self.window_width - self.canvas_x - self.border_width + self.canvas_h = self.window_height - 2 * self.border_width + + # Info box + self.infobox_w = self.toolbar_w - 2 * self.border_width + self.infobox_h = 50 + self.infobox_x = 2 * self.border_width + self.infobox_y = self.window_height - 2 * self.border_width - self.infobox_h + + return diff --git a/Paint.py b/Paint.py index d925331..2a17eb1 100755 --- a/Paint.py +++ b/Paint.py @@ -1,386 +1,51 @@ -from GameData import * -import os +from Widgets import * -class MyButton(): - def __init__( self , image , x , y , size , grow , name = 'NONE' , detail = ['Description'] , colour = coolblue , function = None): - self.file = pygame.image.load(image) - self.size = size - self.grow = grow - self.colour = colour - self.name = name - self.detail = detail +def display_list(output, painting): + print("Executed") + # Clear Screen + output.blit_background() - self.image = pygame.transform.scale(pygame.image.load(image),(self.size,self.size)) - self.image.set_alpha(25) - - - self.rect = self.image.get_rect() - self.rect.x = x - self.rect.y = y - - - self.function = function - self.beingClicked = False - - - - def displayButton(self): - self.mouse= pygame.mouse.get_pos() - self.clicked= pygame.mouse.get_pressed() - - - - - if self.rect.x0: - self.draw_list.pop() - - - - output.blitBackground() - output.blitMenu() - - for i in self.draw_list: - pygame.draw.circle( window , i[1] , i[0] , i[2]) - - - - def cleanlist( self ): - self.cleaned_list = [] - - #Removing Duplicates - for i in self.draw_list: - if i not in self.cleaned_list: - - self.cleaned_list.append(i) - - - print len(self.draw_list) - print len( self.cleaned_list ) - -class PaintData: - def __init__( self ): - self.selected = None - self.b_size = 10 - self.b_darkness = 0 - - self.primecolour = red - self.setColour() - - - - - def performFunctions( self ): - self.blitDefault() - - - if self.selected!=None: - if self.selected.beingClicked == True: - - if self.selected.name == 'Brush Size +' and self.selected.name != 'Pencil': - self.b_size+=0.1 - - elif self.selected.name == 'Brush Size -' and self.selected.name != 'Pencil': - if self.b_size>0: - self.b_size-=0.1 - - if self.selected.name == 'Lighten Brush': - if self.b_darkness < 200: - self.b_darkness+=1 - self.setColour() - - elif self.selected.name == 'Darken Brush': - if self.b_darkness > -200: - self.b_darkness-=1 - self.setColour() - - elif self.selected.name == 'Pencil': - self.colour = silver - self.b_size = 2 - - if self.selected.name == 'Brush': - self.colour = red - self.b_size = 10 - - elif self.selected.name == 'Eraser': - self.colour = output.bordercolour - - - elif self.selected.name == 'Clear': - - self.b_size = 10 - output.blitBackground() - painting.draw_list = [] - - def setColour(self): - self.colour = tupadd( self.primecolour , int(self.b_darkness) ) - - def blitDefault(self): #Blitting stuff like brushsize - - message_to_screen( window , "Shade : "+str(int(self.b_darkness*-1)) , coolyellow , 80 , 455 , 20 ) #BrushDarkness - message_to_screen( window , "Size : "+str(int(self.b_size)) , coolgreen , 80 , 515 , 20 ) #BrushSize - - pygame.draw.circle( window , black , (135 , 630) , int(paintData.b_size)+2 ) #Outline - pygame.draw.circle( window , paintData.colour , (135 , 630) , int(paintData.b_size)) #How the brushlooks - - - - - - - - - - - - - - -output = Output( (24, 39, 53) , coolblue ) #The Background -painting = Painting() -paintData = PaintData() - -brush = MyButton(os.path.join("Resources","brush.png") , 25 , 33 , 100 , 120 , 'Brush' , [ '*PAINT COLOURS*' , ' ' , 'Current Size : '] , coolred ) -pencil = MyButton(os.path.join("Resources","color_pencil.png") , 130 , 39 , 100 , 120 , 'Pencil' , [ '*DRAW*' , ' ' , 'Current Size : '] , carrot ) -eraser = MyButton(os.path.join("Resources","eraser.png"), 30 , 176 , 100 , 120 , 'Eraser' , [ '*CLEARS SELECTED*' , ' ' , 'Current Size : '] , coolblue ) -rbin = MyButton(os.path.join("Resources","bin.png"), 135 , 176 , 100 , 120 , 'Clear' , [ '*CLEARS ALL*' , ' ' , 'Current Size : '] , cloud ) -#colour = MyButton('Resources/colour.png' , 82 , 320 , 100 , 120 , 'Colour' , [ '*CLEARS ALL*' , ' ' , 'Current Size : '] , cloud ) - -bplus = MyButton(os.path.join("Resources","plus.png") , 31 , 510 , 35 , 45 , 'Brush Size +' , [ '**INCREASE SIZE**' , 'Current Size : '] , coolred ) -bminus = MyButton(os.path.join("Resources","minus.png"), 200 , 510 , 35 , 50 , 'Brush Size -' , [ '**DECREASE SIZE**' , 'Current Size : '] , coolblue ) - -cplus = MyButton(os.path.join("Resources","plus.png"), 31 , 450 , 35 , 45 , 'Darken Brush' , [ '**INCREASE SIZE**' , 'Current Size : '] , coolred ) -cminus = MyButton(os.path.join("Resources","minus.png"), 200 , 450 , 35 , 50 , 'Lighten Brush' , [ '**DECREASE SIZE**' , 'Current Size : '] , coolblue ) - -black_b = ColourButton( black , 150 , 330 , 40 , 50 , 'Black' ) -white_b = ColourButton( white , 190 , 330 , 40 , 50 , 'White' ) - -red_b = ColourButton( red , 50 , 330 , 20 , 25 , 'Red' ) -cred_b = ColourButton( coolred , 50 , 350 , 20 , 25 , 'Red' ) - -yellow_b = ColourButton( yellow , 70 , 330 , 20 , 25 , 'Yellow' ) -cyellow_b = ColourButton( coolyellow , 70 , 350 , 20 , 25 , 'Yellow' ) - -blue_b = ColourButton( blue , 90 , 330 , 20 , 25 , 'Blue' ) -cblue_b = ColourButton( coolblue , 90 , 350 , 20 , 25 , 'Blue' ) - -green_b = ColourButton( green , 110 , 330 , 20 , 25 , 'Green' ) -cgreen_b = ColourButton( coolgreen , 110 , 350 , 20 , 25 , 'Green' ) - -# - -skin_b = ColourButton( (255,160,122) , 50 , 370 , 20 , 25 , 'Skin' ) -pink_b = ColourButton( (255,105,180) , 70 , 370 , 20 , 25 , 'Yellow' ) -brown_b = ColourButton( (139,69,19) , 90 , 370 , 20 , 25 , 'Blue' ) -grey_b = ColourButton( (169,169,169) , 110 , 370 , 20 , 25 , 'Green' ) - -def diplay_list(): - print "Executed" - #clear Screen - output.blitBackground() - - #Draw + # Draw for i in painting.cleaned_list: - pygame.draw.circle( window , i[1] , i[0] , i[2]) - + pygame.draw.circle(output.base.window, i[1], i[0], i[2]) + return +def show_cur_canvas(output, painting, file_system): + img = file_system.get_cur() + if img is not None: + painting.clear() + output.set_bg_canvas(img) + output.blit_background() + return -##green = Planet('Images/PlanetScreen/Green Planet.png' , 300 , 300 , 150 , 200 , 'level_Green' , 'Artemis' , ['Knowledge Center','Has Quizes and can keep track of financial situations'] , coolgreen ) -##red = Planet('Images/PlanetScreen/Red Planet.png' , 500 , 300 , 150 , 200 , 'level_Red' , 'Zeus' , ['Home','Place where you review all your progress'] , coolred) -##yellow = Planet('Images/PlanetScreen/Black Planet.png' , 700 , 300 , 150 , 200 , 'level_Black' , 'Hades ' , ['The Mystery Planet','Planet that is in complete mystery'] , tupadd(silver,-70) ) +def show_next_canvas(output, painting, file_system): + img = file_system.get_next() + if img is not None: + painting.clear() + output.set_bg_canvas(img) + output.blit_background() + return -def Paint(): - output.blitBackground() +def paint_loop(output, painting, file_system, buttons, color_buttons): + output.blit_background() + show_cur_canvas(output, painting, file_system) while True: - for event in pygame.event.get() : + for event in pygame.event.get(): if event.type == pygame.QUIT: - fullquit() + full_quit() if event.type == pygame.KEYDOWN: - if event.key==pygame.K_ESCAPE: - run.blue_planet() + if event.key == pygame.K_ESCAPE: + full_quit() - if event.key==pygame.K_RETURN: + if event.key == pygame.K_RETURN: painting.cleanlist() - print painting.cleaned_list + print(painting.cleaned_list) if event.key == pygame.K_BACKSPACE: painting.undo_mode = True @@ -390,72 +55,25 @@ def Paint(): if event.key == pygame.K_BACKSPACE: painting.undo_mode = False + if event.key == pygame.K_s: + file_system.save_img(output.paint_canvas) + show_next_canvas(output, painting, file_system) + # Draw Everything + output.blit_menu() + for button in buttons: + button.display_button() - # Draw Everythin - - - - - #output.blitBackground() - output.blitMenu() - - pencil.displayButton() - brush.displayButton() - eraser.displayButton() - rbin.displayButton() - #colour.displayButton() - - bplus.displayButton() - bminus.displayButton() - - cplus.displayButton() - cminus.displayButton() - - # # # - black_b.displayColour() - white_b.displayColour() - - red_b.displayColour() - yellow_b.displayColour() - blue_b.displayColour() - green_b.displayColour() - cred_b.displayColour() - cyellow_b.displayColour() - cblue_b.displayColour() - cgreen_b.displayColour() - - skin_b.displayColour() - pink_b.displayColour() - brown_b.displayColour() - grey_b.displayColour() - - #printCOOD( window , 0, 0 ) + for color_button in color_buttons: + color_button.display_color() # Update Function - paintData.performFunctions() - painting.get_position() - - - # Logic Testing - - - - - - - - - - - - + painting.perform_functions() + painting.mouse_actions() # Delay framerate - clock.tick (FPS) - # Update Screen + output.base.clock.tick(output.base.FPS) + # Update Screen pygame.display.update() - -Paint() diff --git a/README.md b/README.md index 66c3205..0b70726 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A Paint tool made using Python Pygame. # To run -`python Paint.py` +`python StartPainter.py` # Requires diff --git a/Resources/brush_culture.png b/Resources/brush_culture.png new file mode 100644 index 0000000..96f8fa0 Binary files /dev/null and b/Resources/brush_culture.png differ diff --git a/Resources/brush_neighborhood.png b/Resources/brush_neighborhood.png new file mode 100644 index 0000000..af71d49 Binary files /dev/null and b/Resources/brush_neighborhood.png differ diff --git a/Resources/brush_vegetation.png b/Resources/brush_vegetation.png new file mode 100644 index 0000000..527da87 Binary files /dev/null and b/Resources/brush_vegetation.png differ diff --git a/Resources/brush_water.png b/Resources/brush_water.png new file mode 100644 index 0000000..f626df2 Binary files /dev/null and b/Resources/brush_water.png differ diff --git a/Resources/pencil_road0.png b/Resources/pencil_road0.png new file mode 100644 index 0000000..e7a8f4c Binary files /dev/null and b/Resources/pencil_road0.png differ diff --git a/Resources/pencil_road1.png b/Resources/pencil_road1.png new file mode 100644 index 0000000..ab0dbf6 Binary files /dev/null and b/Resources/pencil_road1.png differ diff --git a/Resources/pencil_road2.png b/Resources/pencil_road2.png new file mode 100644 index 0000000..1d41c49 Binary files /dev/null and b/Resources/pencil_road2.png differ diff --git a/Resources/pencil_road3.png b/Resources/pencil_road3.png new file mode 100644 index 0000000..2dba234 Binary files /dev/null and b/Resources/pencil_road3.png differ diff --git a/StartPainter.py b/StartPainter.py new file mode 100644 index 0000000..4e0d25c --- /dev/null +++ b/StartPainter.py @@ -0,0 +1,39 @@ +import os +import argparse +from Widgets import * +from Paint import * +from ButtonUI import * +from FileSystem import * + + +def main(): + parser = argparse.ArgumentParser(description='Map Painter') + parser.add_argument('--startName', action='store', type=str, default='N30.500E116.390N30.510E116.400.png', + help='The file which is processed firstly') + parser.add_argument('--inputDir', action='store', type=str, default='D:/Data/MapDatabase/StreetMaps', + help='Street map input directory') + parser.add_argument('--outputDir', action='store', type=str, default='D:/Data/MapDatabase/SketchMap', + help='Street map output directory') + parser.add_argument('--outputName', action='store', type=str, default='OutputMap.png', + help='The name of output image') + parser.add_argument('--blank', action='store_true', default=False, + help='Draw from a blank background') + arg = parser.parse_args() + + base = BaseGame() + file_system = FileSystem(arg.startName, arg.inputDir, arg.outputDir, arg.outputName, blank=arg.blank) + output = Output(base, Colors.mountain, (24, 39, 53), Colors.coolblue) # The Background + paint_data = PaintData() + painting = Painting(output, paint_data) + + buttons = create_buttons(output, painting) + + color_buttons = create_color_button(output, painting) + + paint_loop(output, painting, file_system, buttons, color_buttons) + + return + + +if __name__ == '__main__': + main() diff --git a/Widgets.py b/Widgets.py new file mode 100644 index 0000000..9063abd --- /dev/null +++ b/Widgets.py @@ -0,0 +1,381 @@ +from GameData import * + + +class Output: + def __init__(self, base, canvas_color, bg_color, tool_space): + self.base = base + self.bg_color = bg_color + self.tool_space = tool_space + self.canvas_color = canvas_color + + self.paint_canvas = pygame.Surface((self.base.canvas_w, self.base.canvas_h)) + self.paint_canvas.fill(self.canvas_color) + + self.bg_canvas = pygame.Surface((self.base.canvas_w, self.base.canvas_h)) + self.bg_canvas.fill(self.canvas_color) + self.set_alpha(self.bg_canvas, 80) + self.bg_canvas_img = None + + self.menu_box = pygame.Surface((self.base.toolbar_w, self.base.toolbar_h)) # menuBox + self.set_alpha(self.menu_box, 80) + self.menu_box.fill(self.tool_space) + + # Used as background for the menu box + self.menu_box_bg = pygame.Surface((self.base.toolbar_w, self.base.toolbar_h)) + self.menu_box_bg.fill(self.bg_color) + + self.ialpha = 150 # For the infobox + self.info_box = pygame.Surface((self.base.infobox_w, self.base.infobox_h)) + self.set_alpha(self.info_box, self.ialpha) + self.info_box.fill(self.bg_color) + return + + def blit_canvas(self): + self.blit_paint_canvas() + self.blit_bg_canvas() + return + + def clear_canvas(self): + self.clear_paint_canvas() + self.clear_bg_canvas() + return + + def blit_paint_canvas(self): + self.base.window.blit(self.paint_canvas, (self.base.canvas_x, self.base.canvas_y)) + return + + def clear_paint_canvas(self): + self.paint_canvas.fill(self.canvas_color) + return + + def blit_bg_canvas(self): + if self.bg_canvas_img is not None: + self.bg_canvas.blit(self.bg_canvas_img, (0, 0)) + self.base.window.blit(self.bg_canvas, (self.base.canvas_x, self.base.canvas_y)) + return + + def clear_bg_canvas(self): + self.bg_canvas.fill(self.canvas_color) + return + + def set_bg_canvas(self, img): + self.bg_canvas_img = pygame.transform.scale(img, (self.base.canvas_w, self.base.canvas_h)) + return + + def blit_background(self): + self.base.window.fill(self.bg_color) + self.clear_canvas() + self.blit_canvas() + return + + def blit_menu(self): + self.base.window.blit(self.menu_box_bg, (self.base.toolbar_x, self.base.toolbar_y)) + + self.base.window.blit(self.menu_box, (self.base.toolbar_x, self.base.toolbar_y)) + self.base.window.blit(self.info_box, (self.base.infobox_x, self.base.infobox_y)) + + self.info_box.fill(self.bg_color) + return + + def set_alpha(self, rectangle, alpha_val=100): + rectangle.set_alpha(alpha_val) + return + + +class PaintData: + def __init__(self): + self.b_size = 15 + self.b_darkness = 0 + + self.prime_color = Colors.water + self.color = None + self.set_color() + return + + def set_color(self): + self.color = tupadd(self.prime_color, int(self.b_darkness)) + return + + +class Painting: # THE OUTPUT + def __init__(self, output, paint_data): + self.output = output + self.paint_data = paint_data + + self.selected = None + self.draw_list = [] + self.i = -1 # used for deletion + self.cleaned_list = [] + + self.undo_mode = False + + self.drawing = False + self.last_mouse_pos = None + + self.mouse = None + self.clicked = None + return + + def insert_draw_list(self, mouse_pos, color, b_size): + ret = [] + if self.drawing and self.last_mouse_pos is not None: + while mouse_pos_distance(mouse_pos, self.last_mouse_pos) >= b_size: + self.last_mouse_pos = forward_a_step(self.last_mouse_pos, mouse_pos, b_size * 0.5) + ret.append([self.last_mouse_pos, color, b_size]) + ret.append([mouse_pos, color, b_size]) + else: + ret.append([mouse_pos, color, b_size]) + self.last_mouse_pos = mouse_pos + return ret + + def mouse_actions(self): + self.mouse = pygame.mouse.get_pos() + self.clicked = pygame.mouse.get_pressed() + if self.clicked == (1, 0, 0): + canvas_x_min = self.output.base.canvas_x + canvas_x_max = self.output.base.canvas_x + self.output.base.canvas_w + canvas_y_min = self.output.base.canvas_y + canvas_y_max = self.output.base.canvas_y + self.output.base.canvas_h + if canvas_x_min < self.mouse[0] < canvas_x_max \ + and canvas_y_min < self.mouse[1] < canvas_y_max: # Inside the canvas + point_list = self.insert_draw_list(self.mouse, self.paint_data.color, int(self.paint_data.b_size)) + self.blit_list(point_list) + self.draw_list.extend(point_list) + self.drawing = True + else: + self.drawing = False + else: + self.drawing = False + + if self.undo_mode: + self.undo() + return + + def perform_functions(self): + self.blit_default() + + if self.selected is not None: + if self.selected.being_clicked: + if self.selected.name == 'Brush Size +' and self.selected.name != 'Pencil': + self.paint_data.b_size += 0.1 + + elif self.selected.name == 'Brush Size -' and self.selected.name != 'Pencil': + if self.paint_data.b_size > 0: + self.paint_data.b_size -= 0.1 + + if self.selected.name == 'Lighten Brush': + if self.paint_data.b_darkness < 200: + self.paint_data.b_darkness += 1 + self.paint_data.set_color() + + elif self.selected.name == 'Darken Brush': + if self.paint_data.b_darkness > -200: + self.paint_data.b_darkness -= 1 + self.paint_data.set_color() + + if self.selected.name == 'Eraser': + self.paint_data.color = self.output.canvas_color + self.paint_data.b_size = 10 + + elif self.selected.name == 'Clear': + self.paint_data.b_size = 10 + self.output.clear_canvas() + self.output.blit_canvas() + self.draw_list = [] + + if self.selected.button_data.b_type == 'normal_button': + self.paint_data.color = self.selected.button_data.color + self.paint_data.b_size = self.selected.button_data.b_size + return + + def blit_default(self): # Blitting stuff like brushsize + message_to_screen(self.output.base.window, "Shade : " + str(int(self.paint_data.b_darkness * -1)), + Colors.coolyellow, 80, 455, 20) # BrushDarkness + message_to_screen(self.output.base.window, "Size : " + str(int(self.paint_data.b_size)), Colors.coolgreen, 80, + 515, 20) # BrushSize + + pygame.draw.circle(self.output.base.window, Colors.black, (135, 630), + int(self.paint_data.b_size) + 2) # Outline + pygame.draw.circle(self.output.base.window, self.paint_data.color, (135, 630), + int(self.paint_data.b_size)) # How the brushlooks + return + + def blit_list(self, points): + for point in points: + cood = point[0] + canvas_cood = (cood[0] - self.output.base.canvas_x, cood[1] - self.output.base.canvas_y) + pygame.draw.circle(self.output.paint_canvas, self.paint_data.color, canvas_cood, int(self.paint_data.b_size)) + self.output.blit_canvas() + return + + def blit(self, cood): + canvas_cood = (cood[0] - self.output.base.canvas_x, cood[1] - self.output.base.canvas_y) + pygame.draw.circle(self.output.paint_canvas, self.paint_data.color, canvas_cood, int(self.paint_data.b_size)) + self.output.blit_canvas() + return + + def undo(self): + if len(self.draw_list) > 0: + self.draw_list.pop() + + self.output.clear_canvas() + + for point in self.draw_list: + mouse_pos = point[0] + canvas_cood = (mouse_pos[0] - self.output.base.canvas_x, mouse_pos[1] - self.output.base.canvas_y) + pygame.draw.circle(self.output.paint_canvas, point[1], canvas_cood, point[2]) + + self.output.blit_canvas() + return + + def clear(self): + self.draw_list = [] + return + + def clean_list(self): + self.cleaned_list = [] + + # Removing Duplicates + for i in self.draw_list: + if i not in self.cleaned_list: + self.cleaned_list.append(i) + + print(len(self.draw_list)) + print(len(self.cleaned_list)) + return + + +class ButtonData: + def __init__(self, b_type, b_size, color): + self.b_type = b_type + self.b_size = b_size + self.color = color + return + + +class MyButton: + def __init__(self, output, painting, image, x, y, size, grow, button_data, name='NONE', detail='Description', + color=Colors.coolblue, function=None): + self.output = output + self.painting = painting + self.button_data = button_data + + self.file = pygame.image.load(image) + self.size = size + self.grow = grow + self.color = color + self.name = name + self.detail = [detail] + + self.image = pygame.transform.scale(pygame.image.load(image), (self.size, self.size)) + self.image.set_alpha(25) + + self.rect = self.image.get_rect() + self.rect.x = x + self.rect.y = y + + self.function = function + self.being_clicked = False + self.hovering = False + + self.mouse = None + self.clicked = None + return + + def display_button(self): + self.mouse = pygame.mouse.get_pos() + self.clicked = pygame.mouse.get_pressed() + + if self.rect.x < self.mouse[0] < self.rect.x + self.size \ + and self.rect.y < self.mouse[1] < self.rect.y + self.size: + self.image = pygame.transform.scale(self.file, (self.grow, self.grow)) + self.output.base.window.blit(self.image, + (self.rect.x - (self.grow - self.size) * 0.5, + self.rect.y - (self.grow - self.size) * 0.5)) + + message_to_screen(self.output.info_box, self.name, self.color, + 0, 0.25 * self.output.base.infobox_h, 20, True) + + self.output.set_alpha(self.output.info_box, 200) # MAKES THE INFO BOX DARKER + + if self.clicked != (1, 0, 0): + self.hovering = True + self.being_clicked = False + elif self.clicked == (1, 0, 0) and self.hovering: + self.painting.selected = self + self.being_clicked = True + else: + self.being_clicked = False + + else: + self.hovering = False + + self.image = pygame.transform.scale(self.file, (self.size, self.size)) # Change image to the original size + self.output.base.window.blit(self.image, (self.rect.x, self.rect.y)) # Display the icon + + self.output.set_alpha(self.output.info_box, self.output.ialpha) # makes the info box to the original color + return + + +class ColorButton: # Buttons + def __init__(self, output, painting, color, x, y, size, grow, button_data, name): + self.output = output + self.painting = painting + self.button_data = button_data + + self.size = size + self.grow = grow + self.color = color + self.name = name + + self.box = pygame.Surface((self.size, self.size)) + self.box.fill(self.color) + + self.rect = self.box.get_rect() + self.rect.x = x + self.rect.y = y + + self.being_clicked = False + self.hovering = False + + self.mouse = None + self.clicked = None + return + + def display_color(self): + self.mouse = pygame.mouse.get_pos() + self.clicked = pygame.mouse.get_pressed() + + if self.rect.x < self.mouse[0] < self.rect.x + self.size \ + and self.rect.y < self.mouse[1] < self.rect.y + self.size: + self.box = pygame.Surface((self.grow, self.grow)) + self.box.fill(self.color) + + self.output.base.window.blit(self.box, + (self.rect.x - (self.grow - self.size) * 0.5, + self.rect.y - (self.grow - self.size) * 0.5)) + + message_to_screen(self.output.info_box, self.name, self.color, + 0, 0.25 * self.output.base.infobox_h, 20, True) + + if self.clicked != (1, 0, 0): + self.hovering = True + self.being_clicked = False + elif self.clicked == (1, 0, 0) and self.hovering: + self.painting.paint_data.prime_color = self.color + self.painting.paint_data.b_darkness = 0 + + self.painting.paint_data.set_color() + + self.being_clicked = True + else: + self.being_clicked = False + + else: + self.hovering = False + + self.box = pygame.Surface((self.size, self.size)) # Change image to the original size + self.box.fill(self.color) + + self.output.base.window.blit(self.box, (self.rect.x, self.rect.y)) # Display the icon + return