Pygame Platformer 2D中的敌人运动

大厨

在我的第一个项目上工作时,我试图对敌人的动作进行分类,下面的代码是我当前的实现。敌人使用玩家位置(target.pos.x)与他们的pos.x之间的距离。希望敌人向左移动20步,然后改变方向,向右移动20步,冲洗并重复。

self.target = game.player
def movement(self):
    self.acc = vec(0, BOSS_GRAVITY)
    if (-17 >= (self.pos.x - self.target.pos.x) >= -200) and self.target.hit_rect.y == self.hit_rect.y:
        self.vel.x -= BOSS_SPEED * -1
        self.enemy_direction = 'R'

    if (200 >= (self.pos.x - self.target.pos.x) >= 17) and self.target.hit_rect.y == self.hit_rect.y:
        self.vel.x += BOSS_SPEED * -1
        self.enemy_direction = 'L'
self.acc.x += self.vel.x * BOSS_FRICTION

    self.vel += self.acc
    self.pos += self.vel
    self.pos += self.vel + 0.5 * self.acc

我希望我的敌人向右移动一定量,然后改变速度,然后以相反的方式保持静止。

金斯利

我希望敌人向左移动20步,然后改变方向,向右移动20步,冲洗并重复。

好的,我们如何实现这一目标?首先是一些定义:

什么是“步伐”?让我们从开始5 pixels左边是-x; +x

还有一些额外的事情要照顾。当对象无法沿所需方向移动时该怎么办?可以turn around

因此,我们需要保留有关该敌人的大量统计信息:位置,步数和行进方向。一旦有了一些基准点,请思考:数据结构现在,我将所有这些内容放入Python类中,但也可以将其放入一个简单列表中。但是,这些数据多于几个点,因此变得笨拙。

# As a list
enemy_image = pygame.image.load( "doomba.png" ).convert_alpha()
enemy_rect  = enemy_image.get_rect()
enemy_rect.center = ( x, y )
enemy1 = [ enemy_rect, enemy_image, PACE_SIZE, TURN_SIZE ]

作为一个班级要好得多:

# As a sprite class
class Enemy( pygame.sprite.Sprite ):
    def __init__( self, x, y, bitmap, pace=5, turn_after=20 ):
            """ Create a new Enemy at that is drawn at (x,y) as the /bitmap/.
                It moves /pace/ pixels each step, left, then right     """
        pygame.sprite.Sprite.__init__( self )
        self.image = pygame.image.load( bitmap ).convert_alpha()
        self.rect  = self.image.get_rect()
        self.rect.center = ( x, y )         # location
        self.pace_size   = pace             # How big each step is
        self.pace_count  = 0                # distance moved
        self.direction   = -1               # Start moving left (-x)
        self.turn_after  = turn_after       # distance limit

(我已经基于PyGame Sprite制作了数据结构,因为它仅花费两行代码,并提供了许多预建功能。)

现在,我们有了一个数据结构(名为Enemy),其中包含一个位置,大小,位图,并记住它走了多远以及向哪个方向移动。但是,它尚未实现任何形式的运动算法。因此,我们添加一下。

Sprite类希望将此算法写入名为的函数中update()每个都会调用此函数,以决定该帧的运动。这可能是不动产,或其他。可以是任何东西。

