在Pygame中将一条线作为精灵与自己的碰撞 [英] Make a line as a sprite with its own collision in Pygame

查看:62
本文介绍了在Pygame中将一条线作为精灵与自己的碰撞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一款将2个玩家之间的直线连接起来的游戏.我要这样做,以便我可以分辨出一个对象(也是一个精灵)何时与直线碰撞.

我想到的方法是创建一条充当精灵的线.这条线将能够根据球员的位置改变长度.

我对PyGame有点陌生,所以我不太确定目前为止:

  class Line(pygame.sprite.Sprite):def __init __():pygame.sprite.Sprite .__ init __(自己)self.image = pygame.Surface([400,400])self.image.set_colorkey((0,0,0))self.rect = self.image.get_rect()self.rect.x = 0self.rect.y = 0pygame.draw.line(屏幕,(0,0,255),(0,0),(400,400),2) 

注意:一个

 导入数学导入pygame类SpriteObject(pygame.sprite.Sprite):def __init __(self,x,y,image):super().__ init __()self.image =图片self.rect = self.image.get_rect(center =(x,y))self.mask = pygame.mask.from_surface(self.image)def更新(自己):self.rect.center = pygame.mouse.get_pos()Line(pygame.sprite.Sprite)类:def __init __(self,x,y):super().__ init __()self.image = pygame.Surface((200,200))self.image.set_colorkey((0,0,0))self.rect = self.image.get_rect(center =(x,y))self.angle = 0def更新(自己):vec =圆(math.cos(self.angle * math.pi/180)* 100),圆(math.sin(self.angle * math.pi/180)* 100)self.angle =(self.angle +1)%360self.image.fill(0)pygame.draw.line(self.image,(255,255,0),(100-vec [0],100-vec [1]),(100 + vec [0],100 + vec [1]),5)self.mask = pygame.mask.from_surface(self.image)pygame.init()窗口= pygame.display.set_mode((500,500))时钟= pygame.time.Clock()sprite_image = pygame.image.load('AirPlane.png').convert_alpha()moving_object = SpriteObject(0,0,sprite_image)line_object = Line(* window.get_rect().center)all_sprites = pygame.sprite.Group([moving_object,line_object])红色= 0运行=真运行时:clock.tick(60)对于pygame.event.get()中的事件:如果event.type == pygame.QUIT:运行=错误all_sprites.update()如果pygame.sprite.collide_mask(moving_object,line_object):红色=最小值(255,红色+4)别的:红色= 0window.fill((红色,0,0))all_sprites.draw(窗口)pygame.display.flip()pygame.quit()出口() 

I am making a game that connects a line between a 2 players. I want to make it so I can tell when an object (which is also a sprite) collides with the line.

The way I thought of doing this is creating a line that acts a sprite. The line will be able to change length depending on where the players are.

I'm a bit new to PyGame so I'm not too sure on what I have so far:

class Line(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface([400,400])
        self.image.set_colorkey((0,0,0))
        self.rect = self.image.get_rect()
        self.rect.x = 0
        self.rect.y = 0
        pygame.draw.line(screen,(0,0,255),(0,0),(400,400),2)

NOTE: A similar post to this already exists, however, what the person is asking in that post is different than in this post. The general idea may be the same, but I'd like to know a simpler way.

解决方案

I recommend to test the collision with bit masks. See How can I made a collision mask? and the documentation of pygame.sprite.collide_mask():

Collision detection between two sprites, using masks.

collide_mask(SpriteLeft, SpriteRight) -> point

Tests for collision between two sprites, by testing if their bitmasks overlap. If the sprites have a "mask" attribute, that is used as the mask, otherwise a mask is created from the sprite image. Intended to be passed as a collided callback function to the *collide functions. Sprites must have a "rect" and an optional "mask" attribute.

All you have to do is add a mask attribute to the Sprites classes. Use pygame.mask.from_surface to creates a Mask from the given Surface:

class Line(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface([400, 400])
        self.image.set_colorkey((0, 0, 0))
        self.rect = self.image.get_rect()
        self.rect.x = 0
        self.rect.y = 0
        pygame.draw.line(screen, (0, 0, 255), (0, 0 ), (400, 400), 2)

        self.mask = pygame.mask.from_surface(self.image)

Use pygame.sprite.collide_mask() to detect the collision between 2 Sprites with a Mask:

class SpriteObject(pygame.sprite.Sprite):
    def __init__(self, x, y, image):
        super().__init__()
        self.image = image
        self.rect = self.image.get_rect(center = (x, y))
        self.mask = pygame.mask.from_surface(self.image)

other_sprite = SpriteObject(0, 0, sprite_image)
line_sprite = Line(*window.get_rect().center)

if pygame.sprite.collide_mask(line_sprite, other_sprite):
    print("hit")

See also Sprite mask


Minimal example:

import math
import pygame

class SpriteObject(pygame.sprite.Sprite):
    def __init__(self, x, y, image):
        super().__init__()
        self.image = image
        self.rect = self.image.get_rect(center = (x, y))
        self.mask = pygame.mask.from_surface(self.image)
    def update(self):
        self.rect.center = pygame.mouse.get_pos()

class Line(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((200, 200))
        self.image.set_colorkey((0, 0, 0))
        self.rect = self.image.get_rect(center = (x, y))
        self.angle = 0
    def update(self):
        vec = round(math.cos(self.angle * math.pi / 180) * 100), round(math.sin(self.angle * math.pi / 180) * 100)
        self.angle = (self.angle + 1) % 360
        self.image.fill(0)
        pygame.draw.line(self.image, (255, 255, 0), (100 - vec[0], 100 - vec[1]), (100 + vec[0], 100 + vec[1]), 5)
        self.mask = pygame.mask.from_surface(self.image)
        
pygame.init()
window = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()

sprite_image = pygame.image.load('AirPlane.png').convert_alpha()
moving_object = SpriteObject(0, 0, sprite_image)
line_object = Line(*window.get_rect().center)
all_sprites = pygame.sprite.Group([moving_object, line_object])
red = 0

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
 
    all_sprites.update()

    if pygame.sprite.collide_mask(moving_object, line_object):
        red = min(255, red+4)
    else: 
        red = 0

    window.fill((red, 0, 0))
    all_sprites.draw(window)
    pygame.display.flip()

pygame.quit()
exit()

这篇关于在Pygame中将一条线作为精灵与自己的碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