Open In App

How to create MS Paint clone with Python and PyGame?

Last Updated : 08 Aug, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will create a simple MS paint program with Python and PyGame.

MS Paint is a simple program made by Microsoft, it allows users to create basic art and painting. Since its inception, MS Paint has been included with every version of Microsoft Windows. MS Paint provides features for drawing and painting in color and tools to create geometrical designs. In this section, we will try to make a simple copy of an MS paint with the help of a python module such as Pygame, random, and os. these modules will help us to make our simple canvas. Before moving further we will discuss some basic concepts of these modules:

  • Pygame:  It consists of computer graphics. Pygame is an open-source set of Python Modules. And as the name suggests, it can be used to create games You can code the games and then use specific commands to change them into an executable file that you can share with your friends to show them the work you have been doing.  It includes  graphics and sound libraries designed for use with the Python programming language.
  • os: This module is used to interact with the operating system.  This is a pre-installed module. The OS module in Python provides functions for interacting with the operating system. OS comes under Python’s standard utility modules.
  • random: This module is used to generate random numbers. This is a pre-installed module. Python Random module is an in-built module of Python which is used to generate random numbers. These are pseudo-random numbers means these are not truly random. This module can be used to perform random actions such as generating random numbers, printing random a value for a list or string, etc.

Packages required

pip install pygame

Example 1: Making A simple Paint Application Using Python

In this example, we will create a canvas in which we can draw a colorful line whenever we press down our mouse key. Every time when we release the mouse click it will choose a different random color with the help of a random module. if the user double clicks then the color of the brush is changed. 
In the code, the round function takes an argument of screen size, the color of the brush, the Start and end position of the axis, and the radius of the brush. with the help of these arguments, we will draw a colorful line.

Python3




import pygame
import random
 
# Making canvas
screen = pygame.display.set_mode((900, 700))
 
# Setting Title
pygame.display.set_caption('GFG Paint')
 
 
draw_on = False
last_pos = (0, 0)
 
# Radius of the Brush
radius = 5
 
 
def roundline(canvas, color, start, end, radius=1):
    Xaxis = end[0]-start[0]
    Yaxis = end[1]-start[1]
    dist = max(abs(Xaxis), abs(Yaxis))
    for i in range(dist):
        x = int(start[0]+float(i)/dist*Xaxis)
        y = int(start[1]+float(i)/dist*Yaxis)
        pygame.draw.circle(canvas, color, (x, y), radius)
 
 
try:
    while True:
        e = pygame.event.wait()
         
        if e.type == pygame.QUIT:
            raise StopIteration
             
        if e.type == pygame.MOUSEBUTTONDOWN:         
            # Selecting random Color Code
            color = (random.randrange(256), random.randrange(
                256), random.randrange(256))
            # Draw a single circle wheneven mouse is clicked down.
            pygame.draw.circle(screen, color, e.pos, radius)
            draw_on = True
        # When mouse button released it will stop drawing   
        if e.type == pygame.MOUSEBUTTONUP:
            draw_on = False
        # It will draw a continuous circle with the help of roundline function.   
        if e.type == pygame.MOUSEMOTION:
            if draw_on:
                pygame.draw.circle(screen, color, e.pos, radius)
                roundline(screen, color, e.pos, last_pos,  radius)
            last_pos = e.pos
        pygame.display.flip()
 
except StopIteration:
    pass
   
# Quit
pygame.quit()


Output:

 

Example 2: Making a paint application to draw and erase in Canvas

In this example, We made a canvas to draw with eight different colors to paint. It also includes features like a clear button which will clear the screen and give us a new canvas to draw, and a + and – button which increases or decrease the brush size. Additionally, it also includes a clock timer to practice painting at a given interval of time. 

Python3




# import library
import pygame 
import random
 
pygame.init()
 
# Setting window size
win_x = 500
win_y = 500
 
win = pygame.display.set_mode((win_x, win_y))
pygame.display.set_caption('Paint')
 
