pygame中面具之间的碰撞 [英] Collision between masks in pygame

查看:75
本文介绍了pygame中面具之间的碰撞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在游戏中遇到碰撞问题,飞船的面具与背景没有正确碰撞,我认为偏移是一个问题,但是我不确定.

我尝试了多种碰撞技术,并检查了很多解决问题的答案,但没有一个能帮助我.

 将pygame导入为pg导入操作系统os.environ ['SDL_VIDEO_WINDOW_POS'] =%d,%d"%(2,29)pg.init()def gameLoop():display_width = 1800display_height = 1000pg.display.set_caption("Kerbal Space Landing Simulator")时钟= pg.time.Clock()display = pg.display.set_mode((display_width,display_height))sprsp = pg.image.load('C:/Users/PC/PycharmProjects/untitled/sprspaceship.png').convert_alpha()cosbg = pg.image.load('C:/Users/PC/PycharmProjects/untitled/cosmos bg.png').convert_alpha()完成=错误宇宙飞船:def __init __(self,x,y,mass):self.x = xself.y = yself.width = 139self.height = 106self.velx = 0self.vely = 0self.mass =质量self.color =(255,255,255)self.spr = sprsp自燃= 500self.mask = pg.mask.from_surface(self.spr)self.angle = 0self.changerot = 0def check_controls():如果键[pg.K_SPACE]和self.fuel>0:如果self.angle>0:self.vely + = 0.005 *(self.angle-90)self.velx + = -0.005 * self.angle别的:self.vely + = -0.005 *(self.angle + 90)self.velx + = -0.005 * self.angleself.fuel + = -3if keys [pg.K_LEFT]和self.angle<90:self.angle + = 2如果键[pg.K_RIGHT]和self.angle>-90:self.angle + = -2def update_pos():self.vely + = 0.01self.x + = self.velxself.y + = self.velyself.mask = pg.mask.from_surface(self.spr)def update_rotation():self.rspr = pg.transform.rotate(self.spr,self.angle)self.changerot-= self.angledef draw():如果自燃>0:pg.draw.rect(display,(255,255,255),(display_width-100,100 + 500-self.fuel,10,self.fuel),0)display.blit(self.rspr,(int(self.x),int(self.y)))self.changerot = 0地形(对象)类:def __init __(self,x,y):self.x = xself.y = yself.mask = pg.mask.from_threshold(display,(160,160,160))self.hitbox = pg.Rect(self.x,self.y,display_width,500)self.ox = display_width//2-self.x//2self.oy = display_height//2-self.y//2def draw():pg.draw.rect(display,(160,160,160),(self.x,self.y,display_width,500),0)飞船=(飞船(500,100,1))地形=(地形(0,800))def redrawGameWindow():display.blit(cosbg,(0,0))spaceship.draw()terrain.draw()pg.display.update()def check_for_collisions():偏移量=(int(spaceship.x -terrain.ox),int(spaceship.y -terrain.oy))打印(胶印)打印(spaceship.mask.overlap(terrain.mask,偏移量))返回spaceship.mask.overlap(terrain.mask,偏移量)#返回spaceship.hitbox.colliderect(terrain.hitbox)#返回pg.sprite.spritecollide(spaceship.spr,terrain.mask,False,pg.sprite.collide_mask)未完成时:对于pg.event.get()中的事件:如果event.type == pg.QUIT:完成=正确键= pg.key.get_pressed()mouse_pressed = pg.mouse.get_pressed()x,y = pg.mouse.get_pos()spaceship.check_controls()spaceship.update_pos()spaceship.update_rotation()如果check_for_collisions()不为None:打印(命中!您已经以速度:"飞船,vely.vely着陆了)出口()redrawGameWindow()clock.tick(60)gameLoop() 

宇宙飞船不与表面碰撞.我知道如何使用更简单的代码修复它,但将来我想使用随机生成的地形.您能帮我解决这些冲突吗?

解决方案

从未设置 Terrain 的掩码.创建适当的地形蒙版:

  class Terrain(对象):def __init __(self,x,y):self.x = xself.y = ymaskSurf = pg.Surface((display_width,display_height)).convert_alpha()maskSurf.fill(0)pg.draw.rect(maskSurf,(160,160,160),(self.x,self.y,display_width,500),0)self.mask = pg.mask.from_surface(maskSurf)打印(self.mask.count())#[...] 

使用

另请参见:面具

I have a problem with collisions in my game, spaceship's mask doesn't collide properly with a background and I believe that offset is a problem, however I'm not sure.

I've tried multiple collision techniques and checked a lot of answers to my problem, but none of them helped me.

import pygame as pg
import os

os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (2, 29)

