我正在用小行星制作游戏,如控件,向上箭头加速, 右箭头顺时针旋转,左箭头逆时针旋转,例如,如果我想减速,我需要旋转180°并加速。 我能够旋转,为此我画了两个向量(速度和航向)。 我试图用矢量来实现这种类型的运动,但也许我不应该这样做? 所以这就是我想出来的。
import pygame
import sys
from pygame.locals import * # pygame.locals.QUIT --> QUIT
# Vector2
vec = pygame.math.Vector2
# initialize pygame
pygame.init()
FPS = 60 # frames per second
fps_clock = pygame.time.Clock()
# set up the window
WIDTH = 800
HEIGHT = 800
DISPLAY = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('VECTOR_2')
FONT = pygame.font.Font(None, 24)
# RGB colors
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
MAX_SPEED = 9
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
# set ship image
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.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT / 2)
self.position = vec(WIDTH / 2, HEIGHT / 2)
self.vel = vec(0, 0)
self.acceleration = vec(0, 0)
# heading vector
self.heading = vec(0, -1) # upwards
self.rect.center = self.position
self.angle_speed = 0
self.angle = 0
def update(self):
self.acceleration = vec(0, 0)
keys = pygame.key.get_pressed()
if keys[K_LEFT]:
self.acceleration.x = -0.2
if keys[K_RIGHT]:
self.acceleration.x = 0.2
if keys[K_UP]:
self.acceleration.y = -0.2
if keys[K_DOWN]:
self.acceleration.y = 0.2
if keys[K_a]:
self.angle_speed = -1
player.rotate()
if keys[K_d]:
self.angle_speed = 1
player.rotate()
# max speed
if self.vel.length() > MAX_SPEED:
self.vel.scale_to_length(MAX_SPEED)
self.vel += self.acceleration
self.position += self.vel
self.rect.center = self.position
def rotate(self):
# rotate the heading vector
self.heading.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 draw_vectors(self, screen):
scale = 20
# vel
pygame.draw.line(screen, GREEN, self.position, (self.position + self.vel * scale), 5)
# desired
pygame.draw.line(screen, RED, self.position, (self.position + self.heading * scale), 5)
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: # game loop
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
DISPLAY.fill(BLACK)
player.wrap_around_screen()
all_sprites.update()
all_sprites.draw(DISPLAY)
player.draw_vectors(DISPLAY)
txt = FONT.render('angle {:.1f}'.format(player.angle), True, (150, 150, 170))
DISPLAY.blit(txt, (10, 10))
pygame.display.update()
fps_clock.tick(FPS)
任何帮助将不胜感激
答案 0 :(得分:3)
你可以给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)