Python 在pygame中,将滚动相机放在迷你窗口中

Python 在pygame中,将滚动相机放在迷你窗口中,python,pygame,window,surface,blit,Python,Pygame,Window,Surface,Blit,我正在尝试创建一个游戏,在这个游戏中,动作显示在主屏幕对象内的一个小框中,为文本和菜单之类的东西腾出周围的空间。因为地图比分配的窗口大,所以我编码了一个基本的“摄像头”,它跟随玩家左右。它基本上是有效的,但是我很难“修剪”这个窗口之外的区域 以下是相关的代码位(编辑以提供工作示例): 导入pygame、os、sys 从pygame.locals导入* pygame.init() 右=‘右’ 左=‘左’ 向上=‘向上’ 向下=‘向下’ 类摄影机(): def_uuuinit_uuuuu(自身,屏幕

我正在尝试创建一个游戏,在这个游戏中,动作显示在主屏幕对象内的一个小框中,为文本和菜单之类的东西腾出周围的空间。因为地图比分配的窗口大,所以我编码了一个基本的“摄像头”,它跟随玩家左右。它基本上是有效的,但是我很难“修剪”这个窗口之外的区域

以下是相关的代码位(编辑以提供工作示例):

导入pygame、os、sys
从pygame.locals导入*
pygame.init()
右=‘右’
左=‘左’
向上=‘向上’
向下=‘向下’
类摄影机():
def_uuuinit_uuuuu(自身,屏幕,x_比率=1,y_比率=1,x_偏移=0,y_偏移=0):
self.screen=screen.copy()
self.rec=self.screen.get_rect()
自恢复宽度*=x_比率
自恢复高度*=y_比率
self.x_offset=x_offset
self.y\u offset=y\u offset
def获取位置(自身):
返回(self.x_offset-self.rec.x,self.y_offset-self.rec.y)
def get_窗口(自):
w=pygame.Rect(self.rec)
w、 左上=(0-self.rec.x,0-self.rec.y)
返回w
def移动(自身、x、y):
“”“将相机移到新位置”“”
self.rec.x=x
self.rec.y=y
def轨迹(自、obj):
而obj.rec.leftself.rec.right:
self.rec.x+=1
当obj.rec.topself.rec.bottom时:
自我记录y+=1
类图:
定义初始值(自身、宽度、高度):
self.width=宽度
自我高度=高度
self.rec=pygame.Rect(0,0,self.width,self.height)
def提取(自身,屏幕):
pygame.draw.rect(屏幕,(200200),self.rec)
Obj类:
定义初始化(self,char,x=0,y=0,width=0,height=0):
self.width=宽度
自我高度=高度
self.rec=pygame.Rect(x,y,宽度,高度)
self.cur\u map=无
self.timers={}
#为雪碧用木炭装点
self.char=char
self.x_dir=1
self.y_dir=1
自身速度=1
self.moving=False
def移动(自我):
如果self.x_dir!=0或self.y_dir!=0:
new_x=self.rec.x+(self.x_dir*self.speed)
new_y=self.rec.y+(self.y_dir*self.speed)
new_rec=pygame.Rect(new_x,new_y,self.width,self.height)
#在地图范围内保持移动
当new_rec.leftself.cur_map.rec.right时:
新建议x-=1
当new_rec.topself.cur_map.rec.bottom时:
新记录y-=1
self.rec=新记录
def set_dir(自我,d):
self.x_dir=0
self.y_dir=0
如果d==左:
self.x_dir=-1
elif d==右:
self.x_dir=1
elif d==向上:
self.y_dir=-1
elif d==向下:
self.y_dir=1
def set_移动(自身,val=True):
self.moving=val
班级游戏:
定义初始化(自):
self.screen_size=(800600)
self.screen=pygame.display.set_模式(self.screen_大小)
self.map\u screen=self.screen.copy()
self.title='RPG'
pygame.display.set_标题(self.title)
self.camera=camera(self.screen,0.75,0.75)#,10,75)
self.fps=80
self.clock=pygame.time.clock()
self.debug=False
self.bg_color=(255255)
self.text_size=18
self.text_font='Arial'
self.text\u style=pygame.font.SysFont(self.text\u font,self.text\u size)
self.key_binds={LEFT:[K_LEFT,K_a],RIGHT:[K_RIGHT,K_d],UP:[K_UP,K_w],DOWN:[K_DOWN,K_s],
“交互”:[K_返回,K_z],“库存”:[K_i,K_空间],“退出”:[K_退出]}
self.player=Obj('p',0,0,10,self.text_大小)
def牵引(自、obj):
char=obj.char
self.draw_文本(char,obj.rec.x,obj.rec.y,screen=self.map_screen)
def draw_文本(自身、文本、x、y、颜色=(0,0,0)、屏幕=无):
textobj=self.text\u style.render(文本,1,颜色)
textrect=textobj.get_rect()
textrect.x=x
textrect.y=y
如果屏幕==无:
“”“使用默认屏幕”“”
self.screen.blit(textobj,textrect)
其他:
screen.blit(textobj、textrect)
def播放(自我):
完成=错误
cur_map=map(800800)
self.map\u screen=pygame.Surface((cur\u map.width,cur\u map.height))
self.map\u屏幕填充(self.bg\u颜色)
bg=pygame.Surface((cur_map.width,cur_map.height))
当前地图绘制(背景)
self.player.cur\u map=cur\u map
虽然没有这样做:
对于pygame.event.get()中的事件:
如果event.type==退出:
pygame.quit()
sys.exit()
如果event.type==KEYDOWN:
如果event.key in self.key_绑定[左]:
self.player.set_dir(左)
self.player.set_moving()
elif event.key in self.key_绑定[右]:
self.player.set_dir(右)
self.player.set_moving()
elif event.key in self.key_绑定[UP]:
self.player.set_dir(向上)
self.player.set_moving()
elif event.key in self.key_绑定[关闭]:
self.player.set_dir(向下)
self.player.set_moving()
elif event.type==KEYUP:
self.player.set_移动(False)
如果self.player.moving:
self.player.move()
import pygame, os, sys
from pygame.locals import *
pygame.init()

RIGHT = 'RIGHT'
LEFT = 'LEFT'
UP = 'UP'
DOWN = 'DOWN'

class Camera():
    def __init__(self, screen, x_ratio = 1, y_ratio = 1, x_offset = 0, y_offset = 0):
        self.screen = screen.copy()
        self.rec = self.screen.get_rect()
        self.rec.width *= x_ratio
        self.rec.height *= y_ratio
        self.x_offset = x_offset
        self.y_offset = y_offset
    def get_pos(self):
        return (self.x_offset - self.rec.x, self.y_offset - self.rec.y)
    def get_window(self):
        w = pygame.Rect(self.rec)
        w.topleft = (0 - self.rec.x, 0 - self.rec.y)
        return w
    def move(self, x, y):
        """Move camera into new position"""
        self.rec.x = x
        self.rec.y = y
    def track(self, obj):
        while obj.rec.left < self.rec.left:
            self.rec.x -= 1
        while obj.rec.right > self.rec.right:
            self.rec.x += 1
        while obj.rec.top < self.rec.top:
            self.rec.y -= 1
        while obj.rec.bottom > self.rec.bottom:
            self.rec.y += 1

class Map:
    def __init__(self, width, height):
        self.width = width
        self.height = height
        self.rec = pygame.Rect(0,0,self.width,self.height)

    def draw(self, screen):
        pygame.draw.rect(screen, (200,200,200), self.rec)

class Obj:
    def __init__(self, char, x = 0, y = 0, width = 0, height = 0):
        self.width = width
        self.height = height
        self.rec = pygame.Rect(x, y, width, height)
        self.cur_map = None
        self.timers = {}

        #Dummying in chars for sprites
        self.char = char

        self.x_dir = 1
        self.y_dir = 1
        self.speed = 1
        self.moving = False        

    def move(self):
        if self.x_dir != 0 or self.y_dir != 0:
            new_x = self.rec.x + (self.x_dir*self.speed)
            new_y = self.rec.y + (self.y_dir*self.speed)
            new_rec = pygame.Rect(new_x, new_y, self.width, self.height)

            #Keep movement within bounds of map
            while new_rec.left < self.cur_map.rec.left:
                new_rec.x += 1
            while new_rec.right > self.cur_map.rec.right:
                new_rec.x -= 1
            while new_rec.top < self.cur_map.rec.top:
                new_rec.y += 1
            while new_rec.bottom > self.cur_map.rec.bottom:
                new_rec.y -= 1

            self.rec = new_rec

    def set_dir(self, d):
        self.x_dir = 0
        self.y_dir = 0
        if d == LEFT:
            self.x_dir = -1
        elif d == RIGHT:
            self.x_dir = 1
        elif d == UP:
            self.y_dir = -1
        elif d == DOWN:
            self.y_dir = 1

    def set_moving(self, val = True):
        self.moving = val

class Game:
    def __init__(self):
        self.screen_size = (800, 600)
        self.screen = pygame.display.set_mode(self.screen_size)
        self.map_screen = self.screen.copy()
        self.title = 'RPG'
        pygame.display.set_caption(self.title)

        self.camera = Camera(self.screen, 0.75, 0.75)#, 10, 75)

        self.fps = 80
        self.clock = pygame.time.Clock()
        self.debug = False
        self.bg_color = (255,255,255)
        self.text_size = 18
        self.text_font = 'Arial'
        self.text_style = pygame.font.SysFont(self.text_font, self.text_size)
        self.key_binds = {LEFT : [K_LEFT, K_a], RIGHT : [K_RIGHT, K_d], UP : [K_UP, K_w], DOWN : [K_DOWN, K_s],
                          'interact' : [K_RETURN, K_z], 'inventory' : [K_i,  K_SPACE], 'quit' : [K_ESCAPE]}

        self.player = Obj('p', 0, 0, 10, self.text_size)     

    def draw(self, obj):
        char = obj.char       
        self.draw_text(char, obj.rec.x, obj.rec.y, screen = self.map_screen)

    def draw_text(self, text, x, y, color = (0,0,0), screen = None):
        textobj = self.text_style.render(text, 1, color)
        textrect = textobj.get_rect()
        textrect.x = x
        textrect.y = y
        if screen == None:
            """Use default screen"""
            self.screen.blit(textobj, textrect)
        else:
            screen.blit(textobj, textrect)

    def play(self):
        done = False
        cur_map = Map(800, 800)
        self.map_screen = pygame.Surface((cur_map.width, cur_map.height))
        self.map_screen.fill(self.bg_color)

        bg = pygame.Surface((cur_map.width, cur_map.height))
        cur_map.draw(bg)

        self.player.cur_map = cur_map

        while not done:

            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == KEYDOWN:
                    if event.key in self.key_binds[LEFT]:
                        self.player.set_dir(LEFT)
                        self.player.set_moving()
                    elif event.key in self.key_binds[RIGHT]:
                        self.player.set_dir(RIGHT)
                        self.player.set_moving()
                    elif event.key in self.key_binds[UP]:
                        self.player.set_dir(UP)
                        self.player.set_moving()
                    elif event.key in self.key_binds[DOWN]:
                        self.player.set_dir(DOWN)
                        self.player.set_moving()

                elif event.type == KEYUP:
                    self.player.set_moving(False)


            if self.player.moving:
                self.player.move()

            self.camera.track(self.player)
            self.clock.tick()

            self.screen.fill(self.bg_color)
            self.map_screen.blit(bg, (0,0))            
            self.draw(self.player)

            pygame.draw.rect(self.map_screen, (0,0,0), self.camera.rec, 1)
            #self.screen.blit(self.map_screen, (0,0), [0 - self.camera.rec.x, 0 - self.camera.rec.y, self.camera.rec.width, self.camera.rec.height])
            self.screen.blit(self.map_screen, self.camera.get_pos(), self.camera.get_window())
            pygame.display.flip()

game = Game()
game.play()
self.screen.blit(self.map_screen, (self.camera.x_offset,self.camera.y_offset), (*self.camera.get_pos(), self.camera.rec.width, self.camera.rec.height))
def get_pos(self):
    return (self.rec.x, self.rec.y)
def draw(self, screen):
    pygame.draw.rect(screen, (200,200,200), self.rec)
    pygame.draw.circle(screen, (255, 255, 255), (50, 50), 20, 2)