pg.init()


def gameLoop():
    display_width = 1800
    display_height = 1000
    pg.display.set_caption("Kerbal Space Landing Simulator")
    clock = pg.time.Clock()
    display = pg.display.set_mode((display_width, display_height))
    sprsp = pg.image.load('C:/Users/PC/PycharmProjects/untitled/sprspaceship.png').convert_alpha()
    cosbg = pg.image.load('C:/Users/PC/PycharmProjects/untitled/cosmos bg.png').convert_alpha()
    done = False

class Spaceship:
    def __init__(self, x, y, mass):
        self.x = x
        self.y = y
        self.width = 139
        self.height = 106
        self.velx = 0
        self.vely = 0
        self.mass = mass
        self.color = (255, 255, 255)
        self.spr = sprsp
        self.fuel = 500
        self.mask = pg.mask.from_surface(self.spr)
        self.angle = 0
        self.changerot = 0

    def check_controls(self):
        if keys[pg.K_SPACE] and self.fuel > 0:
            if self.angle > 0:
                self.vely += 0.005 * (self.angle - 90)
                self.velx += -0.005 * self.angle
            else:
                self.vely += -0.005 * (self.angle + 90)
                self.velx += -0.005 * self.angle

            self.fuel += -3
        if keys[pg.K_LEFT] and self.angle < 90:
            self.angle += 2
        if keys[pg.K_RIGHT] and self.angle > -90:
            self.angle += -2

    def update_pos(self):
        self.vely += 0.01
        self.x += self.velx
        self.y += self.vely
        self.mask = pg.mask.from_surface(self.spr)

    def update_rotation(self):
        self.rspr = pg.transform.rotate(self.spr, self.angle)
        self.changerot -= self.angle

    def draw(self):
        if self.fuel > 0:
            pg.draw.rect(display, (255, 255, 255), (display_width - 100, 100 + 500 - self.fuel, 10, self.fuel), 0)
        display.blit(self.rspr, (int(self.x), int(self.y)))

        self.changerot = 0

class Terrain(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.mask = pg.mask.from_threshold(display, (160, 160, 160))
        self.hitbox = pg.Rect(self.x, self.y, display_width, 500)
        self.ox = display_width // 2 - self.x // 2
        self.oy = display_height // 2 - self.y // 2

    def draw(self):
        pg.draw.rect(display, (160, 160, 160), (self.x, self.y, display_width, 500), 0)

spaceship = (Spaceship(500, 100, 1))
terrain = (Terrain(0, 800))

def redrawGameWindow():
    display.blit(cosbg, (0, 0))
    spaceship.draw()
    terrain.draw()
    pg.display.update()

def check_for_collisions():
    offset = (int(spaceship.x - terrain.ox), int(spaceship.y - terrain.oy))
    print(offset)
    print(spaceship.mask.overlap(terrain.mask, offset))
    return spaceship.mask.overlap(terrain.mask, offset)
    # return spaceship.hitbox.colliderect(terrain.hitbox)
    # return pg.sprite.spritecollide(spaceship.spr, terrain.mask, False, pg.sprite.collide_mask)

while not done:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            done = True

    keys = pg.key.get_pressed()
    mouse_pressed = pg.mouse.get_pressed()
    x, y = pg.mouse.get_pos()

    spaceship.check_controls()
    spaceship.update_pos()
    spaceship.update_rotation()
    if check_for_collisions() is not None:
        print('Hit! You\'ve hit the ground with the speed:', spaceship.vely)
        exit()

    redrawGameWindow()
    clock.tick(60)

gameLoop()

Spaceship doesn't collide with the surface. I know how to fix it using simpler code, but in future I want to use randomly generated terrain. Could you help me with these collisions?

解决方案

The mask for the Terrain is never set. Crate a proper Terrain mask:

class Terrain(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
        maskSurf = pg.Surface((display_width, display_height)).convert_alpha()
        maskSurf.fill(0)
        pg.draw.rect(maskSurf, (160, 160, 160), (self.x, self.y, display_width, 500), 0)
        self.mask = pg.mask.from_surface(maskSurf)
        print(self.mask.count())
 
        # [...]

When using pygame.mask.Mask.overlap(), then you've to check the overlapping of the Spaceship and the Terrain, rather than the Terrain and the Spaceship.
Since the Terrain mask is a mask of the entire screen, the offset for the overlap() test is the position of the Spaceship:

def check_for_collisions():
    offset = (int(spaceship.x), int(spaceship.y))
    collide = terrain.mask.overlap(spaceship.mask, offset)
    print(offset, collide)
    return collide


Minimal example:

See also: Mask

这篇关于pygame中面具之间的碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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