Pygameで更新せずにオブジェクトをウィンドウに永続的に貼り付けるにはどうすればよいですか?

ジョナサン

Pygameを使用してAtariBreakoutを再現しようとしています。問題が発生しました。タイルの3行すべてを3つのリストに入れ、それらを印刷して、ボールが当たる前にその場所にとどまらせたいと思います。

これはコードです:

import pygame
import random

pygame.init()

screenWidth = 1200
screenHeight = 700

window = pygame.display.set_mode((screenWidth,screenHeight))
pygame.display.set_caption('Atari Breakout')

pygame.mouse.set_pos(-500,650)


class Plate():

    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 5

    def draw_plate(self):
        pygame.mouse.set_visible(True)
        pos = pygame.mouse.get_pos()
        self.x = pos[0]-100

        pygame.draw.rect(window, (00,00,255), (self.x, self.y ,self.width, self.height))


class Circle():

    def __init__(self, x, y, radius):
        self.x = x
        self.y = y
        self.radius = radius
        self.vel_x = 5
        self.vel_y = 5


class Tiles():

    def __init__(self, x, y, width, height, color):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.color = color

    def draw(self):
        if self.color == 'red':
            pygame.draw.rect(window, (255,0,0), (self.x, self.y, self.width, self.height))
        elif self.color == 'green':
            pygame.draw.rect(window, (44,176,55), (self.x, self.y, self.width, self.height))
        elif self.color == 'blue':
            pygame.draw.rect(window, (0,191,255), (self.x, self.y, self.width, self.height))
        pygame.display.update()


def draw_titles():
    first_row = []
    second_row = []
    third_row = []
    preset_width1 = [70, 120, 200, 30, 240, 140, 130, 120, 80]                       # nine elements
    preset_width2 = [70, 120, 200, 30, 240, 140, 130, 120, 80]
    preset_width3 = [70, 120, 200, 30, 240, 140, 130, 120, 80]
    random.shuffle(preset_width1)
    random.shuffle(preset_width2)
    random.shuffle(preset_width3)
    #print(f'preset_width1 is: {preset_width1}')
    put_width1 = []
    put_width2 = []
    put_width3 = []

    for t in range(1,10):

        if t==1:
            width = preset_width1.pop(0)
            put_width1.append(width)
            #print(f'put_width1 is: {put_width1}')


        if t==1:
            x = 0 + 5
        else:
            add = sum(put_width1)
            #print(f'add is: {add}')
            x = t*5 + add
            #print(f'x is: {x}')

        if t>1:
            width = preset_width1.pop(0)
            put_width1.append(width)
            #print(f'put_width1 is: {put_width1}')

        y = 125

        height = 35


        first_row.append(Tiles(x,y,width,height,'red'))

        if t == 9:
            break

    for t in range(1,10):

        if t==1:
            width = preset_width2.pop(0)
            put_width2.append(width)

        if t==1:
            x = 0 + 5
        else:
            add = sum(put_width2)
            x = t*5 + add

        if t>1:
            width = preset_width2.pop(0)
            put_width2.append(width)

        y = 170

        height = 35

        second_row.append(Tiles(x,y,width,height,'green'))

        if t == 9:
            break

    for t in range(1,10):

        if t==1:
            width = preset_width3.pop(0)
            put_width3.append(width)

        if t==1:
            x = 0 + 5
        else:
            add = sum(put_width3)
            x = t*5 + add

        if t>1:
            width = preset_width3.pop(0)
            put_width3.append(width)

        y = 215

        height = 35

        third_row.append(Tiles(x,y,width,height,'blue'))

        if t == 9:
            break


    for num in range(0,9):
        first_row[num].draw()

    for num in range(0,9):
        second_row[num].draw()

    for num in range(0,9):
        third_row[num].draw()

    keys = pygame.key.get_pressed()
    if keys[pygame.K_BACKSPACE]:
        run = False







# main loop
plate = Plate(10,650,200,40)
ball = Circle(600,300,10)
run = True
start = False
bounds = pygame.Rect(0, 0, 1200, 700)


