Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用pygame减少对象之间的距离_Python_Pygame - Fatal编程技术网

Python 使用pygame减少对象之间的距离

Python 使用pygame减少对象之间的距离,python,pygame,Python,Pygame,我正在研究太空入侵者的变异。现在所有的敌人都在水平移动,当第一个或最后一个敌人击中窗口边界时,所有的敌人都开始向相反的方向移动 我的问题是,当敌人在窗口右边界击中几次时,最后一个敌人和前一个敌人之间的距离正在减小。下面的gif显示了一个问题 我认为问题出在敌方类中的移动方法中,但我不确定这一点 我的代码: import pygame import os import random # CONST WIDTH, HEIGHT = 800, 800 WIN = pygame.display.se

我正在研究太空入侵者的变异。现在所有的敌人都在水平移动,当第一个或最后一个敌人击中窗口边界时,所有的敌人都开始向相反的方向移动

我的问题是,当敌人在窗口右边界击中几次时,最后一个敌人和前一个敌人之间的距离正在减小。下面的gif显示了一个问题

我认为问题出在
敌方
类中的
移动
方法中,但我不确定这一点

我的代码:

import pygame
import os
import random

# CONST
WIDTH, HEIGHT = 800, 800
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
FPS = 60

BACKGROUND = pygame.image.load(os.path.join("assets", "background.png"))

PLAYER_IMG = pygame.image.load(os.path.join("assets", "player-space-ship.png"))
PLAYER_VELOCITY = 7
PLAYER_LIVES = 3

ENEMY_IMG = pygame.image.load(os.path.join("assets", "Enemy1.png"))
ENEMY_VELOCITY = 1
ENEMY_ROWS = 3
ENEMY_COOLDOWN_MIN, ENEMY_COOLDOWN_MAX = 60, 60 * 4
ENEMIES_NUM = 10

LASER_IMG = pygame.image.load(os.path.join("assets", "laser-bullet.png"))
LASER_VELOCITY = 10

pygame.init()
pygame.display.set_caption("Galaxian")
font = pygame.font.SysFont("Comic Sans MS", 20)


class Ship:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.ship_img = None
        self.laser = None

    def draw(self, surface):
        if self.laser:
            self.laser.draw(surface)
        surface.blit(self.ship_img, (self.x, self.y))

    def get_width(self):
        return self.ship_img.get_width()

    def get_height(self):
        return self.ship_img.get_height()

    def get_rect(self):
        return self.ship_img.get_rect(topleft=(self.x, self.y))

    def move_laser(self, vel, obj):
        if self.laser:
            self.laser.move(vel)
            if self.laser.is_offscreen():
                self.laser = None
            elif self.laser.collision(obj):
                self.laser = None
                obj.kill()

    def fire(self):
        if not self.laser:
            x = int(self.get_width() / 2 + self.x - 4)
            y = self.y - 9
            self.laser = Laser(x, y)


class Player(Ship):
    def __init__(self, x, y):
        super().__init__(x, y)
        self.ship_img = PLAYER_IMG
        self.mask = pygame.mask.from_surface(self.ship_img)
        self.score = 0
        self.lives = PLAYER_LIVES

    def move_laser(self, vel, objs):
        if self.laser:
            self.laser.move(vel)
            if self.laser.is_offscreen():
                self.laser = None
            else:
                for obj in objs:
                    if self.laser and self.laser.collision(obj):
                        self.score += 1
                        objs.remove(obj)
                        self.laser = None

    def get_lives(self):
        return self.lives

    def get_score(self):
        return self.score

    def kill(self):
        self.lives -= 1

    def collision(self, obj):
        return is_collide(self, obj)


class Enemy(Ship):
    y_offset = 0
    rect = None

    def __init__(self, x, y):
        super().__init__(x, y)
        self.ship_img = ENEMY_IMG
        self.mask = pygame.mask.from_surface(self.ship_img)
        self.vel = ENEMY_VELOCITY
        self.cooldown = random.randint(ENEMY_COOLDOWN_MIN, ENEMY_COOLDOWN_MAX)

    def move(self, objs):
        if self.x + self.vel + self.get_width() > WIDTH or self.x + self.vel < 0:
            for obj in objs:
                obj.vel *= -1

        self.x += self.vel

    def can_fire(self, enemies):
        if self.cooldown > 0:
            self.cooldown -= 1
            return False
        self.cooldown = random.randint(ENEMY_COOLDOWN_MIN, ENEMY_COOLDOWN_MAX)
        self.rect = pygame.Rect((self.x, self.y), (self.get_width(), HEIGHT))
        for enemy in enemies:
            if self.rect.contains(enemy.get_rect()) and enemy != self:
                return False
        return True

    def collision(self, obj):
        return is_collide(self, obj)


class Laser:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.img = LASER_IMG
        self.mask = pygame.mask.from_surface(self.img)

    def draw(self, surface):
        surface.blit(self.img, (self.x, self.y))

    def move(self, vel):
        self.y += vel

    def is_offscreen(self):
        return self.y + self.get_height() < 0 or self.y > HEIGHT

    def get_width(self):
        return self.img.get_width()

    def get_height(self):
        return self.img.get_height()

    def collision(self, obj):
        return is_collide(self, obj)


def is_collide(obj1, obj2):
    offset_x = obj2.x - obj1.x
    offset_y = obj2.y - obj1.y
    return obj1.mask.overlap(obj2.mask, (offset_x, offset_y)) != None


def spawn_enemies(count):
    distance = int(WIDTH / (count + 1))
    enemies = []
    enemy_width = ENEMY_IMG.get_width()
    enemy_height = ENEMY_IMG.get_height()

    if distance >= enemy_width * 2:
        for i in range(count):
            x = distance * (i + 1) - enemy_width
            for row in range(ENEMY_ROWS):
                enemies.append(Enemy(x, (row + 1) * enemy_height * 2))
    return enemies


def game():
    is_running = True
    clock = pygame.time.Clock()
    player = Player(int(WIDTH / 2), int(HEIGHT - PLAYER_IMG.get_height() - 20))
    enemies = spawn_enemies(ENEMIES_NUM)
    background = pygame.transform.scale(BACKGROUND, (WIDTH, HEIGHT))
    bg_y = 0

    def redraw():
        WIN.blits(((background, (0, bg_y - HEIGHT)), (background, (0, bg_y)),))
        score = font.render(f"Punktacja: {player.get_score()}", True, (255, 255, 255))
        lives_text = font.render(f"Życia: {player.get_lives()}", True, (255, 255, 255))
        WIN.blit(score, (20, 20))
        WIN.blit(lives_text, (WIDTH - lives_text.get_width() - 20, 20))
        player.draw(WIN)
        for enemy in enemies:
            enemy.draw(WIN)

    while is_running:
        clock.tick(FPS)
        redraw()

        # Move backgrounds
        if bg_y < HEIGHT:
            bg_y += 1
        else:
            bg_y = 0

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                is_running = False
                break

        key = pygame.key.get_pressed()
        if key[pygame.K_LEFT] and (player.x - PLAYER_VELOCITY) >= 0:
            player.x -= PLAYER_VELOCITY
        if (
            key[pygame.K_RIGHT]
            and (player.x + player.get_width() + PLAYER_VELOCITY) <= WIDTH
        ):
            player.x += PLAYER_VELOCITY
        if key[pygame.K_SPACE]:
            player.fire()

        player.move_laser(-LASER_VELOCITY, enemies)
        for enemy in enemies:
            if enemy.can_fire(enemies):
                enemy.fire()
            enemy.move(enemies)
            enemy.move_laser(LASER_VELOCITY, player)

        pygame.display.update()
    pygame.quit()


