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

Python 3.x 如何使对象自行移动以避免与其他对象发生碰撞,python-3.x,pygame,python-3.6,Python 3.x,Pygame,Python 3.6,我做这个游戏是为了躲避来自不同方向的物体。我试图实现的是让这个对象(由计算机控制的“玩家”类)能够像用户控制的玩家一样闪避 我尝试使用pygame提供的基本冲突处理(当然,阅读一些关于它如何工作以及如何解决问题的文档)。我所做的基本上是检查一个对象的右矩形位置是否与“玩家”的左矩形重叠,反之亦然,因此它会向相反方向移动以避免碰撞 TITLE = "Dodging-IA Attempt"; WIDTH = 320; HEIGHT = 400; FPS = 60; BLACK = (0,0,0);

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

我尝试使用pygame提供的基本冲突处理(当然,阅读一些关于它如何工作以及如何解决问题的文档)。我所做的基本上是检查一个对象的右矩形位置是否与“玩家”的左矩形重叠,反之亦然,因此它会向相反方向移动以避免碰撞

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();
TITLE=“躲避IA尝试”;
宽度=320;高度=400;
FPS=60;
黑色=(0,0,0);白色=(255255);
红色=(255,0,0);绿色=(0255,0);蓝色=(0,0255);
导入pygame作为pg;
导入随机、数学;
类游戏():
定义初始化(自):
self.screen=pg.display.set_模式((宽度、高度));
self.clock=pg.time.clock();self.dt=FPS/1000;
self.running=True;
self.all_sprite=pg.sprite.Group();
self.bullets=pg.sprite.Group();
self.other_sprite=pg.sprite.Group();
self.player=player();self.all_精灵添加(self.player);
self.bullet_spawn=bulletsawn();self.other_sprite.add(self.bullet_spawn);
职业玩家(第三页精灵):
定义初始化(自):
雪碧。雪碧。uuu初始(自我);
self.image=pg.Surface((16,32));self.image.fill(绿色);
self.rect=self.image.get_rect();
self.rect.centerx=宽度//2;
自校正y=高度*3//4;
self.vx=self.vy=300;
def更新(自我,dt):
通过;
类项目符号(第页精灵,精灵):
定义初始化(self,x):
雪碧。雪碧。uuu初始(自我);
self.image=pg.Surface((16,16));self.image.fill(红色);
self.rect=self.image.get_rect();
self.rect.centerx=x;
self.rect.bottom=0;
self.vy=70;
def更新(自我,dt):
自校正y+=self.vy*dt;
如果self.rect.top>高度:
self.kill();
类BulletSpawn(pg.sprite.sprite):
定义初始化(自):
雪碧。雪碧。uuu初始(自我);
self.image=pg.Surface((1,1));self.rect=self.image.get_rect();
self.new_bullet=pg.time.get_ticks();
def更新(自我):
现在=pg.time.get_ticks();
如果现在-self.new\u bullet>500:
self.new_bullet=now;
对于范围(5)中的i:
bullet=bullet(random.randint(8,宽度-8));
游戏。子弹。添加(子弹);
游戏。所有精灵。添加(子弹);
pg.init();
pg.display.set_标题(标题);
游戏=游戏();
在游戏运行时:
game.dt=game.clock.tick(FPS)/1000;
对于pg.event.get()中的事件:
如果event.type==pg.QUIT:
game.running=False;
hits=pg.sprite.spritecollide(游戏.玩家,游戏.子弹,错误)
点击率:
如果hit.rect.right>game.player.rect.left:#道奇向左移动
game.player.rect.x+=game.player.vx*game.dt
打印(“向左减淡”)
如果hit.rect.left
因此,“玩家”总是朝着一个方向移动,无论是否在其路径上发生碰撞,而不是实际水平躲避下落的物体。我该怎么做才能得到这个?也许我必须重新制定碰撞的条件?
非常感谢您抽出宝贵的时间。

无论玩家和bullet rect在碰撞时刻的位置如何,
bullet.rect.right
始终大于
player.rect.left
bullet.rect.left
始终小于
player.rect.right
。如果你在纸上画画,你就能直观地看到它。这里最好检查移动侧推矩形中心。 这段代码:

如果hit.rect.right>game.player.rect.left:#闪避向左移动
game.player.rect.x+=game.player.vx*game.dt
打印(“向左减淡”)
如果hit.rect.left
您可以在上面更改:

如果hit.rect.center>game.player.rect.center:
game.player.rect.x-=game.player.vx*game.dt
elif hit.rect.center

你可以做一些优化来缓解抽搐,但我认为错误的本质是显而易见的。

检查盒子边缘是否在玩家范围内是一种方法。如果你让检查包含在内,玩家应该闪避,即使只有边缘对齐

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")

如果hit.rect.right>=game.player.rect.left和hit.rect.left哦,我明白了,这确实有效!虽然。。。它一直朝着同一个方向前进(左边,也许这与条件句的顺序有关,或者我猜是这样…),即使右边有更多的空间,sorta也试图朝这个方向躲闪。但它成功了,所以还是谢谢你!非常感谢你!我试过你的代码,效果很好。。。我有点明白上面发生了什么,有点傻,因为我不去想它。。。谢谢,它会按预期移动,并且物体会“明智地”选择躲避的位置。我非常感谢你的帮助。