首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >游戏中的蛇游戏

游戏中的蛇游戏
EN

Code Review用户
提问于 2017-02-12 14:10:57
回答 1查看 743关注 0票数 5

这是我的第一个游戏,并寻求一些帮助来改进当前的代码,因为我已经确定了很多我认为可以更有效地编写的代码,特别是检查哪个键被按下的片段,但是我不知道如何改进它。

代码语言:javascript
复制
import pygame
from pygame.locals import *
import random
import sys


pygame.init()

FPS = 30
fpsClock = pygame.time.Clock()

WIN_WIDTH = 680 #width of window
WIN_HEIGHT = 500 #height of window

DISPLAY = (WIN_WIDTH, WIN_HEIGHT) #variable for screen display
DEPTH = 32 #standard
FLAGS = 0 #standard
BLACK = (0, 0, 0) #black
RED = (255, 0, 0) #red
GOLD = (255, 215, 0)
LOL = (14, 18, 194)
YOLO = (155, 98, 245)
WHITE = (255, 255, 255)

screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
pygame.display.set_caption('Snaek')                                      

collision_coords = [1]
snake_parts = [1]
Score = 0
speed = 12
snakex = 125
snakey = 70
size = 20


# --- classes ---
class Snake(pygame.Rect):
    def __init__(self, x, y, screen, size, colour):
        pygame.Rect.__init__(self, x, y, size, 20)
        self.screen = screen
        self.colour = colour
        self.x = x
        self.y = y


    def draw(self, screen):
        pygame.draw.rect(self.screen, self.colour, self)

    def coordinates(self):
        return self.x, self.y

class Food(pygame.Rect):
    def __init__(self, x, y, screen):
        pygame.Rect.__init__(self, x, y, 20, 20)
        self.screen = screen

    def draw(self, screen):
        pygame.draw.rect(self.screen, GOLD, self)

class Barrier(pygame.Rect):

    def __init__(self, x, y, screen):
        pygame.Rect.__init__(self, x, y, 40, 20)
        self.screen = screen 
    def draw(self, screen):
        pygame.draw.rect(self.screen, LOL, self)

class GameMenu():
    def __init__(self, screen, options):
        self.screen = screen
        self.options = options



# --- functions ---
def get_food_pos(WIN_WIDTH, WIN_HEIGHT):
    WIN_WIDTH = random.randint(100, WIN_WIDTH-150)
    WIN_HEIGHT = random.randint(100, WIN_HEIGHT-150)
    return WIN_WIDTH, WIN_HEIGHT

def texts(score):
   font=pygame.font.Font(None,30)
   scoretext=font.render("Score:"+' ' + str(score), 1,(255,255,255))
   screen.blit(scoretext, (500, 15))








eaten = True
pressed_right = True
pressed_left = False
pressed_up = False
pressed_down = False
pygame.key.set_repeat(10,10)

level = [
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP", 
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",                                          
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
]

def display_menu():
    while True:
        screen.fill(BLACK)
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONUP:
                pos = pygame.mouse.get_pos()
                if 385 > pos[0] > 275:
                    if 202 > pos[1] > 185:
                        return
                    elif 293 > pos[1] > 275:
                        pygame.quit()
                        sys.exit()    
                    else:
                        pass



        font = pygame.font.Font(None, 30)
        play_game = font.render("Play Game", 1, WHITE)
        quit_game = font.render("Quit Game", 1, WHITE)

        screen.blit(play_game, (275, 185))
        screen.blit(quit_game, (275, 275))
        pygame.display.update()
        fpsClock.tick(FPS)    


display_menu()

while True:
    screen.fill(BLACK)

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

        elif event.type == pygame.KEYDOWN:          # check for key presses          
            if event.key == pygame.K_LEFT:
                if pressed_right:
                    pressed_right = True# left arrow turns left
                else:
                    pressed_left = True
                    pressed_right = False
                    pressed_up = False
                    pressed_down = False
            elif event.key == pygame.K_RIGHT:
                if pressed_left:
                    pressed_left = True# right arrow turns right
                else: 
                    pressed_right = True
                    pressed_left = False
                    pressed_up = False
                    pressed_down = False
            elif event.key == pygame.K_UP:
                if pressed_down:# up arrow goes up
                    pressed_down = True
                else:
                    pressed_up = True
                    pressed_right = False
                    pressed_left = False
                    pressed_down = False
            elif event.key == pygame.K_DOWN:
                if pressed_up:
                    break
                else:
                    pressed_down = True
                    pressed_right = False
                    pressed_up = False
                    pressed_left = False

    x = snakex
    y = snakey
    collision_coords = [1]



    if pressed_left:
        snakex -= speed
    elif pressed_right:
        snakex += speed
    elif pressed_up:
        snakey -= speed
    elif pressed_down:
        snakey += speed

    snake_parts[0] = Snake(snakex, snakey, screen, int(size), RED)
    collision_coords[0] = snake_parts[0].coordinates()
    snake_parts[0].draw(screen)



    if eaten:
        foodx, foody = get_food_pos(WIN_WIDTH, WIN_HEIGHT)
        eaten = False

    my_food = Food(foodx, foody, screen)
    my_food.draw(screen)

    if snake_parts[0].colliderect(my_food):
        eaten = True
        screen.fill(BLACK)
        a_snake = Snake(snakex, snakey, screen, int(size), RED)
        snake_parts.append(a_snake)
        Score += 1


    for i in range(1, len(snake_parts)):
        tempx, tempy = snake_parts[i].coordinates()
        snake_parts[i] = Snake(x, y, screen, int(size), RED)
        collision_coords.append(snake_parts[i].coordinates())
        snake_parts[i].draw(screen)
        x, y = tempx, tempy





    platform_x = 0
    platform_y = 0

    for row in level:
        for col in row:
            if col == "P":
                col = Barrier(platform_x, platform_y, screen)
                col.draw(screen)
                if snake_parts[0].colliderect(col):
                    pygame.quit()
                    sys.exit()

            platform_x += 15
        platform_y += 20
        platform_x = 0

    for i in range(2, len(collision_coords)):
        if int(collision_coords[0][1]) == int(collision_coords[i][1]) and int(collision_coords[0][0]) == int(collision_coords[i][0]):
            pygame.quit()
            sys.exit()    

    texts(Score)



    pygame.display.update()
    fpsClock.tick(FPS) 
EN

回答 1

Code Review用户

回答已采纳

发布于 2017-02-12 19:00:22

有相当多的代码,所以我将指出我注意到的前几件事。

  • 命名:您有一些常量--所有大写都是好的,但也有小写的常量和一个(Score)的常量,两者都不是。我要说的是,对于常量,要坚持所有的大写。
  • 小错误(Snaek)
  • xy并没有说太多,但是你用它们作为蛇的老位置,所以可能把它们重命名为orig_xorig_y
  • pygame.key.set_repeat(10, 10)在这里是无用的,你可以删除它。
  • get_food_pos获取屏幕的宽度和高度作为参数,但不需要用相同的方式命名它们,这实际上是非常误导的。简单地将它们命名为widthheight,并返回food_xfood_y,而不是相同的变量。

现在开始执行。

  • 是的,按键处理程序可以用较少的代码编写。您可以有一个键按的数组,并使用这些值来确定您应该去的地方。

您可以这样初始化它:

代码语言:javascript
复制
(LEFT, RIGHT, UP, DOWN) = (0, 1, 2, 3)
pressed = [0, 1, 0, 0]

在主循环中,这样使用它:

代码语言:javascript
复制
for event in pygame.event.get():
    if event.type == QUIT:
        pygame.quit()
        sys.exit()
    elif event.type == pygame.KEYDOWN:          # check for key presses
        if event.key == pygame.K_LEFT and not pressed[RIGHT]:
            pressed = [-1, 0, 0, 0]
        elif event.key == pygame.K_RIGHT and not pressed[LEFT]:
            pressed = [0, 1, 0, 0]
        elif event.key == pygame.K_UP and not pressed[DOWN]:
            pressed = [0, 0, -1, 0]
        elif event.key == pygame.K_DOWN and not pressed[UP]:
            pressed = [0, 0, 0, 1]

snakex += speed * (pressed[LEFT] + pressed[RIGHT])
snakey += speed * (pressed[UP] + pressed[DOWN])

这里发生的是,如果按下其中一个键,数组将包含所有的零值,但按下的键除外。那里的值将是负的或正的,这取决于方向,所以你可以简单地把结果相加并乘以你的速度。

显示菜单也可以用不同的方式编写。

  • 首先,我希望返回一个值,并使用它来确定用户是否想退出。然后我会把它重命名为类似get_menu_choice的东西。
  • 如果不更改任何内容,就不需要不断地重新绘制,因此绘图代码可以在while循环之外。
  • 如果您想检测任何东西和矩形之间的冲突,那么就有一个特定的方法。你得到你的鼠标位置,并检查它是否与一个矩形碰撞。

总之,类似这样的事情:

代码语言:javascript
复制
def get_menu_choice():
    screen.fill(BLACK)
    font = pygame.font.Font(None, 30)
    play_game = font.render("Play Game", 1, WHITE)
    quit_game = font.render("Quit Game", 1, WHITE)

    screen.blit(play_game, (275, 185))
    screen.blit(quit_game, (275, 275))
    pygame.display.update()
    fpsClock.tick(FPS)

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
        pos = pygame.mouse.get_pos()
        (mouse_clicked, _, __) = pygame.mouse.get_pressed()
        start_game_rect = pygame.Rect(275, 185, 110, 27)
        quit_game_rect = pygame.Rect(275, 275, 110, 27)
        if mouse_clicked:
            if start_game_rect.collidepoint(pos):
                return 1
            if quit_game_rect.collidepoint(pos):
                return 0

if get_menu_choice() == 0:
    pygame.quit()
    sys.exit()
票数 6
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/155162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档