pygame中的摄像头设置和碰撞问题

时间:2017-11-16 14:16:42

标签: python camera pygame

我目前正在尝试在pygame上编写一个简单的平台游戏,但是当我尝试将相机功能添加到游戏中时,我遇到了碰撞问题。

这是我的代码:

为了不使问题太大,我会剪切包含移动,碰撞和绘图的代码部分。

Index.py

  • 删除了 init 和setup_tiles函数。

    import pygame
    from settings import *
    from tiles import *
    from player import *
    from camera import *
    
    pygame.init()
    
    
    class Window:
    
      def game_loop(self):
    
        while not self.crashed:
    
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.crashed = True
    
            self.movement()
    
            self.window.blit(self.background, (0, 0))
            self.all_sprites.clear(self.window, self.background)
            self.player.update(self.all_sprites)
            self.camera.update(self.player)
            self.player.draw(self.window)
            # self.all_sprites.draw(self.window)
            for sprite in self.all_sprites:
                self.window.blit(sprite.image, self.camera.apply(sprite))
    
            pygame.display.flip()
    
            self.clock.tick(60)
    
        quit()
        pygame.quit()
    
    def movement(self):
        keys = pygame.key.get_pressed()
    
        if keys[pygame.K_w]:
            self.player.velocity_y = -3
            self.player.rect.y += self.player.velocity_y
            for sprite in self.all_sprites:
                if self.player.collide_Y(sprite):
                    self.player.rect.y = self.player.rect.y - self.player.velocity_y
    
        elif keys[pygame.K_s]:
            self.player.velocity_y = 3
            self.player.rect.y += self.player.velocity_y
            for sprite in self.all_sprites:
                if self.player.collide_Y(sprite):
                    self.player.rect.y = self.player.rect.y - self.player.velocity_y
    
        if keys[pygame.K_a]:
            self.player.velocity_x = -3
            self.player.rect.x += self.player.velocity_x
            for sprite in self.all_sprites:
                if self.player.collide_X(sprite):
                    self.player.rect.x = self.player.rect.x - self.player.velocity_x
    
        elif keys[pygame.K_d]:
            self.player.velocity_x = 3
            self.player.rect.x += self.player.velocity_x
            for sprite in self.all_sprites:
                if self.player.collide_X(sprite):
                    self.player.rect.x = self.player.rect.x - self.player.velocity_x
    
    window = Window()
    
    window.game_loop()
    

Tiles.py

import pygame
from settings import *

class Tiles(pygame.sprite.Sprite):

    def __init__(self, file, pos):
        pygame.sprite.Sprite.__init__(self)
        self.bitmap = pygame.image.load(file)
        self.bitmap = pygame.transform.scale(self.bitmap, (TILE_SIZE, TILE_SIZE))
        self.image = pygame.Surface((TILE_SIZE, TILE_SIZE), pygame.HWSURFACE | pygame.SRCALPHA)
        self.image.blit(self.bitmap, (0, 0))
        self.rect = self.image.get_rect()
        self.rect.x, self.rect.y = pos

Player.py

  • 删除了 init 功能

    import pygame
    from settings import *
    
    
    class Player(pygame.sprite.Sprite):
    
    def draw(self, window):
        window.blit(self.image, (self.rect.x, self.rect.y))
    
    def collide_X(self, sprite):
        if (self.rect.x + self.width >= sprite.rect.x >= self.rect.x and self.rect.y + self.height >= sprite.rect.y + TILE_SIZE >=
            self.rect.y) or (self.rect.x + self.width >= sprite.rect.x + TILE_SIZE >= self.rect.x
            and self.rect.y + self.height >= sprite.rect.y + TILE_SIZE >= self.rect.y) or (self.rect.x + self.width >= sprite.rect.x >= self.rect.x and
            sprite.rect.y + TILE_SIZE >= self.rect.y + self.height >= sprite.rect.y >= self.rect.y):
            print 'True'
            return True
        else:
            return False
    
    def collide_Y(self, sprite):
        if (self.rect.y + self.height + self.velocity_y >= sprite.rect.y >= self.rect.y and self.rect.x + self.width >=
            sprite.rect.x >= self.rect.x) or (self.rect.y + self.height >= sprite.rect.y + TILE_SIZE >= self.rect.y + self.velocity_y
            and self.rect.x + self.width >= sprite.rect.x >= self.rect.x):
            return True
        else:
            return False
    

Camera.py

import pygame
from settings import *


class Camera:
    def __init__(self, width, height):
        self.camera = pygame.Rect(0, 0, width, height)
        self.width = width
        self.height = height

    def apply(self, target):
        return target.rect.move(self.camera.topleft)

    def update(self, target):
        x = - target.rect.x + int(WIDTH/2)
        y = - target.rect.y + int(HEIGHT/2)
        self.camera = pygame.Rect(x, y, self.width, self.height)

Settings.py

WIDTH = 800
HEIGHT = 600

TILE_SIZE = 32

LEVEL_1 = [
    'TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT',
    'B                             V                       V',
    'B                             V                       V',
    'B                             V                       V',
    'B                             V                       V',
    'TTTTTTTTTB                    V                       V',
    'B                             V                       V',
    'B                             V                       V',
    'B                             V                       V',
    'B                             V                       V',
    'B                             V                       V',
    'B                             V                       V',
    'B                                                     V',
    'B                                                     V',
    'B                                                     V',
    'B              VTTTTTTTTTTTTTTTTTTTTTTTTB             V',
    'B                             V                       V',
    'B                             V                       V',
    'TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT'
]

LEVEL_1_WIDTH = len(LEVEL_1[0])*TILE_SIZE
LEVEL_1_HEIGHT = len(LEVEL_1)*TILE_SIZE

没有相机的碰撞

enter image description here

这是没有相机的碰撞,因为你可以看到它工作正常。

与相机碰撞

enter image description here

当我添加相机功能时,会发生这种情况

如果你想测试它,请从game_loop中删除#并使用相机应用来评论绘图。

    # self.all_sprites.draw(self.window)
    for sprite in self.all_sprites:
        self.window.blit(sprite.image, self.camera.apply(sprite))

我在Window 10 x64机器中使用python 2.7。

1 个答案:

答案 0 :(得分:1)

您根本没有将相机变换应用于player实例:它以绝对游戏坐标绘制,而其他所有内容都以相机坐标绘制。

另一方面,碰撞检查总是在游戏绝对坐标中完成。

在绘制之前,您必须将相机应用到播放器。正如您的代码所示,看起来您只需将播放器添加到all_sprites组,并完全删除Player.draw方法。然后,如果您愿意,请更正Camera.update方法上的某些内容,以便在地图的边界处,播放器并不总是以屏幕为中心。