gpt4 book ai didi

python - 如何轻松更改代码的功能?

转载 作者:行者123 更新时间:2023-12-04 10:36:39 25 4
gpt4 key购买 nike

我想让我的游戏“返回”到主菜单,我想知道我是否可以在它自己的“内部”使用游戏窗口功能,以便它创建一个“重置”。基本上,如果我的 Sprite 碰撞并显示“游戏结束”,我想按“后退”按钮,如果我再次按播放,它会显示一个“重置”的游戏,其中“计时器”、“小行星” ”,“船”,仿佛又在玩一个新游戏一样回到了起点。

我还想知道给我的任何错误是否对我的问题有任何意义?

代码/游戏大部分都在工作。它只是没有“重置”的目的。

这是错误:

"C:\Users\Myke Sustento\AppData\Local\Programs\Python\Python38-32\python.exe" "B:/PROGRAMMING RELATED/PYTHON PROJECTS/FINAL.py"
B:/PROGRAMMING RELATED/PYTHON PROJECTS/FINAL.py:261: SyntaxWarning: "is" with a literal. Did you mean "=="?
if bullet_state is "fire":
B:/PROGRAMMING RELATED/PYTHON PROJECTS/FINAL.py:322: SyntaxWarning: "is" with a literal. Did you mean "=="?
if bullet_state is "ready":
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
B:/PROGRAMMING RELATED/PYTHON PROJECTS/FINAL.py:171: DeprecationWarning: an integer is required (got type float). Implicit conversion to integers using __int__ is deprecated, and may be removed in a future version of Python.
display.blit(ammoboximg,(x,y))
Traceback (most recent call last):
File "B:/PROGRAMMING RELATED/PYTHON PROJECTS/FINAL.py", line 374, in <module>
gamewindow()
File "B:/PROGRAMMING RELATED/PYTHON PROJECTS/FINAL.py", line 315, in gamewindow
gamewindow()
File "B:/PROGRAMMING RELATED/PYTHON PROJECTS/FINAL.py", line 315, in gamewindow
gamewindow()
File "B:/PROGRAMMING RELATED/PYTHON PROJECTS/FINAL.py", line 315, in gamewindow
gamewindow()
File "B:/PROGRAMMING RELATED/PYTHON PROJECTS/FINAL.py", line 330, in gamewindow
keys = pygame.key.get_pressed()
pygame.error: video system not initialized

Process finished with exit code 1

这是整个代码:
# initialization of pygame
import pygame
import random
import math


pygame.init()
# creating the display
display = pygame.display.set_mode((500, 500))

# title & icon
spaceship = pygame.image.load("Space Blitz Sprites/spaceship.png")
pygame.display.set_icon(spaceship)
pygame.display.set_caption("SpaceBlitz")

# main menu sprites
spaceblitz = pygame.image.load("Space Blitz Sprites/spaceblitz.png")
play = pygame.image.load("Space Blitz Sprites/play.png")
howtoplay = pygame.image.load("Space Blitz Sprites/howtoplay.png")
about = pygame.image.load("Space Blitz Sprites/about.png")
quit = pygame.image.load("Space Blitz Sprites/quit.png")

# inside main menu
instruction = pygame.image.load("Space Blitz Sprites/instruction.png")
back = pygame.image.load("Space Blitz Sprites/back.png")
aboutdev = pygame.image.load("Space Blitz Sprites/aboutdev.png")

# main menu music
music = pygame.mixer.music.load("Space Blitz Sprites/mountaintrails.mp3")

# PlayerSpriteMovement
playerimg = pygame.image.load("Space Blitz Sprites/spaceship.png")
playerX = 250
playerY = 400
velocity = 3
clock = pygame.time.Clock()

# Bullet
bulletimg = pygame.image.load("Space Blitz Sprites/bullet.png")
bulletX = 0
bulletY = playerY
bulletx_change = 0
bulletY_change = 8
bullet_state = "ready"
bullet_ammo = 5
bulletfont = pygame.font.Font('freesansbold.ttf', 16)
# Ammo Box
ammoboximg = pygame.image.load('Space Blitz Sprites/ammo.png')
ammoboxX = random.randint(0,468)
ammoboxY = random.randint(-1000,-800)
ammoboxY_change = -1.5

# Asteroid
asteroidimg = []
asteroidX = []
asteroidY = []
asteroidX_change = []
asteroidY_change = []
no_of_enemies = 40

def mainmenu():
global menuselect
global spaceblitz
menu = True
pygame.mixer.music.play(50)
pygame.mixer.music.set_volume(0.2)
while menu:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
pos = pygame.mouse.get_pos()
if start.collidepoint(pos):
menu = False
menuselect = 1
pygame.mixer.music.stop()
if controls.collidepoint(pos):
menu = False
menuselect = 2
pygame.mixer.music.stop()
if developer.collidepoint(pos):
menu = False
menuselect = 3
pygame.mixer.music.stop()
if exit.collidepoint(pos):
menu = False
menuselect = 4

display.fill((0, 0, 0))
display.blit(spaceblitz, (170,150))
start = display.blit(play, (170,250))
controls = display.blit(howtoplay, (170,300))
developer = display.blit(about, (170,350))
exit = display.blit(quit, (170,400))
pygame.display.flip()
pygame.display.update()

def controls():
global menuselect
global menu
controls = True
while controls:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
pos = pygame.mouse.get_pos()
if balik.collidepoint(pos):
controls = False
menu = True
menuselect = 0
balik = display.blit(back, (0,450))
display.blit(instruction, (0,0))
pygame.display.flip()
pygame.display.update()
display.fill((0, 0, 0))

def developers():
global menuselect
global menu
dev = True
while dev:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
pos = pygame.mouse.get_pos()
if balik.collidepoint(pos):
dev = False
menu = True
menuselect = 0
balik = display.blit(back, (0, 450))
display.blit(aboutdev, (0, 0))
pygame.display.flip()
pygame.display.update()
display.fill((0, 0, 0))

# Asteroid
for r in range(no_of_enemies):
asteroidimg.append(pygame.image.load("Space Blitz Sprites/asteroid.png"))
asteroidX.append(random.randint(-100, 500))
asteroidY.append(random.randint(-300, -30))
asteroidX_change.append(0)
asteroidY_change.append(2)




# Game Over Text
overfont = pygame.font.Font('freesansbold.ttf',32)


# Sprite image
def player(x, y):
display.blit(playerimg, (x, y))

def fire_bullet(x, y):
global bullet_state
if bullet_ammo > -1:
bullet_state = "fire"
display.blit(bulletimg, (x + 9, y + -7))
else:
bullet_state = "ready"

def ammobox(x,y):
display.blit(ammoboximg,(x,y))

def AmBoxCollision(ammoboxX,ammoboxY,playerX,playerY):
ammoboxdistance = math.sqrt((math.pow(ammoboxX - playerX, 2)) + (math.pow(ammoboxY - playerY, 2)))
if ammoboxdistance < 27:
return True
else:
return False

def ammo():
global bullet_ammo
global ammo_decrease
ammo_decrease = 1
bullet_ammo -= ammo_decrease



def asteroid(x, y, r):
display.blit(asteroidimg[r], (x, y))




def BulCollision(asteroidX, asteroidY, bulletX, bulletY):
buldistance = math.sqrt((math.pow(bulletX - asteroidX, 2)) + (math.pow(bulletY - asteroidY, 2)))
if buldistance < 27:
return True
else:
return False
def PlayCollision(asteroidX, asteroidY, playerX, playerY):
playdistance = math.sqrt((math.pow(playerX - asteroidX, 2)) + (math.pow(playerY - asteroidY, 2)))
if playdistance < 27:
return True
else:
return False
def gameover_screen():
overtext = overfont.render("GAME OVER",True,(255,255,255))
display.blit(overtext, (150,250))

# mainloop
def gamewindow():
global menuselect
global playerX
global playerY
global velocity
global clock
global bulletX
global bulletY
global bulletY_change
global bullet_state
global asteroidX
global asteroidY
global asteroidY_change
global no_of_enemies
global ammoboxX
global ammoboxY
global ammoboxY_change
global dev
global menu
global bullet_ammo
global ammo_decrease
global passed_time
font = pygame.font.Font(None, 54)
font_color = pygame.Color('white')
start_time = pygame.time.get_ticks()
run_timer = True
running = True

while running:
clock.tick(60)
display.fill((0, 0, 0))
AmmoBoxCollision = AmBoxCollision(ammoboxX,ammoboxY,playerX,playerY)
if AmmoBoxCollision:
ammoboxY = random.randint(-1000, -800)
ammoboxX = random.randint(0, 468)
if bullet_ammo <= 4 and bullet_ammo > -1:
bullet_ammo += 1
if bullet_ammo == -1:
bullet_ammo +=2


if bullet_ammo == -1 or bullet_ammo == 0:
bullet_text = bulletfont.render("Ammo:%d" % bullet_ammo, True, (0, 0, 0))
display.blit(bullet_text, (10, 468))
noammo = bulletfont.render("NO AMMO",True,(255,255,255))
display.blit(noammo,(10,468))
else:
bullet_text = bulletfont.render("Ammo:%d" % bullet_ammo, True, (255, 255, 255))
display.blit(bullet_text, (10, 468))

if bullet_state is "fire":
fire_bullet(bulletX, bulletY)
bulletY -= bulletY_change

if bulletY <= 0:
bulletY = playerY
bullet_state = "ready"

for r in range(no_of_enemies):
asteroid(asteroidX[r], asteroidY[r], r)
asteroidY[r] += asteroidY_change[r]
if asteroidY[r] >= 500:
asteroidY[r] = random.randint(-300, -30)
asteroidX[r] = random.randint(-100, 500)

Bulletcollision = BulCollision(asteroidX[r], asteroidY[r], bulletX, bulletY)
if Bulletcollision:
bulletY = playerY
bullet_state = "ready"
asteroidX[r] = random.randint(-100, 500)
asteroidY[r] = random.randint(-300, -30)

# Game over
PlayerCollision = PlayCollision(asteroidX[r], asteroidY[r], playerX, playerY)

if PlayerCollision:
for j in range(no_of_enemies):
asteroidY_change[j] = 0
asteroidY[j] = random.randint(-300, -30)
asteroidX[j] = random.randint(-100, 500)
asteroidY_change[j] = 2

velocity = 0
bulletY_change = 0
bulletY = 600
ammoboxY_change = 0
run_timer = False
gameover_screen()
playerX = 250
playerY = 400
velocity = 3


# movement
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()

if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
pos = pygame.mouse.get_pos()
if balik.collidepoint(pos):
running = False
menu = True
menuselect = 0


if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
if bullet_ammo <= 5 and bullet_ammo > -1:
if bullet_state is "ready":
bulletX = playerX
bulletY = playerY
fire_bullet(bulletX, bulletY)
ammo()


# player movement
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
playerX -= velocity

if keys[pygame.K_RIGHT]:
playerX += velocity

if keys[pygame.K_DOWN]:
playerY += velocity

if keys[pygame.K_UP]:
playerY -= velocity

# Border
if playerX <= 0:
playerX = 0
elif playerX >= 468:
playerX = 468
if playerY <= 0:
playerY = 0
elif playerY >= 468:
playerY = 468

if ammoboxY > 500:
ammoboxY = random.randint(-1000,-800)
ammoboxX = random.randint(0,468)
ammobox(ammoboxX,ammoboxY)
ammoboxY -= ammoboxY_change

if run_timer:
current_time = pygame.time.get_ticks()
passed_time = current_time - start_time

text = font.render(str(passed_time / 1000), True, font_color)
display.blit(text, (50, 50))
balik = display.blit(back, (350, 450))
player(playerX, playerY)
pygame.display.update()

mainmenu()
while True:
if menuselect == 0:
mainmenu()
elif menuselect == 1:
gamewindow()
elif menuselect == 2:
controls()
elif menuselect == 3:
developers()
elif menuselect == 4:
pygame.quit()

这是我想放置重置按钮的地方(在 PlayerCollision 或 balik.collidepoint(pos) 中)
        if PlayerCollision:
for j in range(no_of_enemies):
asteroidY_change[j] = 0
asteroidY[j] = random.randint(-300, -30)
asteroidX[j] = random.randint(-100, 500)
asteroidY_change[j] = 2

velocity = 0
bulletY_change = 0
bulletY = 600
ammoboxY_change = 0
run_timer = False
gameover_screen()
playerX = 250
playerY = 400
velocity = 3


# movement
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()

if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
pos = pygame.mouse.get_pos()
if balik.collidepoint(pos):
running = False
menu = True
menuselect = 0


if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
if bullet_ammo <= 5 and bullet_ammo > -1:
if bullet_state is "ready":
bulletX = playerX
bulletY = playerY
fire_bullet(bulletX, bulletY)
ammo()

如果我问了很多问题,我很抱歉。这是我用 Python 编写的第一个代码(或一般的编程),所以我真的不知道大多数东西是如何工作的。另外,代码是我的代码和我的队友的代码的混合,所以这个程序中的一半代码对我来说是陌生的。非常感谢有关 future 编码实践的提示,但我现在只想完成我的游戏,所以我想完成我遇到的当前(也是最后一个)问题。

最佳答案

正如您所说,您刚刚开始并正在学习。非常好!您刚刚遇到了一个可以从中学到很多东西的问题:添加新功能 .一般来说,这个问题更适合 code review stack exchange但我认为它也适合这里。

那么问题究竟出在哪里呢?你说你想让你的游戏“回到”主菜单。你提出了一个(我发现)难以遵循的实现,并跟进了一堆我确信有效但很难(对我来说)阅读的代码。老实说,我发现您能够写出多少令人印象深刻的东西,尤其是因为这是您第一次编码!

在我看来,您真正的问题不是如何“返回”,而是如何使您的代码可修复/可更新。非常值得学习的一课。您当前的代码难以更新有几个原因:

  • 您的所有代码都在一个文件中,难以导航
  • 您有全局变量,很难跟踪
  • 您使用了许多难以更改/跟踪
  • 的硬编码值。

    为什么这是个问题?如果你想改变一些东西,你找不到在哪里改变什么,因为你找不到任何东西,因为到处都是代码。然后,一旦找到它,由于全局变量,您无法真正了解所有内容。最后,硬编码值使您无法知道您是否已修复所有内容,或忘记了导致错误的数字(例如,您想将屏幕放大两倍,更改所有图片大小,但忘记更新速度)。

    那么你如何改变这种情况呢?

    好吧,首先尝试拆分您的代码,以便更轻松地查找内容。我喜欢把东西放在这样的文件夹中:
    my_project/
    main.py
    .gitignore
    core/
    game_mechanics/
    player.py
    bullet.py
    asteroid.py
    game_setup/
    main_menu.py
    run_game.py
    config/
    config.yaml
    utils/
    read_config.py
    tests/
    test1.py
    test2.py

    这可能看起来令人生畏,所以让我们超越一切:

    Main.py :您运行的主文件。它看起来像这样:
    from example_file import example_function

    def main(config):
    while True:
    settings = main_menu()
    play_game(settings)

    if __name__ == '__main__':
    config = load_config()
    main(config)

    当您运行时 main.py它将加载配置,然后运行主要组件。这个文件应该很短,所以很容易理解发生了什么。例如,在这里,您可以通过运行 main_menu() 获得设置。然后使用这些设置玩游戏。当游戏退出时,主菜单再次显示。

    接下来是 .gitignore 使用 git 时需要的文件。如果你不知道这是什么/你应该用谷歌搜索它,它会让你的生活更轻松。

    在您的 核心文件夹中包含游戏特有的所有主要功能。这是您放置大部分代码的地方。将其拆分为逻辑文件很重要,这样您就可以轻松找到内容。

    在您的 实用工具文件夹中,您有想要在项目之间共享的实用功能。

    在您的 配置文件夹,您可以存储设置。这应该包含您使用的所有“数字或字母值”,这样您就不必通过代码手动更改任何地方的数字(并且可能忘记一个),而是将其传递。

    这解决了您必须找到什么地方的问题。一切都很好地订购,您可以轻松找到它。如果您想更改大型功能(如添加新菜单),您可以在主文件中轻松完成此操作。

    下一个问题是全局变量的使用。你有很多这样的值,这使得很难跟踪哪个值是什么。您可能很清楚,但想象一下,当您一年后回来并且值“随机”改变时,您如何找到变化的地方?

    相反,尝试将内容传递给您的函数,如下所示:
    def square_n(n):
    return n * n

    a = 5
    a_squared = square_n(a)

    这使得更容易阅读在哪里发生了什么。

    最后,如前所述,硬编码值使所有内容都很难更新。以屏幕尺寸加倍为例。你把所有东西都放大了一倍,但忘记把一个速度分量加倍(因为你忽略了它)。这可能是一个“奇怪的错误”,需要一些时间来修复。相反,尝试将所有这些值保存在您的配置中,并如上所示传递它们。这看起来像这样:
    def print_hello_world_n_times(n):
    for i in range(n):
    print("hello world")

    config = load_config()
    # config = {'a': 5, 'b': 10}
    a = config['a']
    print_hello_world_n_times(a)

    很抱歉,我不会为您的问题提供复制粘贴解决方案。我认为对您来说,自己重新构造代码然后看看更改其功能要容易得多,这会更有用。

    成功!

    关于python - 如何轻松更改代码的功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60150950/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com