Pygameでスクロールする背景(レベルエディタ)を実装する方法

スポンサーリンク

この記事では、レベルエディタを構築していきます。

レベルエディタは、ゲーマーがプレイするための素晴らしいチャレンジングなゲーム環境を作成するのにとても便利です。

このパートでは、スクロールする背景と作業用のグリッドを作成することに集中します。

まずは、今までの成果を見てみましょう。

続きを読む パート1: Pythonでレベルエディタ – セットアップと背景画像


スポンサーリンク

パート1 – ファイナルコード

この最後のパートでは、レベルエディターのセットアップを作成し、ウィンドウに背景画像を追加することに成功しました。

前編のコードは以下の通りです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import pygame
pygame.init()
 
screen_width = 800
screen_height = 640
 
lower_margin = 100
side_margin = 300
 
screen = pygame.display.set_mode((screen_width+side_margin,screen_height+lower_margin))
pygame.display.set_caption('Level Editor')
 
tree1 = pygame.image.load('Images/Background_Images/grass1.png').convert_alpha()
tree2 = pygame.image.load('Images/Background_Images/grass2.png').convert_alpha()
mountain = pygame.image.load('Images/Background_Images/mountain.png').convert_alpha()
sky = pygame.image.load('Images/Background_Images/sky.png').convert_alpha()
 
def paint_bg():
    screen.blit(sky,(0,0))
    screen.blit(mountain,(0,screen_height-mountain.get_height()-300))
    screen.blit(tree1,(0,screen_height-tree1.get_height()-150))
    screen.blit(tree2,(0,screen_height-tree2.get_height()))
     
running = True
while(running):
     
    paint_bg()
     
    for event in pygame.event.get():
        if(event.type==pygame.QUIT):
            running = False
             
    pygame.display.update()
 
pygame.quit()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import pygame
pygame.init()
 
screen_width = 800
screen_height = 640
 
lower_margin = 100
side_margin = 300
 
screen = pygame.display.set_mode((screen_width+side_margin,screen_height+lower_margin))
pygame.display.set_caption('Level Editor')
 
scroll_left = False
scroll_right = False
scroll = 0
scroll_speed = 1
 
tree1 = pygame.image.load('Images/Background_Images/grass1.png').convert_alpha()
tree2 = pygame.image.load('Images/Background_Images/grass2.png').convert_alpha()
mountain = pygame.image.load('Images/Background_Images/mountain.png').convert_alpha()
sky = pygame.image.load('Images/Background_Images/sky.png').convert_alpha()
 
def paint_bg():
    screen.blit(sky,(0,0))
    screen.blit(mountain,(0,screen_height-mountain.get_height()-300))
    screen.blit(tree1,(0,screen_height-tree1.get_height()-150))
    screen.blit(tree2,(0,screen_height-tree2.get_height()))
     
running = True
while(running):
     
    paint_bg()
     
    for event in pygame.event.get():
        if(event.type==pygame.QUIT):
            running = False
         
        if(event.type == pygame.KEYDOWN):
            if(event.key == pygame.K_LEFT):
                scroll_left = True
            if(event.key == pygame.K_RIGHT):
                scroll_right = True
             
        if(event.type == pygame.KEYUP):
            if(event.key == pygame.K_LEFT):
                scroll_left = False
            if(event.key == pygame.K_RIGHT):
                scroll_right = False
         
    pygame.display.update()
 
pygame.quit()

背景のスクロール機能

スクロールする背景を扱う前に、以下のような変数を宣言する必要があります。

scroll_left
scroll_right
scroll
scroll_speed

宣言は関数が実行される前に行われる。

以下では、行13から順に変数を宣言している。

これらの変数の宣言の後、スクロール機能を実現するために、実行ループの中でイベントに応じて条件文を追加する必要がある。

1. スクロール変数とキーの宣言

さて、スクロールイベントを発生させるには、左に移動するには LEFT 矢印キーを押し、右に移動するには RIGHT 矢印キーを押す必要があります。

従って、イベントのタイプは KEYDOWN となります。

さらに、キーが K_LEFT であれば scroll_left 変数を True にし、K_RIGHTscroll_right 変数についても同様の処理を行います。

また、キーが離されたときの動作も追加する必要があります。

なぜなら、そのときはスクロールを停止する必要があり、両方の変数が再びFalseに設定されるからです。

このようなイベントタイプは KEYUP イベントです。

