반응형

텍스트 길이에 맞게 사이즈가 자동으로 조절되는 UI 이미지를 만들어 보자.

 

짧은 텍스트

 

긴 텍스트

 

dialog box.png
0.00MB

대화 상자 이미지를 임포트한다.

 

 

대화상자 이미지 인스펙터 창에서 아래와 같이 변경하고 Apply를 클릭한다.

  • Sprite Mode - Single
  • Mesh Type - Full Rect
  • Filter Mode - Point (no filter)
  • Compression - None

 

 

Sprite Editor에서 적당히 Border를 설정한다.

 

UI - Image를 생성하고 그 하위에 UI - Text - TextMeshPro를 생성한다.

 

 

Text 오브젝트는 아래와 같이 설정한다.

  • Font Asset - 필요하다면 Window - TextMeshPro - Font Asset Creator에서 폰트를 생성해 지정한다.
  • Alignment - Center, Middle 설정

 

 

 

Image 오브젝트는 아래와 같이 설정한다.

  • Source Image - 위에서 설정한 대화 상자 이미지를 지정한다.
  • Image Type - Sliced

Vertical Layout Group 컴포넌트 추가

  • Padding - 이미지와 텍스트에 맞게 적당히 설정한다.
  • Child Alignment - Middle Center
  • Control Child Size - Width, Height 체크 (Height는 꼭 하지 않아도 된다)

Content Size Fitter 추가

  • Horizontal Fit - Preferred Size

 

이제 텍스트를 변경해 보자.

 

변경된 텍스트 길이에 맞게 이미지 사이즈가 자동으로 조절된다.

 

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

2D Sprite에 Text를 추가해 보자.

 

렌더러가 충돌하기 때문에 Sprite에 그냥 Text를 추가할 수 없다.

 

우선 텍스트를 추가하려는 오브젝트에 Empty 오브젝트를 하나 추가한다.

 

빈 오브젝트에서 Text를 추가한다.

 

Rect Transform - Width, Height를 텍스트에 맞게 조절하고 다른 옵션도 적당히 세팅한다.

 

Text가 표시된다.

 

 

하지만 텍스트 길이에 따라 항상 이미지 크기를 조절해야 한다.

Content Size Fitter 컴포넌트와 간단한 스크립트를 사용하면 자동으로 텍스트 길이에 맞는 이미지를 표시할 수 있다.

dialog box.png
0.00MB

 

실습을 위해 위 이미지를 임포트한다.

 

Inspector 에서 위와 같이 설정한다.

 

Sprite Editor 에서 위와 같이 설정한다.

 

2D Sprite Renderer에는 위 이미지 파일을 지정하고 자식(텍스트) 오브젝트에는 Content Size Fitter 컴포넌트를 추가하고 아래와 같이 설정한다.

 

 

Content Size Fitter - Horizontal Fit - Preferred Size로 변경한다.

이제 Rect Transform - Width 필드가 비활성화 되어 수정할 수 없게 된다.

 

using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class word : MonoBehaviour
{
    void Start()
    {
        RectTransform crt = GetComponentInChildren<RectTransform>();
        crt.gameObject.GetComponent<TextMeshPro>().text = "Very very long long text";
        // 미리 자식 오브젝트 Rect Transform을 가져오고, TextMeshPro - text 변경

        LayoutRebuilder.ForceRebuildLayoutImmediate(crt);
        // Forces an immediate rebuild of the layout element and child layout elements
        // affected by the calculations.
        // 위에서 TexhMeshPro - text 값이 변경되고 Content Size Fitter에 의해
        // Rect Transform - Width(sizeDelta.x) 값이 변경 되지만 바로 되지는 않는다.
        // 아래 코드에서 값을 가져오기 전에 업데이트 한다.

        Debug.Log(crt);
        Debug.Log(crt.sizeDelta.x);

        SpriteRenderer sr = GetComponent<SpriteRenderer>();
        sr.size = new Vector2(crt.sizeDelta.x + 0.7f, sr.size.y);
        // 폰트, 폰트 사이즈, 이미지에 따라 다르겠지만 이 예제의 경우
        // Rect Transform - Width(sizeDelta.x) 값에 0.7f를 더하면 적당하다.
    }

    void Update()
    {        
    }
}

 

