【发布时间】:2021-05-04 08:58:16
【问题描述】:
这是我在这里写的第一篇文章。通过从这里获得的几个教程和一些建议,我创建了简单的游戏。 有人可以看看代码吗?有没有更好的方法来构建这些功能? 我知道它看起来很乱,但至少它的工作;) 因为这是我的第一场比赛,我真的很喜欢它。这是我的代码 game.py 文件中的代码:
import sys
import pygame
from rocket import Rocket
class Game(object):
def __init__(self):
# configuration
self.tps_max = 100.0
# initialization
pygame.init()
self.screen = pygame.display.set_mode((1280, 720))
self.screen_rect = self.screen.get_rect()
self.tps_clock = pygame.time.Clock()
self.tps_delta = 0.0
self.player = Rocket(self)
game = True
while game is True:
# Handle events
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit(0)
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
sys.exit(0)
# ticking
self.tps_delta += self.tps_clock.tick() / 1000.0
while self.tps_delta > 1 / self.tps_max:
self.tick()
self.tps_delta -= 1 / self.tps_max
# drawing
self.screen.fill((164, 222, 245))
self.draw()
pygame.display.flip()
def tick(self):
# check input
self.player.tick()
def draw(self):
self.player.draw()
if __name__ == "__main__":
Game()
Rocket.py 文件中的代码:
import pygame
import random
import math
import sys
from pygame.math import Vector2
pygame.font.init()
font = pygame.font.Font(None, 30)
class Rocket(object):
def __init__(self, game):
self.game_over = False
self.game = game
size = self.game.screen.get_size()
self.speed = 3.0
self.wind_force = 0.2
self.wind_angle = random.randint(0, 359)
self.current_force = 0.1
self.current_angle = random.randint(0, 359)
self.random_change = 0
self.pos = Vector2(size[0] / 2, size[1] / 2)
self.vel = Vector2(0, 0)
self.acc = Vector2(0, 0)
# heading vector
self.heading = self.vel.angle_to(Vector2(0, 1))
self.angle_speed = 0
def addforce(self, force):
self.acc += force
def tick(self):
# Input
pressed = pygame.key.get_pressed()
if pressed[pygame.K_w]:
self.addforce(Vector2(0, -self.speed * 0.6).rotate(self.heading))
if pressed[pygame.K_s]:
self.addforce(Vector2(0, self.speed * 0.3).rotate(self.heading))
# self.addforce(Vector2(0, self.speed))
if pressed[pygame.K_d]:
self.addforce(Vector2(0, self.speed * 0.3).rotate(self.heading - 90))
if pressed[pygame.K_a]:
self.addforce(Vector2(0, self.speed * 0.3).rotate(self.heading + 90))
if pressed[pygame.K_q]:
self.angle_speed -= 1
if pressed[pygame.K_e]:
self.angle_speed += 1
# Physics
self.wind_angle = (self.wind_angle + random.randint(-2, 2)) % 360
self.wind_force += ((random.randint(-1, 2)) / 1000)
self.current_angle = (self.current_angle + 0.1 * random.randint(-1, 1)) % 360
self.current_force += ((random.randint(-1, 2)) / 1000)
self.vel *= 0.5
self.vel += Vector2(0, self.wind_force).rotate(self.wind_angle)
self.vel += Vector2(0, self.current_force).rotate(self.current_angle)
self.vel += self.acc
self.pos += self.vel
self.acc *= 0.5
self.angle_speed *= 0.5
self.heading = (self.heading + self.angle_speed) % 360
# offset
# check distance from centre to vessel pos
self.offset = math.hypot(((self.vel[0] - self.pos[0]) + 640), ((self.vel[1] - self.pos[1]) + 360))
# offset as 1
self.offset /= 750
# offset as accuracy in %
self.offset = int((1 - self.offset) * 100)
# gamer over to do
if self.offset < 0:
sys.exit(0)
else:
pass
def draw(self):
# base shape
vessel = [Vector2(5, 10), Vector2(-5, 10), Vector2(-5, -10), Vector2(0, -15), Vector2(5, -10)]
wind_arrow = [Vector2(0, 10), Vector2(0, 20), Vector2(20, 20), Vector2(20, 30), Vector2(30, 15), Vector2(20, 0),
Vector2(20, 10)]
current_arrow = [Vector2(0, 10), Vector2(0, 20), Vector2(20, 20), Vector2(20, 30), Vector2(30, 15),
Vector2(20, 0),
Vector2(20, 10)]
# rotating points
vessel = [p.rotate(self.heading) for p in vessel]
wind_arrow = [p.rotate(self.wind_angle + 90) for p in wind_arrow]
current_arrow = [p.rotate(self.current_angle + 90) for p in current_arrow]
# centered position & scale
vessel = [self.pos + p * 6 for p in vessel]
wind_arrow = [self.pos + p for p in wind_arrow]
current_arrow = [self.pos + p for p in current_arrow]
# draw shape
pygame.draw.polygon(self.game.screen, (255, 177, 10), vessel)
pygame.draw.polygon(self.game.screen, (233, 66, 245), wind_arrow)
pygame.draw.polygon(self.game.screen, (22, 57, 217), current_arrow)
def write(text, location, color=(0, 0, 0)):
self.game.screen.blit(font.render(text, True, color), location)
write(" Accuracy:" + str(self.offset), (20, 10))
write('Wind direction: ' + str(round(self.wind_angle)) + "deg . Wind force: " + str(
round((self.wind_force * 10), 2)), (20, 40))
write('Current direction: ' + str(round(self.current_angle)) + "deg . Current force: " + str(
round(self.current_force, 2)),
(20, 60))
# def writegameover(text, location, color=(0, 0, 0)):
# self.game.screen.blit(font.render(text, True, color), location)
# if self.game_over:
# writegameover(" GAME OVER", (200, 100))
我很高兴我所拥有的,这比我预期的要容易。更少我了解所有代码。我可以做一些小的修改,但我知道我的游戏远非完美。 除了清理和优化之外,我无法处理的问题是游戏结束屏幕。 我不知道game_over方法()放在哪里。现在我刚刚设置在满足 game_over 条件时退出游戏,但我想显示一些带有问题“再次玩?”的游戏结束屏幕有一些分数。我知道最好的解决方案是实现状态 Running、reset、game_over 等,但这对我来说太复杂了。 你能帮我解决这个问题吗?同样,请理解这是我的第一个 python 应用程序,所以你们的任何建议将不胜感激。
经过一些修改,我的 Rocket.py 文件仍然没有显示 Game over subtitle:
import pygame
import random
import math
import sys
from pygame.math import Vector2
pygame.font.init()
font = pygame.font.Font(None, 30)
class Rocket(object):
def __init__(self, game):
self.game_over = False
self.game = game
size = self.game.screen.get_size()
self.speed = 3.0
self.wind_force = 0.2
self.wind_angle = random.randint(0, 359)
self.current_force = 0.1
self.current_angle = random.randint(0, 359)
self.random_change = 0
self.pos = Vector2(size[0] / 2, size[1] / 2)
self.vel = Vector2(0, 0)
self.acc = Vector2(0, 0)
# heading vector
self.heading = self.vel.angle_to(Vector2(0, 1))
self.angle_speed = 0
def addforce(self, force):
self.acc += force
def tick(self):
# Input
pressed = pygame.key.get_pressed()
if pressed[pygame.K_w]:
self.addforce(Vector2(0, -self.speed * 0.6).rotate(self.heading))
if pressed[pygame.K_s]:
self.addforce(Vector2(0, self.speed * 0.3).rotate(self.heading))
# self.addforce(Vector2(0, self.speed))
if pressed[pygame.K_d]:
self.addforce(Vector2(0, self.speed * 0.3).rotate(self.heading - 90))
if pressed[pygame.K_a]:
self.addforce(Vector2(0, self.speed * 0.3).rotate(self.heading + 90))
if pressed[pygame.K_q]:
self.angle_speed -= 1
if pressed[pygame.K_e]:
self.angle_speed += 1
# Physics
self.wind_angle = (self.wind_angle + random.randint(-2, 2)) % 360
self.wind_force += ((random.randint(-1, 2)) / 1000)
self.current_angle = (self.current_angle + 0.1 * random.randint(-1, 1)) % 360
self.current_force += ((random.randint(-1, 2)) / 1000)
self.vel *= 0.5
self.vel += Vector2(0, self.wind_force).rotate(self.wind_angle)
self.vel += Vector2(0, self.current_force).rotate(self.current_angle)
self.vel += self.acc
self.pos += self.vel
self.acc *= 0.5
self.angle_speed *= 0.5
self.heading = (self.heading + self.angle_speed) % 360
# offset
# check distance from centre to vessel pos
self.offset = math.hypot(((self.vel[0] - self.pos[0]) + 640), ((self.vel[1] - self.pos[1]) + 360))
# offset as 1
self.offset /= 750
# offset as accuracy in %
self.offset = int((1 - self.offset) * 100)
# gamer over to do
if self.offset < 0:
# sys.exit(0)
self.writegameover(" GAME OVER:", (200, 100))
else:
pass
def draw(self):
# base shape
vessel = [Vector2(5, 10), Vector2(-5, 10), Vector2(-5, -10), Vector2(0, -15), Vector2(5, -10)]
wind_arrow = [Vector2(0, 10), Vector2(0, 20), Vector2(20, 20), Vector2(20, 30), Vector2(30, 15), Vector2(20, 0),
Vector2(20, 10)]
current_arrow = [Vector2(0, 10), Vector2(0, 20), Vector2(20, 20), Vector2(20, 30), Vector2(30, 15),
Vector2(20, 0),
Vector2(20, 10)]
# rotating points
vessel = [p.rotate(self.heading) for p in vessel]
wind_arrow = [p.rotate(self.wind_angle + 90) for p in wind_arrow]
current_arrow = [p.rotate(self.current_angle + 90) for p in current_arrow]
# centered position & scale
vessel = [self.pos + p * 6 for p in vessel]
wind_arrow = [self.pos + p for p in wind_arrow]
current_arrow = [self.pos + p for p in current_arrow]
# draw shape
pygame.draw.polygon(self.game.screen, (255, 177, 10), vessel)
pygame.draw.polygon(self.game.screen, (233, 66, 245), wind_arrow)
pygame.draw.polygon(self.game.screen, (22, 57, 217), current_arrow)
def write(text, location, color=(0, 0, 0)):
self.game.screen.blit(font.render(text, True, color), location)
write(" Accuracy:" + str(self.offset), (20, 10))
write('Wind direction: ' + str(round(self.wind_angle)) + "deg . Wind force: " + str(
round((self.wind_force * 10), 2)), (20, 40))
write('Current direction: ' + str(round(self.current_angle)) + "deg . Current force: " + str(
round(self.current_force, 2)),
(20, 60))
def writegameover(self, text, location, color=(0, 0, 0)):
self.game.screen.blit(font.render(text, True, color), location)
【问题讨论】:
-
嗨 Dan3el,欢迎!我很高兴你在这里得到了一些答案,但对于未来,我想我会推荐一种不同的方式在这里发帖,以最大限度地提高你得到好的答案的机会。尝试直接在标题或第一句话中解决问题。背景很好,但如果人们必须阅读大量背景,他们可能不会。我建议在一开始就说“有没有更好的方法来构建这些功能”。无论如何,我希望这对您将来有所帮助。祝你好运
标签: python pygame code-cleanup