以下のコードを見て、先に説明したことをすべて確認してください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import pygame
pygame.init()
 
screen_width = 800
screen_height = 640
 
lower_margin = 100
side_margin = 300
 
screen = pygame.display.set_mode((screen_width+side_margin,screen_height+lower_margin))
pygame.display.set_caption('Level Editor')
 
scroll_left = False
scroll_right = False
scroll = 0
scroll_speed = 1
 
tree1 = pygame.image.load('Images/Background_Images/grass1.png').convert_alpha()
tree2 = pygame.image.load('Images/Background_Images/grass2.png').convert_alpha()
mountain = pygame.image.load('Images/Background_Images/mountain.png').convert_alpha()
sky = pygame.image.load('Images/Background_Images/sky.png').convert_alpha()
 
def paint_bg():
    screen.blit(sky,(-scroll,0))
    screen.blit(mountain,(-scroll,screen_height-mountain.get_height()-300))
    screen.blit(tree1,(-scroll,screen_height-tree1.get_height()-150))
    screen.blit(tree2,(-scroll,screen_height-tree2.get_height()))
     
running = True
while(running):
     
    paint_bg()
     
    if(scroll_left==True):
        scroll-=5
     
    if(scroll_right==True):
        scroll+=5
         
    for event in pygame.event.get():
        if(event.type==pygame.QUIT):
            running = False
         
        if(event.type == pygame.KEYDOWN):
            if(event.key == pygame.K_LEFT):
                scroll_left = True
            if(event.key == pygame.K_RIGHT):
                scroll_right = True
             
        if(event.type == pygame.KEYUP):
            if(event.key == pygame.K_LEFT):
                scroll_left = False
            if(event.key == pygame.K_RIGHT):
                scroll_right = False
         
    pygame.display.update()
 
pygame.quit()

しかし、これではまだスクロールが追加されません。

変数に値を代入していますが、まだ何もしていません。

2. スクロール条件の作成

背景描画関数を呼び出した後の実行ループで、以下のような条件文を作成します。

ウィンドウをピクセル値 5 でスクロールさせたいのですが、もう一つ重要なことは、背景画像をスクロールの始点から両方向に描画することです。

そのため、paint_bg 関数で画像の開始座標を scroll に変更します。

そしてもう一つ重要なことは、正しい方向にスクロールさせるために、座標の前に minus ( – ) を追加する必要があるということです。

この出力を見て、あなたはきっとショックを受けることでしょう。

自分で試してみてください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import pygame
pygame.init()
 
screen_width = 800
screen_height = 640
 
lower_margin = 100
side_margin = 300
 
screen = pygame.display.set_mode((screen_width+side_margin,screen_height+lower_margin))
pygame.display.set_caption('Level Editor')
 
scroll_left = False
scroll_right = False
scroll = 0
scroll_speed = 1
 
tree1 = pygame.image.load('Images/Background_Images/grass1.png').convert_alpha()
tree2 = pygame.image.load('Images/Background_Images/grass2.png').convert_alpha()
mountain = pygame.image.load('Images/Background_Images/mountain.png').convert_alpha()
sky = pygame.image.load('Images/Background_Images/sky.png').convert_alpha()
 
def paint_bg():
     
    screen.fill((144,201,120)) # Green Color
    width = sky.get_width()
    for x in range(4):
        screen.blit(sky,((x*width)-scroll,0))
        screen.blit(mountain,((x*width)-scroll,screen_height-mountain.get_height()-300))
        screen.blit(tree1,((x*width)-scroll,screen_height-tree1.get_height()-150))
        screen.blit(tree2,((x*width)-scroll,screen_height-tree2.get_height()))
     
running = True
while(running):
     
    paint_bg()
     
    if(scroll_left==True and scroll>0):
        scroll-=5
     
    if(scroll_right==True):
        scroll+=5
         
    for event in pygame.event.get():
        if(event.type==pygame.QUIT):
            running = False
         
        if(event.type == pygame.KEYDOWN):
            if(event.key == pygame.K_LEFT):
                scroll_left = True
            if(event.key == pygame.K_RIGHT):
                scroll_right = True
             
        if(event.type == pygame.KEYUP):
            if(event.key == pygame.K_LEFT):
                scroll_left = False
            if(event.key == pygame.K_RIGHT):
                scroll_right = False
         
    pygame.display.update()
 
pygame.quit()
 

