无法让我的精灵沿着航点移动

时间:2017-12-19 20:05:17

标签: python pygame

我在开车的过程中遇到了问题。对于作业,我必须制作一个模拟器。我需要让汽车产生,让他们检查交通灯是红色,橙色还是绿色,以及绿灯出现时的移动。我怎样才能使我生成的汽车沿着我指定的航点移动,使用我制作的航点创建类? 我有以下python文件,它列出了航点。

waypoints.py:

class WayPoint:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def getX(self):
        return self.x
    def getY(self):
        return self.y

class WayPointsList:
    def __init__(self):
        self.wayPoints = []
    def add_wayPoint(self, x, y):
        self.wayPoints.append(WayPoint(x, y))
    def __len__(self):
        return len(self.wayPoints)
    def get_wayPoint(self, i):
        return [self.wayPoints[i].getX(), self.wayPoints[i].getY()]

当我打电话给这个班级时,我使用它的方式是这样的:

l = WayPointsList
l.add_wayPoint(55,67)

这是 main.py

import math
import random, assets
from bus import Bus
from car import Car
from lights import Lights
from waypoints import WayPointsList
import pygame as pg


class Mainstuff(object):
    def __init__(self):
        pg.init()
        self.clock = pg.time.Clock()
        self.screen = pg.display.set_mode((assets.screen_width, assets.screen_height))
        self.background = pg.image.load(assets.background)
        self.running = True
        self.car_group = pg.sprite.Group()
        self.light_group = pg.sprite.Group()

    def event_loop(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                running = False
            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_1:
                    car110 = Car()
                    car110.set_image(assets.furore)
                    car110.rotate(180)
                    car110.set_position(0, 273)
                    self.car_group.add(car110)
                elif event.key == pg.K_2:
                    car109 = Car()
                    car109.set_image(assets.hachura)
                    car109.rotate(180)
                    car109.set_position(0, 306)
                    self.car_group.add(car109)
                elif event.key == pg.K_3:
                    car108 = Car()
                    car108.set_image(assets.jefferson)
                    car108.rotate(180)
                    car108.set_position(0, 343)
                    self.car_group.add(car108)
                elif event.key == pg.K_4:
                    car107 = Car()
                    car107.set_image(assets.michelli)
                    car107.rotate(270)
                    car107.set_position(410, 550)
                    self.car_group.add(car107)
                elif event.key == pg.K_5:
                    car106 = Car()
                    car106.set_image(assets.traceAM)
                    car106.rotate(270)
                    car106.set_position(460, 550)
                    self.car_group.add(car106)
                elif event.key == pg.K_6:
                    car105 = Car()
                    car105.set_image(assets.traceAM)
                    car105.set_position(750, 300)
                    self.car_group.add(car105)
                elif event.key == pg.K_7:
                    car104 = Car()
                    car104.set_image(assets.rumbler)
                    car104.set_position(750, 265)
                    self.car_group.add(car104)
                elif event.key == pg.K_8:
                    car103 = Car()
                    car103.set_image(assets.rumbler)
                    car103.rotate(90)
                    car103.set_position(294, 0)
                    self.car_group.add(car103)
                elif event.key == pg.K_9:
                    car102 = Car()
                    car102.set_image(assets.rumbler)
                    car102.rotate(90)
                    car102.set_position(337, 0)
                    self.car_group.add(car102)
                elif event.key == pg.K_0:
                    car101 = Car()
                    car101.set_image(assets.rumbler)
                    car101.rotate(90)
                    car101.set_position(380, 0)
                    self.car_group.add(car101)
                elif event.key == pg.K_b:
                    car201 = Bus()
                    car201.set_image(assets.bus)
                    car201.set_position(700, 229)
                    self.car_group.add(car201)
                elif event.key == pg.K_x:
                    self.car_group.empty()
    def update(self):
        self.screen.fill(assets.white)
        self.car_group.update()
        #self.light_group.update()
    def draw(self):
        self.screen.blit(self.background,(0,0))
        self.car_group.draw(self.screen)
        self.light_group.draw(self.screen)
    def run(self):
        while self.running:
            self.event_loop()
            self.update()
            self.draw()
            pg.display.update()
            self.clock.tick(assets.FPS)

if __name__ == '__main__':
    test = Mainstuff()
    test.run()
    pg.quit()

这是 car.py

import pygame, assets, math
class Car(pygame.sprite.Sprite):
    def __init__(self):
        super(Car, self).__init__()
        self.image = pygame.Surface((assets.car_width, assets.car_height))
        self.image.fill(assets.red)
        self.rect = self.image.get_rect()
        self.speed = 1
        self.angle = 0
    def set_position(self, x, y):
        self.rect.x = x
        self.rect.y = y
    def get_x_position(self):
        return self.rect.x
    def get_y_position(self):
        return self.rect.y
    def set_image(self, filename=None):
        if filename != None:
            self.image = pygame.image.load(filename).convert()
            #self.image.fill(assets.green)
            self.rect = self.image.get_rect()
    def rotate(self, angle):
        self.angle = angle
        self.image = pygame.transform.rotate(self.image, angle)
        self.rect = self.image.get_rect()
    #not sure what to do here
    def move_position(self, x, y):

        # use angle to calculate direction
        radius_angle = math.radians(self.angle)
        self.rect.x -= self.speed * math.cos(radius_angle)
        self.rect.y -= self.speed * math.sin(radius_angle)
        print('move', self.angle, self.rect.x, self.rect.y)
    def update(self):
        self.move_position(0, 0)

1 个答案:

答案 0 :(得分:2)

我做了个例子。

从列表中选择第一个点作为起始位置,第二个点作为目标。

它使用pygame.math.Vector2()计算一步

current = current + (target - current).normalize() * speed

当玩家进入目标时,它会从列表中获得下一个目标点。

enter image description here

#!/usr/bin/env python3

import pygame

# === CONSTANS === (UPPER_CASE names)

BLACK = (  0,   0,   0)
WHITE = (255, 255, 255)

RED   = (255,   0,   0)
GREEN = (  0, 255,   0)
BLUE  = (  0,   0, 255)

SCREEN_WIDTH  = 600
SCREEN_HEIGHT = 400

# === CLASSES === (CamelCase names)

class Player():

    def __init__(self, waypoints, loop=False):

        # create green circe 
        r = 10

        self.image = pygame.Surface((2*r, 2*r)).convert_alpha()
        self.rect = self.image.get_rect()

        self.image.fill((0,0,0,0))
        pygame.draw.circle(self.image, (0,255,0), (r, r), r)

        # ---

        self.loop = loop

        self.speed = 5

        self.waypoints = waypoints
        self.next_point = 0

        # set current position
        # I use Vector2 because it keeps position as float numbers 
        # and it makes calcuations easier and more precise
        self.current = pygame.math.Vector2(self.waypoints[0])

        # set position in rect to draw it
        self.rect.center = self.current

        # set end point if exists on list
        self.target_index = 1
        if self.target_index < len(self.waypoints) - 1:
            self.target = pygame.math.Vector2(self.waypoints[self.target_index])
            self.moving = True
        else:
            self.target = self.current
            self.moving = False

    def move(self):

        if self.moving:

            # get distance to taget
            distance = self.current.distance_to(self.target)

            # 
            if distance > self.speed:
                self.current = self.current + (self.target - self.current).normalize() * self.speed
                self.rect.center = self.current
            else:
                # put player in tagert place, 
                # and find new target on list with waypoints 

                self.current = self.target
                self.rect.center = self.current

                # set next end point if exists on list
                self.target_index += 1
                if self.target_index < len(self.waypoints):
                    self.target = pygame.math.Vector2(self.waypoints[self.target_index])
                else:
                    if self.loop:
                        self.target_index = 0
                    else:
                        self.moving = False


    def draw(self, surface):
        surface.blit(self.image, self.rect)

# === MAIN === (lower_case names)

# --- init ---

pygame.init()

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
screen_rect = screen.get_rect()

# --- objects ---

start = pygame.math.Vector2(screen_rect.centerx, screen_rect.bottom)
end = start
length = 150

waypoints = [(50, 50), (400, 150), (500, 50), (450, 350), (200, 200), (100, 350), (50, 50)]

player = Player(waypoints, True)

# --- mainloop ---

clock = pygame.time.Clock()
is_running = True


while is_running:

    # --- events ---

    for event in pygame.event.get():

        # --- global events ---

        if event.type == pygame.QUIT:
            is_running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                is_running = False

        # --- objects events ---

            # empty

    # --- updates ---

        # empty

    player.move()

    # --- draws ---

    screen.fill(BLACK)

    for start, end in zip(waypoints, waypoints[1:]):
        pygame.draw.line(screen, RED, start, end)

    player.draw(screen)

    pygame.display.update()

    # --- FPS ---

    clock.tick(25)

# --- the end ---

pygame.quit()

BTW:因为当玩家从一个点移动到另一个点时(目标没有改变位置)玩家不会改变方向,所以它只能计算一次这个值

(target - current).normalize() * speed

并在下一个点作为目标时重新计算。

BTW:示例如何使用math模块进行计算以回答

finding change in x and y given two points and length of vector