while run:
    pygame.time.Clock().tick(120)

    for event in pygame.event.get():
        if event == pygame.QUIT:
            run = False


    plate.draw_plate()



    keys = pygame.key.get_pressed()


    # bounce algorithem 
    if keys[pygame.K_SPACE]:
        start = True

    if start:
        ball.y -= ball.vel_y        
        ball.x += ball.vel_x

        if ball.x - ball.radius < bounds.left or ball.x + ball.radius > bounds.right:
            ball.vel_x *= -1 
        if ball.y - ball.radius < bounds.top or ball.y + ball.radius > bounds.bottom:
            ball.vel_y *= -1 

    pygame.draw.rect(window, (0, 0, 0), bounds, 1)
    pygame.draw.circle(window, (44,176,55), (ball.x, ball.y), ball.radius)
    #pygame.display.update()


    draw_titles()



    # close call
    if keys[pygame.K_BACKSPACE]:
        run = False
        break





    window.fill((0,0,0))
    pygame.display.update()




pygame.quit()

これは理想的な状況です。

理想的な状況

しかし、代わりに、それは狂ったようにリフレッシュします。問題は、draw_titles()関数をメインのWhileループ内に配置することです。しかし、draw_tiles()それ機能しなくなっ関数をコーディングする方法だと思いますdraw_titles()ループの前に置くと、タイルが表示されてすぐに消え、ボールとプレートの両方が表示されません。

オンラインで調査を行ったところ、テキストと画像のチュートリアルが表示されました。画像は使って.blit()ますが、画像だけだと思います。

私はこれを修正するために多くのバリエーションを試しましたが、役に立ちませんでした。助けてください。

ありがとうございました。

怠惰

簡単な修正は次のとおりです。

import pygame
import random

pygame.init()

screenWidth = 1200
screenHeight = 700

window = pygame.display.set_mode((screenWidth,screenHeight))
pygame.display.set_caption('Atari Breakout')

pygame.mouse.set_pos(-500,650)


class Plate():

    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 5

    def draw_plate(self):
        pygame.mouse.set_visible(True)
        pos = pygame.mouse.get_pos()
        self.x = pos[0]-100

        pygame.draw.rect(window, (00,00,255), (self.x, self.y ,self.width, self.height))


class Circle():

    def __init__(self, x, y, radius):
        self.x = x
        self.y = y
        self.radius = radius
        self.vel_x = 5
        self.vel_y = 5


class Tiles():

    def __init__(self, x, y, width, height, color):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.color = color

    def draw(self):
        if self.color == 'red':
            pygame.draw.rect(window, (255,0,0), (self.x, self.y, self.width, self.height))
        elif self.color == 'green':
            pygame.draw.rect(window, (44,176,55), (self.x, self.y, self.width, self.height))
        elif self.color == 'blue':
            pygame.draw.rect(window, (0,191,255), (self.x, self.y, self.width, self.height))

first_row = []
second_row = []
third_row = []

def create_titles():
    preset_width1 = [70, 120, 200, 30, 240, 140, 130, 120, 80]                       # nine elements
    preset_width2 = [70, 120, 200, 30, 240, 140, 130, 120, 80]
    preset_width3 = [70, 120, 200, 30, 240, 140, 130, 120, 80]
    random.shuffle(preset_width1)
    random.shuffle(preset_width2)
    random.shuffle(preset_width3)
    #print(f'preset_width1 is: {preset_width1}')
    put_width1 = []
    put_width2 = []
    put_width3 = []

    for t in range(1,10):

        if t==1:
            width = preset_width1.pop(0)
            put_width1.append(width)
            #print(f'put_width1 is: {put_width1}')


        if t==1:
            x = 0 + 5
        else:
            add = sum(put_width1)
            #print(f'add is: {add}')
            x = t*5 + add
            #print(f'x is: {x}')

        if t>1:
            width = preset_width1.pop(0)
            put_width1.append(width)
            #print(f'put_width1 is: {put_width1}')

        y = 125

        height = 35


        first_row.append(Tiles(x,y,width,height,'red'))

        if t == 9:
            break

    for t in range(1,10):

        if t==1:
            width = preset_width2.pop(0)
            put_width2.append(width)

        if t==1:
            x = 0 + 5
        else:
            add = sum(put_width2)
            x = t*5 + add

        if t>1:
            width = preset_width2.pop(0)
            put_width2.append(width)

        y = 170

        height = 35

        second_row.append(Tiles(x,y,width,height,'green'))

        if t == 9:
            break

    for t in range(1,10):

        if t==1:
            width = preset_width3.pop(0)
            put_width3.append(width)

        if t==1:
            x = 0 + 5
        else:
            add = sum(put_width3)
            x = t*5 + add

        if t>1:
            width = preset_width3.pop(0)
            put_width3.append(width)

        y = 215

        height = 35

        third_row.append(Tiles(x,y,width,height,'blue'))

        if t == 9:
            break

# main loop
plate = Plate(10,650,200,40)
ball = Circle(600,300,10)
run = True
start = False
bounds = pygame.Rect(0, 0, 1200, 700)

create_titles()

while run:
    pygame.time.Clock().tick(120)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()
    # bounce algorithem 
    if keys[pygame.K_SPACE]:
        start = True
    # close call
    if keys[pygame.K_BACKSPACE]:
        run = False
        break

    if start:
        ball.y -= ball.vel_y        
        ball.x += ball.vel_x

        if ball.x - ball.radius < bounds.left or ball.x + ball.radius > bounds.right:
            ball.vel_x *= -1 
        if ball.y - ball.radius < bounds.top or ball.y + ball.radius > bounds.bottom:
            ball.vel_y *= -1 

    window.fill((0,0,0))
    plate.draw_plate()
    pygame.draw.rect(window, (0, 0, 0), bounds, 1)
    pygame.draw.circle(window, (44,176,55), (ball.x, ball.y), ball.radius)
    for tile in first_row:
        tile.draw()
    for tile in second_row:
        tile.draw()
    for tile in third_row:
        tile.draw()

    pygame.display.update()

pygame.quit()

画面に描画するときは、最初に画面の表面をクリアしてから、次のようにすべてのオブジェクトを描画します。

    ...
    window.fill((0,0,0))
    plate.draw_plate()
    pygame.draw.rect(window, (0, 0, 0), bounds, 1)
    pygame.draw.circle(window, (44,176,55), (ball.x, ball.y), ball.radius)
    for tile in first_row:
        tile.draw()
    for tile in second_row:
        tile.draw()
    for tile in third_row:
        tile.draw() 
    ...

すべての描画関連のものが1か所にあることに注意してください。このように、それはより明確で混乱が少なくなります。

pygame.display .flip()(または.update())をフレームごとに1回だけ呼び出すようにしてくださいRabbid76がすでにコメントで述べているように)。

また、リストをdraw_titles関数の外に移動し、名前をに変更しましたcreate_titlesこの関数はタイルを作成するため、すべてのフレームではなく、1回だけ実行する必要があります。

また、おそらくpygameSpriteGroupクラスを調べる必要がありますいくつかのpygame機能を利用して一緒にハッキングした例を次に示します。

import pygame
import random

class Paddle(pygame.sprite.Sprite):

    def __init__(self, x, y, width, height, bounds, *grps):
        super().__init__(*grps)
        self.image = pygame.Surface((width, height))
        self.image.fill((0,0,255))
        self.rect = self.image.get_rect(topleft=(x, y))
        self.bounds = bounds

    def update(self, dt):
        pos = pygame.mouse.get_pos()
        self.rect.centerx = pos[0]
        self.rect.clamp_ip(self.bounds)