在这里您可以看到我们正在计算移入的步数self.pace_count,然后根据步长(调整位图的x位置(保持在)。如果敌人向左移动,则需要减去步速大小,向右则增加步速大小。我们可以通过我们在添加量乘以自动执行此操作,无论是每当敌人转身时就设置方向值。self.rectself.pace_sizeself.direction-11

    def update( self ):
        """ Implement the movement algorithm """
        # Walk pace in the current direction
        self.pace_count += 1
        self.rect.x     += self.direction * self.pace_size     # Move some pixels

        # We need to turn around if walked enough paces in the same direction
        if ( self.pace_count >= self.turn_after ):
            # Turn around!
            self.direction *= -1           # reverses the pixel distance
            self.pace_count = 0            # reset the pace count

        # We also should change direction if we hit the screen edge
        if ( self.rect.x <= 0 ):
            self.direction  = 1             # turn right
            self.pace_count = 0
        elif ( self.rect.x >= WINDOW_WIDTH - self.rect.width ):
            self.direction  = -1
            self.pace_count = 0

因此,当敌人按照设定的步数行走时,方向会反转并且步数最终归零。但是,如果我们撞到屏幕的一侧,我们还需要调头。发生这种情况时,只有一种明显的转弯方法,因此方向绝对会改变,而不是反向。该代码可能会变得更简单,因为它每次基本上都执行几乎相同的操作。但是,我已经花了更长的时间来清楚地说明所涉及的步骤。

而且,算法得以实现。看着演示,它的方式太快。因此,我们还要结合实时速度。

太快的蘑菇

控制运动速度的一种简单方法是在步骤之间设置延迟。首先确定敌人移动的频率(例如,每100毫秒),存储self.speed一次,然后采取最后一步的时间self.pace_time然后,当需要更新时,请查看PyGame时钟,看看是否经过了足够的毫秒,然后才移动敌人。否则什么都不做。

def update( self ):
    """ Implement the movement algorithm """
    time_now = pygame.time.get_ticks()               # what time is it
    if ( time_now > self.pace_time + self.speed ):   # time to move again?
        self.pace_time = time_now                    # remember move time

        # Walk pace in the current direction
        self.pace_count += 1

这给出了更静定的动作。我调整了敌人以使其更频繁地移动,但步幅较小。因此,现在它也不会遍历整个窗口。将速度控制为时间的函数,而不是帧速率,这一点很重要。例如,如果我只是将pace尺寸0.2像素设置为上方,请确保将蘑菇放慢到一定速度。但这仅在我的计算机上是准确的如果帧速率仅为21 FPS,突然又降低了2/3,该怎么办?如果帧率为160 FPS怎么办?那将是超快的。因此,请保持由实时毫秒(而不是帧速率和距离)控制的任何类型的速度和运动。

慢蘑菇

无论如何,这足以让您继续使用自己的运动算法。如果对代码有疑问,请发表评论。

参考代码:

import pygame

# Window size
WINDOW_WIDTH    = 600
WINDOW_HEIGHT   = 400
WINDOW_SURFACE  = pygame.HWSURFACE|pygame.DOUBLEBUF

DARK_BLUE = (   3,   5,  54)

class Enemy( pygame.sprite.Sprite ):
    def __init__( self, x, y, pace, bitmap, turn_after=20, speed=100 ):
        """ Create a new Enemy at that is drawn at (x,y) as the /bitmap/.
            It moves /pace/ pixels left, then right   """
        pygame.sprite.Sprite.__init__( self )    
        self.image = pygame.image.load( bitmap ).convert_alpha()
        self.rect  = self.image.get_rect()
        self.rect.center = ( x, y )         # location
        self.pace_size   = pace             # How big each step is
        self.pace_count  = 0                # distance moved
        self.direction   = -1               # Start moving left (-x)
        self.turn_after  = turn_after       # distance limit
        self.speed       = speed            # Milliseconds per pace
        self.pace_time   = 0                # time of last step

    def update( self ):
        """ Implement the movement algorithm """
        time_now = pygame.time.get_ticks()               # what time is it
        if ( time_now > self.pace_time + self.speed ):   # is it time to move again
            self.pace_time = time_now

            # Walk pace in the current direction
            self.pace_count += 1
            self.rect.x     += self.direction * self.pace_size     # Move some pixels

            # We need to turn around if walked enough paces in the same direction
            if ( self.pace_count >= self.turn_after ):
                # Turn around!
                self.direction *= -1           # reverses the pixel distance
                self.pace_count = 0            # reset the pace count

            # We also should change direction if we hit the screen edge
            if ( self.rect.x <= 0 ):
                self.direction  = 1             # turn right
                self.pace_count = 0
            elif ( self.rect.x >= WINDOW_WIDTH - self.rect.width ):
                self.direction  = -1
                self.pace_count = 0


### initialisation
pygame.init()
pygame.mixer.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), WINDOW_SURFACE )
pygame.display.set_caption("Movement Algorithm Example")

### Sprite and Sprite Group
pos_x     = WINDOW_WIDTH//2
pos_y     = WINDOW_HEIGHT//2
pace_size = 7
enemy = Enemy( pos_x, pos_y, pace_size, "mushroom.png" )

all_sprites_group = pygame.sprite.Group()
all_sprites_group.add( enemy )


### Main Loop
clock = pygame.time.Clock()
done = False
while not done:

    # Handle user-input
    for event in pygame.event.get():
        if ( event.type == pygame.QUIT ):
            done = True
        elif ( event.type == pygame.MOUSEBUTTONUP ):
            # On mouse-click
            pass
        elif ( event.type == pygame.KEYUP ):
            pass

    # Movement keys
    #keys = pygame.key.get_pressed()
    #if ( keys[pygame.K_UP] ):
    #    print("up")

    # Update the window, but not more than 60fps
    all_sprites_group.update()
    window.fill( DARK_BLUE )
    all_sprites_group.draw( window )
    pygame.display.flip()

    # Clamp FPS
    clock.tick_busy_loop(60)

pygame.quit()

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Pygame中用于简单2D Platformer的碰撞检测问题

来自分类Dev

Java 2D Platformer引力

来自分类Dev

在Pygame中的2D空间中实现平滑运动

来自分类Dev

C#XNA 2D Platformer跳跃问题

来自分类Dev

2D Array Platformer Wall Collision - Javascript

来自分类Dev

2D Platformer游戏,使玩家的相机在html5中查看

来自分类Dev

Pygame吃豆子-敌人随机运动

来自分类Dev

LibGdx Box2d Platformer Jump实现

来自分类Dev

LOVE2D游戏引擎; 2D Platformer碰撞系统

来自分类Dev

在Pygame中自上而下的运动

来自分类Dev

3D Platformer Controller - 在不同方向运行

来自分类Dev

Pygame 简单运动:敌人模仿玩家运动并回溯步骤

来自分类Dev

pygame敌人向玩家的2维运动,如何计算x和y速度?

来自分类Dev

pygame敌人向玩家的2维运动,如何计算x和y速度?

来自分类Dev

减慢Pygame中的运动圈

来自分类Dev

pygame中的随机系统运动

来自分类Dev

Pygame中的随机运动

来自分类Dev

如何让敌人跟随pygame中的玩家?

来自分类Dev

Pygame / Python测试列表中的敌人之间?

来自分类Dev

在Pygame中不会停止的敌人

来自分类Dev

如何在 pygame 中添加敌人?

来自分类Dev

如何让敌人跟随 Pygame 中的玩家?

来自分类Dev

pygame随机移动敌人

来自分类Dev

随机生成敌人pygame

来自分类Dev

运动背景pygame

来自分类Dev

随机运动pygame

来自分类Dev

Pygame雪碧运动故障

来自分类Dev

pygame状态使运动流畅

来自分类Dev

pygame雪碧运动