Sprite Renderer가 있는 부모 오브젝트(Square)에 위 스크립트를 추가한다.

 

 

게임을 실행하기 전 텍스트

 

게임 실행 후 텍스트

 

게임을 실행하면 텍스트가 바뀌고 그에 맞게 이미지의 길이도 자동으로 변경된다.

 

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

유니티 2D Sprite 및 Tile Palette의 각 tile마다 물리적 충돌과 그림자 적용을 위한 Physics Shape을 설정할 수 있다.

 

스프라이트를 임포트하면 Inspector - Sprite Mode - Generate Physics Shape 설정을 체크해서 Physics Shape 설정을 하지 않은 스프라이트에 대해 기본 Physics Shape을 생성하게 할 수 있다. 하지만 이 설정은 shape이 임의로 정해진다.

 

원하는 Physics Shape 설정을 위해 Sprite에서 Open Sprite Editor 클릭 - Sprite Editor를 Custom Physics Shape으로 바꾼다

 

아래 Outline Tool에서 Generate 클릭. (아니면 원하는 Tile에서 클릭&드래그로 Physics Shape을 만들 수 있다)

 

원하는 형태로 shape을 변경한다. shape은 여러 개 만들 수 있다. 여기서 만드는 Physics Shape은 그림자 뿐만 아니라 충돌 처리를 위한 경계로도 사용된다.

 

위 그림처럼 필요에 맞게 변경한다.

 

타일맵은 Tilemap Collider 2D를 추가하고 Composite Operation을 Merge로 바꾼다. Composite Collider 2D를 추가하고, 같이 추가되는 Rigidbody 2D에서 Body Type을 Static으로 바꾼다. (Body Type이 Dynamic으로 되어 있으면 게임 실행 시 밑으로 떨어진다)

 

Shadow Caster 2D를 추가하고 Casting Source를 Composite Collider 2D로 바꾼다. (Composite Collider 2D 관련 과정은 충돌 계산 및 그림자 효과를 효율적으로 만들기 위한 것이다. 그냥 Tilemap Collider 2D와 Shadow Caster 2D만 추가해서 Shadow Caster 2D의 Casting Source를 Tilemap Collider 2D로 바꾸고 사용해도 문제는 없다)

 

만약 위 과정을 진행 하고나서 나중에 Sprite의 Physics Shape을 바꾸면 이미 만들어져 있는 Tilemap에서는 바뀐 Physics Shape이 바로 적용되지 않는다. 이때는 Tilemap Collider 2D를 Reset한다. (그러면 Composite Operation을 다시 Merge로 바꿔줘야 한다)

 

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

Godot Sprite에는 Colorkey를 설정하는 옵션이 없다.PNG 이미지는 알파 채널을 통해 투명 배경을 설정할 수 있어 상관 없지만 JPG, BMP같은 이미지 파일은 투명 배경이 없어 곤란하다. 하지만 셰이더를 이용해 같은 효과를 만들 수 있다.

 

스프라이트를 추가하고 텍스쳐를 지정한다.

 

Material - New Shader Material을 선택한다.

 

Shader - New Shader를 선택한다.

 

적당한 이름을 지정하고 셰이더 파일을 생성한다.

 

 

Shader Editor를 활성화 한다.

 

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
shader_type canvas_item;
// Get texture and a key that we want as transparent
uniform sampler2D Diffuse;
uniform vec4 ChromaKey : source_color;
 
void vertex() {
    // Called for every vertex the material is visible on.
}
 
void fragment() {
    // Called for every pixel the material is visible on.
    
    // The color value is the sampled pixel color
    COLOR = texture(Diffuse, UV);
 
    // If the color is the same as the chroma key, make it transparent.
    if (COLOR == ChromaKey) {
        COLOR.a = 0.0;
    }
}
 
//void light() {
    // Called for every pixel for every light affecting the CanvasItem.
    // Uncomment to replace the default light processing function with this one.
//}
 

 

위와 같은 코드를 작성한다.

 

Shader Parameters를 아래와 같이 지정한다.

ChromaKey: R:54 G:61 B:82 A:255 (Godot 이미지의 배경색)

Diffuse: 텍스쳐 이미지와 동일하게 지정

