Loading [MathJax]/jax/output/CommonHTML/jax.js

Prijavi problem


Obeleži sve kategorije koje odgovaraju problemu

Još detalja - opišite nam problem


Uspešno ste prijavili problem!
Status problema i sve dodatne informacije možete pratiti klikom na link.
Nažalost nismo trenutno u mogućnosti da obradimo vaš zahtev.
Molimo vas da pokušate kasnije.

Mouse events

In the “switch” example we have shown how we can react in a program when the user presses a mouse button. Although for the user a click seems like a single action, we have seen that for the computer it is a sequence of events that starts with an event of the type pg.MOUSEBUTTONDOWN.

In the following examples and tasks, we will use three types of mouse-generated events:

  • Pressing any mouse button (like in the example with the switch), in which case event.type has a value of pg.MOUSEBUTTONDOWN

  • Releasing a mouse button, in which case event.type has a value of pg.MOUSEBUTTONUP

  • Moving the mouse, in which case event.type has a value of pg.MOUSEMOTION. In fact, when moving the mouse multiple such events are generated (each of them describing a small mouse movement in a very short time interval, so each event of this kind usually describes a movement of only a few pixels).

Event objects whose type is pg.MOUSEBUTTONDOWN also contain some additional information, such as:

  • event.pos - the position of the mouse at the time of registering the event (already used in the switch example)

  • event.button - a number from 1 to 5 indicating which mouse button is pressed (1 - left, 2 - middle, 3 - right, 4 - scroll up, 5 - scroll down)

Some of the additional event data contained in pg.MOUSEMOTION event objects are:

  • event.pos - the position of the mouse after the mouse motion event

  • event.rel - an ordered pair that describes how much the mouse position has changed since the previous mouse motion event

  • event.buttons - a three-element list of logical values, which determine for each of the three mouse buttons (0 - left, 1 - middle, 2 - right) whether it was pressed during mouse movement.

Click processing - exercises

You may not have noticed that in the “switch” program from the previous lesson, the light can be turned on and off by clicking any mouse button. This is because the same type of event is generated for each mouse button, and we did not check which button was pressed when the event occurred.

Task - left button as a switch:

Copy the “switch” program here, then modify it so that the light can be switched on and off only with the left mouse button.

Hint: Use event.button data.

x
 

(PyGame__interact_switch_left_button_eng)

Task - three switches:

Use parts of the “switch” program and create a program that simulates the work of three switches, as shown in the example.

../_images/Shema3_Off.png ../_images/Shema3_On.png ../_images/SwitchOff.png ../_images/SwitchOn.png ../_images/BulbOff.png ../_images/BulbOn.png
 
1
import pygame as pg, petljapg
2
(width, height) = (800, 500)
3
canvas = petljapg.open_window(width, height, "Switches")
4
5
schema_images = (pg.image.load('Shema3_Off.png'), pg.image.load('Shema3_On.png'))
6
switch_images = (pg.image.load('SwitchOff.png'), pg.image.load('SwitchOn.png'))
7
bulb_images = (pg.image.load('BulbOff.png'), pg.image.load('BulbOn.png'))
8
9
switch_on = [False, False, False]
10
switch_pos = [(100, 200), (300, 150), (300, 250)]
11
bulb_pos = (500, 100)
12
13
# finish the program
14

(PyGame__interact_switches_eng)

Other mouse events

As it was mentioned at the beginning of this lesson, a program can also respond to mouse button release and mouse motion events. To do that, it is necessary to compare the value of event.type with the constants pg.MOUSEBUTTONUP and pg.MOUSEMOTION. The following are tasks where you can try this out.

Task - drawing lines:

Complete the program so that it can draw straight lines, as in the example.

36
 
1
import pygame as pg, petljapg
2
(width, height) = (400, 400)
3
canvas = petljapg.open_window(400, 400, "Lines with mouse")
4
5
mosue_pos = (0, 0)
6
line_start = mosue_pos
7
line_is_being_drawn = False
8
previous_lines = []
9
10
def new_frame():
11
    canvas.fill(pg.Color("white")) # paint canvas
12
    if line_is_being_drawn:
13
        pg.draw.line(canvas, pg.Color('black'), line_start, mosue_pos)
14
15
    for a, b in previous_lines:
16
        pg.draw.line(canvas, pg.Color('black'), a, b)
17
18
19
def handle_event(event):
20
    global line_is_being_drawn, line_start, mosue_pos
21
22
23
    # add statements here that work as follows:
24
25
    # if the event type is "mouse button down":
26
    #     the line drawing mode is switched on
27
    #     we start the line at the current position of the mouse
28
    # otherwise, if the event type is "mouse button going up":
