微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ubuntu pygame 窗口未显示在蛇中

如何解决ubuntu pygame 窗口未显示在蛇中

所以,我正在观看 youtube 上的视频,关于使用 pygame 模块在 Python 上制作 Snake 游戏.. 这很令人困惑.. 现在我遇到了一个问题.. pygame 窗口突然打开和关闭,然后输出中没有错误

我运行了这堆代码

import os
os.environ['disPLAY'] = ': 0.0' 
import pygame
pygame.init()
import random
from enum import Enum
from collections import namedtuple

font = pygame.font.Font('PermanentMarker-Regular.ttf',25)
#font = pygame.font.SysFont('arial',25)

class Direction(Enum):
    RIGHT = 1
    LEFT = 2
    UP = 3
    DOWN = 4


Point = namedtuple('Point',('x','y'))

WHITE = (255,255,255)
RED = (247,33,25)
BLUE = (0,255)
CYAN = (255,1)
BLACK = [0,0]


BLOCK_SIZE = 20
SPEED = 40
class SnakeGame:
    def __init__(self,w=640,h=480):
        self.w = w
        self.h = h
        # init display
        self.display = pygame.display.set_mode((self.w,self.h))
        pygame.display.set_caption("Snake")
        self.clock = pygame.time.Clock()


        # init game state 
        self.direction = Direction.RIGHT

        self.head = Point(self.w/2,self.h/2)
        self.snake = [self.head,Point(self.head.x-BLOCK_SIZE,self.head.y),Point(self.head.x-(2*BLOCK_SIZE),self.head.y)]

        self.score = 0
        self.food = None
        self._place_food()

    def _place_food(self):
        x = random.randint(0,(self.w-BLOCK_SIZE)//BLOCK_SIZE) * BLOCK_SIZE
        y = random.randint(0,(self.h-BLOCK_SIZE)//BLOCK_SIZE) * BLOCK_SIZE
        self.food = Point(x,y)
        if self.food in self.snake:
            self._place_food()
            self.head = Point(x,y)        

    def _move(self,direction):
        x = self.head.x
        y = self.head.y
        if direction == Direction.RIGHT:
            x += BLOCK_SIZE
        elif direction == Direction.LEFT:
            x -= BLOCK_SIZE
        elif direction == Direction.UP:
            y -= BLOCK_SIZE
        elif direction == Direction.DOWN:
            y += BLOCK_SIZE

    def _is_collision(self):
        # hits boundary
        if self.head.x > self.w - BLOCK_SIZE or self.head.x < 0 or self.head.y > self.h - BLOCK_SIZE or self.head.y < 0:
            return True
        # hits itself
        if self.head in self.snake[1:]:
            return True
        return False

        pygame.display.flip()



    def play_step(self):
        # collect user input
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    self.direction = Direction.LEFT
                elif event.key == pygame.K_RIGHT:
                    self.direction = Direction.RIGHT
                elif event.key == pygame.K_UP:
                    self.direction = Direction.UP
                elif event.key == pygame.K_DOWN:
                    self.direction = Direction.DOWN
        #2. move
        self._move(self.direction)
        self.snake.insert(0,self.head)

        #3. check if game over
        game_over = False
        if self._is_collision():
            game_over = True
        #4. place new food or move snake
        if self.head == self.food:
            self.score += 1
            self._place_food()
        else:
            self.snake.pop()

        #5. update ui and clock
        self._update_ui()
        self.clock.tick(SPEED)
        #6. return game over and score
        return game_over,self.score

    def _update_ui(self):
        self.display.fill(BLACK)
    
        for pt in self.snake:
            pygame.draw.rect(self.display,CYAN,pygame.Rect(pt.x,pt.y,BLOCK_SIZE,BLOCK_SIZE))
            pygame.draw.rect(self.display,BLUE,pygame.Rect(pt.x+4,pt.y+4,12,12))
        
        pygame.draw.rect(self.display,RED,pygame.Rect(self.food.x,self.food.y,BLOCK_SIZE))

        text = font.render("score:",str(self.score),True,WHITE)
        self.display.blit(text,[0,0])

if __name__ == '__main__':
    game = SnakeGame()

    # game loop
    while True:
        game_over,score = game.play_step()

        if game_over == True:
            break
    print("Final score {}".format(score))
        # break if game over


    pygame.quit()

问题可能是因为我放错了一个方法或在脚本中做了一些事情..

解决方法

有4个问题:

  1. head 方法之后更新 move() 属性:
class SnakeGame:
    # [...]

    def _move(self,direction):
        x = self.head.x
        y = self.head.y
        if direction == Direction.RIGHT:
            x += BLOCK_SIZE
        elif direction == Direction.LEFT:
            x -= BLOCK_SIZE
        elif direction == Direction.UP:
            y -= BLOCK_SIZE
        elif direction == Direction.DOWN:
            y += BLOCK_SIZE

        self.head = Point(x,y)        # <--- this is missing
  1. 您必须连接乐谱文本的字符串(请参阅 TypeError: Invalid foreground RGBA argument):

text = font.render("Score:",str(self.score),True,WHITE)

text = font.render("Score:" + str(self.score),WHITE)
  1. 绘制场景后更新显示:
def _update_ui(self):
        self.display.fill(BLACK)
    
        for pt in self.snake:
            pygame.draw.rect(self.display,CYAN,pygame.Rect(pt.x,pt.y,BLOCK_SIZE,BLOCK_SIZE))
            pygame.draw.rect(self.display,BLUE,pygame.Rect(pt.x+4,pt.y+4,12,12))
        
        pygame.draw.rect(self.display,RED,pygame.Rect(self.food.x,self.food.y,BLOCK_SIZE))

        text = font.render("Score:" + str(self.score),WHITE)
        self.display.blit(text,[0,0])
        
        pygame.display.flip()          # <--- this is missing
  1. 使用 pygame.time.Clock 控制每秒帧数,从而控制游戏速度。

tick() 对象的方法 pygame.time.Clock 以这种方式延迟游戏,即循环的每次迭代消耗相同的时间段。见pygame.time.Clock.tick()

这个方法应该每帧调用一次。

if __name__ == '__main__':
    game = SnakeGame()

    # game loop
    clock = pygame.time.Clock()
    while True:
        clock.tick(10)

        game_over,score = game.play_step()

        if game_over == True:
            break
    print("Final score {}".format(score))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。