Colors are not filling in certain places - python-3.x

I am utilizing turtle to make a xmastree. The task is to color the individual pieces. The "trunk" portion of code works and will fill correctly. The Layer1(), Layer2(), and Layer3() do not fill with color as they should. Any help would be appreciated.
I have looked through the other problems on stack overflow. I have repositioned my variables. Still, nothing.
""" Lab 9 Exercise 3
Author: Jonathan Wheatley
Define a function drawXmasTree(t, blc, scale = 1) You may add further parameters beyond the first three if you wish (note: give any additional parameters default values!). Your
tree should resemble three filed, superimposed green triangles (containing colored ball ornamets) over a brown trunk.
blc and scale should work as in the preceding exercise. Show results at two different scales.
"""
from turtle import Turtle
scale = 1.25
def drawXmasTree():
a = trunk()
b = Layer1()
c = Layer2()
d = Layer3()
def trunk():
t = Turtle()
t.pencolor("brown")
t.fillcolor("brown")
t.shape("turtle")
t.up()
t.goto((scale * -100), (scale * -100))
t.down()
for count in range(2):
t.begin_fill()
t.forward(scale * 10)
t.left(90)
t.forward(scale *100)
t.left(90)
t.end_fill()
t.hideturtle()
def Layer1():
t = Turtle()
t.pencolor("green")
t.fillcolor("green")
t.shape("turtle")
t.up()
t.goto((scale * -150), 0)
t.down()
for count in range(3):
t.begin_fill()
t.forward(scale * 110)
t. left(120)
t.end_fill()
t.hideturtle()
def Layer2():
t = Turtle()
t.pencolor("green")
t.fillcolor("green")
t.shape("turtle")
t.up()
t.goto((scale * -147), 15)
t.down()
for count in range(3):
t.begin_fill()
t.forward(scale * 104)
t.left(120)
t.end_fill()
t.hideturtle()
def Layer3():
t = Turtle()
t.fillcolor("green")
t.pencolor("green")
t.shape("turtle")
t.up()
t.goto((scale * -145), 30)
t.down()
for count in range(3):
t.begin_fill()
t.forward(scale * 100)
t.left(120)
t.end_fill()
t.hideturtle()
def main():
u = drawXmasTree()
main()
When the code is run the turtle should display, draw in the correct colored line, and then the shape should fill.

So, in running so more tests, I seem to be getting positive results by breaking the begin_fill() and end_fill out of the for loop. I don't know why this was working in the Trunk() section but it does not work in the subsequent sections.
Please, if you find a way to make this code better let me know. I would love to learn something and improve my coding.
Thank you.

Related

Interference of canvas items and problem in setting coordinates

I'm working on an animation of a moving object, while drawing it's path.
I want to draw the pixels in which the center of the object went through... but guess what? python decided to set the NW anchor of the image with the coordinates I send, instead of the center. I infer it has something to do with the pixels I draw simultaneously (creating a one pixel rectangle). so the image appear on the right of the path bellow... I want the center of it to be on the top of the pixels... adding the main of the code:
from tkinter import*
import time
dt = 0.01
clock_place = (500, 10)
def round_two(t, t0):
return round((t-t0)*100)/100
def round_three(t, t0):
return round((t-t0)*1000)/1000
# showing 'real time motion' for a known path (also cyclic), with
# parametric representation
def paint_known_path(x_pos, y_pos, t_0):
window = Tk()
canvas = Canvas(window, height=700, width=1000)
canvas.pack()
canvas.config(background='black')
tennis_ball = PhotoImage(file='tennis ball.png')
t = t_0
x = x_pos(t_0)
y = y_pos(t_0)
particle = canvas.create_image(x, y, image=tennis_ball)
clock = canvas.create_text(clock_place, text=round_two(t, t_0),
fill='white')
while True:
canvas.create_rectangle(x, y, x, y, outline='red')
canvas.itemconfig(clock, text=round_two(t, t_0))
t += dt
x = x_pos(t)
y = y_pos(t)
canvas.moveto(particle, x, y)
window.update()
if x == x_pos(t_0) and y == y_pos(t_0):
if t - t_0 > 100*dt:
break
time.sleep(dt)
canvas.create_text((500, 100), text='orbit duration: ' +
str(round_three(t, t_0)), fill='white')
window.mainloop()
It turns out to be quite a bit require, but here is the main completion components.
The first additional part that you need to add:
# print('the ten ball height', tennis_ball.height(), tennis_ball.width())
# tennis ball dimensions
tb_hght = tennis_ball.height()
tb_wdth = tennis_ball.width()
mid_point_x = x + tennis_ball.height() / 2
mid_point_y = y + tennis_ball.width() / 2
Secondly, also needed to add some functions to for x_pos and y_pos like this (these are just example functions to make the code work):
def x_pos(a):
# any function of t,
return 100
def y_pos(a):
# any function of t,
return 100
Furthermore, you need to call the function at the end like this:
paint_known_path(x_pos,y_pos,0)
Finally, need to add the mid_point_x and mid_point_y to the path that is drawn (as these will be the image centre points).

