2016-12-27 138 views
0

目标:知道什么时候一个精灵点击/主动用鼠标如何检测鼠标和精灵之间的碰撞/鼠标悬停?

使用:Python的3.2 64位,pygame的1.92 64位,64位Windows 7

我花了6个小时无果......我尝试:

s.rect.collidepoint(pygame.mouse.get_pos()) 
s.collidepoint(pygame.mouse.get_pos()) 
s.sprite.spritecollide(pygame.mouse.get_pos()) 
s.spritecollide(pygame.mouse.get_pos()) 
s.sprite.collide_rect(pygame.mouse.get_pos()) 
s.collide_rect(pygame.mouse.get_pos()) 

我也试着转动鼠标的位置,我真的不想做,就像是有人在这里提到的其他在另一个岗位,为雪碧和碰撞一样,具有相同的结果; (

我能够succ essfully鼠标与图像相撞,但只要我把图像变成一个精灵类,它就成了一场噩梦......精灵类有什么问题?或者我是在浪费时间试图使用精灵来制作漂亮的碰撞特征,而只是使用rect碰撞的图像呢?

保持于获取AttributeError的: '谢尔顿' 对象没有属性 '矩形'(s.Rect.collidepoint) 或AttributeError的: '元组' 对象没有属性 'collidepoint'(s.collidepoint) 或AttributeError的: 'Rake'对象没有属性'sprite'(s.sprite.collidepoint)

由于我是python/pygame的新手,我应该将这个检测放在Sprite类本身的Update/Render方法中,或者我使用错误的事件轮询?

我没有打扰试图重新编码鼠标按下/上/拖动,因为我甚至无法获得鼠标悬停到

希望这一次的工作后得到一个工作响应......别人没“T;(

感谢您的帮助

代码:

import pygame 
from pygame import * 
from pygame.locals import * 
from pygame.sprite import * 

class Sheldon(Sprite): 
    def __init__(self): 
     Sprite.__init__(self) 
     self.image = transform.scale(image.load('sheldon.jpg').convert(),(230,310)) 
     self.rect = self.image.get_rect() 

class Rake(Sprite): 
    def __init__(self): 
     Sprite.__init__(self) 
     self.image = transform.scale(image.load('rake.jpg').convert(),(230,310)) 
     self.rect = self.image.get_rect() 

class Sprite_Mouse_Location(Sprite): 
    def __init__(self,x,y): 
     Sprite.__init__(self) 
     self.rect = pygame.Rect(x,y,1,1) 
     print(self.rect) 

pygame.init() 
window = display.set_mode((800,600)) 
sheldon = Sheldon() 
sheldon.rect = (10,10) 
all_sprites = Group(sheldon) 
rake = Rake() 
rake.rect = (400,250) 
all_sprites.add(rake) 
x,y = pygame.mouse.get_pos() 
mouse_sprite = Sprite_Mouse_Location(x,y) 
running = True 

while running == True: 
    for event in pygame.event.get(): 
     if event.type == QUIT or event.type == KEYUP and event.key == K_ESCAPE : 
      pygame.quit() 

     elif event.type == MOUSEMOTION : 
      for s in all_sprites : 
       if pygame.sprite.collide_rect(s,mouse_sprite): 
        print("hit") 

    window.fill((0,0,0)) 
    all_sprites.update() 
    all_sprites.draw(window) 
    display.update() 
+0

你必须使用[pygame.Rect()](http://www.pygame.org/docs/ref/rect.html) – furas

+0

我没有,但它不工作要么,但也许我有使用元组而不是(x,y,w,h)?我再次尝试self.rect.collidepoint(x,y),但仍然无法让它工作...反正它现在是固定的;) –

回答

0

你不需要Sprite_Mouse_Location

BTW:设置位置,你需要

rake.rect.topleft = (400, 250) 

# or 

rake.rect.x = 400 
rake.rect.y = 250 

rake.rect = (400, 250) 

,因为它与tuple


示例代码替换pygame.Rect()

我使用Surface而不是image.load(),因此每个人都可以在没有图像的情况下运行它。

import pygame 

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

BLACK = (0, 0, 0) 
RED = (255, 0, 0) 
GREEN = (0, 255, 0) 

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

class Sheldon(pygame.sprite.Sprite): 

    def __init__(self, x, y): 
     pygame.sprite.Sprite.__init__(self) 

     self.image = pygame.Surface((230, 310)) 
     self.image.fill(RED) 

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

    def check_click(self, mouse): 
     if self.rect.collidepoint(mouse): 
      print("hit RED") 

class Rake(pygame.sprite.Sprite): 

    def __init__(self, x, y): 
     pygame.sprite.Sprite.__init__(self) 

     self.image = pygame.Surface((230, 310)) 
     self.image.fill(GREEN) 

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

    def check_click(self, mouse): 
     if self.rect.collidepoint(mouse): 
      print("hit GREEN") 

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

# - init - 

pygame.init() 
window = pygame.display.set_mode((800,600)) 

# - objects - 

sheldon = Sheldon(10, 10) 
#sheldon.rect.topleft = (10, 10) 

rake = Rake(400, 250) 
#rake.rect.topleft = (400, 250) 

all_sprites = pygame.sprite.Group() 
all_sprites.add(sheldon, rake) 

# - mainloop - 

running = True 

while running: 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT or \ 
      (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE): 
      running = False 

     elif event.type == pygame.MOUSEBUTTONDOWN: 
      for s in all_sprites: 
       s.check_click(event.pos) 

    window.fill(BLACK) 
    all_sprites.update() 
    all_sprites.draw(window) 
    pygame.display.update() 

# - end -  

pygame.quit() 
+0

谢谢......我将验证它对我来说是否适用于后者...... –

+0

谢谢......对我更好......我希望我可以直接做一个跟进问题来优化这里的另一个问题 –

0

有很多的事情,与你的代码怎么回事编码可以在冷杉很难。吨,但要坚持!只要你不断尝试,不要放弃,你会更好!你的错误发生是因为循环上面,你正在设置你的各种精灵的矩形变量为元组而不是矩形。 Rects不是元组,它们有一些元组没有的变量,而collide_rect需要一些变量。我在下面的代码中提出了一些关于其他问题的评论。

import pygame 
from pygame import * 
from pygame.locals import * 
from pygame.sprite import * 

class Sheldon(Sprite): 
    def __init__(self): 
     Sprite.__init__(self) 
     self.image = transform.scale(image.load('sheldon.jpg').convert(),(230,310)) 
     self.rect = self.image.get_rect() 

class Rake(Sprite): 
    def __init__(self): 
     Sprite.__init__(self) 
     self.image = transform.scale(image.load('rake.jpg').convert(),(230,310)) 
     self.rect = self.image.get_rect() 

class Sprite_Mouse_Location(Sprite): 
    def __init__(self,x,y): 
     Sprite.__init__(self) 
     self.rect = pygame.Rect(x,y,1,1) 
     print(self.rect) 

pygame.init() 
window = display.set_mode((800,600)) 
sheldon = Sheldon() 
sheldon.rect = (10,10) # (10,10) is not a rect! 
         # pygame.Rect(0,0,10,10) is a rect! 
all_sprites = Group(sheldon) 
rake = Rake() 
rake.rect = (400,250) # Same as above comment. 
all_sprites.add(rake) 
x,y = pygame.mouse.get_pos()    # If you are going to make the mouse 
mouse_sprite = Sprite_Mouse_Location(x,y) # a sprite, then update your mouse position in the loop. 
running = True 

while running == True: 
    for event in pygame.event.get(): 
     if event.type == QUIT or event.type == KEYUP and event.key == K_ESCAPE : 
      pygame.quit() 

     elif event.type == MOUSEMOTION : 
      # You could have this instead. 
      # mouse_sprite.rect.x, mouse_sprite.rect.y = pygame.mouse.get_pos() 
      # Then move the for loop below to be out of the event loop. 

      for s in all_sprites : 
       if pygame.sprite.collide_rect(s,mouse_sprite): 
        print("hit") 

    window.fill((0,0,0)) 
    all_sprites.update() 
    all_sprites.draw(window) 
    display.update() 

我也建议通过pygame tutorial会以及看其他人的pygame的代码,并试图逐行理解。这些提示都帮助我。祝你好运。

+0

dooo ...好的谢谢...我错过了rects的东西.. 。从来没有得到元组术语的权利......让我看看这是否能解决它...我不能相信我昨天晚上有sprite图层去工作;)感谢鼓励...我会检查出那个tut列表看看我是否错过了任何... 25在我的桌面上的python/pygame图书,并没有一点帮助,当涉及到自己编程... –

+0

感谢alanxoc3和新的一天,我得到它的工作...我在这里插入代码非常困难,必须多次执行。 –

+0

好吧我正在尝试发布解决方案: –

0

感谢alanxoc3,新的一天,代码在这里工作 发帖,因为我敢肯定,另一个新手会想要做这种类型的点击鼠标

# to create a group of sprites and use the mouse over them individually 
import pygame 
from pygame import * 
from pygame.locals import * 
from pygame.sprite import * 

class Sheldon(Sprite): 
    def __init__(self): 
     pygame.sprite.Sprite.__init__(self,self.groups) #have to have groups here, not documented well 
     self.image = transform.scale(image.load('sheldon.jpg').convert(),(230,310)) 
     self.rect = self.image.get_rect() 

    def clickCheck(self,smouse): 
     if pygame.sprite.collide_rect(smouse, self): #could not use sritecollison because it would flag whole group 
      print('hit sheldon') # this if the check mouse that its working 
#------------------------------------------ 
class Rake(Sprite): 
    def __init__(self): 
     pygame.sprite.Sprite.__init__(self,self.groups) 
     self.image = transform.scale(image.load('rake.jpg').convert(),(230,310)) 
     self.rect = self.image.get_rect() 

    def clickCheck(self,smouse): 
     if pygame.sprite.collide_rect(smouse, self): 
      print('hit rake') 
#-------------------------------------------   
class Sprite_Mouse_Location(Sprite): 
    def __init__(self): 
     pygame.sprite.Sprite.__init__(self) 
     self.rect = pygame.Rect(0 , 0 , 1 , 1) # no updating needed here 
#--------------------------------------------   
pygame.init() 
window = display.set_mode((800,600)) 
mouse_sprite = Sprite_Mouse_Location() # had to create a mouse as sprite to use the sprite collision feature 
all_sprites = pygame.sprite.Group() # have to declare first, no well documented 
Sheldon.groups = all_sprites  # better than all_sprites = Group(sheldon), and can be assigned before instantiation of sheldon!!! 
sheldon = Sheldon() 
sheldon.rect = (10,10,230,310) 
Rake.groups = all_sprites 
rake = Rake() 
rake.rect = (400,250,230,310) 
running = True 

while running == True: 

    for event in pygame.event.get(): 

     if event.type == QUIT or event.type == KEYUP and event.key == K_ESCAPE : 
      pygame.quit() 

     elif event.type == MOUSEBUTTONDOWN: 
      if event.button == 1: 
       mouse_sprite.rect.x , mouse_sprite.rect.y = pygame.mouse.get_pos() # have to have this to update mouse here or get wrong location 
       for s in all_sprites: #can't have outside the event or it will continuously check 
        s.clickCheck(mouse_sprite) 

    window.fill((0,0,0)) 
    all_sprites.update() # have to have this for group sprites 
    all_sprites.draw(window) # have to have this for sprites 
    display.flip()