# Class for drawing
class drawing(object):
 
    def __init__(self):
        '''constructor'''
        self.color = (0, 0, 0)
        self.width = 10
        self.height = 10
        self.rad = 6
        self.tick = 0
        self.time = 0
        self.play = False
         
    # Drawing Function
    def draw(self, win, pos):
        pygame.draw.circle(win, self.color, (pos[0], pos[1]), self.rad)
        if self.color == (255, 255, 255):
            pygame.draw.circle(win, self.color, (pos[0], pos[1]), 20)
 
    # detecting clicks
    def click(self, win, list, list2):
        pos = pygame.mouse.get_pos()  # Localização do mouse
 
        if pygame.mouse.get_pressed() == (1, 0, 0) and pos[0] < 400:
            if pos[1] > 25:
                self.draw(win, pos)
        elif pygame.mouse.get_pressed() == (1, 0, 0):
            for button in list:
                if pos[0] > button.x and pos[0] < button.x + button.width:
                    if pos[1] > button.y and pos[1] < button.y + button.height:
                        self.color = button.color2
            for button in list2:
                if pos[0] > button.x and pos[0] < button.x + button.width:
                    if pos[1] > button.y and pos[1] < button.y + button.height:
                        if self.tick == 0:
                            if button.action == 1:
                                win.fill((255, 255, 255))
                                self.tick += 1
                            if button.action == 2 and self.rad > 4:
                                self.rad -= 1
                                self.tick += 1
                                pygame.draw.rect(
                                    win, (255, 255, 255), (410, 308, 80, 35))
 
                            if button.action == 3 and self.rad < 20:
                                self.rad += 1
                                self.tick += 1
                                pygame.draw.rect(
                                    win, (255, 255, 255), (410, 308, 80, 35))
 
                            if button.action == 5 and self.play == False:
                                self.play = True
                                game()
                                self.time += 1
                            if button.action == 6:
                                self.play = False
                                self.time = 0
 
        for button in list2:
            if button.action == 4:
                button.text = str(self.rad)
 
            if button.action == 7 and self.play == True:
                button.text = str(40 - (player1.time // 100))
            if button.action == 7 and self.play == False:
                button.text = 'Time'
 
# Class for buttons
class button(object):
 
    def __init__(self, x, y, width, height, color, color2, outline=0, action=0, text=''):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
        self.color = color
        self.outline = outline
        self.color2 = color2
        self.action = action
        self.text = text
         
# Class for drawing buttons
    def draw(self, win):
 
        pygame.draw.rect(win, self.color, (self.x, self.y,
                                           self.width, self.height), self.outline)
        font = pygame.font.SysFont('comicsans', 30)
        text = font.render(self.text, 1, self.color2)
        pygame.draw.rect(win, (255, 255, 255), (410, 446, 80, 35))
        # pygame.draw.rect(win, (255, 255, 255), (410, 308, 80, 35))
        win.blit(text, (int(self.x+self.width/2-text.get_width()/2),
                        int(self.y+self.height/2-text.get_height()/2)))
 
 
def drawHeader(win):
    # Drawing header space
    pygame.draw.rect(win, (175, 171, 171), (0, 0, 500, 25))
    pygame.draw.rect(win, (0, 0, 0), (0, 0, 400, 25), 2)
    pygame.draw.rect(win, (0, 0, 0), (400, 0, 100, 25), 2)
 
    # Printing header
    font = pygame.font.SysFont('comicsans', 30)
 
    canvasText = font.render('Canvas', 1, (0, 0, 0))
    win.blit(canvasText, (int(200 - canvasText.get_width() / 2),
                          int(26 / 2 - canvasText.get_height() / 2) + 2))
 
    toolsText = font.render('Tools', 1, (0, 0, 0))
    win.blit(toolsText, (int(450 - toolsText.get_width() / 2),
                         int(26 / 2 - toolsText.get_height() / 2 + 2)))
 
 
def draw(win):
    player1.click(win, Buttons_color, Buttons_other)
 
    pygame.draw.rect(win, (0, 0, 0), (400, 0, 100, 500),
                     2# Drawing button space
    pygame.draw.rect(win, (255, 255, 255), (400, 0, 100, 500),)
    pygame.draw.rect(win, (0, 0, 0), (0, 0, 400, 500),
                     2# Drawing canvas space
    drawHeader(win)
 
    for button in Buttons_color:
        button.draw(win)
 
    for button in Buttons_other:
        button.draw(win)
 
    pygame.display.update()
 
 
def main_loop():
    run = True
    while run:
        keys = pygame.key.get_pressed() 
        for event in pygame.event.get():
            if event.type == pygame.QUIT or keys[pygame.K_ESCAPE]:
                run = False
 
        draw(win)
 
        if 0 < player1.tick < 40:
            player1.tick += 1
        else:
            player1.tick = 0
 
        if 0 < player1.time < 4001:
            player1.time += 1
        elif 4000 < player1.time < 4004:
            gameOver()
            player1.time = 4009
        else:
            player1.time = 0
            player1.play = False
 
    pygame.quit()
 
 
def game():
    object = ['Casa', 'cachoro', 'caneta', 'bola de futebol', 'caneca', 'Computador',
              'Chocolate', 'Jesus', 'Celular', 'Iphone', 'Teclado(instrumento)', 'teclado(computador)']
 
    font = pygame.font.SysFont('comicsans', 40)
    font2 = pygame.font.SysFont('comicsans', 25)
    text = font.render('Sua Palavra é: ' +
                       object[random.randint(0, (len(object) - 1))], 1, (255, 0, 0))
    Aviso = font2.render('Somente deve olhar essa tela a pessoa que vai desenhar:', 1,
                         (255, 0, 0))
    Aviso2 = font.render('Agora pode olhar', 1,
                         (255, 0, 0))
    i = 0
    time = 1500
    while i < 1500:
        pygame.time.delay(10)
        i += 1
        icount = int((1500/100) - (i // 100))
        time = font.render(str(icount), 1, (255, 0, 0))
        win.fill((255, 255, 255))
        if int(icount) > 10:
            win.blit(Aviso, (int(5), int(250 - Aviso.get_height() / 2)))
        elif 5 < int(icount) < 11:
            win.blit(Aviso, (int(5), int(100 - text.get_height() / 2)))
            win.blit(text, (int(250 - text.get_width() / 2),
                            int(250 - text.get_height() / 2)))
        else:
            win.blit(Aviso2, (int(250 - Aviso2.get_width() / 2),
                              int(250 - Aviso2.get_height() / 2)))
 
        win.blit(time, (int(250 - time.get_width() / 2), 270))
        pygame.display.update()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                i = 1001
                pygame.quit()
    win.fill((255, 255, 255))
 
# Ending Function
def gameOver():
    font = pygame.font.SysFont('comicsans', 40)
    text = font.render('GAME OVER', 1, (255, 0, 0))
    i = 0
    while i < 700:
        pygame.time.delay(10)
        i += 1
 
        win.fill((255, 255, 255))
        win.blit(text, (int(250 - text.get_width() / 2),
                        250 - text.get_height() / 2))
        pygame.display.update()
        print(7 - (i // 100))
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                i = 1001
                pygame.quit()
    win.fill((255, 255, 255))
 
 
player1 = drawing()
# Fill colored to our paint
win.fill((255, 255, 255))
pos = (0, 0)
 
# Defining color buttons
redButton = button(453, 30, 40, 40, (255, 0, 0), (255, 0, 0))
blueButton = button(407, 30, 40, 40, (0, 0, 255), (0, 0, 255))
greenButton = button(407, 76, 40, 40, (0, 255, 0), (0, 255, 0))
orangeButton = button(453, 76, 40, 40, (255, 192, 0), (255, 192, 0))
yellowButton = button(407, 122, 40, 40, (255, 255, 0), (255, 255, 0))
purpleButton = button(453, 122, 40, 40, (112, 48, 160), (112, 48, 160))
blackButton = button(407, 168, 40, 40, (0, 0, 0), (0, 0, 0))
whiteButton = button(453, 168, 40, 40, (0, 0, 0), (255, 255, 255), 1)
 
# Defining other buttons
clrButton = button(407, 214, 86, 40, (201, 201, 201), (0, 0, 0), 0, 1, 'Clear')
 
smallerButton = button(407, 260, 40, 40, (201, 201, 201), (0, 0, 0), 0, 2, '-')
biggerButton = button(453, 260, 40, 40, (201, 201, 201), (0, 0, 0), 0, 3, '+')
sizeDisplay = button(407, 306, 86, 40, (0, 0, 0), (0, 0, 0), 1, 4, 'Size')
playButton = button(407, 352, 86, 40, (201, 201, 201), (0, 0, 0), 0, 5, 'Play')
stopButton = button(407, 398, 86, 40, (201, 201, 201), (0, 0, 0), 0, 6, 'Stop')
timeDisplay = button(407, 444, 86, 40, (0, 0, 0), (0, 0, 0), 1, 7, 'Time')
 
Buttons_color = [blueButton, redButton, greenButton, orangeButton,
                 yellowButton, purpleButton, blackButton, whiteButton]
Buttons_other = [clrButton, smallerButton, biggerButton,
                 sizeDisplay, playButton, stopButton, timeDisplay]
 
main_loop()
 
list = pygame.font.get_fonts()
print(list)


Output:

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads