代码之家  ›  专栏  ›  技术社区  ›  DarkBlood202

如何使对象自行移动以避免与其他对象发生碰撞

  •  0
  • DarkBlood202  · 技术社区  · 5 年前

    我做这个游戏是为了躲避来自不同方向的物体。我要实现的是让这个对象(一个由计算机控制的“player”类)能够像用户控制的播放器那样躲避。

    TITLE = "Dodging-IA Attempt";
    WIDTH = 320; HEIGHT = 400;
    FPS = 60;
    
    BLACK = (0,0,0); WHITE = (255,255,255);
    RED = (255,0,0); GREEN = (0,255,0); BLUE = (0,0,255);
    
    import pygame as pg;
    import random, math;
    
    class Game():
        def __init__(self):
            self.screen = pg.display.set_mode((WIDTH,HEIGHT));
            self.clock = pg.time.Clock(); self.dt = FPS/1000;
            self.running = True;
            self.all_sprites = pg.sprite.Group();
            self.bullets = pg.sprite.Group();
            self.other_sprites = pg.sprite.Group();
    
            self.player = Player(); self.all_sprites.add(self.player);
            self.bullet_spawn = BulletSpawn(); self.other_sprites.add(self.bullet_spawn);
    
    
    class Player(pg.sprite.Sprite):
        def __init__(self):
            pg.sprite.Sprite.__init__(self);
            self.image = pg.Surface((16,32)); self.image.fill(GREEN);
            self.rect = self.image.get_rect();
            self.rect.centerx = WIDTH//2;
            self.rect.y = HEIGHT*3//4;
            self.vx = self.vy = 300;
    
        def update(self,dt):
            pass;
    
    class Bullet(pg.sprite.Sprite):
        def __init__(self,x):
            pg.sprite.Sprite.__init__(self);
            self.image = pg.Surface((16,16)); self.image.fill(RED);
            self.rect = self.image.get_rect();
            self.rect.centerx = x;
            self.rect.bottom = 0;
            self.vy = 70;
    
        def update(self,dt):
            self.rect.y += self.vy * dt;
            if self.rect.top > HEIGHT:
                self.kill();
    
    class BulletSpawn(pg.sprite.Sprite):
        def __init__(self):
            pg.sprite.Sprite.__init__(self);
            self.image = pg.Surface((1,1)); self.rect = self.image.get_rect();
            self.new_bullet = pg.time.get_ticks();
    
        def update(self):
            now = pg.time.get_ticks();
            if now - self.new_bullet > 500:
                self.new_bullet = now;
                for i in range(5):
                    bullet = Bullet(random.randint(8,WIDTH-8));
                    game.bullets.add(bullet);
                    game.all_sprites.add(bullet);
    
    pg.init();
    pg.display.set_caption(TITLE);
    
    game = Game();
    
    while game.running:
    
        game.dt = game.clock.tick(FPS)/1000;
    
        for event in pg.event.get():
            if event.type == pg.QUIT:
                game.running = False;
    
        hits = pg.sprite.spritecollide(game.player,game.bullets,False)
        for hit in hits:
            if hit.rect.right > game.player.rect.left:  #dodge moving to left
                game.player.rect.x += game.player.vx*game.dt
                print("DODGED TO LEFT")
            if hit.rect.left < game.player.rect.right:  #dodge moving to right
                game.player.rect.x -= game.player.vx*game.dt
                print("DODGED TO RIGHT")
    
    
        game.all_sprites.update(game.dt);
        game.other_sprites.update();
    
        game.screen.fill(BLUE);
        game.all_sprites.draw(game.screen)
        game.other_sprites.draw(game.screen)
        pg.display.flip();
    
    pg.quit();
    

    因此,“玩家”总是朝着一个且只有一个方向移动,不管它是否在其路径上发生碰撞,而不是实际地水平躲避坠落的物体。我该怎么做才能得到这个?也许我得重新计算碰撞的条件? 非常感谢您抽出时间。

    0 回复  |  直到 5 年前
        1
  •  1
  •   user11563547 user11563547    5 年前

    检查框边是否在播放器范围内是一种方法。如果你把检查包括在内,即使只有边缘对齐,玩家也应该躲闪。

    if hit.rect.right >= game.player.rect.left and hit.rect.left <= game.player.rect.left:
        game.player.rect.x += game.player.vx*game.dt
        print("DODGED TO LEFT")
    elif hit.rect.left <= game.player.rect.right and hit.rect.right >= game.player.rect.right:
        game.player.rect.x -= game.player.vx*game.dt
        print("DODGED TO RIGHT")
    
        2
  •  2
  •   TTaykAH    5 年前

    bullet.rect.right 总是比 player.rect.left bullet.rect.left 总是小于 player.rect.right

            if hit.rect.right > game.player.rect.left:  #dodge moving to left
                game.player.rect.x += game.player.vx*game.dt
                print("DODGED TO LEFT")
            if hit.rect.left < game.player.rect.right:  #dodge moving to right
                game.player.rect.x -= game.player.vx*game.dt
                print("DODGED TO RIGHT")
    

    您可以更改:

            if hit.rect.center > game.player.rect.center:
                game.player.rect.x -= game.player.vx*game.dt
            elif hit.rect.center < game.player.rect.center:
                game.player.rect.x += game.player.vx*game.dt