Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.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游戏,Flappy Bird';什么样的管道会出现?_Python_Pygame - Fatal编程技术网

如何制作python游戏,Flappy Bird';什么样的管道会出现?

如何制作python游戏,Flappy Bird';什么样的管道会出现?,python,pygame,Python,Pygame,根据YouTube上的教程,我创建了一个Flappy Bird游戏,使用python构建的整洁系统: 当我完成了所有的代码,在那里他运行它并且让游戏正常运行,我的代码没有在屏幕上显示管道。我的代码如下: import pygame, neat, time, os, random ##import all of the variables we'll need for AI running pygame.font.init() ##enables using fonts/text on scre

根据YouTube上的教程,我创建了一个Flappy Bird游戏,使用python构建的整洁系统:

当我完成了所有的代码,在那里他运行它并且让游戏正常运行,我的代码没有在屏幕上显示管道。我的代码如下:


import pygame, neat, time, os, random
##import all of the variables we'll need for AI running
pygame.font.init()
##enables using fonts/text on screen.
WIN_WIDTH = 500
WIN_HEIGHT = 800
##define the size of the window. We're working with a GUI for flappy bird AI.

BIRD_IMGS = [pygame.transform.scale2x(pygame.image.load(os.path.join("imgs", "bird1.png"))), pygame.transform.scale2x(pygame.image.load(os.path.join("imgs", "bird2.png"))), pygame.transform.scale2x(pygame.image.load(os.path.join("imgs", "bird3.png")))]
##import the images of the bird from the images directory. There are three as to make up the states of flapping.

PIPE_IMG = pygame.transform.scale2x(pygame.image.load(os.path.join("imgs", "pipe.png")))
##import the texture for the pipes from the same directory.

BASE_IMG = pygame.transform.scale2x(pygame.image.load(os.path.join("imgs", "base.png")))
BG_IMG = pygame.transform.scale2x(pygame.image.load(os.path.join("imgs", "bg.png")))
##repeat for the ground and the background. They are seperate pieces as to allow for handling the collision with the ground being death.

STAT_FONT = pygame.font.SysFont("comicsans", 50)

class Bird: ##define the bird and its system as a class.
    IMGS = BIRD_IMGS ##easier system for calling back to our list of bird images
    MAX_ROTATION = 25
    ROT_VEL = 20
    ANIMATION_TIME = 5
    ##some definitions to do with making sure the bird can't just start spinning around aimlessly instead of looking like it should be going forward.

    def __init__(self, x, y): ##essentially telling the AI/game what the bird starts out as, and how to define each thing.
        self.x = x ##the distance forward on the screen
        self.y = y ##how high up on the screen the bird is
        self.tilt = 0 ##the angle the bird is at
        self.tick_count = 0 ##essentially handles all of the physics
        self.vel = 0 ##speed.
        self.height = self.y ##a bit more about the height
        self.img_count = 0 ##which image of the bird to be automatically loading (pre-flight)
        self.img = self.IMGS[0] ##references back to the IMGS variable at the start of the class, defining to the system that the 0 on the previous line means bird1.png

    def jump(self):
        self.vel = -10.5 ##tells the game where to start. 0,0 is in the top left. This is near to half way down.
        self.tick_count = 0 ##keeps track of when the last jump was. All for physics of bird.
        self.height = self.y ##where bird started from, where the bird is now.

    def move(self):
        self.tick_count += 1 ##it's jumped one, now the tick registers that.
        d = self.vel*self.tick_count + 1.5*self.tick_count**2 ##this is literally just a physics equation to calculate where the bird is going. Tells game how much player is moving up/down and how long player has been moving for.
        if d >= 16: ##assigning terminal velocity. Going much faster can make the game unplayable. If going faster than 16 pixels per second, just start going 16 pixels per second.
            d = 16 ##if d has gone higher than 16, just make it 16 again. Terminal velocity.
        if d < 0: ##if for some reason, there's no velocity, such as at the very start of the game, give a very slight jump boost of -2 pixels (upwards 2)
            d -= 2
        self.y = self.y + d ##make sure the new Y position is calculated with the variable we just made.
        if d < 0 or self.y < self.height + 50: ##assign bird tilting for model
            if self.tilt < self.MAX_ROTATION:
                self.tilt = self.MAX_ROTATION
        else:
            if self.tilt > -90: ##eventually, nosedive when going down.
                self.tilt -= self.ROT_VEL

    def draw(self, win): ##this one draws the bird and window onto the screen. It creates the window, adds the bird to it, etc. Kind of confusing, but I will try to keep the comments simple enough.
       self.img_count += 1 ##this just checks how many times/how long the current image of the bird has been on screen.
       if self.img_count < self.ANIMATION_TIME:
           self.img = self.IMGS[0]
       elif self.img_count < self.ANIMATION_TIME*2:
           self.img = self.IMGS[1]
       elif self.img_count < self.ANIMATION_TIME*3:
           self.img = self.IMGS[2]

       elif self.img_count == self.ANIMATION_TIME*4 + 1:
           self.img = self.IMGS[0]
           self.img_count = 0 ##essentially, this just does a check for how long each anim has been playing, and if it should change the image. It gets really complicated to actually explain though, so sorry.
       if self.tilt <= -80:
           self.img = self.IMGS[1]
           self.img_count = self.ANIMATION_TIME*2 ##this prevents frames being skipped.

       rotated_image = pygame.transform.rotate(self.img, self.tilt) ##this will rotate the bird using all of the logic we just defined above.
       new_rect = rotated_image.get_rect(center=self.img.get_rect(topleft = (self.x, self.y)).center) ##changes the center of rotation for the bird from the top left to the center of the screen.
       win.blit(rotated_image, new_rect.topleft)

    def get_mask(self):
        return pygame.mask.from_surface(self.img) ##to be used for accurate collision later.

class Pipe: ##now we make the pipes.
    GAP = 200 ##distance between each other.
    VEL = 5 ##how fast they're moving towards the left.

    def __init__(self, x):
        self.x = x ##position as last time.
        self.height = 0 ##height to be defined by a random system later.
        self.gap = 100 ##gap again to be updated by a random system later.
        self.top = 0 ##where the top pipe is. To be defined by random system later.
        self.bottom = 0 ##same as prior, but for the bottom pipe instead.
        self.PIPE_TOP = pygame.transform.flip(PIPE_IMG, False, True) ##flipping the top pipe. By default the model is upright, we need one going the other way as well.
        self.PIPE_BOTTOM = PIPE_IMG ##here's the bottom pipe now imported.
        self.passed = False ##has bird passed pipe? Default false
        self.set_height() ##set the height for the pipe, dealt with later.

    def set_height(self):
        self.height = random.randrange(50, 450) ##random height for the pipes.
        self.top = self.height - self.PIPE_TOP.get_height() ##defining the top pipe's height using the bottom pipe.
        self.bottom = self.height + self.GAP ##defining the distance between the pipes

    def move(self): ##defining the movement, just moving the pipes to the left.
        self.x -= self.VEL

    def draw(self, win): ##drawing the pipes as we want them to appear on screen
        win.blit(self.PIPE_TOP, (self.x, self.top))
        win.blit(self.PIPE_BOTTOM, (self.x, self.bottom))

    def collide(self, bird): ##this is all the code for PIXEL PERFECT collision. Instead of box collision, it checks to see if coloured pixels are overlapping to avoid deaths that didn't deserve to be deaths.
        bird_mask = bird.get_mask()
        top_mask = pygame.mask.from_surface(self.PIPE_TOP)
        bottom_mask = pygame.mask.from_surface(self.PIPE_BOTTOM) ##masks the images, allowing to spot pixels from blank space.

        top_offset = (self.x - bird.x, self.top - round(bird.y)) ##checks distance from bird, round is because we cannot have decimal numbers, so it rounds to nearest whole
        bottom_offset = (self.x - bird.x, self.bottom - round(bird.y))

        b_point = bird_mask.overlap(bottom_mask, bottom_offset) ##checks the first point of overlapping for bird and bottom pipe
        t_point = bird_mask.overlap(top_mask, top_offset) ##repeat for top pipe

        if t_point or b_point:
            return True

        return False

class Base:
    VEL = 5
    WIDTH = BASE_IMG.get_width()
    IMG = BASE_IMG

    def __init__(self, y): ##same as pipe and bird, defining all of the variables.
        self.y = y
        self.x1 = 0
        self.x2 = self.WIDTH
    def move(self): ##defining movement speed to velocity.
        self.x1 -= self.VEL
        self.x2 -= self.VEL

        if self.x1 + self.WIDTH < 0: ##it creates two versions of the image, one directly behind the other, therefore it looks like one continuous image. If one has left the screen completely, move it back to behind the other one and get going again.
            self.x1 = self.x2 + self.WIDTH
        if self.x2 + self.WIDTH < 0:
            self.x2 = self.x1 + self.WIDTH
    def draw(self, win):
        win.blit(self.IMG, (self.x1, self.y))
        win.blit(self.IMG, (self.x2, self.y))

def draw_window(win, birds, pipes, base, score):
    win.blit(BG_IMG, (0,0)) ##set up the background image for the game
    for pipe in pipes:
        pipe.draw(win) ##draw the pipes
    base.draw(win) ##draw the floor into the window
    for bird in birds:
        bird.draw(win) ##draw the bird into the window
    pygame.display.update() ##update the display
    text = STAT_FONT.render("Score: " + str(score), 1, (255,255,255))
    win.blit(text, (WIN_WIDTH - text.get_width() - 15, 10))

def main(genomes, config):
    nets = []
    ge = []
    birds = []
    for _, g in genomes:
        net = neat.nn.FeedForwardNetwork.create(g, config)
        nets.append(net)
        birds.append(Bird(230, 350))
        g.fitness = 0
        ge.append(g)
    base = Base(730) ##place the base of the window at 730
    pipes = [Pipe(600)]
    score = 0
    win = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT)) ##define the window.
    clock = pygame.time.Clock() ##start a clock so that the game runs at a consistent speed and is not relative to FPS(*COUGH* BETHESDA AND FALLOUT 76 *COUGH*)
    run = True ##by default of course, the game is running.
    while run: ##while the game is running. Pygame doesn't like to close without being informed prior.
        clock.tick(30) ##define the speed of that clock.
        for event in pygame.event.get(): ##keeps track of whenever something is triggered, such as user clicking mouse, or AI activating output
            if event.type == pygame.QUIT: ##check if the active event is a quit-based event to close the game.
                run = False ##tell run it is now false as to allow the while loop to stop.
                pygame.quit() ##when any quit function, such as clicking the red X is triggered (windows) it will close the game, and tell pygame and python to shut off.
                quit()

        pipe_ind = 0
        if len(birds) > 0:
            if len(pipes) > 1 and birds[0].x > pipes[0].x + pipes[0].PIPE_TOP.get_width():
                pipe_ind = 1
        else:
            run = False
            break
        for x, bird in enumerate(birds):
            bird.move()
            ge[x].fitness += 0.1

            output = nets[x].activate((bird.y, abs(bird.y - pipes[pipe_ind].height), abs(bird.y - pipes[pipe_ind].bottom)))

            if output[0] > 0.5:
                bird.jump()
        add_pipe = False
        base.move() ##moves the base.
        rem = []
        for pipe in pipes: ##it gets each pipe option in the list of pipes
            for x, bird in enumerate(birds):
                if pipe.collide(bird): ##if the pipe collides with the bird using specified collision in that section, kill player
                    ge[x].fitness -= 1
                    birds.pop(x)
                    nets.pop(x)
                    ge.pop(x)
                if not pipe.passed and pipe.x < bird.x: ##once the pipe has been passed by the bird, add a new one.
                    pipe.passed = True
                    add_pipe = True
            if pipe.x + pipe.PIPE_TOP.get_width() < 0: ##once the pipes has left the screen, remove the pipe, add it to a list of removed pipes
                rem.append(pipe)
                pipe.move() ##enable pipe movement.
        if add_pipe: ##add one score to the player once the pipe has been passed.
            score += 1
            for g in ge:
                g.fitness += 5
            pipes.append(Pipe(600))
        for r in rem:
            pipes.remove(r)
        for x, bird in enumerate(birds):
            if bird.y + bird.img.get_height() >= 730 or bird.y < 0: ##handling for bird hitting floor.
                birds.pop(x)
                nets.pop(x)
                ge.pop(x)

        draw_window(win, birds, pipes, base, score) ##calls the above draw window stuff



def run(config_path): ##start running the new config.
    config = neat.config.Config(neat.DefaultGenome, neat.DefaultReproduction, neat.DefaultSpeciesSet, neat.DefaultStagnation, config_path) ##pull in a ton of stuff for NEAT to work with

    p = neat.Population(config) ##set our population (how many AIs will go per generation/how many birds are on screen at once. The config is 100, as this is best for evolution-performance.)
    p.add_reporter(neat.StdOutReporter(True))
    stats = neat.StatisticsReporter()
    p.add_reporter(stats)

    winner = p.run(main,50)


