Home > database >  How can I move a list of tkinter lines in a set space?
How can I move a list of tkinter lines in a set space?

Time:10-16


    import time
    from tkinter import *
    
    class Template:
        def __init__(self):
            self.window = Tk()
            self.window.title("2D Display")
    
            self.canvas = self.canvas_display()
            self.line1 = self.line_creation(650,350,500 * .3, 1000)
            self.line3 = self.line_movement_creation(0, 350,2000, 350)
            self.horizon = self.canvas.create_line(0,350,2000, 350, width = 2, fill ="white")
            self.speedx = 0 # x movement of line3
            self.speedy = 9 # y movement of line3
            self.active = True
            self.pos1 = []
    
            self.move_active()  #Code that creates the problem
            self.canvas.update()
    
        def canvas_display(self):  #canvas
            canvas = Canvas(self.window, width=500, height=400, background='black')
            canvas.pack(expand=True, fill="both")
            canvas.update()
            return canvas

Upwards is Initialization

        def line_creation(self,x,y,x1,y1): #creation of multple lines
            spacing = 0
            lines = []  # could list([])
            for i in range(11):
                id = self.canvas.create_line( x, y, x1   spacing, y1, width=2, fill="white")
                lines.append(id)
                spacing  = 100
                pos1 = self.canvas.coords(id)
                self.pos1 = pos1
                print(self.pos1)
    
            return lines
    

This is the creation method for the vertices lines

        def line_movement_creation(self,x,y,x1,y1):
            spacing1 = 0
            lines = []
            for i in range(4):
                id = self.canvas.create_line(x , y spacing1, x1, y1   spacing1, width=2, fill="white")
                lines.append(id)
                spacing1  = 100
                #line = [] equal all horizontal and vertical, 12 - 15 equal horizontal moving lines
            return lines

The is the creation for the horizontal lines

        def line_update(self): #line movement method
            for line in self.line3:
                self.canvas.move(line, self.speedx, self.speedy)
                #Create variables for all x and y values for the lines
                pos = self.canvas.coords(line)
                print(pos)
                if pos[3] >= 800:
                    self.canvas.move(line, self.speedx, self.speedy - 460)
    
    
        def move_active(self):
            if self.active:
                self.line_update()
                self.window.after(40, self.move_active)

This is what moves the lines creating an illusion of movement. I want to take the list of horizontal lines and set them between the outer most vertical lines. So it would stay between the vertical lines. Creating a road like image. I think I need to make a separate list for both but I am not sure. So to clarify I can someone help show me how to make the horizontal lines not attach to the ends of the screen but to inside the horizontal lines Code Demonstration

        def run(self):
            self.window.mainloop()
    
    if __name__ == '__main__':
        Temp = Template()
        Temp.run()

CodePudding user response:

So, first I would suggest that you use some game engine like pygame because it is faster and provides a bit more options and other stuff but here it is with tkinter (basically it is some simple trigonometry):

import tkinter as tk
import math


class Canvas(tk.Canvas):
    def __init__(self, parent, width=700, height=500, **kwargs):
        super().__init__(parent, width=width, height=height, **kwargs)
        self.width = width
        self.height = height
        self.angle = 70
        self.speedy = 10
        self.change_speed_ms = 50
        self.draw_angle(self.angle, 5)
        self.lines, self.interval = self.init_lines(amount=5)
        self.draw_lines()

    @property
    def radians(self):
        return math.radians(self.angle)

    def draw_angle(self, view_angle, lines):
        orient = 0
        adjacent = self.height // 2
        step = view_angle // lines
        half = view_angle // 2
        for angle in range(orient - half, orient   half   step, step):
            rad = math.radians(angle)
            delta = math.tan(rad) * adjacent
            x1, y1 = self.width // 2, self.height // 2
            x2, y2 = x1   delta, y1   adjacent
            self.create_line(x1, y1, x2, y2)

    def init_lines(self, amount=5):
        interval = round((self.height // 2) / amount)
        coordinate_list = list()
        offset = self.height // 2
        for y in range(0, self.height // 2   interval, interval):
            delta = math.tan(self.radians / 2) * y
            x1 = self.width // 2 - delta
            x2 = self.width // 2   delta
            y1 = y2 = y   offset
            line = self.create_line(x1, y1, x2, y2)
            coordinate_list.append((line, (x1, y1, x2, y2)))
        return coordinate_list, interval

    def draw_lines(self):
        tmp_lst = list()
        for id_, (x1, y1, x2, y2) in self.lines:
            y1  = self.speedy
            if y1 > self.height   self.interval - self.speedy:
                y1 = self.height // 2
            y = y2 = y1
            adjacent = y - self.height // 2
            delta = math.tan(self.radians / 2) * adjacent
            x1 = self.width // 2 - delta
            x2 = self.width // 2   delta
            self.coords(id_, x1, y1, x2, y2)
            tmp_lst.append((id_, (x1, y1, x2, y2)))
        self.lines = tmp_lst
        self.after(self.change_speed_ms, self.draw_lines)


root = tk.Tk()

Canvas(root, highlightthickness=0).pack()

root.mainloop()

So the main method here is Canvas().draw_lines(). First of you get a list of line IDs and their coordinates at set intervals based on the amount of total lines, then you iterate over them, change their y value and accordingly calculate the opposite side of a right-angle triangle using tan and the adjacent side which is known from the current y coordinate and the starting point (the middle).

  • Related