How to create MS Paint clone with Python and pygame
Why not do both?
Draw a circle at each endpoint and a line between the two.
EDIT rofl, just couldn't stop myself.
Actually, you don't want to use pygame.draw.line
because it cheats. It fills a 1 pixel wide row or column (depending on angle of attack) of pixels. If you do go at a roughly perpendicular angle, 0 deg or 90 deg, this isn't an issue, but at 45's, you'll notice a sort of string bean effect.
The only solution is to draw a circle at every pixel's distance. Here...
import pygame, random
screen = pygame.display.set_mode((800,600))
draw_on = False
last_pos = (0, 0)
color = (255, 128, 0)
radius = 10
def roundline(srf, color, start, end, radius=1):
dx = end[0]-start[0]
dy = end[1]-start[1]
distance = max(abs(dx), abs(dy))
for i in range(distance):
x = int( start[0]+float(i)/distance*dx)
y = int( start[1]+float(i)/distance*dy)
pygame.draw.circle(srf, color, (x, y), radius)
try:
while True:
e = pygame.event.wait()
if e.type == pygame.QUIT:
raise StopIteration
if e.type == pygame.MOUSEBUTTONDOWN:
color = (random.randrange(256), random.randrange(256), random.randrange(256))
pygame.draw.circle(screen, color, e.pos, radius)
draw_on = True
if e.type == pygame.MOUSEBUTTONUP:
draw_on = False
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
pygame.quit()
Not blitting at each loop step can improve the speed of the drawing (using this code adapted from the previous one allow to remove lag problem on my machine)
import pygame, random
screen = pygame.display.set_mode((800,600))
draw_on = False
last_pos = (0, 0)
color = (255, 128, 0)
radius = 10
def roundline(srf, color, start, end, radius=1):
dx = end[0]-start[0]
dy = end[1]-start[1]
distance = max(abs(dx), abs(dy))
for i in range(distance):
x = int( start[0]+float(i)/distance*dx)
y = int( start[1]+float(i)/distance*dy)
pygame.display.update(pygame.draw.circle(srf, color, (x, y), radius))
try:
while True:
e = pygame.event.wait()
if e.type == pygame.QUIT:
raise StopIteration
if e.type == pygame.MOUSEBUTTONDOWN:
color = (random.randrange(256), random.randrange(256), random.randrange(256))
pygame.draw.circle(screen, color, e.pos, radius)
draw_on = True
if e.type == pygame.MOUSEBUTTONUP:
draw_on = False
if e.type == pygame.MOUSEMOTION:
if draw_on:
pygame.display.update(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
pygame.quit()
For the first problem, you need have a background, even if its just a color. I had the same problem with a replica pong game i made. Here is an example of a replica paint program I made, left click to draw, right click to erase, click on the color image to choose a color, and up button to clear screen:
import os
os.environ['SDL_VIDEO_CENTERED'] = '1'
from pygamehelper import *
from pygame import *
from pygame.locals import *
from vec2d import *
from math import e, pi, cos, sin, sqrt
from random import uniform
class Starter(PygameHelper):
def __init__(self):
self.w, self.h = 800, 600
PygameHelper.__init__(self, size=(self.w, self.h), fill=((255,255,255)))
self.img= pygame.image.load("colors.png")
self.screen.blit(self.img, (0,0))
self.drawcolor= (0,0,0)
self.x= 0
def update(self):
pass
def keyUp(self, key):
if key==K_UP:
self.screen.fill((255,255,255))
self.screen.blit(self.img, (0,0))
def mouseUp(self, button, pos):
pass
def mouseMotion(self, buttons, pos, rel):
if pos[1]>=172:
if buttons[0]==1:
#pygame.draw.circle(self.screen, (0,0,0), pos, 5)
pygame.draw.line(self.screen, self.drawcolor, pos, (pos[0]-rel[0], pos[1]-rel[1]),5)
if buttons[2]==1:
pygame.draw.circle(self.screen, (255,255,255), pos, 30)
if buttons[1]==1:
#RAINBOW MODE
color= self.screen.get_at((self.x, 0))
pygame.draw.line(self.screen, color, pos, (pos[0]-rel[0], pos[1]-rel[1]), 5)
self.x+= 1
if self.x>172: self.x=0
else:
if pos[0]<172:
if buttons[0]==1:
self.drawcolor= self.screen.get_at(pos)
pygame.draw.circle(self.screen, self.drawcolor, (250, 100), 30)
def draw(self):
pass
#self.screen.fill((255,255,255))
#pygame.draw.circle(self.screen, (0,0,0), (50,100), 20)
s = Starter()
s.mainLoop(40)