Pygame: क्यों रबड़ उपकरण काम नहीं करता है की तरह का इरादा है?

0

सवाल

मैं कोशिश कर रहा हूँ का निर्माण करने के लिए एक बुनियादी पिक्सेल कला संपादक, और वर्तमान में कठिन संघर्ष को खोजने के साथ त्रुटि में कोड. पेंसिल अच्छा काम करता है, लेकिन इरेज़र नहीं है.

दिखा रहा है नमूना क्या हो रहा है:

मुख्य फ़ाइल

import pygame as pg
from settings import *
from gui import *
from canvas import Canvas
from utils import Tools

from os import path
import sys

class Pyxel:

    def __init__(self, tile_size: int):
        pg.init()

        # Main screen
        self.screen = pg.display.set_mode((WIDTH, HEIGHT))
        self.screen_rect = self.screen.get_rect()
        #
        pg.display.set_caption(TITLE)
        self.clock = pg.time.Clock()
        pg.key.set_repeat(500, 100)
        self.load_data()
        
        
        self.tile_size = tile_size

    def load_data(self):
        game_folder = path.dirname(__file__)
        img_folder = path.join(game_folder, 'img')
        font_folder = path.join(game_folder, 'fonts')

        self.pencil_icon = pg.image.load(path.join(img_folder, PENCIL_ICON)).convert_alpha()
        self.pencil_icon_hover = pg.image.load(path.join(img_folder, PENCIL_HOVER)).convert_alpha()
        self.pencil_icon_clicked = pg.image.load(path.join(img_folder, PENCIL_CLICKED)).convert_alpha()
        self.eraser_icon = pg.image.load(path.join(img_folder, ERASER_ICON)).convert_alpha()
        self.eraser_icon_hover = pg.image.load(path.join(img_folder, ERASER_HOVER)).convert_alpha()
        self.eraser_icon_clicked = pg.image.load(path.join(img_folder, ERASER_CLICKED)).convert_alpha()

    def new(self):
        """ Initialize variables and do the initial setup """

        self.canvas = Canvas(self)
        self.gui = GUI(self)
        self.tool_buttons = pg.sprite.Group()
        self.load_toolbtns()
        self.selected_tool = self.pencil_tool
        self.selected_tool.clicked = True
        self.selected_color = BLACK
        self.canvas_grid = []
        for x in range(0, self.tile_size):
            self.canvas_grid.append([])
            for y in range(0, self.tile_size):
                self.canvas_grid[x].append({"color":None, "status":False})
        
    

    def load_toolbtns(self):
        self.pencil_tool = ToolBtns(self, self.pencil_icon, self.pencil_icon_hover, self.pencil_icon_clicked, 5, 5, Tools.pencil)
        self.erase_tool = ToolBtns(self, self.eraser_icon, self.eraser_icon_hover, self.eraser_icon_clicked, 42, 5, Tools.eraser)

    def run(self):
        """ App loop """
        self.running = True
        while self.running:
            self.dt = self.clock.tick(FPS)
            self.draw()
            self.events()

    def quit(self):
        pg.quit()
        sys.exit()

    def events(self):
        # catch all the events here

        for event in pg.event.get():
            mouse_state = pg.mouse.get_pressed()
            x, y = self.get_tile()
            if event.type == pg.QUIT:
                self.quit()

            elif event.type == pg.MOUSEBUTTONDOWN:
                # event.button = (left, middle, right, wheel up, wheel down)
                if event.button == 1 and self.selected_tool.tool_type == Tools.pencil:
                    print(x, y)
                    self.register_pixel(x, y, draw=True)
                elif event.button == 1 and self.selected_tool.tool_type == Tools.eraser:
                    print(x, y)
                    self.register_pixel(x, y, draw=False)
            elif event.type == pg.MOUSEMOTION:
                
                # mouse_state = Bool(left, middle, right)
                if mouse_state[0] and self.selected_tool.tool_type == Tools.pencil:
                    print(x, y)
                    self.register_pixel(x, y, draw=True)
                if mouse_state[0] and self.selected_tool.tool_type == Tools.eraser:
                    print(x, y)
                    self.register_pixel(x, y, draw=False)

            for btn in self.tool_buttons:

                if btn.rect.collidepoint(pg.mouse.get_pos()):
                    btn.hovered = True
                    if mouse_state[0]:
                        if btn.tool_type != self.selected_tool.tool_type:
                            self.selected_tool.clicked = False
                        self.selected_tool = btn
                        self.selected_tool.clicked = True
                else:
                    btn.hovered = False
                            

    def get_tile(self):
        """ Returns the tile that the mouse is pointing """

        x, y = pg.mouse.get_pos()
        x -= self.canvas.rect.x
        y -= self.canvas.rect.y
        dx = x // self.tile_size
        dy = y // self.tile_size
        if (dx >= 0 and dy >= 0) and (dx <= self.tile_size - 1 and dy <= self.tile_size - 1):
            return (dx, dy)
        return None, None

    def register_pixel(self, x, y, draw=True):
        """ Register new pixels onto the canvas matrix
            Default color is BLACK """
        
        if x is None or y is None:
            return
        try:
            self.canvas_grid[x][y] = {"color":self.selected_color, "status":True} if draw else {"color":None, "status":False}
        except IndexError:
            print("Index Error: out of canvas range")

    def draw(self):
        self.screen.fill(SCREEN_COLOR)
        self.canvas.draw()
        self.canvas.draw_pixel(self.canvas_grid)
        self.gui.draw()
        self.tool_buttons.update()
        self.tool_buttons.draw(self.screen)
        pg.display.flip()

if __name__ == "__main__":

    tile_size = int(input("Tile Size >> "))
    p = Pyxel(tile_size)
    p.new()
    while True:
        p.run()

कैनवास फ़ाइल

import pygame as pg
from settings import *

class Canvas:

    def __init__(self, app):
        self.app = app
        self.screen = app.screen
        self.image = pg.Surface((CANVAS_WIDTH, CANVAS_HEIGHT))
        self.image.fill(WHITE)
        self.rect = self.image.get_rect(center = app.screen_rect.center)

    def draw(self):
        self.screen.blit(self.image, self.rect)
        self.grid()

    def grid(self):
        for x in range(0, CANVAS_WIDTH, TILESIZE):
            pg.draw.line(self.image, LIGHTGREY, (x, 0), (x, self.rect.bottom))
        for y in range(0, CANVAS_HEIGHT, TILESIZE):
            pg.draw.line(self.image, LIGHTGREY, (0, y), (self.rect.right, y))

    def draw_pixel(self, canvas_data):
        """ Draws pixels on the screen """

        for row, data in enumerate(canvas_data):
            for col, px in enumerate(data):
                if px:
                    if px["status"]:
                        #self.canvas.image.fill(px["color"], pg.Rect(row * self.tile_size, col * self.tile_size, self.tile_size, self.tile_size))
                        pg.draw.rect(self.image, px["color"], pg.Rect(row * self.app.tile_size, col * self.app.tile_size, self.app.tile_size, self.app.tile_size))

जीयूआई फ़ाइल

import pygame as pg
from settings import *
from utils import Tools

class GUI:

    """ This is just the background, for now """

    def __init__(self, app):
        self.app = app
        self.screen = app.screen
        self.image = pg.Surface((GUI_WIDTH, GUI_HEIGHT))
        self.image.fill(GUI_COLOR)
        self.rect = self.image.get_rect()

    #TODO
    def add_btn(self):
        pass

    def draw(self):
        self.screen.blit(self.image, self.rect)

class ToolBtns(pg.sprite.Sprite):

    def __init__(self, app, base, hover_image, clicked_image, x, y, tool_type: Tools):
        self.groups = app.tool_buttons
        pg.sprite.Sprite.__init__(self, self.groups)
        self.gui_surface = app.gui.image
        self.gui_rect = app.gui.rect
        self.screen = app.screen

        self.base_image = base
        self.hover_image = hover_image
        self.clicked_image = clicked_image

        self.tool_type = tool_type

        self.x = x
        self.y = y
        
        self.image = self.base_image
        self.rect = self.base_image.get_rect()
        self.rect.x = self.gui_rect.x + x
        self.rect.y = self.gui_rect.y + y
        
        self.hovered = False
        self.clicked = False

    def update(self):
        if self.hovered:
            self.image = self.hover_image
        if self.clicked:
            self.image = self.clicked_image
        else:
            self.image = self.base_image
        self.rect = self.image.get_rect()
        self.rect.x = self.gui_rect.x + self.x
        self.rect.y = self.gui_rect.y + self.y

उपकरण फ़ाइल

from enum import Enum, auto

class Tools(Enum):

    pencil = auto()
    eraser = auto()

सेटिंग्स फ़ाइल

# (R, G, B)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
DARKGREY = (129, 129, 129)
LIGHTGREY = (190, 190, 190)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)

TITLE = "Pyx"
WIDTH = 1400
HEIGHT = 1400
TILESIZE = 32
FPS = 60

GUI_WIDTH = 100
GUI_HEIGHT = 100
GUI_COLOR = (222, 222, 222)

CANVAS_WIDTH = TILESIZE * TILESIZE
CANVAS_HEIGHT = TILESIZE * TILESIZE
CANVAS_X = int(WIDTH * 0.5)
CANVAS_Y = int(HEIGHT * 0.5)
SCREEN_COLOR = DARKGREY
GRID_COLOR = LIGHTGREY 

# ICONS
PENCIL_ICON = 'pencil_icon.png'
PENCIL_HOVER = 'pencil_icon_hover.png'
PENCIL_CLICKED = 'pencil_icon_clicked.png'
ERASER_ICON = 'eraser_icon.png'
ERASER_HOVER = 'eraser_icon_hover.png'
ERASER_CLICKED = 'eraser_icon_clicked.png'

मैं सिर्फ प्रकाशित किया गया था सभी अपने कोड है, क्योंकि यह splitted में कई फ़ाइलों और मैं नहीं करना चाहते हैं कुछ भी याद आती है महत्वपूर्ण है. मुझे आशा है कि यह बहुत ज्यादा नहीं है.

धन्यवाद

pygame python
2021-11-22 21:31:56
1

सबसे अच्छा जवाब

2

आप आकर्षित करने के लिए है एक आयत में पृष्ठभूमि रंग (सफेद) अगर "स्थिति" गलत है और क्षेत्र में मिट जाता है:

class Canvas:
   
    # [...]

    def draw_pixel(self, canvas_data):
        """ Draws pixels on the screen """

        for row, data in enumerate(canvas_data):
            for col, px in enumerate(data):
                if px:
                    color = px["color"] if px["status"] else (255, 255, 255)
                    rect = pg.Rect(row * self.app.tile_size, col * self.app.tile_size, self.app.tile_size, self.app.tile_size)
                    pg.draw.rect(self.image, color, rect) 
                    
2021-11-22 21:55:36

मैं के रूप में एक ही परिणाम के साथ मेरे कोड :/
WhiteHeadbanger

ओह, नहीं, मैं सिर्फ भूल को मिटा करने के लिए if px["status"] लाइन! इस आकर्षण की तरह काम किया! धन्यवाद Rabbid :)
WhiteHeadbanger

अन्य भाषाओं में

यह पृष्ठ अन्य भाषाओं में है

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

इस श्रेणी में लोकप्रिय

लोकप्रिय सवाल इस श्रेणी में