class Circle(pygame.sprite.Sprite):

    def __init__(self, x, y, radius, bounds, *grps):
        super().__init__(*grps)
        self.image = pygame.Surface((radius, radius))
        self.image.set_colorkey((1, 2, 3))
        self.image.fill((1, 2, 3))
        self.rect = self.image.get_rect(topleft=(x, y))
        pygame.draw.circle(self.image, (44,176,55), (radius//2, radius//2), 5)
        self.vel = pygame.Vector2((5, 5))
        self.pos = self.rect.center
        self.bounds = bounds

    def update(self, dt):
        self.pos += self.vel * min(dt/15, 10)
        self.rect.center = self.pos

        if self.rect.left < self.bounds.left or self.rect.right > self.bounds.right:
            self.vel.x *= -1
        if self.rect.top < self.bounds.top or self.rect.bottom > self.bounds.bottom:
            self.vel.y *= -1

        self.rect.clamp_ip(self.bounds)

    def bounce(self, sprite):
        if self.rect.top <= sprite.rect.top or sprite.rect.bottom >= sprite.rect.bottom:
            self.vel.y *= -1
        elif self.rect.left <= sprite.rect.left or sprite.rect.right >= sprite.rect.right:
            self.vel.x *= -1


class Tiles(pygame.sprite.Sprite):

    def __init__(self, x, y, width, height, color,  *grps):
        super().__init__(*grps)
        self.image = pygame.Surface((width, height))
        self.image.fill(color)
        self.rect = self.image.get_rect(topleft=(x, y))

    def hit(self):
        self.kill()

def main():
    pygame.init()
    screen = pygame.display.set_mode((1200, 700))
    screen_rect = screen.get_rect()
    pygame.display.set_caption('Atari Breakout')

    sprites = pygame.sprite.Group()
    tiles = pygame.sprite.Group()
    paddle = Paddle(10,650,200,40, screen_rect, sprites)
    ball = Circle(600,300,10, screen_rect, sprites)

    preset = [70, 120, 200, 30, 240, 140, 130, 120, 80]
    y = 215
    for color in ['blue', 'green', 'red']:
        x = 5
        line = preset[:]
        random.shuffle(line)
        for width in line:
            Tiles(x, y, width, 35, pygame.Color(color), sprites, tiles)
            x += width + 5
        y -= 45

    dt = 0
    clock = pygame.time.Clock()
    while True:
        pygame.time.Clock().tick(120)

        # events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_BACKSPACE:
                    return

        # game logic
        tile = pygame.sprite.spritecollideany(ball, tiles)
        if tile:
            tile.hit()
            ball.bounce(tile)

        if pygame.sprite.collide_rect(paddle, ball):
            ball.bounce(paddle)

        sprites.update(dt)

        # drawing
        screen.fill((0,0,0))
        sprites.draw(screen)
        pygame.draw.rect(screen, (0, 0, 0), screen_rect, 1)

        pygame.display.update()
        dt = clock.tick(120)

    pygame.quit()

if __name__ == '__main__':
    main()

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Pygameで更新せずにオブジェクトをウィンドウに永続的に貼り付けるにはどうすればよいですか?

分類Dev

オブジェクトの座標として永続的に設定せずに、pygameでタッチしているときにオブジェクトの長方形を形状の長方形に設定するにはどうすればよいですか?

分類Dev

オブジェクト指向プログラミングを使用せずに、tkinterでキャンバスオブジェクトのサイズをウィンドウサイズに変更するにはどうすればよいですか?

分類Dev

クリップボードからPythonウィンドウに貼り付けるにはどうすればよいですか?

分類Dev

JavaScriptでMathオブジェクトのプロパティをウィンドウに公開するにはどうすればよいですか?

分類Dev

フォアグラウンドにジャンプせずにパペッティアブラウザをバックグラウンドで実行し続けるにはどうすればよいですか?

分類Dev

'chrome.tabs.create()'で作成されたタブのウィンドウオブジェクトを取得するにはどうすればよいですか?

分類Dev

Pygame。サーフェスのサイズを変更し、すべてのオブジェクトを新しいウィンドウサイズに比例させるにはどうすればよいですか?

分類Dev

Pygame。サーフェスのサイズを変更し、すべてのオブジェクトを新しいウィンドウサイズに比例させるにはどうすればよいですか?

分類Dev

JerseyにHibernateによって永続化されたオブジェクトにリストを表示させるにはどうすればよいですか?

分類Dev

openGL c ++の同じウィンドウに2つのオブジェクトを描画するにはどうすればよいですか?

分類Dev

親を保存せずに、Railsのオブジェクトに子の関連付けを構築するにはどうすればよいですか?

分類Dev

クラスに割り当てる動的オブジェクト名を作成するにはどうすればよいですか?/異なるTkinterのオブジェクト名で複数のウィンドウを作成する方法

分類Dev

オブジェクトをドラッグせずにクリックして、シーンビューのマウスポイントにオブジェクトを作成するにはどうすればよいですか?

分類Dev

ReactJSでウィンドウオブジェクトを使用するにはどうすればよいですか?

分類Dev

VBAで特定の外部アプリウィンドウ(オブジェクト)を参照するにはどうすればよいですか?

分類Dev

Angular 2でウィンドウオブジェクトを使用するにはどうすればよいですか?

分類Dev

vue jsでウィンドウオブジェクトにアクセスするにはどうすればよいですか?

分類Dev

コード名1で、残りをブロックせずにUIのカウンターを更新するにはどうすればよいですか?

分類Dev

コピー/貼り付けでクラッシュしないプロキシを使用してtkinterテキストウィジェットが変更されたかどうかを追跡するにはどうすればよいですか?

分類Dev

ウィンドウオブジェクトのlocation属性にアクセスするにはどうすればよいですか?

分類Dev

Mongooseでオブジェクト全体を動的に更新せずに、ネストされたフィールドオブジェクトを更新するにはどうすればよいですか?

分類Dev

ループカウンターを使用して、オブジェクトを動的に作成し、そのカウンターを使用してオブジェクトに名前を付けるにはどうすればよいですか?

分類Dev

モックオブジェクトに名前を付けるにはどうすればよいですか?

分類Dev

QTextEditウィジェットをサブクラス化せずにmousePressEvent関数を定義するにはどうすればよいですか?

分類Dev

JPAを使用してエンティティー内のマップ(java.util.Map)オブジェクトを永続化し、永続性を確実にカスケードするにはどうすればよいですか?

分類Dev

mongoDBにあるオブジェクトの数でテーブルに連続して番号を付けるにはどうすればよいですか?

分類Dev

ウィジェットのオブジェクト名にフォーカスを合わせるにはどうすればよいですか?

分類Dev

AndroidのレイアウトXMLでオブジェクトにアニメーションを添付するにはどうすればよいですか?

Related 関連記事

  1. 1

    Pygameで更新せずにオブジェクトをウィンドウに永続的に貼り付けるにはどうすればよいですか?

  2. 2

    オブジェクトの座標として永続的に設定せずに、pygameでタッチしているときにオブジェクトの長方形を形状の長方形に設定するにはどうすればよいですか?

  3. 3

    オブジェクト指向プログラミングを使用せずに、tkinterでキャンバスオブジェクトのサイズをウィンドウサイズに変更するにはどうすればよいですか?

  4. 4

    クリップボードからPythonウィンドウに貼り付けるにはどうすればよいですか?

  5. 5

    JavaScriptでMathオブジェクトのプロパティをウィンドウに公開するにはどうすればよいですか?

  6. 6

    フォアグラウンドにジャンプせずにパペッティアブラウザをバックグラウンドで実行し続けるにはどうすればよいですか?

  7. 7

    'chrome.tabs.create()'で作成されたタブのウィンドウオブジェクトを取得するにはどうすればよいですか?

  8. 8

    Pygame。サーフェスのサイズを変更し、すべてのオブジェクトを新しいウィンドウサイズに比例させるにはどうすればよいですか?

  9. 9

    Pygame。サーフェスのサイズを変更し、すべてのオブジェクトを新しいウィンドウサイズに比例させるにはどうすればよいですか?

  10. 10

    JerseyにHibernateによって永続化されたオブジェクトにリストを表示させるにはどうすればよいですか?

  11. 11

    openGL c ++の同じウィンドウに2つのオブジェクトを描画するにはどうすればよいですか?

  12. 12

    親を保存せずに、Railsのオブジェクトに子の関連付けを構築するにはどうすればよいですか?

  13. 13

    クラスに割り当てる動的オブジェクト名を作成するにはどうすればよいですか?/異なるTkinterのオブジェクト名で複数のウィンドウを作成する方法

  14. 14

    オブジェクトをドラッグせずにクリックして、シーンビューのマウスポイントにオブジェクトを作成するにはどうすればよいですか?

  15. 15

    ReactJSでウィンドウオブジェクトを使用するにはどうすればよいですか?

  16. 16

    VBAで特定の外部アプリウィンドウ(オブジェクト)を参照するにはどうすればよいですか?

  17. 17

    Angular 2でウィンドウオブジェクトを使用するにはどうすればよいですか?

  18. 18

    vue jsでウィンドウオブジェクトにアクセスするにはどうすればよいですか?

  19. 19

    コード名1で、残りをブロックせずにUIのカウンターを更新するにはどうすればよいですか?

  20. 20

    コピー/貼り付けでクラッシュしないプロキシを使用してtkinterテキストウィジェットが変更されたかどうかを追跡するにはどうすればよいですか?

  21. 21

    ウィンドウオブジェクトのlocation属性にアクセスするにはどうすればよいですか?

  22. 22

    Mongooseでオブジェクト全体を動的に更新せずに、ネストされたフィールドオブジェクトを更新するにはどうすればよいですか?

  23. 23

    ループカウンターを使用して、オブジェクトを動的に作成し、そのカウンターを使用してオブジェクトに名前を付けるにはどうすればよいですか?

  24. 24

    モックオブジェクトに名前を付けるにはどうすればよいですか?

  25. 25

    QTextEditウィジェットをサブクラス化せずにmousePressEvent関数を定義するにはどうすればよいですか?

  26. 26

    JPAを使用してエンティティー内のマップ(java.util.Map)オブジェクトを永続化し、永続性を確実にカスケードするにはどうすればよいですか?

  27. 27

    mongoDBにあるオブジェクトの数でテーブルに連続して番号を付けるにはどうすればよいですか?

  28. 28

    ウィジェットのオブジェクト名にフォーカスを合わせるにはどうすればよいですか?

  29. 29

    AndroidのレイアウトXMLでオブジェクトにアニメーションを添付するにはどうすればよいですか?

ホットタグ

アーカイブ