Pass a variable into a for range loop and then grow the value?

In Turtle graphics I'm trying to create a series of boxes, one within the next. My main question is how does one pass values into a for i in range(4): loop and have the values increase or decrease by a value? Here, I've created two boxes but I'd like to make the second smaller and fit in the first?
import turtle as t
def block(x, y, length, scale):
for i in range(2):
t.up()
t.goto(x,y)
t.down()
for i in range(4):
t.forward(length * scale)
t.right(90)
block(100, 100, 100, 1)
t.mainloop()
You need to make your starting x and y coordinates and side length variables, change them every time through the loop, and move the turtle every time. Something like this:
import turtle as t
x = 100
y = 100
side = 100
decrease = 10
num_rect = 2
for i in range (num_rect):
t.up()
t.goto(x, y)
t.down()
for i in range(4):
t.forward(side)
t.right(90)
x += decrease / 2
y -= decrease / 2
side -= decrease
t.mainloop()

Scale tiny TileMap to a larger size in PyTMX and PyGame

So I managed to create, import and display a 16x16 TileMap in my PyGame project.
I have my asset layer called ground and an Objects layer originally called objects.
Tile software screenshot with my layers
Then I've got this simple code to create my TileMap :
class TiledMap:
def __init__(self, filename):
tm = pytmx.load_pygame(filename, pixelalpha=True)
self.width = tm.width * TILE_SIZE
self.height = tm.height * TILE_SIZE
self.tmxdata = tm
def render(self, surface):
ti = self.tmxdata.get_tile_image_by_gid
for layer in self.tmxdata.visible_layers:
if isinstance(layer, pytmx.TiledTileLayer):
for x, y, gid, in layer:
tile = ti(gid)
if tile:
tile = pg.transform.scale(tile,(TILE_SIZE,TILE_SIZE))
surface.blit(tile, (x * TILE_SIZE,
y * TILE_SIZE))
def make_map(self):
temp_surface = pg.Surface((self.width, self.height), pg.SRCALPHA).convert_alpha()
self.render(temp_surface)
return temp_surface
EDIT: I've forgot to say that my 16x16 map is actually rescaled to a 64x64 (TILE_SIZE) image, but only for the visible layer ground, I want to do it with the objects layer too.
This is working great to scale my "visible layer" which is ground.
But when I draw the collisions you can see that the objects are still really small and don't fit my new map resolution :
Game screenshot with in Blue:Player hit box and in Yellow:Colliders
As you can see the hit boxes of the walls I've set in my TileMap are not correctly scaled.
So question is, how to scale the Objects layer of a TileMap with pyTMX ?
Thank you all.
So I found a way to correct it, I don't know if it's the cleanest way to do it but here is the solution code :
def new(self):
# Initialization and setup for a new game
self.all_sprites = pg.sprite.LayeredUpdates()
self.walls = pg.sprite.Group()
self.items = pg.sprite.Group()
for tile_object in self.map.tmxdata.objects:
tile_object.x *= int(TILE_SIZE / self.map.tilesize)
tile_object.y *= int(TILE_SIZE / self.map.tilesize)
obj_center = vec(tile_object.x + tile_object.width / 2,
tile_object.y + tile_object.height / 2)
if tile_object.name == 'player':
self.player = Player(self, obj_center.x, obj_center.y)
elif tile_object.name in ['pickaxe']:
Item(self, obj_center, tile_object.name)
else:
tile_object.width *= int(TILE_SIZE / self.map.tilesize)
tile_object.height *= int(TILE_SIZE / self.map.tilesize)
# if tile_object.name == 'zombie':
# Mob(self, tile_object.x, tile_object.y)
if tile_object.name == 'wall':
Obstacle(self, tile_object.x, tile_object.y, tile_object.width, tile_object.height)
self.camera = Camera(self.map.width, self.map.height)
self.paused = False
self.draw_debug = False
So in my game.new() function I'm retrieving the sprites of the player and the objects by parsing a spritesheet and I already scale them to the correct size. But for the other entities size and for position the correction is simply to multiply the values with the correct number. Number which is the scaling factor : 16x16 to a 64x64 tilesets gives 64/16 which is 4.
So I just had to multiply the entities x, y, width and height by 4.
Hope it will help someone anyway.

