What would the most efficient way be to draw a pixel using turtle in Python?
If I were to draw, let's say, a pixel art of Mario for example, with a lot of squares (see pixel art below), what would the most efficient way be to do this? I've tried it, but the code is very long, even cutting it down with functions to the best of my ability.
Mario Image
Here is my code, it works, but is not very efficient:
import turtle
from turtle import *
speed(0)
def redSquare():
fillcolor("red")
begin_fill()
for i in range(4):
forward(30)
right(90)
end_fill()
def blueSquare():
fillcolor("royalblue")
begin_fill()
for i in range(4):
forward(30)
right(90)
end_fill()
def yellowSquare():
fillcolor("yellow")
begin_fill()
for i in range(4):
forward(30)
right(90)
end_fill()
def skinSquare():
fillcolor("sandybrown")
begin_fill()
for i in range(4):
forward(30)
right(90)
end_fill()
def brownSquare():
fillcolor("saddlebrown")
begin_fill()
for i in range(4):
forward(30)
right(90)
end_fill()
def blackSquare():
fillcolor("black")
begin_fill()
for i in range(4):
forward(30)
right(90)
end_fill()
penup()
goto(100, -150)
pendown()
brownSquare()
penup()
goto(70, -150)
pendown()
brownSquare()
penup()
goto(40, -150)
pendown()
brownSquare()
penup()
goto(10, -150)
pendown()
brownSquare()
penup()
goto(10, -120)
pendown()
brownSquare()
penup()
goto(40, -120)
pendown()
brownSquare()
penup()
goto(70, -120)
pendown()
brownSquare()
penup()
goto(40, -90)
pendown()
blueSquare()
penup()
goto(10, -90)
pendown()
blueSquare()
penup()
goto(-20, -90)
pendown()
blueSquare()
penup()
goto(-20, -60)
pendown()
blueSquare()
penup()
goto(-50, -60)
pendown()
blueSquare()
penup()
goto(10, -60)
pendown()
blueSquare()
penup()
goto(40, -60)
pendown()
blueSquare()
penup()
goto(70, -60)
pendown()
skinSquare()
penup()
goto(100, -60)
pendown()
skinSquare()
penup()
goto(100, -30)
pendown()
skinSquare()
penup()
goto(70, -30)
pendown()
skinSquare()
penup()
goto(40, -30)
pendown()
skinSquare()
penup()
goto(10, -30)
pendown()
blueSquare()
penup()
goto(-20, -30)
pendown()
blueSquare()
penup()
goto(-50, -30)
pendown()
blueSquare()
penup()
goto(-50, 0)
pendown()
blueSquare()
penup()
goto(-20, 0)
pendown()
yellowSquare()
penup()
goto(10, 0)
pendown()
blueSquare()
penup()
goto(40, 0)
pendown()
redSquare()
penup()
goto(70, 0)
pendown()
skinSquare()
penup()
goto(100, 0)
pendown()
skinSquare()
penup()
goto(100, 30)
pendown()
redSquare()
penup()
goto(70, 30)
pendown()
redSquare()
penup()
goto(40, 30)
pendown()
redSquare()
penup()
goto(10, 30)
pendown()
redSquare()
penup()
goto(-20, 30)
pendown()
blueSquare()
penup()
goto(-50, 30)
pendown()
blueSquare()
penup()
goto(-50, 60)
pendown()
redSquare()
penup()
goto(-20, 60)
pendown()
blueSquare()
penup()
goto(10, 60)
pendown()
redSquare()
penup()
goto(40, 60)
pendown()
redSquare()
penup()
goto(70, 60)
pendown()
redSquare()
penup()
goto(10, 90)
pendown()
redSquare()
penup()
goto(-20, 90)
pendown()
redSquare()
penup()
goto(-50, 90)
pendown()
redSquare()
penup()
goto(-50, 120)
pendown()
skinSquare()
penup()
goto(-50, 120)
pendown()
skinSquare()
penup()
goto(-20, 120)
pendown()
skinSquare()
penup()
goto(10, 120)
pendown()
skinSquare()
penup()
goto(40, 120)
pendown()
skinSquare()
penup()
goto(70, 120)
pendown()
skinSquare()
penup()
goto(100, 150)
pendown()
blackSquare()
penup()
goto(70, 150)
pendown()
blackSquare()
penup()
goto(40, 150)
pendown()
blackSquare()
penup()
goto(10, 150)
pendown()
blackSquare()
penup()
goto(-20, 150)
pendown()
skinSquare()
penup()
goto(-50, 150)
pendown()
skinSquare()
penup()
goto(-50, 180)
pendown()
skinSquare()
penup()
goto(-20, 180)
pendown()
skinSquare()
penup()
goto(10, 180)
pendown()
skinSquare()
penup()
goto(40, 180)
pendown()
blackSquare()
penup()
goto(70, 180)
pendown()
skinSquare()
penup()
goto(100, 180)
pendown()
skinSquare()
penup()
goto(130, 180)
pendown()
skinSquare()
penup()
goto(100, 210)
pendown()
skinSquare()
penup()
goto(70, 210)
pendown()
skinSquare()
penup()
goto(40, 210)
pendown()
skinSquare()
penup()
goto(10, 210)
pendown()
blackSquare()
penup()
goto(-20, 210)
pendown()
skinSquare()
penup()
goto(-50, 210)
pendown()
skinSquare()
penup()
goto(-50, 240)
pendown()
skinSquare()
penup()
goto(-20, 240)
pendown()
skinSquare()
penup()
goto(10, 240)
pendown()
blackSquare()
penup()
goto(40, 240)
pendown()
skinSquare()
penup()
goto(100, 270)
pendown()
redSquare()
penup()
goto(70, 270)
pendown()
redSquare()
penup()
goto(40, 270)
pendown()
redSquare()
penup()
goto(10, 270)
pendown()
redSquare()
penup()
goto(-20, 270)
pendown()
redSquare()
penup()
goto(-50, 270)
pendown()
redSquare()
penup()
goto(-50, 300)
pendown()
redSquare()
penup()
goto(-20, 300)
pendown()
redSquare()
penup()
goto(10, 300)
pendown()
redSquare()
penup()
goto(-80, 300)
pendown()
redSquare()
penup()
goto(-110, 300)
pendown()
redSquare()
penup()
goto(-140, 300)
pendown()
redSquare()
penup()
goto(-80, 270)
pendown()
redSquare()
penup()
goto(-110, 270)
pendown()
redSquare()
penup()
goto(-140, 270)
pendown()
redSquare()
penup()
goto(-170, 270)
pendown()
redSquare()
penup()
goto(-170, 240)
pendown()
brownSquare()
penup()
goto(-140, 240)
pendown()
brownSquare()
penup()
goto(-110, 240)
pendown()
brownSquare()
penup()
goto(-80, 240)
pendown()
skinSquare()
penup()
goto(-80, 210)
pendown()
skinSquare()
penup()
goto(-110, 210)
pendown()
skinSquare()
penup()
goto(-140, 210)
pendown()
brownSquare()
penup()
goto(-170, 210)
pendown()
skinSquare()
penup()
goto(-200, 210)
pendown()
brownSquare()
penup()
goto(-200, 180)
pendown()
brownSquare()
penup()
goto(-170, 180)
pendown()
skinSquare()
penup()
goto(-140, 180)
pendown()
brownSquare()
penup()
goto(-110, 180)
pendown()
brownSquare()
penup()
goto(-80, 180)
pendown()
skinSquare()
penup()
goto(-80, 180)
pendown()
skinSquare()
penup()
goto(-80, 150)
pendown()
skinSquare()
penup()
goto(-110, 150)
pendown()
skinSquare()
penup()
goto(-140, 150)
pendown()
skinSquare()
penup()
goto(-170, 150)
pendown()
brownSquare()
penup()
goto(-200, 150)
pendown()
brownSquare()
penup()
goto(-140, 120)
pendown()
skinSquare()
penup()
goto(-110, 120)
pendown()
skinSquare()
penup()
goto(-80, 120)
pendown()
skinSquare()
penup()
goto(-80, 90)
pendown()
redSquare()
penup()
goto(-110, 90)
pendown()
blueSquare()
penup()
goto(-140, 90)
pendown()
redSquare()
penup()
goto(-170, 90)
pendown()
redSquare()
penup()
goto(-200, 60)
pendown()
redSquare()
penup()
goto(-170, 60)
pendown()
redSquare()
penup()
goto(-140, 60)
pendown()
redSquare()
penup()
goto(-110, 60)
pendown()
blueSquare()
penup()
goto(-80, 60)
pendown()
redSquare()
penup()
goto(-80, 30)
pendown()
blueSquare()
penup()
goto(-110, 30)
pendown()
blueSquare()
penup()
goto(-140, 30)
pendown()
redSquare()
penup()
goto(-170, 30)
pendown()
redSquare()
penup()
goto(-200, 30)
pendown()
redSquare()
penup()
goto(-230, 30)
pendown()
redSquare()
penup()
goto(-230, 0)
pendown()
skinSquare()
penup()
goto(-200, 0)
pendown()
skinSquare()
penup()
goto(-170, 0)
pendown()
redSquare()
penup()
goto(-140, 0)
pendown()
blueSquare()
penup()
goto(-110, 0)
pendown()
yellowSquare()
penup()
goto(-80, 0)
pendown()
blueSquare()
penup()
goto(-80, -30)
pendown()
blueSquare()
penup()
goto(-110, -30)
pendown()
blueSquare()
penup()
goto(-140, -30)
pendown()
blueSquare()
penup()
goto(-170, -30)
pendown()
skinSquare()
penup()
goto(-200, -30)
pendown()
skinSquare()
penup()
goto(-230, -30)
pendown()
skinSquare()
penup()
goto(-230, -60)
pendown()
skinSquare()
penup()
goto(-200, -60)
pendown()
skinSquare()
penup()
goto(-170, -60)
pendown()
blueSquare()
penup()
goto(-140, -60)
pendown()
blueSquare()
penup()
goto(-110, -60)
pendown()
blueSquare()
penup()
goto(-80, -60)
pendown()
blueSquare()
penup()
goto(-110, -90)
pendown()
blueSquare()
penup()
goto(-140, -90)
pendown()
blueSquare()
penup()
goto(-170, -90)
pendown()
blueSquare()
penup()
goto(-140, -120)
pendown()
brownSquare()
penup()
goto(-170, -120)
pendown()
brownSquare()
penup()
goto(-200, -120)
pendown()
brownSquare()
penup()
goto(-230, -150)
pendown()
brownSquare()
penup()
goto(-200, -150)
pendown()
brownSquare()
penup()
goto(-170, -150)
pendown()
brownSquare()
penup()
goto(-140, -150)
pendown()
brownSquare()
exitonclick()
what would the most efficient way be to do this?
I agree with @martineau's general approach (+1) but since you want the most efficient way, I'd change a few things. I'd use stamping instead of drawing to reduce the amount of code and speed it up. I'd also use strings of letters to represent the color pixels instead of arrays of integers. And I'd store the image upside up instead of upside down. I find this makes it easier to enter the image as a touch typist and makes it easier to visualize the image even in the encoded form. And I'd throw tracer()
at the problem:
from turtle import Screen, Turtle
PIXEL_SIZE = 30
CURSOR_SIZE = 20
COLORS = {
'B': 'blue',
'K': 'black',
'O': 'orange',
'R': 'red',
'T': 'brown',
'W': 'white',
'Y': 'yellow',
}
PIXELS = [
"WWWRRRRRRWWWW",
"WWRRRRRRRRRRW",
"WWTTTOOOKOWWW",
"WTOTOOOOKOOOW",
"WTOTTOOOOKOOO",
"WTTOOOOOKKKKW",
"WWWOOOOOOOOWW",
"WWRRBRRRRWWWW",
"WRRRBRRBRRRWW",
"RRRRBBBBRRRRW",
"OORBYBBYBROOW",
"OOOBBBBBBOOOW",
"OOBBBBBBBBOOW",
"WWBBBWWBBBWWW",
"WTTTWWWWTTTWW",
"TTTTWWWWTTTTW",
]
WIDTH, HEIGHT = len(PIXELS[0]), len(PIXELS)
screen = Screen()
screen.setup((WIDTH + 3) * PIXEL_SIZE, (HEIGHT + 3) * PIXEL_SIZE)
screen.tracer(False)
turtle = Turtle()
turtle.hideturtle()
turtle.shape('square')
turtle.shapesize(PIXEL_SIZE / CURSOR_SIZE)
turtle.penup()
x0 = -WIDTH/2 * PIXEL_SIZE
y0 = HEIGHT/2 * PIXEL_SIZE
for i, row in enumerate(PIXELS):
turtle.setposition(x0, y0 - i * PIXEL_SIZE)
for pixel in row:
turtle.color(COLORS[pixel])
turtle.stamp()
turtle.forward(PIXEL_SIZE)
screen.tracer(True)
screen.exitonclick()
This approach even works for literal pixels:
The quickest way would probably be to define a function that draws the shape of a pixel of the proper size at the current turtle position, and then call repeatedly in a pair of nested for
loops.
Here's an example:
import turtle
COLORS = {0: 'white',
1: 'red',
2: 'blue',
3: 'green',
4: 'black',
5: 'yellow',
6: 'orange'}
PIXELS = [[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 4, 0, 4, 0, 0],
[0, 0, 0, 2, 3, 0, 0, 0],
[0, 0, 0, 3, 2, 0, 0, 0],
[0, 5, 4, 4, 4, 4, 4, 0],
[0, 0, 6, 6, 6, 6, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]]
WIDTH, HEIGHT = len(PIXELS[0]), len(PIXELS)
scn = turtle.Screen()
pen = turtle.Turtle()
def pixel():
for i in range(4):
pen.forward(30)
pen.left(90)
pen.forward(30)
if __name__ == "__main__" :
scn.setup(600, 600)
pen.speed(0)
pen.hideturtle()
for i in range(WIDTH):
pen.up()
pen.setpos(0, 30*i) # Row position.
pen.down()
row = PIXELS[i]
for j in range(HEIGHT):
col = COLORS[row[j]]
pen.fillcolor(col)
pen.begin_fill()
pixel()
pen.end_fill()
print('done - press any key to exit')
turtle.onkeypress(exit)
turtle.listen()
turtle.done()
Result: