반응형

파이게임 수학 벡터 함수 중 유용한 내용.

 

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
import math
 
pygame.init()
pygame.display.set_caption("Super fun game development")
screen = pygame.display.set_mode((640480))
clock = pygame.time.Clock()
 
# pygame.math.Vector2.rotate
# rotates a vector by a given angle in degrees.
 
# pygame.math.Vector2.rotate_rad
# rotates a vector by a given angle in radians.
 
vec = pygame.math.Vector2(math.sqrt(2), 0)
print(vec.rotate(45))
# (sqrt(2), 0) 벡터를 반시계방향으로 45도 회전한 벡터.
# 벡터의 길이는 그대로 유지된다.
 
v1 = pygame.math.Vector2(300400)
 
# project(Vector2) -> Vector2
# Returns the projected vector. This is useful for collision
# detection in finding the components in a certain direction.
# (e.g. in direction of the wall).
v2 = v1.project(pygame.math.Vector2(10))
print(v2)
# (3, 4) 벡터가 X축(1, 0)에 투영되었을 때의 벡터.
 
v3 = v1.project(pygame.math.Vector2(01))
print(v3)
# (3, 4) 벡터가 Y축(0, 1)에 투영되었을 때의 벡터.
 
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
 
    screen.fill("black")
 
    pygame.draw.line(screen, "red", (00), v1, 20)
    pygame.draw.line(screen, "green", (00), v2, 20)
    pygame.draw.line(screen, "blue", (00), v3, 20)
 
    pygame.display.flip()
 
    clock.tick(60)
 
pygame.quit()
 

 

 

벡터의 회전(rotate)과 투영(project)

 

 

Project

 

Projection of a on b (a1), and rejection of a from b (a2).

 

When 90&deg; < &theta; &le; 180&deg;, a1 has an opposite direction with respect to b.

 

반응형
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
import pygame
 
pygame.init()
pygame.display.set_caption("Super fun game development")
screen = pygame.display.set_mode((640480))
clock = pygame.time.Clock()
 
position = pygame.math.Vector2(screen.get_width()/2, screen.get_height()/2)
velocity = pygame.math.Vector2(11).normalize() * 5
 
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
 
    screen.fill("black")
 
    if position.y > screen.get_height():
        velocity.reflect_ip(pygame.math.Vector2(01))
        # 천장이나 바닥에 부딪히면 (0, 1)의 법선 백터를 갖는 평면에 반사.
    elif position.y < 0:
        velocity.reflect_ip(pygame.math.Vector2(01))
    elif position.x > screen.get_width():
        velocity.reflect_ip(pygame.math.Vector2(10))
        # 오른쪽이나 왼쪽에 부딪히면 (1, 0)의 법선 백터를 갖는 평면에 반사.
    elif position.x < 0:
        velocity.reflect_ip(pygame.math.Vector2(10))  
 
    position = position + velocity
    pygame.draw.circle(screen, "red", position, 20)
    pygame.display.flip()
 
    clock.tick(60)
 
pygame.quit()
 

 

 

 

반응형
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
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
:

Python PyOpenGL

Python 2023. 9. 11. 22:59 |
반응형

파이썬에서 OpenGL을 사용해 보자.

 

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
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
 
def Display():
    glClear(GL_COLOR_BUFFER_BIT)
 
    glBegin(GL_QUADS)
    glVertex2f(0.50.5)
    glVertex2f(-0.50.5)
    glVertex2f(-0.5-0.5)
    glVertex2f(0.5-0.5)
    glEnd()
    
    glFlush()
    
if __name__ == "__main__":
    glutInit()
 
    #glutInitDisplayMode(GLUT_RGB)
    #glutInitWindowSize(640, 480)
    #glutInitWindowPosition(400, 300)
    glutCreateWindow("OpenGL")
    glutDisplayFunc(Display)
    glutMainLoop()
 

 

 

윈도우에 사각형이 표시된다.

 

pip install PyOpenGL
pip install PyOpenGL_accelerate

위 명령으로 공식 PyOpenGL, PyOpenGL_accelerate를 설치하면 OpenGL.GLUT에 문제가 있는 경우가 있다. 예를 들어 glutinit()를 실행하면 아래와 같은 에러가 발생한다.

NullFunctionError: Attempt to call an undefined function glutInit, check for bool(glutInit) before calling.

만약 에러가 발생한다면 설치한 패키지를 삭제하고 아래 링크에서 받아 다시 설치한다.

Unofficial Windows Binaries for Python Extension Packages

 

PyOpenGL_accelerate-3.1.6-cp311-cp311-win_amd64.whl
0.34MB
PyOpenGL-3.1.6-cp311-cp311-win_amd64.whl
2.64MB

 

 

하지만 OpenGL.GLUT을 사용하지 않는다면 공식 패키지를 사용해도 상관 없다. 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
import pygame
from pygame.locals import *
 
from OpenGL.GL import *
from OpenGL.GLU import *
 
def Display():
    glBegin(GL_QUADS)
    glVertex2f(0.50.5)
    glVertex2f(-0.50.5)
    glVertex2f(-0.5-0.5)
    glVertex2f(0.5-0.5)
    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()
 
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        glRotatef(1312)
        Display()
 
        pygame.display.flip()
        clock.tick(30)
 
if __name__ == '__main__':
   main()
 

 

 

 

※ 참고

OpenGL 강좌

 

반응형
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
import time
 
def MyCoroutine():
    num = 0
    while True:
        x = yield num
        num += 1
        print(x)
        time.sleep(0.5)
 
co = MyCoroutine()
next(co)
time.sleep(1)
# 코루틴을 시작하고 yield 명령에서 대기한다.
 
print(co.send(100))
time.sleep(1)
# 코루틴에 100을 전달(x에 100 대입)하고 num을 받아서 출력한다.
# num 값은 yield 명령이 실행되는 시점에 결정된 값(0)이 아니고
# 코루틴이 끝나는 시점에 결정된 값(1)이 전달된다.
 
print(co.send(200))
time.sleep(1)
# 코루틴에 200을 전달(x에 200 대입)하고 num을 받아서 출력한다.
 
next(co)
# 코루틴에 아무 값도 전달하지 않고(그래서 None이 출력된다) 다음
# yield 까지 진행하고 받아온 num 값은 무시.
 
print(next(co))
# 마찬가지로 코루틴에 아무 값도 전달하지 않고 다름 yield 까지 진행.
# 이번엔 num 값을 받아서 출력한다.
 
co.close()
 

 

 

 

반응형
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
import asyncio
import time
 
async def show_text(text, delay):
    for i in range(5):
        print(text + " " + str(i))
        await asyncio.sleep(delay)
        # coroutine asyncio.sleep(delay, result=None)
        # Block for delay seconds. If result is provided,
        # it is returned to the caller when the coroutine
        # completes. sleep() always suspends the current
        # task, allowing other tasks to run.
    return text
 
async def main():
    #result = await asyncio.gather(
    #    show_text("first", 0.5),
    #    show_text("second", 0.5),
    #    show_text("third", 1)
    #    )
    #print(result)
 
    task1 = asyncio.create_task(show_text("first"0.5))
    task2 = asyncio.create_task(show_text("second"0.5))
    task3 = asyncio.create_task(show_text("third"1))
    # The asyncio.create_task() function to run coroutines
    # concurrently as asyncio Tasks.
 
    await task1
    await task2
    await task3
    # Awaiting on a coroutine.
 
    print("result: " + task1.result())
    print("result: " + task2.result())
    print("result: " + task3.result())
    
if __name__ == "__main__":
    start = time.time()
    asyncio.run(main())
    # The asyncio.run() function to run the top-level
    # entry point “main()” function.
    end = time.time()
    print(end - start)
 

 

 

총 소요시간은 5초이다.

첫 번째, 두 번째, 세 번째 작업의 소요시간 총 합이 아닌, 가장 긴 작업 시간을 가진 세 번째 작업의 소요시간인 5초가 걸린다.

 

Coroutines and Tasks

 

반응형
Posted by J-sean
: