杰瑞科技汇

python canvas move

Of course! Moving objects on a Python canvas is a fundamental task, especially when creating games, animations, or interactive applications. The term "canvas" usually refers to the tkinter.Canvas widget, which is the most common GUI toolkit that comes built-in with Python.

python canvas move-图1
(图片来源网络,侵删)

I'll guide you through the core concepts and provide several examples, from simple to more complex.

Core Concept: The Canvas Coordinate System

First, understand that a tkinter.Canvas uses a coordinate system where:

  • The top-left corner is (0, 0).
  • The x coordinate increases as you move right.
  • The y coordinate increases as you move down.

Method 1: The Basic Approach (move and coords)

There are two primary ways to move an object on a canvas.

A) Using canvas.move(item, dx, dy)

This is the simplest method. It doesn't set an object's absolute position; instead, it moves the object by a certain offset.

python canvas move-图2
(图片来源网络,侵删)
  • item: The ID of the object you want to move (returned when you create it).
  • dx: The change in the x-coordinate (delta x).
  • dy: The change in the y-coordinate (delta y).

B) Using canvas.coords(item, x1, y1, x2, y2, ...) (for absolute positioning)

This method sets the object's coordinates to a new, absolute position. You must provide all the coordinates required to define the object's shape.

  • For a rectangle, you need 4 coordinates: x1, y1, x2, y2.
  • For an oval, you need 4 coordinates: x1, y1, x2, y2.
  • For a line, you need 4 coordinates: x1, y1, x2, y2.
  • For a polygon, you need all its vertex coordinates.

Example 1: Moving a Rectangle with a Button

This is the most straightforward example. We'll create a window with a canvas and a button. Clicking the button will move the rectangle.

import tkinter as tk
# --- Constants ---
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 300
CANVAS_WIDTH = 350
CANVAS_HEIGHT = 250
RECT_SIZE = 50
MOVE_AMOUNT = 10
# --- Functions ---
def move_rectangle():
    """Moves the rectangle by a fixed amount."""
    # The move() function shifts the object by dx and dy
    canvas.move(rect_id, MOVE_AMOUNT, 0)
# --- Setup the main window ---
window = tk.Tk()
window.title("Canvas Move Example")
window.geometry(f"{WINDOW_WIDTH}x{WINDOW_HEIGHT}")
# --- Create the Canvas ---
canvas = tk.Canvas(window, width=CANVAS_WIDTH, height=CANVAS_HEIGHT, bg="lightgray")
canvas.pack(pady=10)
# --- Create an object on the canvas ---
# The create_rectangle method returns an ID for the object
rect_id = canvas.create_rectangle(
    50, 50, 
    50 + RECT_SIZE, 50 + RECT_SIZE, 
    fill="blue", 
    outline="darkblue"
)
# --- Create a button to trigger the movement ---
move_button = tk.Button(window, text="Move Right", command=move_rectangle)
move_button.pack()
# --- Start the application's main loop ---
window.mainloop()

How it works:

  1. canvas.create_rectangle(...) draws the blue square and stores its unique ID in rect_id.
  2. When you click the "Move Right" button, the move_rectangle function is called.
  3. canvas.move(rect_id, MOVE_AMOUNT, 0) takes the rectangle with rect_id and moves it 10 pixels to the right (dx=10) and 0 pixels down (dy=0).

Example 2: Moving an Object with Arrow Keys

For more interactive control, like in a game, you'll want to use keyboard events.

python canvas move-图3
(图片来源网络,侵删)
import tkinter as tk
# --- Constants ---
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 300
CANVAS_WIDTH = 350
CANVAS_HEIGHT = 250
BALL_SIZE = 30
MOVE_SPEED = 10
# --- Functions ---
def move_ball(event):
    """Moves the ball based on the key pressed."""
    # Get the current coordinates of the ball
    coords = canvas.coords(ball_id)
    # Calculate new coordinates
    if event.keysym == "Up":
        new_coords = (coords[0], coords[1] - MOVE_SPEED, coords[2], coords[3] - MOVE_SPEED)
    elif event.keysym == "Down":
        new_coords = (coords[0], coords[1] + MOVE_SPEED, coords[2], coords[3] + MOVE_SPEED)
    elif event.keysym == "Left":
        new_coords = (coords[0] - MOVE_SPEED, coords[1], coords[2] - MOVE_SPEED, coords[3])
    elif event.keysym == "Right":
        new_coords = (coords[0] + MOVE_SPEED, coords[1], coords[2] + MOVE_SPEED, coords[3])
    else:
        return # Do nothing if it's not an arrow key
    # Update the ball's position using coords()
    canvas.coords(ball_id, *new_coords)