if __name__ == "__main__":##loading in the config file to create the network.
    local_dir = os.path.dirname(__file__)
    config_path = os.path.join(local_dir, "config-feedforward.txt")
    run(config_path)

导入pygame、neat、time、os、random
##导入AI运行所需的所有变量
pygame.font.init()
##启用在屏幕上使用字体/文本。
宽度=500
WIN_高度=800
##定义窗口的大小。我们正在为flappy bird AI使用GUI。
BIRD_IMGS=[pygame.transform.scale2x(pygame.image.load(os.path.join(“IMGS”,“bird1.png”)))),pygame.transform.scale2x(pygame.image.load(“IMGS”,“bird2.png”)),pygame.transform.scale2x(pygame.image.load(os.path.join(“IMGS”,“bird3.png”))]
##从images目录导入鸟的图像。有三种方法组成拍打状态。
PIPE\u IMG=pygame.transform.scale2x(pygame.image.load(os.path.join(“imgs”、“PIPE.png”))
##从同一目录导入管道的纹理。
BASE\u IMG=pygame.transform.scale2x(pygame.image.load(os.path.join(“imgs”,“BASE.png”))
BG_IMG=pygame.transform.scale2x(pygame.image.load(os.path.join(“imgs”、“BG.png”))
##对地面和背景重复上述步骤。它们是分开的,以便处理与地面的碰撞。
STAT\u FONT=pygame.FONT.SysFont(“comicsans”,50)
类Bird:##将Bird及其系统定义为类。
IMGS=BIRD_IMGS###更简单的系统,用于返回我们的鸟类图像列表
最大旋转=25
ROT_等级=20
动画时间=5
##一些定义是为了确保鸟不能只是开始漫无目的地旋转,而不是看起来应该向前。
定义(self,x,y):##基本上告诉AI/游戏鸟开始时是什么,以及如何定义每一件事。
self.x=x##屏幕上向前的距离
self.y=y##这只鸟在屏幕上有多高
self.tilt=0##鸟所处的角度
self.tick_count=0##基本上处理所有物理
self.vel=0##速度。
self.height=self.y##关于高度的更多信息
self.img_count=0##自动加载的鸟的哪个图像(飞行前)
self.img=self.IMGS[0]##引用回类开头的IMGS变量,向系统定义上一行的0表示bird1.png
def跳转(自):
self.vel=-10.5告诉游戏从哪里开始。0,0位于左上角。这接近一半了。
self.tick_count=0##跟踪上次跳转的时间。所有这些都是关于鸟类的物理学。
self.height=self.y#鸟从哪里开始,现在在哪里。
def移动(自我):
self.tick_count+=1##它跳了一个,现在tick记录了它。
d=self.vel*self.tick_count+1.5*self.tick_count**2##这实际上只是一个计算鸟要去哪里的物理方程。告诉游戏有多少玩家上下移动以及玩家移动了多长时间。
如果d>=16:##指定终点速度。速度过快会使游戏无法进行。如果速度超过每秒16像素,就开始每秒16像素。
d=16##如果d高于16,只需再次将其设为16。终端速度
如果d<0:##如果由于某种原因,没有速度,例如在游戏开始时,会稍微增加-2像素的跳跃(向上2)
d-=2
self.y=self.y+d###确保新的y位置是使用我们刚刚创建的变量计算的。
如果d<0或self.y-90:##最终,下潜时俯冲。
自倾斜-=自旋转水平
def draw(self,win):##这一个将鸟和窗口绘制到屏幕上。它创建了一个窗口,给它添加了一只鸟,等等。有点让人困惑,但我会尽量让评论足够简单。
self.img_count+=1##这只是检查鸟的当前图像在屏幕上出现了多少次/多长时间。
如果self.img\u计数如果self.tilt您将
管道.move()缩进了太多次。
应该是

如果pipe.x+pipe.pipe\u TOP.get\u width()<0:
rem.append(管道)
管道。移动()#启用管道移动。

您是否有特定问题?我们不能期望为您调试整个程序,对吗?请看,。是的,我明白这一点。我提到了管道部分的问题,我只是不知道具体需要包括什么才能使管道部分有意义。