반응형

기본적인 파티클 시스템 사용.

 

GPUParticles2D를 추가하고 Process Material에 ParticleProcessMaterial을 생성한다.

 

확대해보면 파티클이 생성되고 있다.

 

눈이 내리는 효과를 만들어 보자.

 

Emission Shape과 Gravity 속성을 위와 같이 변경한다.

 

Turbulence, Time - Lifetime 속성을 위와 같이 변경한다.

 

 

자연스럽게 눈이 내린다.

 

이번엔 비가 내리는 효과를 만들어 보자.

 

Direction, Gravity, Initial Velocity 속성을 위와 같이 변경한다.

 

Turbulence를 비활성화하고 Trails 속성을 활성화 하고 Lifetime을 적장히 조절한다.

 

비가 내린다.

 

 

Emission Mask를 사용해 특정 영역에서 파티클을 생성해 보자.

 

파티클 노드를 선택하고 GPUParticles2D - Load Emission Mask를 선택한다.

 

letter.png
0.01MB

 

마스크로 사용할 이미지를 선택한다.

 

Solid Pixels를 선택하고 OK를 클릭한다.

 

Amount, Direction, Initial Velocity 속성을 조절한다.

 

 

Turbulence, Time - Lifetime 속성을 조절한다.

 

Solid Pixels

 

Border Pixels

 

Directed Border Pixels

 

 

Color, Hue Variation 속성을 조절한다.

 

 

Texture를 지정하고 그에 맞게 Scale 속성을 설정한다.

 

flare-lens.png
0.31MB

 

 

※ 참고

2D particle Systems

 

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

타일맵에 Collision Layer, Collision Mask를 설정하고 게임 실행 중 코드에서 Custom Data에 따라 적절히 바꿀 수 있다.

 

타일맵을 준비한다.

 

TileMap - Tile Set- Physics Layers - Collision Layer/Mask를 설정한다.

 

TileMap - Tile Set - Custom Data Layers에 원하는 데이터 이름과 타입을 설정한다.

 

Custom Data를 지정할 타일을 선택하고 Custom Data에 원하는 데이터 값을 설정한다. 위에서 bool 타입을 설정했기 때문에 On(True)이 표시된다. (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
using Godot;
 
public partial class player : Node2D
{
    [Export]
    CharacterBody2D character;
 
    public override void _Ready()
    {
        //character = GetNode<CharacterBody2D>("CharacterBody2D");
    }
 
    public override void _Process(double delta)
    {
        Vector2I mousePosition = GetNode<TileMap>("TileMap").LocalToMap(GetViewport().GetMousePosition());
        // 마우스 커서 위치를 타일맵 좌표로 변환한다.
        int layers = GetNode<TileMap>("TileMap").GetLayersCount();
        // 타일맵 레이어 갯수를 가져온다.
 
        for (int layer = 0; layer < layers; layer++)
        {
            TileData td = GetNode<TileMap>("TileMap").GetCellTileData(layer, mousePosition);
            // 마우스가 위치한 타일의 타일 데이터를 가져온다.
            if (td != null)
            {
                GD.Print($"Layer: {layer}");
                GD.Print($"CustomData: {td.GetCustomData("extraData")}");
                // TileMap - Inspector - Custom Data Layers 에서 추가한 변수를
                // TileSet탭 - Tiles탭 - Select - Custom Data 에서 세팅한 값.
 
                //GetNode<TileMap>("TileMap").TileSet.SetPhysicsLayerCollisionLayer(layer, 8);
                //GetNode<TileMap>("TileMap").TileSet.SetPhysicsLayerCollisionMask(layer, 16);
                // extraData 값을 확인하고 그에 맞게 레이어 값을 바꿀 수 있다.
 
                //int groundLayer = 1;
                //int buildingLayer = 2;
                //character.SetCollisionLayerValue(groundLayer, false);
                //character.SetCollisionMaskValue(buildingLayer, true);
                // 아니면 상화에 따라 캐릭터의 collision layer/mask 값을 바꿀 수 있다.
                // 주의할 점은 SetCollisionXXXValue()의 레이어 값은 1~32이므로 미리 변경하고 싶은
                // 레이어 번호를 변수에 저장하고 사용하자. 0 이 들어가면 안된다.
            }
            else
            {
                GD.Print("NULL");
            }
 
            GD.Print($"Collision Layer:" +
                $"{GetNode<TileMap>("TileMap").TileSet.GetPhysicsLayerCollisionLayer(layer)}");
            GD.Print($"Collision Mask:" +
                $"{GetNode<TileMap>("TileMap").TileSet.GetPhysicsLayerCollisionMask(layer)}");
            // 1번 레이어(마스크) value: 1
            // 2번 레이어(마스크) value: 2
            // 3번 레이어(마스크) value: 4
            // 4번 레이어(마스크) value: 8
            // ... 9번 레이어(마스크) value: 256 ...
        }
    }
}
 

 

 

스크립트를 작성한다.

 

게임을 실행하면 마우스 위치에 따라 정보가 표시된다.

 

반응형

'Godot' 카테고리의 다른 글

[Godot] 2D Navigation Basic Setup  (0) 2023.10.06
[Godot] Wall Jump 벽 점프  (0) 2023.10.02
[Godot] RayCast2D C# Example  (0) 2023.09.27
[Godot] Area2D Gravity 중력  (0) 2023.09.27
[Godot] AddChild(), RemoveChild()  (0) 2023.09.26
Posted by J-sean
:
반응형

Only two matching methods currently accept a mask: CV_TM_SQDIFF and CV_TM_CCORR_NORMED


The mask should have a CV_8U or CV_32F depth and the same number of channels and size as the target image. In CV_8U case, the mask values are treated as binary, i.e. zero and non-zero. In CV_32F case, the values should fall into [0..1] range and the target image pixels will be multiplied by the corresponding mask pixel values.


OpenCV matchTemplate 함수에 마스크를 적용해서 (배경이 다른) 같은 이미지를 모두 찾을 수 있다. 마스크는 CV_8U 아니면 CV_32F의 깊이값을 가져야 하며 target image와 같은 채널 수와 사이즈를 가져야 한다.


2019/07/08 - [Software/OpenCV] - Template Matching(Image Searching) - 부분 이미지 검색

2019/07/10 - [Software/OpenCV] - Template Matching(Image Searching) for multiple objects - 반복되는 이미지 모두 찾기


<Target>


<Mask>


<Source>


There are 3 objects(bones) to find in the source image.

Each of them has a different background as below.


Below code explains how to spot different background multiple objects with a mask.

Adjust threshold value if it doesn't work properly.

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
#include <opencv2/opencv.hpp>
#include <time.h>
 
using namespace cv;
using namespace std;
 
int main()
{
    clock_t start, end;
    double minVal;
    Point minLoc;
    double threshold = 0.001;
    int count = 0;
 
    Mat FinalImage = imread("source.png", IMREAD_COLOR);
    if (FinalImage.empty())
        return -1;
 
    // Grayscale source, target and mask for faster calculation.
    Mat SourceImage;
    cvtColor(FinalImage, SourceImage, CV_BGR2GRAY);
 
    Mat TargetImage = imread("target.png", IMREAD_GRAYSCALE);
    if (TargetImage.empty())
        return -1;
 
    Mat Mask = imread("mask.png", IMREAD_GRAYSCALE);
    if (Mask.empty())
        return -1;
 
    Mat Result;
 
    start = clock();
    // Mask must have the same datatype and size with target image.
    // It is not set by default. Currently, only the TM_SQDIFF and TM_CCORR_NORMED methods are supported.
    matchTemplate(SourceImage, TargetImage, Result, TM_SQDIFF, Mask); // Type of the template matching operation: TM_SQDIFF
    normalize(Result, Result, 01, NORM_MINMAX, -1, Mat());
    minMaxLoc(Result, &minVal, NULL&minLoc, NULL);
 
    for (int i = 0; i < Result.rows; i++)
        for (int j = 0; j < Result.cols; j++)
            if (Result.at<float>(i, j) < threshold)
            {
                rectangle(FinalImage, Point(j, i), Point(j + TargetImage.cols, i + TargetImage.rows), Scalar(00255), 1);
                count++;
            }
    end = clock();
 
    cout << "Searching time: " << difftime(end, start) / CLOCKS_PER_SEC << endl;
    cout << "Minimum Value: " << minVal << " " << minLoc << endl;
    cout << "Threshold: " << threshold << endl;
    cout << "Found: " << count << endl;
 
    imshow("Mask", Mask);
    imshow("TargetImage", TargetImage);
    imshow("Result", Result);
    imshow("FinalImage", FinalImage);
 
    waitKey(0);
 
    return 0;
}
cs




Grayscale target image


Binary mask


Result image


Final image


Found 3 bones in 0.097 secs.



반응형
Posted by J-sean
: