Python 如何在pygame中让摄像头跟踪自上而下的汽车

Python 如何在pygame中让摄像头跟踪自上而下的汽车,python,camera,pygame,topdown,Python,Camera,Pygame,Topdown,对于pygame和一般的游戏编程来说都是新手,我只是想知道如何在自上而下的汽车游戏中让摄像头跟踪汽车(没什么特别的)——想想微型机器吧!我使用的是Python3.6,我有一辆自行车在旋转和移动。我一直在这里的代码更短,但我有一个静态图像作为参考,如果相机工作 以下是我所拥有的: import pygame, math, sys, random from pygame.locals import * display_width = 1280 display_height = 800 # Set

对于pygame和一般的游戏编程来说都是新手,我只是想知道如何在自上而下的汽车游戏中让摄像头跟踪汽车(没什么特别的)——想想微型机器吧!我使用的是Python3.6,我有一辆自行车在旋转和移动。我一直在这里的代码更短,但我有一个静态图像作为参考,如果相机工作

以下是我所拥有的:

import pygame, math, sys, random
from pygame.locals import *

display_width = 1280
display_height = 800

# Sets size of screen
screen = pygame.display.set_mode((display_width, display_height))

# Initialises clock
clock = pygame.time.Clock()

# Colours
white = (255,255,255)
black = (0,0,0)

class Entity(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

class VehicleSprite(Entity):
    # Creates a vehicle class
    MAX_FORWARD_SPEED = 10
    MAX_REVERSE_SPEED = 2
    ACCELERATION = 0.05
    TURN_SPEED = 0.000000000001

    def __init__(self, image, position):
        Entity.__init__(self)

        # Creates object instance off
        pygame.sprite.Sprite.__init__(self)
        self.src_image = pygame.image.load(image)
        self.position = position
        self.speed = self.direction = 0
        self.k_left = self.k_right = self.k_down = self.k_up = 0


    def update(self, time):
        # SIMULATION
        self.speed += (self.k_up +self.k_down)
        if self.speed > self.MAX_FORWARD_SPEED:
            self.speed = self.MAX_FORWARD_SPEED
        if self.speed < -self.MAX_REVERSE_SPEED:
            self.speed = -self.MAX_REVERSE_SPEED

        # Degrees sprite is facing (direction)
        self.direction += (self.k_right + self.k_left)
        x, y = self.position
        rad = self.direction * math.pi / 180
        x += -self.speed*math.sin(rad)
        y += -self.speed*math.cos(rad)
        self.position = (x, y)
        self.image = pygame.transform.rotate(self.src_image, self.direction)
        self.rect = self.image.get_rect()
        self.rect.center = self.position

class Background(pygame.sprite.Sprite):
    def __init__(self, image_file, location):
        pygame.sprite.Sprite.__init__(self)  #call Sprite initializer
        self.image = pygame.image.load(image_file)
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = location

rect = screen.get_rect()

# Background
BackGround = Background('/home/pi/gametuts/images/backgrounds/bkg_img.png', [0, 0])

# Bike image load
bike = VehicleSprite('/home/pi/gametuts/images/BikePixelBig.png', rect.center)
bike_group = pygame.sprite.RenderPlain(bike)

# Ball image load
ball = VehicleSprite('/home/pi/gametuts/images/ironball.png', rect.center)
ball_group = pygame.sprite.RenderPlain(ball)

# Main game loop
def game_loop():

    while 1:
        #USER INPUT
        # Sets frame rate
        time = clock.tick(60)
        for event in pygame.event.get():
            if not hasattr(event, 'key'): continue
            down = event.type == KEYDOWN

            # Bike Input (Player 1)
            if event.key == K_d: bike.k_right = down * -5
            elif event.key == K_a: bike.k_left = down * 5
            elif event.key == K_w: bike.k_up = down * 2
            elif event.key == K_s: bike.k_down = down * -2      

            # Quit
            elif event.key == K_ESCAPE: sys.exit(0)

        #RENDERING

        # Game background
        screen.fill(white)
        screen.blit(BackGround.image, BackGround.rect)

        # Bike render
        bike_group.update(time)
        bike_group.draw(screen)

        ball_group.update(time)
        ball_group.draw(screen)

        pygame.display.flip()


game_loop()
pygame.quit()
quit()
导入pygame、数学、系统、随机
从pygame.locals导入*
显示宽度=1280
显示高度=800
#设置屏幕的大小
screen=pygame.display.set_模式((显示宽度、显示高度))
#初始化时钟
clock=pygame.time.clock()
#颜色
白色=(255255)
黑色=(0,0,0)
类实体(pygame.sprite.sprite):
定义初始化(自):
pygame.sprite.sprite.\uuuuu init\uuuuuuu(自我)
车辆等级Prite(实体):
#创建一个车辆类
最大前进速度=10
最大反向速度=2
加速度=0.05
转动速度=0.000000000001
定义初始(自我、图像、位置):
实体。u u初始化(自)
#创建对象实例关闭
pygame.sprite.sprite.\uuuuu init\uuuuuuu(自我)
self.src_image=pygame.image.load(image)
self.position=位置
自速度=自方向=0
self.k_left=self.k_right=self.k_down=self.k_up=0
def更新(自我,时间):
#模拟
self.speed+=(self.k_向上+self.k_向下)
如果self.speed>self.MAX\u前进速度:
self.speed=self.MAX\u前进速度
如果self.speed<-self.MAX\u REVERSE\u速度:
self.speed=-self.MAX\u REVERSE\u速度
#精灵朝向的度数(方向)
self.direction+=(self.k_right+self.k_left)
x、 y=自身位置
rad=self.direction*math.pi/180
x+=-self.speed*math.sin(rad)
y+=-self.speed*math.cos(rad)
self.position=(x,y)
self.image=pygame.transform.rotate(self.src_image,self.direction)
self.rect=self.image.get_rect()
self.rect.center=self.position
类背景(pygame.sprite.sprite):
def_uuuinit_uuu(自我、图像文件、位置):
pygame.sprite.sprite.\uuuu初始化(self)\uuuu调用sprite初始值设定项
self.image=pygame.image.load(图像文件)
self.rect=self.image.get_rect()
self.rect.left,self.rect.top=位置
rect=screen.get_rect()
#背景
背景=背景('/home/pi/gametuts/images/backgrounds/bkg_img.png',[0,0])
#自行车图像加载
bike=VehicleSprite('/home/pi/gametuts/images/BikePixelBig.png',rect.center)
bike_group=pygame.sprite.RenderPlain(自行车)
#球像载荷
ball=VehicleSprite('/home/pi/gametuts/images/ironball.png',rect.center)
ball\u group=pygame.sprite.RenderPlain(ball)
#主游戏循环
def game_loop():
而1:
#用户输入
#设置帧速率
时间=时钟。滴答声(60)
对于pygame.event.get()中的事件:
如果不是hasattr(事件“键”):继续
down=event.type==KEYDOWN
#自行车输入(播放器1)
如果event.key==K_d:bike.K_right=down*-5
elif event.key==K_a:bike.K_left=down*5
elif event.key==K_w:bike.K_up=down*2
elif event.key==K_s:bike.K_down=down*-2
#退出
elif event.key==K_ESCAPE:sys.exit(0)
#渲染
#游戏背景
屏幕填充(白色)
screen.blit(BackGround.image、BackGround.rect)
#自行车粉刷机
自行车组。更新(时间)
自行车组绘制(屏幕)
球组。更新(时间)
球组抽签(屏幕)
pygame.display.flip()
博弈(循环)
pygame.quit()
退出

提前谢谢

实现摄像头的最简单方法是使用a作为摄像头,从每个帧中减去玩家速度,并在闪电游戏期间将其添加到所有游戏元素的位置

import pygame as pg
from pygame.math import Vector2


class Player(pg.sprite.Sprite):

    def __init__(self, pos, walls, *groups):
        super().__init__(*groups)
        self.image = pg.Surface((30, 50))
        self.image.fill(pg.Color('dodgerblue'))
        self.rect = self.image.get_rect(center=pos)
        self.vel = Vector2(0, 0)
        self.pos = Vector2(pos)
        self.walls = walls
        self.camera = Vector2(0, 0)

    def update(self):
        self.camera -= self.vel  # Change the camera pos if we're moving.
        # Horizontal movement.
        self.pos.x += self.vel.x
        self.rect.centerx = self.pos.x
        # Change the rect and self.pos coords if we touched a wall.
        for wall in pg.sprite.spritecollide(self, self.walls, False):
            if self.vel.x > 0:
                self.rect.right = wall.rect.left
            elif self.vel.x < 0:
                self.rect.left = wall.rect.right
            self.pos.x = self.rect.centerx
            self.camera.x += self.vel.x  # Also move the camera back.

        # Vertical movement.
        self.pos.y += self.vel.y
        self.rect.centery = self.pos.y
        for wall in pg.sprite.spritecollide(self, self.walls, False):
            if self.vel.y > 0:
                self.rect.bottom = wall.rect.top
            elif self.vel.y < 0:
                self.rect.top = wall.rect.bottom
            self.pos.y = self.rect.centery
            self.camera.y += self.vel.y


class Wall(pg.sprite.Sprite):

    def __init__(self, x, y, w, h, *groups):
        super().__init__(*groups)
        self.image = pg.Surface((w, h))
        self.image.fill(pg.Color('sienna2'))
        self.rect = self.image.get_rect(topleft=(x, y))


def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()
    all_sprites = pg.sprite.Group()
    walls = pg.sprite.Group()
    for rect in ((100, 170, 90, 20), (200, 100, 20, 140),
                 (400, 60, 150, 100), (300, 470, 150, 100)):
        walls.add(Wall(*rect))
    all_sprites.add(walls)
    player = Player((320, 240), walls, all_sprites)

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_d:
                    player.vel.x = 5
                elif event.key == pg.K_a:
                    player.vel.x = -5
                elif event.key == pg.K_w:
                    player.vel.y = -5
                elif event.key == pg.K_s:
                    player.vel.y = 5
            elif event.type == pg.KEYUP:
                if event.key == pg.K_d and player.vel.x > 0:
                    player.vel.x = 0
                elif event.key == pg.K_a and player.vel.x < 0:
                    player.vel.x = 0
                elif event.key == pg.K_w and player.vel.y < 0:
                    player.vel.y = 0
                elif event.key == pg.K_s and player.vel.y > 0:
                    player.vel.y = 0

        all_sprites.update()

        screen.fill((30, 30, 30))
        for sprite in all_sprites:
            # Add the player's camera offset to the coords of all sprites.
            screen.blit(sprite.image, sprite.rect.topleft+player.camera)

        pg.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()

要使对象始终显示在显示器的中心,而不是移动对象(当玩家点击按键时),您需要将所有其他对象都朝相反方向移动。换言之,每次更新后对象的位置都保持不变。我尝试过这样做,但旋转逻辑不起作用(只是感觉不象车辆),另外我想要多人游戏和其他对象,如投射物,如果可能的话,我希望它们相对于静态背景。即使包含旋转(可能还有其他移动对象),同样的排序反转逻辑也会适用。中心思想是将感兴趣的对象保持在显示器上相同的位置(如果涉及旋转,则保持方向)。我将尝试一下,谢谢您的评论!太棒了,看起来像王牌!我试试看,谢谢!谢谢你的帮助,尽管我正在努力让它在汽车旋转时工作,而且很难给相机一个明确的“x,y”位置(我对这一点可能也没有帮助!)每当我向左或向右旋转时,相机都会变得非常时髦!太完美了,相机离我想要的已经足够近了,现在可以理解逻辑了;)非常感谢你的帮助!
import math
import random

import pygame


pygame.init()
screen = pygame.display.set_mode((1280, 800))
rect = screen.get_rect()
clock = pygame.time.Clock()

WHITE = pygame.Color('white')
# Load images globally and reuse them in your program.
# Also use the `.convert()` or `.convert_alpha()` methods after
# loading the images to improve the performance.
VEHICLE1 = pygame.Surface((40, 70), pygame.SRCALPHA)
VEHICLE1.fill((130, 180, 20))
VEHICLE2 = pygame.Surface((40, 70), pygame.SRCALPHA)
VEHICLE2.fill((200, 120, 20))
BACKGROUND = pygame.Surface((1280, 800))
BACKGROUND.fill((30, 30, 30))


class Entity(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)


class VehicleSprite(Entity):
    MAX_FORWARD_SPEED = 10
    MAX_REVERSE_SPEED = 2
    ACCELERATION = 0.05
    TURN_SPEED = 0.000000000001

    def __init__(self, image, position):
        Entity.__init__(self)
        self.src_image = image
        self.image = image
        self.rect = self.image.get_rect(center=position)
        self.position = pygame.math.Vector2(position)
        self.velocity = pygame.math.Vector2(0, 0)
        self.speed = self.direction = 0
        self.k_left = self.k_right = self.k_down = self.k_up = 0

    def update(self, time):
        # SIMULATION
        self.speed += self.k_up + self.k_down
        # To clamp the speed.
        self.speed = max(-self.MAX_REVERSE_SPEED,
                         min(self.speed, self.MAX_FORWARD_SPEED))

        # Degrees sprite is facing (direction)
        self.direction += (self.k_right + self.k_left)
        rad = math.radians(self.direction)
        self.velocity.x = -self.speed*math.sin(rad)
        self.velocity.y = -self.speed*math.cos(rad)
        self.position += self.velocity
        self.image = pygame.transform.rotate(self.src_image, self.direction)
        self.rect = self.image.get_rect(center=self.position)


class Background(pygame.sprite.Sprite):

    def __init__(self, image, location):
        pygame.sprite.Sprite.__init__(self)
        self.image = image
        self.rect = self.image.get_rect(topleft=location)


def game_loop():
    background = Background(BACKGROUND, [0, 0])
    bike = VehicleSprite(VEHICLE1, rect.center)
    ball = VehicleSprite(VEHICLE2, rect.center)

    bike_group = pygame.sprite.Group(bike)
    ball_group = pygame.sprite.Group(ball)
    all_sprites = pygame.sprite.Group(bike_group, ball_group)

    camera = pygame.math.Vector2(0, 0)
    done = False

    while not done:
        time = clock.tick(60)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
            elif event.type == pygame.KEYDOWN:
                # Bike Input (Player 1)
                if event.key == pygame.K_d:
                    bike.k_right = -5
                elif event.key == pygame.K_a:
                    bike.k_left = 5
                elif event.key == pygame.K_w:
                    bike.k_up = 2
                elif event.key == pygame.K_s:
                    bike.k_down = -2

                elif event.key == pygame.K_ESCAPE:
                    done = True
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_d:
                    bike.k_right = 0
                elif event.key == pygame.K_a:
                    bike.k_left = 0
                elif event.key == pygame.K_w:
                    bike.k_up = 0
                elif event.key == pygame.K_s:
                    bike.k_down = 0

        camera -= bike.velocity

        all_sprites.update(time)

        screen.fill(WHITE)
        screen.blit(background.image, background.rect)

        for sprite in all_sprites:
            screen.blit(sprite.image, sprite.rect.topleft+camera)

        pygame.display.flip()


game_loop()
pygame.quit()