2017-07-11 119 views
0

经过大约一个小时的灾难和我的代码修改后,我似乎无法让我的敌人精灵在平台上来回移动。所以任何帮助,将不胜感激:d如何让精灵在pygame的平台上来回移动?

测试文件,特制超快速....

import pygame, sys, os 

GAME_TITLE = "GAME" 
WINDOW_WIDTH, WINDOW_HEIGHT = 1280, 720 
BLACK = (0, 0, 0) 
BLUE = (0, 255, 0) 
RED = (255, 0, 0) 
FPS = 60 

ENEMY_ACC = 0.3 
ENEMY_FRICTION = -0.12 
ENEMY_GRAVITY = 0.5 

vec = pygame.math.Vector2 

class Platform(pygame.sprite.Sprite): 
    def __init__(self, game, x, y, w, h): 
     pygame.sprite.Sprite.__init__(self) 
     self.game = game 
     self.group = self.game.platform_list 
     self.image = pygame.Surface((1280, 100)) 
     self.rect = self.image.get_rect() 
     pygame.draw.rect(self.image, RED, (x, y, w, h)) 


class Enemy(pygame.sprite.Sprite): 
    def __init__(self, game, pos): 
     pygame.sprite.Sprite.__init__(self) 
     self.game = game 
     self.group = self.game.enemy_list 
     self.image = pygame.Surface((100, 100)) 
     pygame.draw.rect(self.image, BLUE, (200, 200, 100, 100)) 
     self.rect = self.image.get_rect() 
     self.pos = vec(pos) 
     self.rect.center = self.pos 
     self.vel = vec(0, 0) 
     self.acc = vec(0, 0) 
     self.direction = "R" 
     self.engage = False 

    def update(self): 
     hits = pygame.sprite.spritecollide(self, self.game.platform_list, False) 
     if hits: 
      plat_right = hits[0].rect.right 
      plat_left = hits[0].rect.left 
      self.pos.y = hits[0].rect.top 
      self.vel.y = 0 

     if self.direction == "R" and not self.engage: 
      if self.rect.right >= plat_right: 
       self.direction = "L" 
       self.acc.x = -ENEMY_ACC 
     if self.direction == "L" and not self.engage: 
      if self.rect.left <= plat_left: 
       self.direction = "R" 
       self.acc.x = -ENEMY_ACC 

     self.acc.x += self.vel.x * ENEMY_FRICTION 
     self.vel += self.acc 
     self.pos += self.vel + 0.5 * self.acc 
     self.rect.midbottom = self.pos 
     self.acc = vec(0, ENEMY_GRAVITY) 

class Game: 
    def __init__(self): 
     pygame.init() 
     pygame.mixer.init() 
     pygame.font.init() 
     os.environ['SDL_VIDEO_CENTERED'] = '1' 
     pygame.display.set_caption(GAME_TITLE) 
     self.window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT)) 
     self.clock = pygame.time.Clock() 
     self.platform_list = pygame.sprite.Group() 
     self.enemy_list = pygame.sprite.Group() 

    def run(self): 
     enemy = Enemy(self, (200, 500)) 
     self.enemy_list.add(enemy) 

     platform = Platform(self, 0, 620, 1280, 100) 
     self.platform_list.add(platform) 

     while True: 
      self.events() 
      self.update() 
      self.draw() 

    def events(self): 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       pygame.quit() 
       sys.exit() 

    def update(self): 
     self.enemy_list.update() 

    def draw(self): 
     self.window.fill(BLACK) 
     self.platform_list.draw(self.window) 
     self.enemy_list.draw(self.window) 
     pygame.display.flip() 

def main(): 
    g = Game() 
    g.run() 

if __name__ == "__main__": 
    main() 
+0

你让我们很难帮你,如果你不给我们一个可执行[MCVE(https://stackoverflow.com/help/mcve),我们可以测试和调试。 – skrx

+0

如果需要,我可以提供更多的代码,我相信我已经提供了必要的代码来识别问题。 –

+0

但是,如果有必要,我会开始制作一个测试文件。 –

回答

1

这里没有acc属性的例子。通过加入ENEMY_GRAVITY加快self.vel,更新self.posself.rect,然后如果它与平台发生碰撞,看看是否到达右边缘或左边缘,然后反转速度。

我已将ENEMY_GRAVITY设置为3并致电clock.tick(30)来限制帧速率。 direction属性似乎不再需要。

class Enemy(pygame.sprite.Sprite): 
    def __init__(self, game, pos): 
     pygame.sprite.Sprite.__init__(self) 
     self.game = game 
     self.group = self.game.enemy_list 
     self.image = pygame.Surface((60, 60)) 
     self.image.fill((30, 90, 200)) 
     self.rect = self.image.get_rect(midbottom=pos) 
     self.pos = vec(pos) 
     self.vel = vec(3, 0) 
     self.engage = False 

    def update(self): 
     self.vel.y += ENEMY_GRAVITY 
     self.pos += self.vel 
     self.rect.midbottom = self.pos 

     hits = pygame.sprite.spritecollide(self, self.game.platform_list, False) 
     for plat in hits: 
      self.pos.y = plat.rect.top 
      self.rect.bottom = plat.rect.top 
      self.vel.y = 0 

      if self.vel.x > 0 and not self.engage: 
       if self.rect.right >= plat.rect.right: 
        self.vel = vec(-3, 0) # Reverse the horizontal velocity. 
      elif self.vel.x < 0 and not self.engage: 
       if self.rect.left <= plat.rect.left: 
        self.vel = vec(3, 0) # Reverse the horizontal velocity.