반응형

OpenGL 화면에 Pygame 이미지(스프라이트)를 렌더링 해 보자.

 

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
import pygame
from pygame.locals import *
 
from OpenGL.GL import *
from OpenGL.GLU import *
 
verticies = ((1-1-1), (11-1), (-11-1), (-1-1-1),
             (1-11), (111), (-1-11), (-111))
edges = ((0,1), (0,3), (0,4), (2,1), (2,3), (2,7), (6,3), (6,4),
         (6,7), (5,1), (5,4), (5,7))
 
def drawCube():
    glBegin(GL_LINES)
    for edge in edges:
        for vertex in edge:
            glVertex3fv(verticies[vertex])
    glEnd()
 
def drawImage(x, y):
    image = pygame.image.load("player.png").convert()
    image.set_colorkey(image.get_at((00)))
    image = pygame.transform.scale(image, (image.get_width()*1.5,
                                           image.get_height()*1.5))
    imageData = pygame.image.tostring(image, "RGBA"True)
    glWindowPos2d(x-image.get_width()/2, y-image.get_height()/2)
    glDrawPixels(image.get_width(), image.get_height(), GL_RGBA,
                 GL_UNSIGNED_BYTE, imageData)
 
pygame.init()
clock = pygame.time.Clock()
display = (640480)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
 
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
 
gluPerspective(45, (display[0]/display[1]), 0.150.0)
glTranslatef(0.00.0-5)
 
run = True
while run:    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
 
    glRotatef(1311)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    drawCube()
    drawImage(display[0]/2, display[1]/2)
    
    pygame.display.flip()
    clock.tick(60)
 
pygame.quit()
exit()
 

 

 

 

반응형
Posted by J-sean
:
반응형

OpenGL 화면에 Pygame 폰트를 렌더링 해 보자.

 

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
import pygame
from pygame.locals import *
 
from OpenGL.GL import *
from OpenGL.GLU import *
 
verticies = ((1-1-1), (11-1), (-11-1), (-1-1-1),
             (1-11), (111), (-1-11), (-111))
edges = ((0,1), (0,3), (0,4), (2,1), (2,3), (2,7), (6,3), (6,4),
         (6,7), (5,1), (5,4), (5,7))
 
def drawCube():
    glBegin(GL_LINES)
    for edge in edges:
        for vertex in edge:
            glVertex3fv(verticies[vertex])
    glEnd()
 
def drawText(x, y, text):
    font = pygame.font.SysFont('arial'64)
    textSurface = font.render(text, True, (125125125255), (2552550255))
    textData = pygame.image.tostring(textSurface, "RGBA"True)
    glWindowPos2d(x-textSurface.get_width()/2, y-textSurface.get_height()/2)
    glDrawPixels(textSurface.get_width(), textSurface.get_height(), GL_RGBA,
                 GL_UNSIGNED_BYTE, textData)
 
pygame.init()
clock = pygame.time.Clock()
display = (640480)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
 
gluPerspective(45, (display[0]/display[1]), 0.150.0)
glTranslatef(0.00.0-5)
 
run = True
while run:    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
 
    glRotatef(1311)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    drawCube()
    drawText(display[0]/2, display[1]/2"Cube")
    
    pygame.display.flip()
    clock.tick(60)
 
pygame.quit()
exit()
 

 

 

 

이번엔 폰트의 배경이 표시되지 않도록 해 보자.

 

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
import pygame
from pygame.locals import *
 
from OpenGL.GL import *
from OpenGL.GLU import *
 
verticies = ((1-1-1), (11-1), (-11-1), (-1-1-1),
             (1-11), (111), (-1-11), (-111))
edges = ((0,1), (0,3), (0,4), (2,1), (2,3), (2,7), (6,3), (6,4),
         (6,7), (5,1), (5,4), (5,7))
 
def drawCube():
    glBegin(GL_LINES)
    for edge in edges:
        for vertex in edge:
            glVertex3fv(verticies[vertex])
    glEnd()
 
def drawText(x, y, text):
    font = pygame.font.SysFont('arial'64)
    textSurface = font.render(text, True, (125125125255)).convert_alpha()
    textData = pygame.image.tostring(textSurface, "RGBA"True)
    glWindowPos2d(x-textSurface.get_width()/2, y-textSurface.get_height()/2)
    glDrawPixels(textSurface.get_width(), textSurface.get_height(), GL_RGBA,
                 GL_UNSIGNED_BYTE, textData)
 