game()
导入pygame
导入操作系统
随机输入
#常数
宽度,高度=800800
WIN=pygame.display.set_模式((宽度、高度))
FPS=60
BACKGROUND=pygame.image.load(os.path.join(“assets”,“BACKGROUND.png”))
PLAYER\u IMG=pygame.image.load(os.path.join(“assets”,“PLAYER space ship.png”))
玩家速度=7
玩家_寿命=3
敌人\u IMG=pygame.image.load(os.path.join(“资产”,“Enemy1.png”))
敌方速度=1
敌方排=3
敌人冷却时间最小值,敌人冷却时间最大值=60,60*4
敌人数量=10
LASER\u IMG=pygame.image.load(os.path.join(“资产”,“激光子弹.png”))
激光速度=10
pygame.init()
pygame.display.set_标题(“Galaxian”)
font=pygame.font.SysFont(“Comic Sans MS”,20)
船舶等级:
定义初始化(self,x,y):
self.x=x
self.y=y
self.ship\u img=无
self.laser=无
def绘图(自、表面):
如果是自动激光:
自动激光绘图(表面)
表面blit(self.ship\u img,(self.x,self.y))
def get_宽度(自身):
返回self.ship\u img.get\u width()
def get_高度(自身):
返回self.ship\u img.get\u height()
def get(自我):
返回self.ship\u img.get\u rect(左上方=(self.x,self.y))
def move_激光器(自身、vel、obj):
如果是自动激光:
自动激光移动(vel)
如果self.laser.is_屏幕外():
self.laser=无
elif自激光碰撞(obj):
self.laser=无
对象kill()
def火灾(自):
如果不是自动激光器:
x=int(self.get_uwidth()/2+self.x-4)
y=self.y-9
自激光=激光(x,y)
职业球员(船):
定义初始化(self,x,y):
super().\uuuu init\uuuu(x,y)
self.ship\u img=玩家\u img
self.mask=pygame.mask.from_surface(self.ship_img)
self.score=0
self.lifes=玩家生命
def move_激光器(自身、vel、objs):
如果是自动激光:
自动激光移动(vel)
如果self.laser.is_屏幕外():
self.laser=无
其他:
对于objs中的obj:
如果自激光和自激光碰撞(obj):
self.score+=1
objs.remove(obj)
self.laser=无
def获取_生命(自我):
回归自我
def get_分数(自我):
返回自我评分
def杀死(自我):
self.lifes-=1
def碰撞(自身、obj):
返回是碰撞(自身,obj)
敌舰级:
y_偏移=0
rect=None
定义初始化(self,x,y):
super().\uuuu init\uuuu(x,y)
self.ship\u img=敌人\u img
self.mask=pygame.mask.from_surface(self.ship_img)
self.vel=敌方速度
self.cooldown=random.randint(敌方最低冷却时间,敌方最高冷却时间)
def移动(自身、objs):
如果self.x+self.vel+self.get_width()>width或self.x+self.vel<0:
对于objs中的obj:
对象级别*=-1
self.x+=self.vel
def can_火力(自身、敌人):
如果自冷却时间>0:
自我冷却时间-=1
返回错误
self.cooldown=random.randint(敌方最低冷却时间,敌方最高冷却时间)
self.rect=pygame.rect((self.x,self.y),(self.get_width(),HEIGHT))
对于敌人中的敌人:
如果self.rect.contains(敌方.get_rect())和敌方!=自我:
返回错误
返回真值
def碰撞(自身、obj):
返回是碰撞(自身,obj)
激光等级:
定义初始化(self,x,y):
self.x=x
self.y=y
self.img=激光
self.mask=pygame.mask.from_surface(self.img)
def绘图(自、表面):
表面blit(self.img,(self.x,self.y))
def移动(自身、水平):
self.y+=vel
def在屏幕外(自身):
返回self.y+self.get_height()<0或self.y>height
def get_宽度(自身):
返回self.img.get_width()
def get_高度(自身):
返回self.img.get_height()
def碰撞(自身、obj):
返回是碰撞(自身,obj)
def发生碰撞(obj1、obj2):
偏移量_x=obj2.x-obj1.x
偏移量_y=obj2.y-obj1.y
返回obj1.mask.overlap(obj2.mask,(偏移量x,偏移量y))!=没有一个
def繁殖敌人(计数):
距离=整数(宽度/(计数+1))
敌人=[]
敌人宽度=敌人图像。获取宽度()
敌方高度=敌方高度。获取高度()
如果距离>=敌方宽度*2:
对于范围内的i(计数):
x=距离*(i+1)-敌方宽度
对于范围内的行(敌人行):
敌人。附加(敌人(x,(行+1)*敌人高度*2))
还敌
def game():
_正在运行=正确吗
clock=pygame.time.clock()
player=player(int(宽度/2),int(高度-player\u IMG.get\u HEIGHT()-20))
敌人=繁殖敌人(敌人数量)
背景=pygame.transform.scale(背景,(宽度,高度))
bg_y=0
def redraw():
WIN.blits(((背景,(0,背景y-高度)),(背景,(0,背景y)),)
score=font.render(f“Punktacja:{player.get_score()}”,真,(255,255,255))
lives_text=font.render(f“Życia:{player.get_lifes()}),True,(255,255))
赢。布利特(得分,(20,20))
blit(lives\u text,(WIDTH-lives\u text.get\u WIDTH()-20,20))
球员。平局(获胜)
对于敌人中的敌人:
敌人。平局(胜利)
当_正在运行时:
时钟滴答声(FPS)
重画
#向后移动
class Enemy(Ship):
    # ... 
    def move(self, objs):
        last_obj = objs[-1]
        if (
            last_obj.x + last_obj.vel + last_obj.get_width() > WIDTH
            or self.x + self.vel < 0
        ):
            for obj in objs:
                obj.vel *= -1
        self.x += self.vel