반응형

파이게임에 간단한 카메라를 만들어 보자.

 

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import pygame
 
pygame.init()
pygame.display.set_caption("Pygame Simple Camera")
screen = pygame.display.set_mode((640480), flags=pygame.RESIZABLE, vsync=1)
clock = pygame.time.Clock()
 
class Camera():
    def __init__(self):
        self.offset = pygame.math.Vector2(00)
        self.speed = 4
        
camera = Camera()
 
def LoadImage(path, scale=None, colorkey=None):
    image = pygame.image.load(path).convert()
 
    if scale is not None:
        image = pygame.transform.scale(image, (image.get_width()*scale, image.get_height()*scale))
 
    if colorkey is not None:
        if colorkey == -1:
            colorkey = image.get_at((00))
        image.set_colorkey(colorkey)
 
    return image
 
class Sprite(pygame.sprite.Sprite):
    def __init__(self, spriteName, position, frames):
        pygame.sprite.Sprite.__init__(self)
 
        self.elapsedTime = 0
        self.limitTime = 1000/frames
        # 1초에 한 사이클. 스프라이트가 8프레임이라면 frames에 8을 대입한다.
        
        self.direction = 1
        self.speed = 4
        self.index = 0
        self.images = [ LoadImage(spriteName, 3-1) ]
        self.image = self.images[self.index]
        self.rect = self.image.get_rect(center=position)
 
    def flip_image(self):
        self.images = [pygame.transform.flip(image, TrueFalsefor image in self.images]
        self.image = self.images[self.index]
 
    def update(self):
        if (camera.offset.x != 0 or camera.offset.y != 0):
                self.rect.move_ip(camera.offset.x, camera.offset.y)
        
        # 1초에 frame번 image 업데이트.
        # self.elapsedTime += clock.get_time()
        # if self.elapsedTime < self.limitTime:
        #     pass
        # else:
        #     self.elapsedTime = 0
        #     self.index += 1
        #     if self.index >= len(self.images):
        #         self.index = 0
        #     self.image = self.images[self.index]
            
def main():
    player = Sprite("character.bmp", (screen.get_width()/2, screen.get_height()/2), 1)
    shop = Sprite("shop.bmp", (screen.get_width()/2, screen.get_height()/2), 1)
    all_sprites = pygame.sprite.Group()
    all_sprites.add(shop)
    all_sprites.add(player)
    
    running = True
    
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                running = False
 
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            if player.direction > 0:
                player.flip_image()
                player.direction = -1
            player.rect.move_ip(-player.speed, 0)            
            
        if keys[pygame.K_RIGHT]:
            if player.direction < 0:
                player.flip_image()
                player.direction = 1
            player.rect.move_ip(player.speed, 0)
        
        if keys[pygame.K_UP]:
            if player.direction < 0:
                player.flip_image()
                player.direction = 1
            player.rect.move_ip(0-player.speed)
        
        if keys[pygame.K_DOWN]:
            if player.direction < 0:
                player.flip_image()
                player.direction = 1
            player.rect.move_ip(0, player.speed)
        
        # 카메라 이동
        if keys[pygame.K_a]:
            camera.offset.x = camera.speed
        if keys[pygame.K_d]:
            camera.offset.x = -camera.speed
        if keys[pygame.K_w]:
            camera.offset.y = camera.speed
        if keys[pygame.K_s]:
            camera.offset.y = -camera.speed
 
        all_sprites.update()
        
        # 스프라이트 업데이트 후 카메라 오프셋 초기화
        camera.offset.x = camera.offset.y = 0        
        
        screen.fill("black")        
        all_sprites.draw(screen)
        pygame.display.flip()
 
        clock.tick(60)
 
    pygame.quit()
 
if __name__ == '__main__':
  main()
 

 

코드를 입력하고 실행한다. set_mode()에 vsync 파라미터를 1로 설정하지 않으면 스프라이트가 움직일때 screen tearing 현상이 일어날 수 있다.

pygame.display.set_mode(..., vsync=1)

 

방향키로 캐릭터를, wasd로 카메라를 움직인다.

 

※ 참고

Cameras in Pygame

 

반응형
Posted by J-sean
: