为了账号安全,请及时绑定邮箱和手机立即绑定

Pygame Wall Sprite Collision

Pygame Wall Sprite Collision

幕布斯6054654 2022-08-02 18:16:47
我正在制作一个类似Rogue的游戏,但在编码方面我是初学者。我已经有我的角色移动,我的墙壁和地板精灵,但我的代码中有一些错误,允许角色在墙壁中移动。我用它来在地板和墙砖之间进行选择,我试图用它来识别墙壁,但它并没有真正起作用。block_path接下来,您可以看到我的代码:screenWidth = 800screenHeight = 600mapHeight = 30mapWidth = 30cellWidth = 32cellHeight = 32screen = pygame.display.set_mode((screenWidth, screenHeight))walkRight = [pygame.image.load('model/r1.png'), pygame.image.load('model/r2.png'), pygame.image.load('model/r3.png'), pygame.image.load('model/r4.png'), pygame.image.load('model/r5.png'), pygame.image.load('model/r6.png')]walkLeft = [pygame.image.load('model/l1.png'), pygame.image.load('model/l2.png'), pygame.image.load('model/l3.png'), pygame.image.load('model/l4.png'), pygame.image.load('model/l5.png'), pygame.image.load('model/l6.png')]walkUp = [pygame.image.load('model/u1.png'), pygame.image.load('model/u2.png'), pygame.image.load('model/u3.png'), pygame.image.load('model/u4.png'), pygame.image.load('model/u5.png'), pygame.image.load('model/u6.png')]Floor = pygame.image.load("map/floor.jpg")wallRight = pygame.image.load("map/rightwall.png")`class struc_Tile():    def __init__(self,block_path):        self.block_path = block_path`class player(object):    def __init__(self,x,y,width,height):        self.x = x        self.y = y        self.width = width        self.height = height        self.vel = 5        self.left = False        self.right = False        self.up = False        self.down = False        self.walkCount = 0    def draw(self,screen):        if self.walkCount + 1 >= 18:            self.walkCount = 0        elif self.left:            screen.blit(walkLeft[self.walkCount//3], (self.x,self.y))            self.walkCount += 1        elif self.right:            screen.blit(walkRight[self.walkCount//3], (self.x,self.y))            self.walkCount += 1        elif self.up:            screen.blit(walkUp[self.walkCount//3], (self.x,self.y))            self.walkCount += 1        elif self.down:            screen.blit(walkDown[self.walkCount//3], (self.x,self.y))
查看完整描述

1 回答

?
呼啦一阵风

TA贡献1802条经验 获得超6个赞

将函数更改为类似这样的函数将在地图的钻孔上创建一个 5 像素的缓冲区。我之所以把它做成5像素,是因为这就是你的角色动作。createmap()


我建议加入一些实际的角色碰撞,以测试你是否无论速度如何都出界。


编辑:我已经包含了完整的代码,因为我所做的更改如果我显示它们,则更容易理解。


我已将您的图像列表更改为列表的字典,因为它们更容易以这种方式调用。您要求的网格是 30x30。由于您显示的单元格宽度为 32x32,因此我将地图更改为 960 x 960。


我已经扩展了您的移动方法以检查碰撞,以查看它是否可以在发生冲突之前移动。我还删除了您的函数,因为向下移动重绘更容易。如果您愿意,可以将其添加回去,但对于此示例,我将其删除。redraw()


import pygame


# Based on the paths in your image

# This should work for your image paths

image = pygame.image.load('model/standing1.png')

Standing = pygame.transform.scale(image, (32, 32))

image = pygame.image.load('map/floor.jpg')

Floor = pygame.transform.scale(image, (32, 32))

image = pygame.image.load('map/rightwall.png')

wallRight = pygame.transform.scale(image, (32, 32))


walkLeft = []

walkRight = []

walkUp = []

walkDown = []


for i in range(1, 19):

    image = pygame.image.load('model/r' + str(i) + '.png')

    walkRight.append(pygame.transform.scale(image, (32, 32)))


    image = pygame.image.load('model/l' + str(i) + '.png')

    walkLeft.append(pygame.transform.scale(image, (32, 32)))


    image = pygame.image.load('model/u' + str(i) + '.png')

    walkUp.append(pygame.transform.scale(image, (32, 32)))


    image = pygame.image.load('model/d' + str(i) + '.png')

    walkDown.append(pygame.transform.scale(image, (32, 32)))


class struc_Tile():

    def __init__(self, block_path):

        self.block_path = block_path


class player(object):

    def __init__(self,x,y,width,height):

        self.x = x

        self.y = y

        self.width = width

        self.height = height

        self.vel = 5

        self.walkCount = 0


        # do something like this with your images

        # if you keep your lists in a dict you can avoid

        # all your boolean direction variables and 

        # the lengthy if else statement

        self.images = {}

        self.images['walkleft'] = walkLeft[:]

        self.images['walkright'] = walkRight[:]

        self.images['walkup'] = walkUp[:]

        self.images['walkdown'] = walkDown[:]



    def draw(self, screen, direction):

        if self.walkCount + 1 >= 18:

            self.walkCount = 0


        # since standing is not in your dict check for that first

        if direction == 'standing':

            screen.blit(Standing, (self.x,self.y))

            self.walkCount = 0

        else:

            screen.blit(self.images[direction][self.walkCount], (self.x,self.y))

            self.walkCount += 1



    def can_move(self, dx, dy):

        # with the buffer created around the border of the map

        # you shouldn't have issues with

        # index out of bounds exceptions

        # EDIT: added better collision

        new_x = self.x + dx

        new_y = self.y + dy

        if gamemap[new_x][new_y].block_path == False:

            if gamemap[new_x + cellWidth][new_y].block_path == False:

                if gamemap[new_x][new_y + cellHeight].block_path == False:

                    if gamemap[new_x + cellWidth][new_y + cellHeight].block_path == False:

                        self.x += dx

                        self.y += dy

                        return True


def createmap():

    newmap = [[struc_Tile(False) for y in range(0, mapHeight)] for x in range (0,mapWidth)]


    # give our upper/left borders a cell width buffer

    # and our bottom/right borders a 2 cell width buffer

    # since blit uses the upper left corner this should account

    # for the sprite width

    # EDIT: Fixed this to accommodate the better collision

    for x in range(0, mapWidth):

        for y in range (0, mapHeight):

            if y < 32 or y + cellWidth >= mapHeight:

                newmap[x][y].block_path = True

            elif x < 32 or x + cellWidth >= mapWidth:

                newmap[x][y].block_path = True



    return newmap


def drawmap(maptodraw):

    # only blit at cellwidth and height intervals

    for x in range(0, mapWidth, cellWidth):

        for y in range(0, mapHeight, cellHeight):

            if maptodraw[x][y].block_path == True:

                screen.blit(wallRight, (x, y))

            else:

                screen.blit(Floor, (x, y))


# Added this function which lets you block or unblock a cell

# simply call like gamemap = block_element(5, 10, gamemap)

# this will block the 6th cell on the x axis and 11th on the y axis

# to unblock a cell call it with block=False

def block_element(x, y, maptoblock, block=True):

    x_cells = int(mapWidth / cellWidth)

    y_cells = int(mapHeight / cellHeight)


    start_x = int(x * cellWidth)

    start_y = int(y * cellHeight)


    end_x = start_x + cellWidth

    end_y = start_y + cellHeight


    print(start_x, end_x)


    if x >= 0 and x < x_cells:

        if y >= 0 and y < y_cells:

            for x in range(start_x, end_x):

                for y in range(start_y, end_y):

                    maptoblock[x][y].block_path = block


    return maptoblock   


pygame.init()


mapHeight = 960

mapWidth = 960


cellWidth = 32

cellHeight = 32


screen = pygame.display.set_mode((mapWidth, mapHeight))


gamemap = createmap()

# blocking/unblocking example

gamemap = block_element(5, 10, gamemap)

gamemap = block_element(0, 8, gamemap, block=False)

gamemap = block_element(0, 9, gamemap, block=False)


clock = pygame.time.Clock()

character = player(64, 64, 32, 32)


run = True

while run:

    clock.tick(18)

    pygame.display.update()


    for event in pygame.event.get():

        if event.type == pygame.QUIT:


            run = False

    # I just used fill since I didn't have a bg image handy

    screen.fill((0, 0, 0))

    drawmap(gamemap)


    # handle the keypresses

    # first check if the character can move that much

    # then draw the movement

    keys = pygame.key.get_pressed()

    if keys[pygame.K_LEFT] and character.can_move(0 - character.vel, 0):

        character.draw(screen, 'walkleft')

    elif keys[pygame.K_RIGHT] and character.can_move(character.vel, 0):

        character.draw(screen, 'walkright')

    elif keys[pygame.K_UP] and character.can_move(0, 0 - character.vel):

        character.draw(screen, 'walkup')

    elif keys[pygame.K_DOWN] and character.can_move(0, character.vel):

        character.draw(screen, 'walkdown')

    else:

        character.draw(screen, 'standing')



查看完整回答
反对 回复 2022-08-02
  • 1 回答
  • 0 关注
  • 100 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号