見てください!スクロールした後、画像がこんなにぐちゃぐちゃになってしまいました。

こんなのでいいんでしょうか?いや、そうですね。

背景を修正しましょう

3. スクロールする背景を最適化する

まず、スクロールする背景をいくつかのランダムな色にしよう。

そのためには、各反復処理で背景を色で塗りつぶし、後で元の背景画像をその上に塗りつぶすようにします。

これを実現するために、変数 x を使って n 回の反復処理を行う(この n は任意の値で良いが、ここでは 4 とした)。

そして、初期座標を変更し、イメージの幅を追加します。

ここでは、画像の幅は同じなので、1つの変数で済みます。

幅が異なる場合は、個別に指定します。

もう一つ必要なのは、スクロールを「制限」することです。

そのために、以下のコードの38行目に条件を追加しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import pygame
pygame.init()
 
screen_width = 800
screen_height = 640
 
lower_margin = 100
side_margin = 300
 
screen = pygame.display.set_mode((screen_width+side_margin,screen_height+lower_margin))
pygame.display.set_caption('Level Editor')
 
scroll_left = False
scroll_right = False
scroll = 0
scroll_speed = 1
 
tree1 = pygame.image.load('Images/Background_Images/grass1.png').convert_alpha()
tree2 = pygame.image.load('Images/Background_Images/grass2.png').convert_alpha()
mountain = pygame.image.load('Images/Background_Images/mountain.png').convert_alpha()
sky = pygame.image.load('Images/Background_Images/sky.png').convert_alpha()
 
def paint_bg():
     
    screen.fill((144,201,120)) # Green Color
    width = sky.get_width()
    for x in range(4):
        screen.blit(sky,((x*width)-scroll,0))
        screen.blit(mountain,((x*width)-scroll,screen_height-mountain.get_height()-300))
        screen.blit(tree1,((x*width)-scroll,screen_height-tree1.get_height()-150))
        screen.blit(tree2,((x*width)-scroll,screen_height-tree2.get_height()))
     
no_rows = 16
no_columns = 150
tile_size = screen_height//no_rows
WHITE = (255, 255, 255)
 
def draw_gridlines():
    #vertical lines
    for c in range(no_columns + 1):
        pygame.draw.line(screen, WHITE, (c * tile_size - scroll, 0), (c * tile_size - scroll, screen_height))
    #horizontal lines
    for c in range(no_rows + 1):
        pygame.draw.line(screen, WHITE, (0, c * tile_size), (screen_width, c * tile_size))
         
running = True
while(running):
     
    paint_bg()
    draw_gridlines()
     
    if(scroll_left==True and scroll>0):
        scroll-=5
     
    if(scroll_right==True):
        scroll+=5
         
    for event in pygame.event.get():
        if(event.type==pygame.QUIT):
            running = False
         
        if(event.type == pygame.KEYDOWN):
            if(event.key == pygame.K_LEFT):
                scroll_left = True
            if(event.key == pygame.K_RIGHT):
                scroll_right = True
             
        if(event.type == pygame.KEYUP):
            if(event.key == pygame.K_LEFT):
                scroll_left = False
            if(event.key == pygame.K_RIGHT):
                scroll_right = False
         
    pygame.display.update()
 
pygame.quit()

画面のグリッドを描画する

グリッド線を描くには、まずスクリーン上に必要な行と列の数を変数で宣言する必要があります(好みに応じて設定できます)。

また、グリッド上の各「正方形」のタイルの大きさを計算する必要があります。

そして、グリッドに色を付けるために色 WHITE を定義しました。

グリッド線をスクリーンに描くために、縦線と横線をスクリーンに描く関数を宣言します。

ループを使って、グリッド線がスクロールに合わせて動き、画面上で静止していないことを確認します。

グリッドラインのコードは、以下のコードの「34行目」あたりから始まります。

LevelEditor Draft1
LevelEditor Scroll Output 1
LevelEditor GridLines Addition

縦線だけで構成されている部分について、疑問に思われるかもしれませんね。

まあ、その部分は後のセクションでサイドパネルでカバーされます。

だから、心配しないでください。


まとめ

このパートの終わりまでに、レベルエディタにスクロール効果を追加し、後でレベルのブロックを配置するのに役立つグリッドラインを追加することを学びました。

次のパートでは、画面にいくつかの要素を追加する方法を学びます。

引き続き、お楽しみに それでは、Happy Learning!


タイトルとURLをコピーしました