【问题标题】:All the sprites have to move in pygame所有的精灵都必须在 pygame 中移动
【发布时间】:2018-01-05 16:58:03
【问题描述】:

我在我的游戏中使用 Vector2 来制作相机。但是当我撞到墙壁时,所有的精灵都开始移动,所以我用墙壁和地板固定它,但我不知道如何固定我的敌人。有什么想法吗?

这是我的代码:

import sys
import pygame as pg
from pygame.math import Vector2

width = 1280
height = 720
x1 = 200
y1 = 100
x2 = 500
y2 = 400
x3 = 100
y3 = 300
x = 0
y = 0

class Player(pg.sprite.Sprite):

    def __init__(self, pos, *groups):
        super().__init__(*groups)
        pg.sprite.Sprite.__init__(self)
        self.image = pg.image.load("character.png")
        self.rect = self.image.get_rect(center=pos)
        self.vel = Vector2(0, 0)
        self.pos = Vector2(pos)

    def update(self):
        self.pos += self.vel
        self.rect.center = self.pos

#enemy class
class Enemy(pg.sprite.Sprite):

    def __init__(self, pos, waypoints, *groups):
        super().__init__(*groups)
        self.image = pg.image.load("enemy.png")
        self.image = pg.transform.scale(self.image, (int(50), int(50)))
        self.rect = self.image.get_rect(center=pos)
        self.vel = Vector2(0,0)
        self.max_speed = 5
        self.pos = Vector2(pos)
        self.waypoints = waypoints
        self.waypoint_index = 0
        self.target = self.waypoints[self.waypoint_index]
        self.target_radius = 50
        self.rect.x = width / 2
        self.rect.y = height / 2

    def update(self):
# A vector pointing from self to the target.
        heading = self.target - self.pos
        distance = heading.length()  # Distance to the target.
        heading.normalize_ip()
        if distance <= 2:  # We're closer than 2 pixels.
          # Increment the waypoint index to swtich the target.
          # The modulo sets the index back to 0 if it's equal to the length.
          self.waypoint_index = (self.waypoint_index + 1) % len(self.waypoints)
          self.target = self.waypoints[self.waypoint_index]
        if distance <= self.target_radius:
                # If we're approaching the target, we slow down.
          self.vel = heading
        else:  # Otherwise move with max_speed.
          self.vel = heading * self.max_speed

        self.pos += self.vel
        self.rect.center = self.pos

#Enemy waypoints
waypoints = [[x1, y1], [x2, y2], [x3, y3]]


class Floor(pg.sprite.Sprite):

    def __init__(self, x, y, *groups):
        super().__init__(*groups)
        self.image = pg.image.load("floor.png")
        self.rect = self.image.get_rect(topleft=(x, y))
        self.rect.x = x
        self.rect.y = y

class SideWall(pg.sprite.Sprite):

    def __init__(self, x, y, *groups):
        super().__init__(*groups)
        self.image = pg.image.load("sidewall.png")
        self.rect = self.image.get_rect(topleft=(x, y))
        self.rect.x = x
        self.rect.y = y

class TopAndBottomWall(pg.sprite.Sprite):

    def __init__(self, x, y, *groups):
        super().__init__(*groups)
        self.image = pg.image.load("topandbottomwall.png")
        self.rect = self.image.get_rect(topleft=(x, y))
        self.rect.x = x
        self.rect.y = y


def main():
    screen = pg.display.set_mode((1280, 720))
    clock = pg.time.Clock()
    #all the sprites group
    all_sprites = pg.sprite.Group()

    #the floor
    floor = Floor(540, -620, all_sprites)

    #player
    player = Player(((width / 2), (height / 2)), all_sprites)

    #walls group
    walls = pg.sprite.Group()

    #all walls
    walltop = TopAndBottomWall(540, -620, all_sprites, walls)
    wallbottom = TopAndBottomWall(540, 410, all_sprites, walls)
    wallleft = SideWall((width / 2) - 100, (height / 2) - 930, all_sprites, walls)
    wallright = SideWall((wallleft.rect.x + (1920 - 50)), (height / 2) - 930, all_sprites, walls)

    #all enemy's
    enemy = Enemy((100, 300), waypoints, all_sprites)

    camera = Vector2(0, 0)

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            #player movement    
            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_d:
                    player.vel.x = 5
                elif event.key == pg.K_a:
                    player.vel.x = -5
                elif event.key == pg.K_w:
                    player.vel.y = -5
                elif event.key == pg.K_s:
                    player.vel.y = 5
            elif event.type == pg.KEYUP:
                if event.key == pg.K_d and player.vel.x > 0:
                    player.vel.x = 0
                elif event.key == pg.K_a and player.vel.x < 0:
                    player.vel.x = 0
                elif event.key == pg.K_w:
                    player.vel.y = 0
                elif event.key == pg.K_s:
                    player.vel.y = 0

        camera -= player.vel

        all_sprites.update()

        if pg.sprite.spritecollide(player, walls, False):
            #stop the left wall from moving
            wallleft.rect.x = wallleft.rect.x + player.vel.x
            wallleft.rect.y = wallleft.rect.y + player.vel.y
            #stop the top wall from moving
            walltop.rect.y = walltop.rect.y + player.vel.y
            walltop.rect.x = walltop.rect.x + player.vel.x
            #stop the right wall from moving
            wallright.rect.x = wallright.rect.x + player.vel.x
            wallright.rect.y = wallright.rect.y + player.vel.y
            #stop the bottom wall from moving
            wallbottom.rect.x = wallbottom.rect.x + player.vel.x
            wallbottom.rect.y = wallbottom.rect.y + player.vel.y
            #stop the floor from moving
            floor.rect.x = floor.rect.x + player.vel.x
            floor.rect.y = floor.rect.y + player.vel.y


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

        for sprite in all_sprites:
            screen.blit(sprite.image, sprite.rect.topleft+camera)

        pg.display.flip()
        clock.tick(30)

main()
pg.quit()

如果您想运行它,这是一个包含文件的链接。 https://geordyd.stackstorage.com/s/hZZ1RWcjal6ecZM

【问题讨论】:

    标签: python animation pygame sprite


    【解决方案1】:

    您正在使用屏幕坐标。您只在检查按键时移动墙壁;你应该同时移动敌人。

    但是有一个更好的方法;如果您添加更多类,则可扩展性更好,并且更少混乱。

    Wall 中删除按键检查并将它们放入Player。这将改变玩家在世界坐标中的位置,与墙壁相同的坐标(静态)和敌人移动(动态)。

    然后在world_position - players_position 处绘制墙壁和敌人,并根据玩家在中心的相对位置进行调整。从技术上讲,甚至玩家本身也被绘制在该位置 - 对他的计算相当于相对于屏幕的零移动。

    为了获得更大的灵活性,您可以考虑一个单独的Camera 类,它默认设置为跟随玩家。这允许你让相机移动到“其他地方”,或者如果玩家靠近你的世界边缘,让他离开屏幕中心。

    【讨论】:

    • 我之前尝试过添加一个相机类,但我不知道怎么做,所以我认为这更容易一些。那么你对如何添加摄像头有什么建议吗?
    • @Geordyd:相机类并不是真正需要的,它只会让你做更多的显示技巧。首先修复您当前的代码以使其正常工作,然后您可以考虑改进。
    • @Geordyd 看看我最近发布的这个simple example。当玩家移动时,我只需更改panning 向量,然后在渲染期间将其添加到平铺位置以进行偏移。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多