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