2017-07-16 62 views
1

我的遊戲是一個簡單的拖放式遊戲,你只需要在其各自的類別中放置一個術語。總共有50個術語可以拖放到背景圖像中顯示的4個類別中。 我很沮喪。我無法找到一個問題/教程來簡單地讓文本框拖動並放置在背景圖像的區域中。 我想做50個術語,用戶可以簡單地在屏幕上拖放。如何在pygame中製作許多可移動的文本框?

我該如何製作多個盒子並向它們添加鼠標事件? 我具有低於下面的代碼:

import pygame 
from pygame.locals import * 

# --- constants --- (UPPER_CASE names) 

DISPLAY_WIDTH = 1720 
DISPLAY_HEIGHT = 1000 
DISPLAY_SIZE = (DISPLAY_WIDTH, DISPLAY_HEIGHT) 
BLACK = (0,0,0) 

ANSWERS_WIDTH = 1500 
ANSWERS_HEIGHT = 750 
ANSWERS_SIZE = (ANSWERS_WIDTH, ANSWERS_HEIGHT) 

# --- classes --- (CamelCase names) 

class Button: 
    def __init__(self, text): 
     self.text = text 
     self.is_hover = False 
     self.default_color = (100,100,100) 
     self.hover_color = (255,255,255) 
     self.font_color = (0,0,0) 
     self.obj = None 

    def label(self): 
     '''button label font''' 
     font = pygame.font.Font(None, 20) 
     return font.render(self.text, 1, self.font_color) 

    def color(self): 
     '''change color when hovering''' 
     if self.is_hover: 
      return self.hover_color 
     else: 
      return self.default_color 

    def draw(self, screen, mouse, rectcoord, labelcoord): 
     '''create rect obj, draw, and change color based on input''' 
     self.obj = pygame.draw.rect(screen, self.color(), rectcoord) 
     screen.blit(self.label(), labelcoord) 

     #change color if mouse over button 
     self.check_hover(mouse) 

    def check_hover(self, mouse): 
     '''adjust is_hover value based on mouse over button - to change hover color''' 
     if self.obj.collidepoint(mouse): 
      self.is_hover = True 
     else: 
      self.is_hover = False 

    #def openWin(self, event): 
    # if event.type == pygame.MOUSEBUTTONDOWN: 
     #  if self.obj.collidepoint(event.pos): 


class Enemy(pygame.sprite.Sprite): 

    def __init__(self, dx, dy, filename): 
     pygame.sprite.Sprite.__init__(self) 

     self.image = pygame.image.load(filename).convert() 

     self.rect = self.image.get_rect() 
     self.rect.x = dx 
     self.rect.y = dy 

     # - or shorter - 
     #self.rect = self.image.get_rect(x=dx, y=dy) 

     self.moving_left = False 
     self.moving_right = False 
     self.moving_up = False 
     self.moving_down = False 

     self.click = False 

    def update(self): 
     if self.moving_left: 
      self.rect.x -= 10 
     if self.moving_right: 
      self.rect.x += 10 
     if self.moving_up: 
      self.rect.y -= 10 
     if self.moving_down: 
      self.rect.y += 10 

     if self.click: 
      self.rect.center = pygame.mouse.get_pos() 

    def handle_event(self, event): 
     if event.type == pygame.KEYDOWN: 
      if event.key == pygame.K_LEFT: 
       self.moving_left = True 
      elif event.key == pygame.K_RIGHT: 
       self.moving_right = True 
      elif event.key == pygame.K_UP: 
       self.moving_up = True 
      elif event.key == pygame.K_DOWN: 
       self.moving_down = True 
     elif event.type == pygame.KEYUP: 
      if event.key == pygame.K_LEFT: 
       self.moving_left = False 
      elif event.key == pygame.K_RIGHT: 
       self.moving_right = False 
      elif event.key == pygame.K_UP: 
       self.moving_up = False 
      elif event.key == pygame.K_DOWN: 
       self.moving_down = False 

    def mouse_event(self, event): 
     if event.type == pygame.MOUSEBUTTONDOWN: 
      if self.rect.collidepoint(event.pos): 
       self.click = True 
     elif event.type == pygame.MOUSEBUTTONUP: 
      self.click = False 

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

# --- fuctions --- (lower_case names) 

    # empty 

# --- main --- (lower_case names) 

# - init - 

pygame.init() 

screen = pygame.display.set_mode(DISPLAY_SIZE,HWSURFACE|DOUBLEBUF|RESIZABLE) 
screen2 = pygame.display.set_mode(ANSWERS_SIZE,HWSURFACE|DOUBLEBUF|RESIZABLE) 

# - objects - 