※ Diffuse에 이미지 지정시 Texture 파라미터의 filter를 선택할 수 없어 이미지가 흐리게 보일 수 있다. 필요하다면 셰이더 코드에서 Diffuse 선언을 아래와 같이 수정한다.

uniform sampler2D Diffuse : filter_nearest;

 

Godot 이미지의 배경이 투명해졌다.

 

 

하지만 게임을 실행해 보면 배경이 투명하지 않다.

 

1
2
3
4
// If the color is the same as the chroma key, make it transparent.
if (distance(COLOR, ChromaKey) < 0.001) {
    COLOR.a = 0.0;
}
 

 

vec4 타입의 ChromaKey와 COLOR 데이터 타입의 비교에서 약간의 오차가 발생하는거 같다.

if()을 위와 같이 수정한다.

 

원하는 색이 정상적으로 투명하게 변한다.

 

※ 참고

이렇게 하나의 스프라이트에 셰이더를 적용하면 같은 씬의 다른 스프라이트에도 모두 같은 방식으로 셰이더를 적용해야 아래와 같은 에러가 생기지 않는 경우가 발생할 수 있다.

E 0:00:01:0199   swap_buffers: Vulkan: Cannot submit graphics queue. Error code: VK_ERROR_DEVICE_LOST
  <C++ Error>    Condition "err" is true. Returning: ERR_CANT_CREATE
  <C++ Source>   drivers/vulkan/vulkan_context.cpp:2536 @ swap_buffers()
E 0:00:01:0208   prepare_buffers: Vulkan: Did not create swapchain successfully. Error code: VK_NOT_READY
  <C++ Error>    Condition "err != VK_SUCCESS" is true. Breaking.
  <C++ Source>   drivers/vulkan/vulkan_context.cpp:2459 @ prepare_buffers()

 

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

AnimatedSprite나 AnimationPlayer를 사용하지 않고 Sprite만으로도 간단한 애니메이션을 만들 수 있다.

 

Sprite2D를 추가하고 Texture를 지정한다. Hframes는 8, Vframes는 7로 조절한다.

 

Scale을 적절히 조절하고 스크립트도 추가한다.

 

char_blue.png
0.02MB

 

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
using Godot;
 
public partial class Control : Sprite2D
{
    public override async void _Process(double delta)
    {
        if (Input.IsActionJustPressed("ui_accept"))
        {
            // 점프 애니메이션
            for (int i = 32; i < 40; i++)
            {
                await ToSignal(GetTree().CreateTimer(0.2),
                    SceneTreeTimer.SignalName.Timeout);
                Frame = i;
            }
        }
 
        if (Input.IsActionJustPressed("ui_cancel"))
        {
            // 전체 애니메이션
            for (int v = 0; v < Vframes; v++)
                for (int h = 0; h < Hframes; h++)
                {
                    await ToSignal(GetTree().CreateTimer(0.2),
                        SceneTreeTimer.SignalName.Timeout);
                    FrameCoords = new Vector2I(h, v);
                }
        }
    }
}
 

 

위와 같은 코드를 작성한다.

엔터키를 누르면 점프, ESC키를 누르면 전체 애니메이션이 플레이 된다. 애니메이션이 플레이 되는 동안 키를 여러번 동시에 누르면 애니메이션이 겹친다.

 

 

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

SDL에 2D 카메라를 만들어 보자.

 

character.bmp
0.00MB
shop.bmp
0.03MB

 

 

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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include "SDL.h"
 
class Camera {
public:
    int m_width;
    int m_height;
    int m_cameraBorder;
    int m_target_width;
    int m_target_height;
    float m_x, m_y;
    SDL_Texture* m_targetTexture;
public:
    Camera(SDL_Renderer* renderer, int width, int height, int border, SDL_BlendMode mode) {
        m_width = width;
        m_height = height;
        m_cameraBorder = border;
        m_target_width = width + border * 2;
        m_target_height = height + border * 2;
        m_x = 0;
        m_y = 0;
        m_targetTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET,
            m_target_width, m_target_height);
        SDL_SetTextureBlendMode(m_targetTexture, mode);
    }
    void Draw(SDL_Renderer* renderer, int windowHeight) {
        float pixel_h = (float)windowHeight / m_height;
        float correction_x = (int)m_x - m_x;
        float correction_y = (int)m_y - m_y;
        SDL_Rect dst = { (int)(correction_x * pixel_h - pixel_h * m_cameraBorder),
            (int)(correction_y * pixel_h - pixel_h * m_cameraBorder),
            (int)(m_target_width * pixel_h),
            (int)(m_target_height * pixel_h) };
        SDL_RenderCopy(renderer, m_targetTexture, NULL&dst);
    }
    void Update(int xDirection, int yDirection) {
        m_x += 0.5f * xDirection;
        m_y += 0.5f * yDirection;
    }
    void CameraReset(SDL_Renderer* renderer, int width, int height, int border, SDL_BlendMode mode) {
        m_width = width;
        m_height = height;
        m_cameraBorder = border;
        m_target_width = width + border * 2;
        m_target_height = height + border * 2;
        SDL_DestroyTexture(m_targetTexture);
        m_targetTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET,
            m_target_width, m_target_height);
        SDL_SetTextureBlendMode(m_targetTexture, mode);
    }
    ~Camera() {
        SDL_DestroyTexture(m_targetTexture);
    }
};
 
class Sprite {
public:
    int width;
    int height;
    float m_destX, m_destY;
    SDL_Surface* surface;
    SDL_Texture* texture;
public:
    Sprite(SDL_Renderer* renderer, const char* filename) {
        surface = SDL_LoadBMP(filename);
        width = surface->w;
        height = surface->h;
        m_destX = 0;
        m_destY = 0;
        texture = SDL_CreateTextureFromSurface(renderer, surface);
        SDL_FreeSurface(surface);
    }
    void DrawSprite(SDL_Renderer* renderer, Camera* camera, int x, int y) {
        SDL_Rect destRect = { (int)(m_destX - camera->m_x) + camera->m_cameraBorder + x,
                (int)(m_destY - camera->m_y) + camera->m_cameraBorder + y,
                width, height };
 
        SDL_RenderCopy(renderer, texture, NULL&destRect);
    }
    ~Sprite() {
        SDL_DestroyTexture(texture);
    }
};
 
int main(int argc, char** argv) {
    const int Window_Width = 640;
    const int Window_Height = 480;
 
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
    SDL_Window* window = SDL_CreateWindow("SDL Simple Camera", SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED, Window_Width, Window_Height, SDL_WINDOW_RESIZABLE);
    SDL_assert(window);
 
    SDL_SetHint(SDL_HINT_RENDER_BATCHING, "1");
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED |
        SDL_RENDERER_PRESENTVSYNC);
    SDL_assert(renderer);
 
    // Init
    Camera camera = Camera(renderer, 1601201, SDL_BLENDMODE_BLEND);
    SDL_assert(camera.m_targetTexture);
    Sprite shopSprite = Sprite(renderer, "shop.bmp");
    Sprite characterSprite = Sprite(renderer, "character.bmp");
 
    int xDirection = 0;
    int yDirection = 0;
 
    SDL_Event event;
    bool quit = false;
 
    while (!quit) {
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_QUIT:
                quit = true;
                break;
            case SDL_KEYDOWN:
                if (event.key.keysym.sym == SDLK_ESCAPE)
                    quit = true;
                if (event.key.keysym.sym == SDLK_LEFT)
                    xDirection = -1;
                if (event.key.keysym.sym == SDLK_RIGHT)
                    xDirection = 1;
                if (event.key.keysym.sym == SDLK_UP)
                    yDirection = -1;
                if (event.key.keysym.sym == SDLK_DOWN)
                    yDirection = 1;
                if (event.key.keysym.sym == SDLK_r)
                    camera.CameraReset(renderer, 1601201, SDL_BLENDMODE_BLEND);
                if (event.key.keysym.sym == SDLK_e)
                    camera.CameraReset(renderer, 6404801, SDL_BLENDMODE_BLEND);
                break;
 
            default:
                xDirection = 0;
                yDirection = 0;
                break;
            }
        }
        camera.Update(xDirection, yDirection);
 
        // Camera target
        SDL_SetRenderTarget(renderer, camera.m_targetTexture);
        SDL_SetRenderDrawColor(renderer, 0000xFF);
        SDL_RenderClear(renderer);
 
        // Draw Sprite
        shopSprite.DrawSprite(renderer, &camera, 00);
        characterSprite.DrawSprite(renderer, &camera, 11666);
 
        // Screen target
        SDL_SetRenderTarget(renderer, NULL);
        SDL_SetRenderDrawColor(renderer, 0x000xFF0x000xFF);
        SDL_RenderClear(renderer);
 
        camera.Draw(renderer, Window_Height);
 
        SDL_RenderPresent(renderer);
    }
 
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
 
    return 0;
}
 

 

코드를 입력하고 빌드한다.

 

실행하면 shop과 character 스프라이트가 표시된다.

 

r, e 키로 해상도를 바꿀 수 있다.

 

방향키로 카메라를 움직일 수 있다.

 

 

※ 참고

Pixel perfect camera in SDL2

 

반응형
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
103
104
105
106
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, position):
        pygame.sprite.Sprite.__init__(self)
 
        self.direction = -1
        self.speed = 4
        self.image = pygame.image.load("player.png").convert()
        self.image.set_colorkey(self.image.get_at((00)))
        self.size = (self.image.get_width()*1.5self.image.get_height()*1.5)
        self.image = pygame.transform.scale(self.image, self.size)
        self.rect = self.image.get_rect(center=position)
        # rectangle이 아닌 circle을 이용해 충돌 감지하기 위한 반지름 속성 설정.
        self.radius = 40
        # 충돌 감지 circle 표시
        pygame.draw.circle(self.image, "red"self.image.get_rect().center, self.radius, 2)
 
    def flip_image(self):
        self.image = pygame.transform.flip(self.image, TrueFalse)
        
    def update(self):
        pass
# 플레이어 클래스
 
class Bubble(pygame.sprite.Sprite):
    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
 
        self.image = pygame.image.load("bubble.png").convert()
        self.image.set_colorkey(self.image.get_at((00)))
        self.size = (self.image.get_width()*6self.image.get_height()*6)
        self.image = pygame.transform.scale(self.image, self.size)
        self.rect = self.image.get_rect(center=position)
        self.collided = False
        # rectangle이 아닌 circle을 이용해 충돌 감지하기 위한 반지름 속성 설정.
        self.radius = 40
        # 충돌 감지 circle 표시
        pygame.draw.circle(self.image, "red"self.image.get_rect().center, self.radius, 2)
 
    def update(self):
        if self.collided == True:
            self.rect.top -= 1
# 버블 클래스
# 충돌(self.collided)을 감지하면 위치(self.rect.top)가 변한다.
 
def main():
    player = Player((screen.get_width()/2, screen.get_height()/2))
    player_sprite = pygame.sprite.Group(player)
    # 플레이어 스프라이트 그룹
 
    bubbles = [
        Bubble((40, screen.get_height()/2)),
        Bubble((160, screen.get_height()/2)),
        Bubble((480, screen.get_height()/2)),
        Bubble((600, screen.get_height()/2))]
    bubble_sprites = pygame.sprite.Group(bubbles)
    # 버블 스프라이트 그룹
 
    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)
 
        # spritecollide()의 마지막 인수 collided에 collide_circle()를 대입한다.
        collision = pygame.sprite.spritecollide(player, bubble_sprites, False, pygame.sprite.collide_circle)
        for bubble in collision:
            bubble.collided = True
        # 플레이어와 버블의 충돌을 감지하고 충돌한 버블의 collided 값을 True로 바꾼다.
        
        player_sprite.update()
        bubble_sprites.update()
                 
        screen.fill("black")
         
        player_sprite.draw(screen)
        bubble_sprites.draw(screen)
    
        pygame.display.flip()
        clock.tick(60)
 
    pygame.quit()
 
if __name__ == '__main__':
  main()
 

 

 

공룡과 버블의 충돌 감지 영역이 빨간 원으로 표시된다.

 

좀 더 확실한 확인을 위해 공룡과 버블의 충돌 감지 circle의 radius를 20으로 바꾸고 다시 실행해 보자.

 

스프라이트는 충돌 했지만 원은 충돌하지 않았기 때문에 충돌로 판정되지 않는다.

 

 

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