pygame.init()
clock = pygame.time.Clock()
display = (640480)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
 
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
 
gluPerspective(45, (display[0]/display[1]), 0.150.0)
glTranslatef(0.00.0-5)
 
run = True
while run:    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
 
    glRotatef(1311)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    drawCube()
    drawText(display[0]/2, display[1]/2"Cube")
    
    pygame.display.flip()
    clock.tick(60)
 
pygame.quit()
exit()
 

 

 

 

반응형
Posted by J-sean
:

[Pygame] PyOpenGL 파이게임

Python 2023. 9. 11. 23:09 |
반응형

파이게임과 PyOpenGL을 연동해 보자.

 

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
import pygame
from pygame.locals import *
 
from OpenGL.GL import *
from OpenGL.GLU import *
 
verticies = (
    (1-1-1), (11-1),
    (-11-1), (-1-1-1),
    (1-11), (111),
    (-1-11), (-111) )
 
edges = (
    (0,1), (0,3), (0,4),
    (2,1), (2,3), (2,7),
    (6,3), (6,4), (6,7),
    (5,1), (5,4), (5,7) )
 
def Cube():
    glBegin(GL_LINES)
    for edge in edges:
        for vertex in edge:
            glVertex3fv(verticies[vertex])
    glEnd()
 
def main():
    pygame.init()
    display = (640,480)
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
    clock = pygame.time.Clock()
 
    gluPerspective(45, (display[0]/display[1]), 0.150.0)
 
    glTranslatef(0.00.0-5)
 
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
 
        glRotatef(1312)
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        Cube()
 
        pygame.display.flip()
        clock.tick(30)
 
if __name__ == '__main__':
   main()
 

 

 

 

※ 참고

PyOpenGL Tutorial1

PyOpenGL Tutorial2

OpenGL 강좌1

OpenGL 강좌2

 

반응형
Posted by J-sean
:
반응형

커서를 바꿔보자.

 

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
import pygame
 
pygame.init()
screen = pygame.display.set_mode((640480))
pygame.display.set_caption("Example code for the cursors module")
 
# 시스템 커서 생성
systemCursor = pygame.cursors.Cursor(pygame.SYSTEM_CURSOR_NO)
#pygame.SYSTEM_CURSOR_ARROW       arrow
#pygame.SYSTEM_CURSOR_IBEAM       i-beam
#pygame.SYSTEM_CURSOR_WAIT        wait
#pygame.SYSTEM_CURSOR_CROSSHAIR   crosshair
#pygame.SYSTEM_CURSOR_WAITARROW   small wait cursor
#                                 (or wait if not available)
#pygame.SYSTEM_CURSOR_SIZENWSE    double arrow pointing
#                                 northwest and southeast
#pygame.SYSTEM_CURSOR_SIZENESW    double arrow pointing
#                                 northeast and southwest
#pygame.SYSTEM_CURSOR_SIZEWE      double arrow pointing
#                                 west and east
#pygame.SYSTEM_CURSOR_SIZENS      double arrow pointing
#                                 north and south
#pygame.SYSTEM_CURSOR_SIZEALL     four pointed arrow pointing
#                                 north, south, east, and west
#pygame.SYSTEM_CURSOR_NO          slashed circle or crossbones
#pygame.SYSTEM_CURSOR_HAND        hand
 
# 비트맵 커서 생성.
bitmapCursor1 = pygame.cursors.Cursor(*pygame.cursors.arrow)
#pygame.cursors.arrow
#pygame.cursors.diamond
#pygame.cursors.broken_x
#pygame.cursors.tri_left
#pygame.cursors.tri_right
 
custom_strings = (           # size: 24x24
  "XX                      ",
  "XXX                     ",
  "XXXX                    ",
  "XX.XX                   ",
  "XX..XX                  ",
  "XX...XX                 ",
  "XX    XX                ",
  "XX     XX               ",
  "XX      XX              ",
  "XX       XX             ",
  "XX        XX            ",
  "XX        XXX           ",
  "XX      XXXXX           ",
  "XX XXX..XX              ",
  "XXXX XX..XX             ",
  "XX   XX..XX             ",
  "     XX..XX             ",
  "      XX..XX            ",
  "      XX..XX            ",
  "       XXXX             ",
  "       XX               ",
  "                        ",
  "                        ",
  "                        ")
 
