我正在用小行星之类的控件制作游戏,向上箭头用于加速,向右箭头顺时针旋转,向左箭头逆时针旋转,例如,如果我想减速,我需要将船旋转 180\xc2\xb0 并加速。\我能够旋转,为此我画了两个向量(速度和航向)。\n我正在尝试用向量实现这种类型的运动,但也许我不应该这样做?\n所以这就是我的想法。
\n\nimport pygame\nimport sys\nfrom pygame.locals import * # pygame.locals.QUIT --> QUIT\n# Vector2\nvec = pygame.math.Vector2\n\n# initialize pygame\npygame.init()\nFPS = 60 # frames per second\nfps_clock = pygame.time.Clock()\n# set up the window\nWIDTH = 800\nHEIGHT = 800\nDISPLAY = pygame.display.set_mode((WIDTH, HEIGHT))\npygame.display.set_caption(\'VECTOR_2\')\nFONT = pygame.font.Font(None, 24)\n# RGB colors\nRED = (255, 0, 0)\nGREEN = (0, 255, 0)\nBLUE = (0, 0, 255)\nWHITE = (255, 255, 255)\nBLACK = (0, 0, 0)\n\nMAX_SPEED = 9\n\n\nclass Player(pygame.sprite.Sprite):\n def __init__(self):\n pygame.sprite.Sprite.__init__(self)\n # set ship image\n self.image = pygame.Surface((70, 50), pygame.SRCALPHA)\n pygame.draw.polygon(self.image, (50, 120, 180), ((35, 0), (0, 35), (70, 35)))\n self.original_image = self.image\n self.rect = self.image.get_rect()\n self.rect.center = (WIDTH / 2, HEIGHT / 2)\n self.position = vec(WIDTH / 2, HEIGHT / 2)\n self.vel = vec(0, 0)\n self.acceleration = vec(0, 0)\n # heading vector\n self.heading = vec(0, -1) # upwards\n self.rect.center = self.position\n self.angle_speed = 0\n self.angle = 0\n\n def update(self):\n self.acceleration = vec(0, 0)\n keys = pygame.key.get_pressed()\n if keys[K_LEFT]:\n self.acceleration.x = -0.2\n if keys[K_RIGHT]:\n self.acceleration.x = 0.2\n\n if keys[K_UP]:\n self.acceleration.y = -0.2\n\n if keys[K_DOWN]:\n self.acceleration.y = 0.2\n\n if keys[K_a]:\n self.angle_speed = -1\n player.rotate()\n if keys[K_d]:\n self.angle_speed = 1\n player.rotate()\n # max speed\n if self.vel.length() > MAX_SPEED:\n self.vel.scale_to_length(MAX_SPEED)\n\n self.vel += self.acceleration\n self.position += self.vel\n\n self.rect.center = self.position\n\n def rotate(self):\n # rotate the heading vector\n self.heading.rotate_ip(self.angle_speed)\n self.angle += self.angle_speed\n if self.angle > 360:\n self.angle -= 360\n elif self.angle < 0:\n self.angle += 360\n self.image = pygame.transform.rotate(self.original_image, -self.angle)\n self.rect = self.image.get_rect(center=self.rect.center)\n\n def draw_vectors(self, screen):\n scale = 20\n # vel\n pygame.draw.line(screen, GREEN, self.position, (self.position + self.vel * scale), 5)\n # desired\n pygame.draw.line(screen, RED, self.position, (self.position + self.heading * scale), 5)\n\n def wrap_around_screen(self):\n """Wrap around screen."""\n if self.position.x > WIDTH:\n self.position.x = 0\n if self.position.x < 0:\n self.position.x = WIDTH\n if self.position.y <= 0:\n self.position.y = HEIGHT\n if self.position.y > HEIGHT:\n self.position.y = 0\n\nall_sprites = pygame.sprite.Group()\nplayer = Player()\nall_sprites.add(player)\n\nwhile True: # game loop\n for event in pygame.event.get():\n if event.type == QUIT:\n pygame.quit()\n sys.exit()\n\n DISPLAY.fill(BLACK)\n player.wrap_around_screen()\n all_sprites.update()\n all_sprites.draw(DISPLAY)\n player.draw_vectors(DISPLAY)\n txt = FONT.render(\'angle {:.1f}\'.format(player.angle), True, (150, 150, 170))\n DISPLAY.blit(txt, (10, 10))\n pygame.display.update()\n fps_clock.tick(FPS)\nRun Code Online (Sandbox Code Playgroud)\n\n任何帮助,将不胜感激
\n您可以给self.acceleration向量一个初始长度(在本例中为 0.2),如果玩家按下 ← 或 → 则旋转它,并且只有按下self.vel↑ 或 ↓ 时才加速(将其添加到向量中)。
import sys
import pygame
from pygame.locals import *
vec = pygame.math.Vector2
pygame.init()
FPS = 60
fps_clock = pygame.time.Clock()
WIDTH = 800
HEIGHT = 800
DISPLAY = pygame.display.set_mode((WIDTH, HEIGHT))
BLACK = (0, 0, 0)
MAX_SPEED = 9
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((70, 50), pygame.SRCALPHA)
pygame.draw.polygon(self.image, (50, 120, 180), ((35, 0), (0, 35), (70, 35)))
self.original_image = self.image
self.position = vec(WIDTH / 2, HEIGHT / 2)
self.rect = self.image.get_rect(center=self.position)
self.vel = vec(0, 0)
self.acceleration = vec(0, -0.2) # The acceleration vec points upwards.
self.angle_speed = 0
self.angle = 0
def update(self):
keys = pygame.key.get_pressed()
if keys[K_LEFT]:
self.angle_speed = -1
player.rotate()
if keys[K_RIGHT]:
self.angle_speed = 1
player.rotate()
# If up or down is pressed, accelerate the ship by
# adding the acceleration to the velocity vector.
if keys[K_UP]:
self.vel += self.acceleration
if keys[K_DOWN]:
self.vel -= self.acceleration
# max speed
if self.vel.length() > MAX_SPEED:
self.vel.scale_to_length(MAX_SPEED)
self.position += self.vel
self.rect.center = self.position
def rotate(self):
# Rotate the acceleration vector.
self.acceleration.rotate_ip(self.angle_speed)
self.angle += self.angle_speed
if self.angle > 360:
self.angle -= 360
elif self.angle < 0:
self.angle += 360
self.image = pygame.transform.rotate(self.original_image, -self.angle)
self.rect = self.image.get_rect(center=self.rect.center)
def wrap_around_screen(self):
"""Wrap around screen."""
if self.position.x > WIDTH:
self.position.x = 0
if self.position.x < 0:
self.position.x = WIDTH
if self.position.y <= 0:
self.position.y = HEIGHT
if self.position.y > HEIGHT:
self.position.y = 0
all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
player.wrap_around_screen()
all_sprites.update()
DISPLAY.fill(BLACK)
all_sprites.draw(DISPLAY)
pygame.display.set_caption('angle {:.1f} accel {} accel angle {:.1f}'.format(
player.angle, player.acceleration, player.acceleration.as_polar()[1]))
pygame.display.update()
fps_clock.tick(FPS)
Run Code Online (Sandbox Code Playgroud)