background_image = pygame.image.load("back.png").convert() 
#button_to_answers = pygame.image.load("basketball.png").convert() 

btn = Button('Button 1') 
btn1 = Button('Button 2') 


enemy = Enemy(100,400, 'hinatest.jpg') 
enemy2 = Enemy(200,200, 'Sora.png') 
enemy3 = Enemy(300,100, 'naruto.png') 
enemy4 = Enemy(500,000, 'Ichigo.jpg') 

# - mainloop - 

clock = pygame.time.Clock() 

gameplay = True 

while gameplay: 

    # - events - 
    mouse = pygame.mouse.get_pos() 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      gameplay = False 
     elif event.type == pygame.KEYDOWN: 
      if event.key == pygame.K_ESCAPE: 
       gameplay = False 

     #elif event.type == pygame.MOUSEBUTTONDOWN: 
     # if btn.obj.collidepoint(mouse): 
      #  print('button 1 clicked') 
      # screen2.blit(pygame.transform.scale(button_to_answers, (1500,720)), (0,0)) 
      # pygame.display.flip() 

     elif event.type==VIDEORESIZE: 
      screen = pygame.display.set_mode(event.dict['size'],HWSURFACE|DOUBLEBUF|RESIZABLE) 
      screen.blit(pygame.transform.scale(background_image,event.dict['size']),(0,0)) 
      pygame.display.flip() 

      display_coordinates = pygame.display.Info() 
      print('current_w = ', display_coordinates.current_w, '\ncurrent_h = ', display_coordinates.current_h, '\n') 

     # - objects event handle - 
     enemy.mouse_event(event) 
     enemy2.mouse_event(event) 
     enemy3.mouse_event(event) 
     enemy4.mouse_event(event) 

    # - updates - 

    enemy.update() 
    enemy2.update() 
    enemy3.update() 
    enemy4.update() 

    # - draws - 

    screen.blit(pygame.transform.scale(background_image, (1720,1000)), (0,0)) 

    btn.draw(screen, mouse, (100,100,100,20), (125,103)) 

    enemy.draw(screen) 
    enemy2.draw(screen) 
    enemy3.draw(screen) 
    enemy4.draw(screen) 
    pygame.display.flip() 

    # - FPS - 

    clock.tick(60) 

    screen.fill(BLACK) 
# - exit - 

pygame.quit() 
+0

請注意,由於我在我的圖像中使用了圖像,您將無法運行代碼。您可以簡單地停用正在更新的圖像以便簡單地運行它,或者使用庫存圖像替換它們以使用拖動功能。 – supahoopa95

+0

您的代碼示例非常長。更好地將其減小到[最小值](https://stackoverflow.com/help/mcve),但要確保它仍然可以執行。 – skrx

+0

謝謝@skrx – supahoopa95

回答

0

創建用於文本對象的一類,將其image到表面FONT.render返回並定義一個變量selected保持當前選擇的文本子圖形。

現在檢查鼠標是否與事件循環中的文本精靈發生衝突,如果是,則將其分配給selected變量。如果發生pygame.MOUSEMOTION事件,請將selected.rect.center設置爲新的event.pos。完成。

import sys 
import pygame as pg 


pg.init() 
FONT = pg.font.Font(None, 42) 


class Text(pg.sprite.Sprite): 

    def __init__(self, text, pos, color, *groups): 
     super().__init__(*groups) 
     self.image = FONT.render(text, True, color) 
     self.rect = self.image.get_rect(center=pos) 


def main(): 
    screen = pg.display.set_mode((640, 480)) 
    clock = pg.time.Clock() 
    all_sprites = pg.sprite.Group(
     Text('hello', (100, 300), pg.Color('steelblue1')), 
     Text('world', (250, 300), pg.Color('sienna1')), 
     ) 

    selected = None 
    done = False 

    while not done: 
     for event in pg.event.get(): 
      if event.type == pg.QUIT: 
       done = True 
      elif event.type == pg.MOUSEBUTTONDOWN: 
       for sprite in all_sprites: 
        if sprite.rect.collidepoint(event.pos): 
         selected = sprite 
         break 
      elif event.type == pg.MOUSEBUTTONUP: 
       selected = None 
      elif event.type == pg.MOUSEMOTION: 
       if selected: 
        selected.rect.center = event.pos 

     all_sprites.update() 
     screen.fill((30, 30, 30)) 
     all_sprites.draw(screen) 

     pg.display.flip() 
     clock.tick(30) 


if __name__ == '__main__': 
    main() 
    pg.quit() 
    sys.exit() 
+1

這是比我更簡單的方式。很簡單!非常高效,謝謝! – supahoopa95