bitmapCursor2 = pygame.cursors.Cursor(
    (2424), (00), *pygame.cursors.compile(custom_strings))
# Cursor클래스 인수: Cursor(size, hotspot, xormasks, andmasks)
# size는 8의 배수. hotspot은 클릭 지점. xormasks와 andmasks는
# pygame.cursors.compile()로 만들 수 있다. compile()에는 직접
# 만든 스트링이나 아래 상수 대입 가능.
#pygame.cursors.thickarrow_strings
#pygame.cursors.sizer_x_strings
#pygame.cursors.sizer_y_strings
#pygame.cursors.sizer_xy_strings
#pygame.cursor.textmarker_strings
 
# Surface 커서 생성.
surf = pygame.Surface((4040)) # 이미지를 로드할 수 도 있다.
surf.fill((1205050))        # 이미지를 로드하는 경우 불필요한 코드
surfaceCursor = pygame.cursors.Cursor((2020), surf)
 
cursors = [systemCursor, bitmapCursor1, bitmapCursor2, surfaceCursor]
cursor_index = 0
 
pygame.mouse.set_cursor(cursors[cursor_index])
 
clock = pygame.time.Clock()
going = True
while going:
    clock.tick(60)
    screen.fill((07530))
    pygame.display.flip()
 
    for event in pygame.event.get():
        if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and
                                        event.key == pygame.K_ESCAPE):
            going = False
 
        # 마우스 버튼이 눌리면 커서를 바꾼다.
        if event.type == pygame.MOUSEBUTTONDOWN:
            cursor_index += 1
            cursor_index %= len(cursors)
            pygame.mouse.set_cursor(cursors[cursor_index])
 
pygame.quit()
 

 

 

마우스를 클릭할 때 마다 커서가 바뀐다.

 

반응형
Posted by J-sean
:
반응형

컴퓨터에 연결된 조이스틱을 조사하고 각 버튼의 상태를 확인해 보자.

 

 

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
import pygame
 
pygame.init()
 
def main():
    clock = pygame.time.Clock()
 
    joysticks = {}
    # 조이스틱을 관리하기 위한 딕셔너리.
 
    done = False
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
 
            if event.type == pygame.JOYBUTTONDOWN:
                print("Joystick button pressed.")
                            
            if event.type == pygame.JOYBUTTONUP:
                print("Joystick button released.")
 
            if event.type == pygame.JOYAXISMOTION:
                print("Joystick axis motion detected.")
                
            if event.type == pygame.JOYDEVICEADDED:
                joy = pygame.joystick.Joystick(event.device_index)
                # 컴퓨터에 연결된 물리적 조이스틱에 접근하기 위한 Joystick 클래스 생성.
                # Joystick 클래스 생성자 인수에는 0 부터 pygame.joystick.get_count()-1 까지 대입한다.
                # event.device_index는 0부터 연결된 조이스틱의 숫자 -1 까지 증가하는거 같다.
                joysticks[joy.get_instance_id()] = joy
                # joysticks 딕셔너리에 새로 생성된 Joystick 클래스를 추가한다.
                # joy.get_instance_id() 는 joystick의 instance ID를 반환한다. 이 값은 Joystick 클래스
                # 생성자 인수로 넣은 값과 같은거 같다. event.instance_id 와 같은 값을 가진다.
                print(f"Joystick #{joy.get_instance_id()} connencted")
 
            if event.type == pygame.JOYDEVICEREMOVED:
                del joysticks[event.instance_id]
                # 조이스틱을 분리하면 joysticks 딕셔너리에서 분리된 조이스틱을 삭제한다.
                print(f"Joystick #{event.instance_id} disconnected")
 
        for joystick in joysticks.values():
        # dictionary.values() 는 dict_values라는 리스트 객체를 리턴하며 이 안에는 값의 목록만 들어 있다.
            jid = joystick.get_instance_id()
            name = joystick.get_name()
            guid = joystick.get_guid()
 
            axes = joystick.get_numaxes()
            for i in range(axes):
                axis = joystick.get_axis(i)
                if axis > 0.1 or axis < -0.1:
                    print(f"ID: {jid} Name: {name}, GUID: {guid}, Axis #{i}, Value: {axis:>6.3f}")
 
            buttons = joystick.get_numbuttons()
            for i in range(buttons):
                button = joystick.get_button(i)
                if button != 0:
                    print(f"ID: {jid} Name: {name}, GUID: {guid}, Button #{i:>2} Value: {button}")
                    
    clock.tick(30)
 
if __name__ == "__main__":
    main()
    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
53
54
55
56
import pygame
 
pygame.init()
 
joy = None
jid = None
name = None
guid = None
 
def main():
    clock = pygame.time.Clock()
    done = False
 
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
 
            if event.type == pygame.JOYBUTTONDOWN:
                print("Joystick button pressed.")
                buttons = joy.get_numbuttons()
                for i in range(buttons):
                    button = joy.get_button(i)
                    if button != 0:
                        print(f"ID: {jid} Name: {name}, GUID: {guid}, Button #{i:>2} Value: {button}")
                            
            if event.type == pygame.JOYBUTTONUP:
                print("Joystick button released.")
 
            if event.type == pygame.JOYAXISMOTION:
                print("Joystick axis motion detected.")
                # 방향 버튼을 눌렀을 때 -1, 0, 1 같은 정수가 나오지 않을 수 도 있다.
                if joy.get_axis(0> 0.5:                    
                    print(f"ID: {jid} Name: {name}, GUID: {guid}, Axis: L/R Value: RIGHT")
                if joy.get_axis(0< -0.5:
                    print(f"ID: {jid} Name: {name}, GUID: {guid}, Axis: L/R, Value: LEFT")
                if joy.get_axis(1> 0.5:
                    print(f"ID: {jid} Name: {name}, GUID: {guid}, Axis: U/D, Value: DOWN")
                if joy.get_axis(1< -0.5:
                    print(f"ID: {jid} Name: {name}, GUID: {guid}, Axis: U/D, Value: UP")
 
            if event.type == pygame.JOYDEVICEADDED:
                joy = pygame.joystick.Joystick(event.device_index)
                jid = joy.get_instance_id()
                name = joy.get_name()
                guid = joy.get_guid()
                print(f"Joystick #{joy.get_instance_id()} connencted")
 
            if event.type == pygame.JOYDEVICEREMOVED:
                print(f"Joystick #{event.instance_id} disconnected")
 
    clock.tick(30)
 
if __name__ == "__main__":
    main()
    pygame.quit()
 

 

 

버튼을 누를때 마다 상태를 표시한다.

 

반응형
Posted by J-sean
:
반응형

움직이던 물체의 속도가 갑자기 0이 되는 것은 자연스럽지 못하다. 자연스럽게 천천히 멈추는 캐릭터를 만들어 보자.

 

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
import pygame
 
pygame.init()
pygame.display.set_caption("Super fun game development")
screen = pygame.display.set_mode((640480))
clock = pygame.time.Clock()
running = True
 
player = pygame.image.load("player.png").convert()
player.set_colorkey(player.get_at((00)))
player_size = (player.get_width()*1.5, player.get_height()*1.5)
player = pygame.transform.scale(player, player_size)
player_pos = player.get_rect()
player_pos.center = (screen.get_width()/2, screen.get_height()/2)
player_speed = 4
player_direction = -1
 
left_released = False
right_released = False
slipcount = 0
slipduration = 60
# 캐릭터 미끄러지는 동작 관련 변수들.
 
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
 
        # 왼쪽, 오른쪽 방향키를 떼는 순간.
        if event.type == pygame.KEYUP and event.key == pygame.K_LEFT:
            left_released = True
            right_released = False
            slipcount = 0    
        elif event.type == pygame.KEYUP and event.key == pygame.K_RIGHT:
            right_released = True
            left_released = False
            slipcount = 0
        # 캐릭터의 미끄러지는 동작이 끝나기 전에 반대 방향 키를 누르는 경우에 대비.
 
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        if player_direction > 0:
            player = pygame.transform.flip(player, TrueFalse)
            player_direction = -1
        player_pos.move_ip(-player_speed, 0)
    if keys[pygame.K_RIGHT]:
        if player_direction < 0:
            player = pygame.transform.flip(player, TrueFalse)
            player_direction = 1            
        player_pos.move_ip(player_speed, 0)
    
    # 왼쪽으로 이동 중 키를 놓았을때 slipduration 프레임 동안 미끄러진다.
    if left_released == True:
        player_pos.move_ip(-pygame.math.lerp(player_speed, 0, (slipcount/slipduration)), 0)
        slipcount += 1
 
        # sliupduration이 지나면 초기화.
        if slipcount > slipduration:
            slipcount = 0
            left_released = False
    
    # 오른쪽으로 이동 중 키를 놓았을때 slipduration 프레임 동안 미끄러진다.
    if right_released == True:
        player_pos.move_ip(pygame.math.lerp(player_speed, 0, (slipcount/slipduration)), 0)
        slipcount += 1
 
        # sliupduration이 지나면 초기화.
        if slipcount > slipduration:
            slipcount = 0
            right_released = False
        
    screen.fill("black")
    screen.blit(player, player_pos)
    
    pygame.display.flip()
    clock.tick(60)
 
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
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
import pygame
 
pygame.init()
pygame.display.set_caption("Super fun game development")
screen = pygame.display.set_mode((640480))
clock = pygame.time.Clock()
running = True
 
player = pygame.image.load("player.png").convert()
player.set_colorkey(player.get_at((00)))
player_size = (player.get_width()*1.5, player.get_height()*1.5)
player = pygame.transform.scale(player, player_size)
player_pos = player.get_rect()
player_pos.center = (screen.get_width()/2, screen.get_height()/2)
player_direction = -1
 
player_speed = 0
player_speed_step = 0.1
player_max_speed = 4
# 속도 관련 변수들.
 
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 = pygame.transform.flip(player, TrueFalse)
            player_direction = -1
        if (abs(player_speed) <= player_max_speed):
            player_speed -= player_speed_step
            if player_speed < -player_max_speed:
                player_speed = -player_max_speed
    # 왼쪽 방향키를 누르면 속도가 음의 방향으로 player_speed_step 씩 증가하다
    # player_max_speed 에서 멈춘다.
 
    if keys[pygame.K_RIGHT]:
        if player_direction < 0:
            player = pygame.transform.flip(player, TrueFalse)
            player_direction = 1
        if (abs(player_speed) <= player_max_speed):
            player_speed += player_speed_step
            if player_speed > player_max_speed:
                player_speed = player_max_speed
    # 오른쪽 방향키를 누르면 속도가 양의 방향으로 player_speed_step 씩 증가하다
    # player_max_speed 에서 멈춘다.
 
    # 왼쪽으로 가는 도중 오른쪽 방향키를 동시에 누른다고 오른쪽으로 가지는
    # 않지만 오른쪽을 바라본다. 하지만 오른쪽으로 가는 도중 왼쪽 방향키를
    # 동시에 눌러도 바라보는 방향이 바뀌지는 않는다. 이유는 왼쪽 방향키
    # 검사보다 오른쪽 방향키 검사(오른쪽으로 바라보게 하는)가 나중에 오기
    # 때문이다. 두 방향 중 나중에 검사하는 오른쪽 방향이 항상 적용되는 것이다.
 
    if not keys[pygame.K_LEFT] and not keys[pygame.K_RIGHT]:
        if player_speed > 0:
            player_speed -= player_speed_step
        elif player_speed < 0:
            player_speed += player_speed_step
    # 오른쪽이나 왼쪽 방향키를 누르고 있지 않으면 속도가 0에 가까워진다.
    
    if abs(player_speed) < 0.1:
        player_speed = 0
    # 속도의 절대값이 0.1보다 작으면 0으로 변경한다.
 
    player_pos.move_ip(player_speed, 0)
 
    screen.fill("black")
    screen.blit(player, player_pos)
    
    pygame.display.flip()
    clock.tick(60)
 
pygame.quit()
 

 

 

매 프레임마다 player_speed_step 만큼 속도가 증감된다.

 

반응형
Posted by J-sean
:
반응형

캐릭터가 마우스를 따라 천천히 회전 하도록 해 보자.

 

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
import pygame
 
pygame.init()
pygame.display.set_caption("Super fun game development")
screen = pygame.display.set_mode((640480))
clock = pygame.time.Clock()
 
class Player(pygame.sprite.Sprite):
    def __init__(self, pos):
        super().__init__()
        self.image = pygame.image.load("player.png").convert()
        self.image.set_colorkey(self.image.get_at((00)))
        self.image = pygame.transform.scale(self.image,
                    (self.image.get_width()*1.5self.image.get_height()*1.5))
        self.original_image = self.image
        # 원본 이미지 보관.
        self.rect = self.image.get_rect(center=pos)
        self.pos = pygame.math.Vector2(pos)
        # pos를 벡터로 변환.
 
        self.preangle = 0
 
    def rotate(self):        
        direction = pygame.mouse.get_pos() - self.pos
        # 플레이어에서 마우스로의 벡터.
        radius, angle = direction.as_polar()
        # radius는 마우스까지의 거리, angle은 방위각.
        # 오른쪽=0(-0), 아래=90, 왼쪽=180(-180), 위=-90
        
        if abs(angle - self.preangle) < 0.5:
        # 이전 프레임의 각도와 현재 각도의 차이가 0.5도 미만이면 보간 없이 회전한다.
            self.image = pygame.transform.rotate(self.original_image, -angle+180)
            # 이미지를 회전하고 각도 보정. 이전 프레임의 회전된 이미지가 아닌
            # 원본 이미지를 이용한다.
            self.rect = self.image.get_rect(center=self.rect.center)
            # rect 재설정.
            self.preangle = angle
        else:
            angle = pygame.math.lerp(self.preangle, angle, 0.02)
            # 이전 프레임의 각도와 현재 각도 사이를 프레임당 2% 보간(interpolate)한다.
            self.preangle = angle        
            self.image = pygame.transform.rotate(self.original_image, -angle+180)
            self.rect = self.image.get_rect(center=self.rect.center)
 
    def update(self):
        self.rotate()
 
def main():
    all_sprites = pygame.sprite.Group(Player(screen.get_rect().center))
 
    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 
    
        all_sprites.update()
    
        screen.fill("black")
        all_sprites.draw(screen)
    
        pygame.display.flip()
        clock.tick(60)
 
    pygame.quit()
 
if __name__ == '__main__':
   main()
 

 

 

캐릭터가 마우스를 향해 천천히 회전한다.

캐릭터를 중점으로 마우스가 2/4분면과 3/4분면 경계를 지날때는 생각과 다르게 반대 방향으로 회전한다.

 

반응형
Posted by J-sean
:
반응형

캐릭터가 마우스를 따라 회전 하도록 해 보자.

 

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
import pygame
 
pygame.init()
pygame.display.set_caption("Super fun game development")
screen = pygame.display.set_mode((640480))
clock = pygame.time.Clock()
 
class Player(pygame.sprite.Sprite):
    def __init__(self, pos):
        super().__init__()
        self.image = pygame.image.load("player.png").convert()
        self.image.set_colorkey(self.image.get_at((00)))
        self.image = pygame.transform.scale(self.image,
                    (self.image.get_width()*1.5self.image.get_height()*1.5))
        self.original_image = self.image
        # 원본 이미지 보관.
        self.rect = self.image.get_rect(center=pos)
        self.pos = pygame.math.Vector2(pos)
        # pos를 벡터로 변환.
 
    def rotate(self):        
        direction = pygame.mouse.get_pos() - self.pos
        # 플레이어에서 마우스로의 벡터.
        radius, angle = direction.as_polar()
        print(angle)
        # radius는 마우스까지의 거리, angle은 방위각.
        # 오른쪽=0(-0), 아래=90, 왼쪽=180(-180), 위=-90
        self.image = pygame.transform.rotate(self.original_image, -angle+180)
        # 이미지를 회전하고 각도 보정. 이전 프레임의 회전된 이미지가 아닌
        # 원본 이미지를 이용한다.
        self.rect = self.image.get_rect(center=self.rect.center)
        # rect 재설정.
 
    def update(self):
        self.rotate()
 
def main():
    all_sprites = pygame.sprite.Group(Player(screen.get_rect().center))
 
    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 
    
        all_sprites.update()
    
        screen.fill("black")
        all_sprites.draw(screen)
    
        pygame.display.flip()
        clock.tick(60)
 
    pygame.quit()
 
if __name__ == '__main__':
   main()
 

 

 

캐릭터가 마우스를 따라 회전한다.

 

반응형
Posted by J-sean
: