第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 Pymunk 和 Pygame 橫向滾動。如何移動相機/視口以僅查看世界的一部分?

使用 Pymunk 和 Pygame 橫向滾動。如何移動相機/視口以僅查看世界的一部分?

手掌心 2021-12-09 14:43:58
從 pymunk 示例中,我看到 pymunk 坐標(biāo)和 pygame 坐標(biāo)之間存在差異。此外,pymunk 僅用于 2D 物理,而 pygame 用于在屏幕上渲染對象/精靈。因此,在尋找如何構(gòu)建攝像機跟隨玩家的環(huán)境時,人們(包括我)最終會感到困惑。我已經(jīng)看過這里的例子,這里,這里和這里(甚至驚訝于沒有人回答這個),但考慮到與同一主題相關(guān)的問題被反復(fù)詢問的數(shù)量,老實說,我覺得這些答案并沒有充分解釋這個概念和要求向社區(qū)展示最簡單的示例,其中所有代碼都帶有注釋。我曾在像 OGRE 和 OSG 這樣的 3D 環(huán)境中工作過,其中相機是一個可以用視錐定義的正確概念,但我很驚訝 2D 世界沒有預(yù)定義的功能。所以:如果不在 pymunk 或 pygame 的官方教程中,至少可以提供一個簡單的示例(以 pymunk 主體作為玩家,世界上很少有 pymunk 主體)作為答案,其中玩家在 2D pymunk+ 中四處移動pygame 世界和相機跟隨玩家?
查看完整描述

1 回答

?
臨摹微笑

TA貢獻1982條經(jīng)驗 獲得超2個贊

好的,我會盡量簡化(我假設(shè)有基本的 pygame 知識)。


首先,讓我們從一些基本的東西開始。一個可以在世界各地移動的小精靈:


import pygame

import random


class Player(pygame.sprite.Sprite):

    def __init__(self):

        super().__init__()

        self.image = pygame.Surface((32, 32))

        self.image.fill(pygame.Color('dodgerblue'))

        self.rect = self.image.get_rect()

        self.pos = pygame.Vector2((100, 200))


    def update(self, events, dt):

        pressed = pygame.key.get_pressed()

        move = pygame.Vector2((0, 0))

        if pressed[pygame.K_w]: move += (0, -1)

        if pressed[pygame.K_a]: move += (-1, 0)

        if pressed[pygame.K_s]: move += (0, 1)

        if pressed[pygame.K_d]: move += (1, 0)

        if move.length() > 0: move.normalize_ip()

        self.pos += move*(dt/5)

        self.rect.center = self.pos


def main():

    pygame.init()

    screen = pygame.display.set_mode((500, 500))

    clock = pygame.time.Clock()

    dt = 0

    player = Player()

    sprites = pygame.sprite.Group(player)

    background = screen.copy()

    background.fill((30, 30, 30))

    for _ in range(1000):

        x, y = random.randint(0, 1000), random.randint(0, 1000)

        pygame.draw.rect(background, pygame.Color('green'), (x, y, 2, 2))


    while True:

        events = pygame.event.get()

        for e in events:

            if e.type == pygame.QUIT:

                return

        sprites.update(events, dt)

        screen.blit(background, (0, 0))

        sprites.draw(screen)

        pygame.display.update()

        dt = clock.tick(60)


if __name__ == '__main__':

    main()

http://img1.sycdn.imooc.com//61b1a5ca0001b7ca05040533.jpg

到目前為止沒有什么瘋狂的。


那么,什么是“相機”?它只是我們用來移動整個“世界”的一個x和一個y值(例如,所有不是 UI 的東西)。它是我們游戲?qū)ο蠛推聊蛔鴺?biāo)之間的抽象。


在我們上面的例子中,當(dāng)一個游戲?qū)ο螅ㄍ婕一虮尘埃┫胍谖恢?繪制時(x, y),我們在屏幕的這個位置繪制它們。


現(xiàn)在,如果我們想要圍繞“攝像機”移動,我們只需創(chuàng)建另一個x, y-pair,并將其添加到游戲?qū)ο蟮淖鴺?biāo)中以確定屏幕上的實際位置。我們開始區(qū)分世界坐標(biāo)(游戲邏輯認(rèn)為物體的位置在哪里)和屏幕坐標(biāo)(物體在屏幕上的實際位置)。


這是我們帶有“camera”(引號中的“camera”)的示例,因為它實際上只是兩個值:


import pygame

import random


class Player(pygame.sprite.Sprite):

    def __init__(self):

        super().__init__()

        self.image = pygame.Surface((32, 32))

        self.image.fill(pygame.Color('dodgerblue'))

        self.rect = self.image.get_rect()

        self.pos = pygame.Vector2((100, 200))


    def update(self, events, dt):

        pressed = pygame.key.get_pressed()

        move = pygame.Vector2((0, 0))

        if pressed[pygame.K_w]: move += (0, -1)

        if pressed[pygame.K_a]: move += (-1, 0)

        if pressed[pygame.K_s]: move += (0, 1)

        if pressed[pygame.K_d]: move += (1, 0)

        if move.length() > 0: move.normalize_ip()

        self.pos += move*(dt/5)

        self.rect.center = self.pos


def main():

    pygame.init()

    screen = pygame.display.set_mode((500, 500))

    clock = pygame.time.Clock()

    dt = 0

    player = Player()

    sprites = pygame.sprite.Group(player)

    # the "world" is now bigger than the screen

    # so we actually have anything to move the camera to

    background = pygame.Surface((1500, 1500))

    background.fill((30, 30, 30))


    # a camera is just two values: x and y

    # we use a vector here because it's easier to handle than a tuple

    camera = pygame.Vector2((0, 0))


    for _ in range(3000):

        x, y = random.randint(0, 1000), random.randint(0, 1000)

        pygame.draw.rect(background, pygame.Color('green'), (x, y, 2, 2))


    while True:

        events = pygame.event.get()

        for e in events:

            if e.type == pygame.QUIT:

                return


        # copy/paste because I'm lazy

        # just move the camera around

        pressed = pygame.key.get_pressed()

        camera_move = pygame.Vector2()

        if pressed[pygame.K_UP]: camera_move += (0, 1)

        if pressed[pygame.K_LEFT]: camera_move += (1, 0)

        if pressed[pygame.K_DOWN]: camera_move += (0, -1)

        if pressed[pygame.K_RIGHT]: camera_move += (-1, 0)

        if camera_move.length() > 0: camera_move.normalize_ip()

        camera += camera_move*(dt/5)


        sprites.update(events, dt)


        # before drawing, we shift everything by the camera's x and y values

        screen.blit(background, camera)

        for s in sprites:

            screen.blit(s.image, s.rect.move(*camera))


        pygame.display.update()

        dt = clock.tick(60)


if __name__ == '__main__':

    main()

http://img1.sycdn.imooc.com//61b1a5e10001033405040530.jpg

現(xiàn)在您可以使用箭頭鍵移動相機。


就是這樣。我們只是將所有內(nèi)容稍微移動一下,然后再將其傳輸?shù)狡聊簧稀?/p>


更完整的例子(支持精靈,停在世界邊緣,平滑移動),請看這個問題。


對于使用 pymunk:它只是有效。它不受將東西繪制到另一個位置的影響,因為它適用于世界坐標(biāo),而不是屏幕坐標(biāo)。唯一的缺陷是 pymunk 的 y 軸與 pygame 的 y 軸相比發(fā)生了翻轉(zhuǎn),但您可能已經(jīng)知道這一點。


下面是一個例子:


import pygame

import random

import pymunk


class Player(pygame.sprite.Sprite):

    def __init__(self, space):

        super().__init__()

        self.space = space

        self.image = pygame.Surface((32, 32))

        self.image.fill(pygame.Color('dodgerblue'))

        self.rect = self.image.get_rect()

        self.pos = pygame.Vector2((100, 200))

        self.body = pymunk.Body(1,1666)

        self.body.position = self.pos

        self.poly = pymunk.Poly.create_box(self.body)

        self.space.add(self.body, self.poly)


    def update(self, events, dt):

        pressed = pygame.key.get_pressed()

        move = pygame.Vector2((0, 0))

        if pressed[pygame.K_w]: move += (0, 1)

        if pressed[pygame.K_a]: move += (-1, 0)

        if pressed[pygame.K_s]: move += (0, -1)

        if pressed[pygame.K_d]: move += (1, 0)

        if move.length() > 0: move.normalize_ip()

        self.body.apply_impulse_at_local_point(move*5)


        # if you used pymunk before, you'll probably already know

        # that you'll have to invert the y-axis to convert between

        # the pymunk and the pygame coordinates.

        self.pos = pygame.Vector2(self.body.position[0], -self.body.position[1]+500)

        self.rect.center = self.pos


def main():

    pygame.init()

    screen = pygame.display.set_mode((500, 500))

    clock = pygame.time.Clock()

    dt = 0


    space = pymunk.Space()

    space.gravity = 0,-100


    player = Player(space)

    sprites = pygame.sprite.Group(player)


    # the "world" is now bigger than the screen

    # so we actually have anything to move the camera to

    background = pygame.Surface((1500, 1500))

    background.fill((30, 30, 30))


    # a camera is just two values: x and y

    # we use a vector here because it's easier to handle than a tuple

    camera = pygame.Vector2((0, 0))


    for _ in range(3000):

        x, y = random.randint(0, 1000), random.randint(0, 1000)

        pygame.draw.rect(background, pygame.Color('green'), (x, y, 2, 2))


    while True:

        events = pygame.event.get()

        for e in events:

            if e.type == pygame.QUIT:

                return


        # copy/paste because I'm lazy

        # just move the camera around

        pressed = pygame.key.get_pressed()

        camera_move = pygame.Vector2()

        if pressed[pygame.K_UP]: camera_move += (0, 1)

        if pressed[pygame.K_LEFT]: camera_move += (1, 0)

        if pressed[pygame.K_DOWN]: camera_move += (0, -1)

        if pressed[pygame.K_RIGHT]: camera_move += (-1, 0)

        if camera_move.length() > 0: camera_move.normalize_ip()

        camera += camera_move*(dt/5)


        sprites.update(events, dt)


        # before drawing, we shift everything by the camera's x and y values

        screen.blit(background, camera)

        for s in sprites:

            screen.blit(s.image, s.rect.move(*camera))


        pygame.display.update()

        dt = clock.tick(60)

        space.step(dt/1000)


if __name__ == '__main__':

    main()

http://img1.sycdn.imooc.com//61b1a5fd0001ae7204770530.jpg

請注意,當(dāng)您使用 時pymunk.Space.debug_draw,您將無法將世界坐標(biāo)轉(zhuǎn)換為屏幕坐標(biāo),因此最好將 pymunk 的東西簡單地繪制到另一個Surface,并將其轉(zhuǎn)換為Surface.


這是pygame_util_demo.py帶有移動相機的 pymunk :


import sys


import pygame

from pygame.locals import *


import pymunk

from pymunk.vec2d import Vec2d

import pymunk.pygame_util


import shapes_for_draw_demos


def main():

    pygame.init()

    screen = pygame.display.set_mode((1000,700)) 

    pymunk_layer = pygame.Surface((1000,700))

    pymunk_layer.set_colorkey((12,12,12))

    pymunk_layer.fill((12,12,12))

    camera = pygame.Vector2((0, 0))

    clock = pygame.time.Clock()

    font = pygame.font.SysFont("Arial", 16)


    space = pymunk.Space()


    captions = shapes_for_draw_demos.fill_space(space)


    # Info

    color = pygame.color.THECOLORS["black"]


    options = pymunk.pygame_util.DrawOptions(pymunk_layer)


    while True:

        for event in pygame.event.get():

            if event.type == QUIT or \

                event.type == KEYDOWN and (event.key in [K_ESCAPE, K_q]):  

                return 

            elif event.type == KEYDOWN and event.key == K_p:

                pygame.image.save(screen, "pygame_util_demo.png")                


        # copy/paste because I'm lazy

        pressed = pygame.key.get_pressed()

        camera_move = pygame.Vector2()

        if pressed[pygame.K_UP]: camera_move += (0, 1)

        if pressed[pygame.K_LEFT]: camera_move += (1, 0)

        if pressed[pygame.K_DOWN]: camera_move += (0, -1)

        if pressed[pygame.K_RIGHT]: camera_move += (-1, 0)

        if camera_move.length() > 0: camera_move.normalize_ip()

        camera += camera_move*5


        screen.fill(pygame.color.THECOLORS["white"])

        pymunk_layer.fill((12,12,12))

        space.debug_draw(options)

        screen.blit(pymunk_layer, camera)

        screen.blit(font.render("Demo example of pygame_util.DrawOptions()", 1, color), (205, 680))

        for caption in captions:

            x, y = caption[0]

            y = 700 - y

            screen.blit(font.render(caption[1], 1, color), camera + (x,y))

        pygame.display.flip()


        clock.tick(30)


if __name__ == '__main__':

    sys.exit(main())

http://img1.sycdn.imooc.com//61b1a6160001b5eb10030732.jpg

查看完整回答
反對 回復(fù) 2021-12-09
  • 1 回答
  • 0 關(guān)注
  • 761 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號