# --- Setup the main window ---
window = tk.Tk()
window.title("Move with Arrow Keys")
window.geometry(f"{WINDOW_WIDTH}x{WINDOW_HEIGHT}")
# --- Create the Canvas ---
canvas = tk.Canvas(window, width=CANVAS_WIDTH, height=CANVAS_HEIGHT, bg="white")
canvas.pack(pady=10)
# --- Create an object on the canvas ---
ball_id = canvas.create_oval(
    150, 125, 
    150 + BALL_SIZE, 125 + BALL_SIZE, 
    fill="red", 
    outline="darkred"
)
# --- Bind keyboard events to the window ---
# We bind to the window, not the canvas, to ensure it always works
window.bind("<Up>", move_ball)
window.bind("<Down>", move_ball)
window.bind("<Left>", move_ball)
window.bind("<Right>", move_ball)
# --- Add instructions ---
instructions = tk.Label(window, text="Use the arrow keys to move the ball.")
instructions.pack()
# --- Start the application's main loop ---
window.mainloop()

How it works:

  1. We use window.bind("<Up>", move_ball) to tell the main window to listen for the "Up" arrow key press and execute the move_ball function when it's detected.
  2. The move_ball function receives an event object as an argument, which contains information about the key press (e.g., event.keysym is the symbol of the key).
  3. We use canvas.coords(ball_id) to get the ball's current absolute position.
  4. We calculate the new position based on the key pressed.
  5. We use canvas.coords(ball_id, *new_coords) to set the ball's new absolute position.

Example 3: Smooth Animation (Using after)

For smooth, continuous movement (like a bouncing ball or a character walking), you use the window.after() method. This schedules a function to be called repeatedly after a certain number of milliseconds.

import tkinter as tk
import random
# --- Constants ---
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 300
CANVAS_WIDTH = 350
CANVAS_HEIGHT = 250
BALL_SIZE = 30
ANIMATION_SPEED = 20 # milliseconds between frames
# --- Variables ---
# We need to store the velocity (speed and direction)
velocity_x = 5
velocity_y = 3
# --- Functions ---
def animate():
    """Updates the ball's position and schedules the next frame."""
    global velocity_x, velocity_y # Use global to modify these variables
    # Get current position
    coords = canvas.coords(ball_id)
    # Calculate new position by adding velocity
    new_coords = (
        coords[0] + velocity_x, coords[1] + velocity_y,
        coords[2] + velocity_x, coords[3] + velocity_y
    )
    # --- Boundary Detection and Bouncing ---
    # If the ball hits the left or right wall
    if new_coords[0] <= 0 or new_coords[2] >= CANVAS_WIDTH:
        velocity_x = -velocity_x # Reverse the x-direction
        canvas.itemconfig(ball_id, fill=random.choice(['red', 'green', 'blue', 'purple', 'orange']))
    # If the ball hits the top or bottom wall
    if new_coords[1] <= 0 or new_coords[3] >= CANVAS_HEIGHT:
        velocity_y = -velocity_y # Reverse the y-direction
        canvas.itemconfig(ball_id, fill=random.choice(['red', 'green', 'blue', 'purple', 'orange']))
    # Update the ball's coordinates
    canvas.coords(ball_id, *new_coords)
    # Schedule this function to run again after ANIMATION_SPEED ms
    window.after(ANIMATION_SPEED, animate)
# --- Setup the main window ---
window = tk.Tk()
window.title("Bouncing Ball Animation")
window.geometry(f"{WINDOW_WIDTH}x{WINDOW_HEIGHT}")
# --- Create the Canvas ---
canvas = tk.Canvas(window, width=CANVAS_WIDTH, height=CANVAS_HEIGHT, bg="black")
canvas.pack(pady=10)
# --- Create an object on the canvas ---
ball_id = canvas.create_oval(
    150, 125, 
    150 + BALL_SIZE, 125 + BALL_SIZE, 
    fill="white", 
    outline=""
)
# --- Start the animation ---
# Call animate() once to start the loop
animate()
# --- Start the application's main loop ---
window.mainloop()

How it works:

  1. We define velocity_x and velocity_y to control the ball's speed and direction.
  2. The animate() function calculates the next position by adding the velocity to the current position.
  3. It checks for collisions with the canvas boundaries. If a collision occurs, it reverses the appropriate velocity component.
  4. canvas.coords() updates the ball's position.
  5. window.after(ANIMATION_SPEED, animate) is the key. It tells Tkinter: "In 20 milliseconds, call the animate function again." This creates a loop that runs continuously, making the ball appear to move smoothly.

Summary: Which Method to Use?

Method When to Use How it Works
canvas.move(item, dx, dy) For simple, relative movements. Moving an object by a fixed amount each time. Shifts the object's current position by an offset.
canvas.coords(item, ...) For setting an object to a specific, absolute position. Essential for keyboard-controlled movement and animation. Overwrites the object's coordinates with new values.
window.after() For creating smooth, continuous animations (games, simulations). Schedules a function to be called repeatedly, creating a game loop.
分享:
扫描分享到社交APP
上一篇
下一篇