Home > Software design >  How can I bind a Canvas Object in a class on tkinter?
How can I bind a Canvas Object in a class on tkinter?

Time:10-29

from tkinter import *
from random import randint as rnd

class SpaceField:
    def __init__(self, window = None):
        self.window = window
        self.window = Tk()
        self.window.title("Asteriods")
        # Define canvas size and active flag
        self.wide, self.high, self.active = 700, 600, True
        self.canvas_display()
        self.asteriod_creation_seperation()
        self.spaceship_creation()
        self.spaceship_movement()
        #self.bullet_creation()

# Start Up

    def spaceship_creation(self):
        self.shipcoords = [] #Dont forget to append
        self.spaceship = self.canvas.create_polygon(340,300,360,
            300, 350,280, outline ="white")
        self.shipcoords.append(self.spaceship)

# Creation of the spaceship

    def spaceship_movement(self):
        self.spaceshipx, self.spaceshipy = 10, 10
        self.canvas.move(self.spaceship, self.spaceshipx, self.spaceshipy)

# Movement of the Spaceship

    def down(self, event):
        print(event.keysym)
        self.spacehipx = 0
        self.spaceshipy = -10

# Event that triggers movement, from the down arrow. Right now it only prints the "down" which means it is sensing I am pressing it, but other than that doesn't move the space ship. Which is what I want.

    def asteriod_creation_seperation(self):
        self.asteroids, self.speed = [], []
        size, radius = 50, 25
        for i in range(25):
            spacex = rnd(size, self.wide - size)
            spacey = rnd(size, self.high - size)
            self.asteroids.append( # Store oval item id
                self.canvas.create_oval(
                    spacex, spacey, spacex size, spacey size,
                    width=2, tags = "asteriod", outline = "white"))
            self.speed.append((rnd(1,4),rnd(1,4))) # Store random speed x, y

# Creation of the Asteroids

    def asteriod_update(self): # MAIN DRIVER: Work on ALL asteroids
        for i, a in enumerate(self.asteroids):
            xx, yy = self.speed[i] # get speed data
            x, y, w, h = self.canvas.coords(a)
            # check for boundary hit then change direction and speed
            if x < 0 or w > self.wide:
                xx = -xx * rnd(1, 4)
            if y < 0 or h > self.high:
                yy = -yy * rnd(1, 4)

            # Limit max and min speed then store it
            self.speed[i] = (max( -4, min( xx, 4)), max( -4, min( yy, 4 )))
            self.canvas.move(a, xx, yy) # update asteroid position

# Movement of the Asteroids

    def move_active(self):
        if self.active:
            self.asteriod_update()
            self.window.after(40, self.move_active)

# Updating the Asteroids Position

    def canvas_display(self):
        self.canvas = Canvas(
            self.window, width = self.wide,
            height = self.high, background = "black")
        self.canvas.pack(expand = True, fill = "both")

# Displaying the Canvas

    def run(self): # Begin asteroids here so that mainloop is executed
        self.window.bind("<KeyPress-Down>", lambda e: SpaceF.down(e))
        self.window.after(200, self.move_active)
        self.window.mainloop()


# Binding Keys and running mainloop

if __name__ == "__main__":
    SpaceF = SpaceField()

    SpaceF.run()

To summarize I want to move the spaceship down using the Downward Arrow Key, but I do not know how to make it move. I think I might have to use an if statement, but any help or a video recommendation would help as well.

CodePudding user response:

Here is a code snippet that demonstrates how to move your spacecraft around at different speeds.

I've given two ways of achieving it.

  1. Use conditional statements
  2. Use list indexing of alternatives

Also you need to make sure canvas has the focus.

class SpaceField:
    def __init__(self, window = None):
        ...

        self.canvas.bind("<Down>", self.down)
        self.canvas.bind("<Up>", self.up)

    def down(self, event):
        if event.state == 262144: # Open key
            y = 1
        elif event.state == 262145: # Shift key
            y = 5
        else: # Control key
            y = 10
        self.canvas.move(self.spaceship, 0, y)

    def up(self, event):
        y = [-1, -5, -10][[262144, 262145, 262148].index(event.state)]
        self.canvas.move(self.spaceship, 0, y)

    def run(self): # Begin asteroids here so that mainloop is executed
        self.window.after(200, self.move_active)

        # make sure canvas has the focus
        self.canvas.focus_force()
        self.window.mainloop()
  • Related