Разработка на коленке

"тут должна быть красивая цитата о программировании"

Перемещать объект в место последнего клика

2024-02-27 22:00

Когда я писал аркадные игрушки, например, Арканоид, то у объекта была либо своя постоянная скорость, и менялось только направление, либо же объект двигался вслед за курсором (пальцем на телефоне).

В этом сниппете я сделал перемещение к конкретной точке, которая ставится кликом мышки.



import pygame as pg


from pygame.math import Vector2
from pygame.time import Clock


class Deck:
    def __init__(self, surface, x, y, velocity=4, size=(140, 30), color=(10, 100, 10)):
        self.surface = surface
        self.position = Vector2(x, y)
        self.velocity = velocity
        self.size = size
        self.color = color

        self.center_x = x + size[0] / 2

        self.rect = pg.rect.Rect(x, y, size[0], size[1])

    def move(self, x):
        self.center_x = x + self.size[0] // 2
        self.position.x = x
        self.rect.x = x

    def render(self):
        pg.draw.rect(self.surface, self.color, self.rect, border_radius=3)


class Mark:
    def __init__(self, surface, x, y, color=(200, 200, 150)):
        self.surface = surface
        self.x = x
        self.y = y
        self.color = color

        self.inner_radius = 6
        self.outer_radius = 16
        self.dash_len = 4
        self.dash_padding = 13

    def render(self):
        pg.draw.circle(
            self.surface,
            self.color,
            (self.x, self.y),
            self.outer_radius,
            1
        )

        pg.draw.circle(
            self.surface,
            self.color,
            (self.x, self.y),
            self.inner_radius
        )

        y = 0
        while y < self.surface.get_height():
            pg.draw.line(
                self.surface, 
                self.color,
                (self.x, y),
                (self.x, y + self.dash_len)
            )
            y += (self.dash_len + self.dash_padding)

class Game:
    def __init__(self, surface):
        self.surface = surface

        self.bg_color = (0, 0, 0)

        self.clock = Clock()
        self.fps = 60

        self.mouse_down_x = None
        self.mouse_offset = 10

        y = self.surface.get_height() - 80
        self.deck = Deck(self.surface, 10, y)
        self.mark = Mark(self.surface, surface.get_width() // 2, y + self.deck.size[1] //2)

        self.working = True

    def process_events(self):
        for e in pg.event.get():
            if e.type == pg.QUIT:
                self.working = False
            elif e.type == pg.KEYDOWN and e.key == pg.K_ESCAPE:
                self.working = False

        if pg.mouse.get_pressed()[0] and self.mouse_down_x is None:
            self.mouse_down_x = pg.mouse.get_pos()[0]

        if not pg.mouse.get_pressed()[0] and self.mouse_down_x is not None:
            x = pg.mouse.get_pos()[0]
            if abs(x - self.mouse_down_x) <= self.mouse_offset:
                self.mark.x = self.mouse_down_x
                if self.mark.x >= self.deck.center_x:
                    self.deck.velocity = abs(self.deck.velocity)
                else:
                    self.deck.velocity = -abs(self.deck.velocity)
            self.mouse_down_x = None

    def update(self):
        if abs(self.deck.center_x - self.mark.x) >= abs(self.deck.velocity):
            self.deck.move(self.deck.position.x + self.deck.velocity)
        else:
            self.deck.move(self.mark.x - self.deck.size[0] // 2)

    def render(self):
        self.surface.fill(self.bg_color)

        self.deck.render()
        self.mark.render()

        pg.display.update()

    def run(self):
        while self.working:
            self.process_events()
            self.update()
            self.render()

            self.clock.tick(self.fps)


def main():
    pg.init()

    size = (1920, 1080)
    flags = pg.FULLSCREEN
    display_surface = pg.display.set_mode(size, flags)
    Game(display_surface).run()

    pg.quit()


if __name__ == "__main__":
    main()

1/move_object_to_click.py