29
    #     the line drawing mode is switched off
30
    #     the new line is from the memorized start of the line to the current position of the mouse
31
    #     add a new line to the list of previous lines
32
    # otherwise, if the event type is "moving mouse":
33
    #     in the mouse_pos variable, remember the current position of the mouse
34
35
petljapg.frame_loop(30, new_frame, handle_event)
36

(PyGame__interact_mouse_lines1_eng)

Task - drawing lines with deletion:

Copy the program for drawing lines below, then add an ability to delete all lines with a right-click.

Hint: To distinguish between left and right mouse buttons in the program, the event.button data must be used again. The code in the handle_event function should now look something like this:

14
 
1
if the event type is "mouse button going down":
2
        if button 1 (left button) is pressed
3
            the line drawing mode is switched on
4
            the new line is from the memorized start of the line to the current position of the mouse
5
        if button 3 (right button) is pressed
6
            empty the list of previous lines
7
    otherwise, if the event type is "releasing mouse button":
8
        if button 1 (left button) is pressed
9
            the line drawing mode is switched off
10
            the new line is from the memorized start of the line to the current position of the mouse
11
            add a new line to the list of previous lines
12
    otherwise, if the event type is "move mouse":
13
        remember the current position of the mouse in the mouse_pos variable
14

(PyGame__interact_mouse_lines2_part_eng)

2

(PyGame__interact_mouse_lines2_eng)

Task - dragging:

The following program shows how to allow the user of the program to drag objects.

Try the program out (drag the apples into the basket) and try to understand it, then answer the questions below.

../_images/apple.png ../_images/basket.png ../_images/drag_scene.png
53
 
1
import pygame as pg, petljapg, random
2
(width, height) = (600, 400)
3
canvas = petljapg.open_window(width, height, "Dragging with mouse")
4
5
basket_image  = pg.image.load("basket.png") # read the basket image
6
apple_image = pg.image.load("apple.png")  # read the apple image
7
scene_image = pg.image.load("drag_scene.png") # read the scene image
8
apple_positions = []
9
for i in range(5):
10
    apple_positions.append((random.randint(50, 200), random.randint(80, 130)))
11
basket_pos = (300, 200)
12
i_apple = -1             # which apple is currently being draged (-1 means none)
13
done = False
14
15
def mouse_is_on_image(mouse_pos, image_pos, image):
16
    x, y = mouse_pos
17
    x0, y0 = image_pos # upper left corner
18
    dx, dy = image.get_width(), image.get_height() # image size
19
    return x0 <= x and x <= x0 + dx and y0 <= y and y <= y0 + dy
20
21
def new_frame():    
22
    canvas.blit(scene_image, (0, 0)) # display scene
23
    if not done:
24
        canvas.blit(basket_image, basket_pos) # display the basket
25
        for apple_pos in apple_positions: # display apples
26
            canvas.blit(apple_image, apple_pos)
27
28
def handle_event(event):
29
    global apple_positions, i_apple, done
30
    if event.type == pg.MOUSEBUTTONDOWN:     # pritisnuto je dugme miša
31
        for i in range(len(apple_positions)):
32
            # if mouse is on one of the apples
33
            if mouse_is_on_image(event.pos, apple_positions[i], apple_image):
34
                i_apple = i    # start dragging
35
                
36
    elif event.type == pg.MOUSEBUTTONUP:     # mouse button released
37
        if mouse_is_on_image(event.pos, basket_pos, basket_image):
38
            del apple_positions[i_apple]
39
            if len(apple_positions) == 0:
40
                done = True
41
        i_apple = -1                           # finish dragging
42
        
43
    elif event.type == pg.MOUSEMOTION:       # mouse moved
44
        if i_apple >= 0:                       # if dragging is in progress
45
            # calculate the position of the apple (upper left corner of the image)
46
            # so that the center of the apple is at the mouse
47
            mouse_x, mouse_y = event.pos
48
            x = mouse_x - apple_image.get_width() // 2
49
            y = mouse_y - apple_image.get_height() // 2
50
            apple_positions[i_apple] = (x, y)
51
52
petljapg.frame_loop(30, new_frame, handle_event)
53

(PyGame__interact_drag_eng)

Q-79: What is the i_apple variable in the program?






Pair the checks in the program with their meaning.
if mouse_is_on_image(event.pos, basket_pos, basket_image):if i_apple >= 0:if len(apple_positions) == 0:if mouse_is_on_image(event.pos, apple_positions[i]
whether the user "took" the applewhether the apple should be deletedwhether the game is overwhether a drag is ongoing

Q-80: How do we distinguish between dragging and plain mouse movement in a program?