review my circle creating code( turtle, python)

im new to python and just started touching turtle. I made this code of circle drawing and i have a few questions:
import turtle
jo = turtle.Turtle()
def polygon(t, r, n, l):
for i in range(30):
jo.fd(n * l)
jo.lt(r * 2 * 3.14)
print(polygon(jo, 2, 3, 4))
turtle.done()
1) i really dont understand how the code i wrote draw a circle.
2) are there any other ways to draw a circle in a similar sytax?
3) is this code is fine or I need to improve it?
i really dont understand how the code i wrote draw a circle.
By shear chance, perhaps. You'll notice that the radius of the circle you draw (~27) has nothing to do with the radius you passed into your polygon() function (2).
You pass radians to the left() function:
jo.lt(r * 2 * 3.14)
although it takes degrees unless told otherwise. You print the result of a function that doesn't return anything:
print(polygon(jo, 2, 3, 4))
Your turtle overshoots at the very end redrawing a small segment of the circle. Finally, you pass a turtle argument to the polygon() function but ignore it and uses the global one instead.
is this code is fine or I need to improve it?
I'd go with something more like:
from math import pi
from turtle import Turtle, Screen
TWO_PI = 2 * pi
def polygon(turtle, radius, sides):
circumference = radius * TWO_PI
for _ in range(sides):
turtle.fd(circumference / sides)
turtle.lt(TWO_PI / sides)
jo = Turtle()
jo.radians()
polygon(jo, 100, 30)
screen = Screen()
screen.mainloop()
are there any other ways to draw a circle in a similar sytax?
from turtle import Turtle, Screen
jo = Turtle()
jo.circle(100, steps=30)
screen = Screen()
screen.mainloop()

How can I use the random module in python turtle?

I'm trying to make a game like the original snake and I want the "food" to go to random places but I'm not really sure how to get it to work with it in a class. There are some other errors in the code but want to focus on the player and the food right now.
import turtle
import random
"""-------"""
t=turtle.Turtle()
s=turtle.Screen()
cube=turtle.Turtle
"""------------"""
WIDTH, HEIGHT=300, 300
DISTANCE=5
"""--------------"""
s.setup(WIDTH,HEIGHT)
"""------------"""
t.width(1)
s.bgcolor("dark green")
"""-----------------"""
class Border():
def check():
x, y = t.position()
if not -WIDTH / 2 < x < WIDTH / 2 or not -HEIGHT / 2 < y < HEIGHT / 2:
t.undo() # undo error
t.speed(0)
t.left(180) # turn around
t.forward(10) # redo movement but in new direction
t.speed(3)
"""-------------"""
randint=random.randint
x=random.randint(cube.xcor, 0)
y=random.randint(0,cube.ycor)
"""---------------"""
class Food():
def block():
cube.color("red")
for i in range(4):
cube.goto(x, -x, y, -y)
cube.begin_fill()
cube.forward(20)
cube.right(90)
cube.end_fill()
"""---------------"""
class Player():
def move_up():
player=False
while player==False:
for i in range(1):
t.forward(DISTANCE)
t.clear()
def move_left():
t.speed(0)
t.left(90)
t.speed(3)
def move_right():
t.speed(0)
t.right(90)
t.speed(3)
"""------------"""
collistion_check=Border()
player1=Player()
s.onkey(Player.move_up,"up")
s.onkey(Player.move_left,"left")
s.onkey(Player.move_right,"right")
s.listen()
Generally speaking, your program is a disaster. As far as your immediate problem with random numbers, this code has an issue:
randint=random.randint
x=random.randint(cube.xcor, 0)
y=random.randint(0,cube.ycor)
Syntax-wise, this should be something more like:
from random import randint
...
x = randint(cube.xcor(), 0)
y = randint(0, cube.ycor())
I.e. it's not clear why you set the variable randint since you don't use it and xcor() and ycor() are methods and require parenthesis.
If your goal is to locate the food randomly on the screen, I'd go with:
x = randint(cube.xcor()/2 - WIDTH/2, WIDTH/2 - cube.xcor()/2)
y = randint(cube.ycor()/2 - HEIGHT/2, HEIGHT/2 - cube.ycor()/2)
Adding variables as you see fit to reduce the redundancies. The biggest problem I see with the remainder of your code is this method:
def move_up():
player=False
while player==False:
for i in range(1):
t.forward(DISTANCE)
t.clear()
It's not clear how player ever becomes True so once you hit the up arrow, you're into an infinite loop. But I assume you'll focus on this once you get the food issue resolved.

Resources