0.

이번 코딩은 처음 도형그리기를 만들고 나서, 도형을 상속받는식으로 또 고친 후, 팩토리 패턴으로 다시 만들었다.

그리고 OOP[각주:1]라는걸 몇번 들어보기도 했고, 중요하다는 이야기도 들었지만 그동안 확실하게 개념이 잡혀있던게 아니었던지라

처음 이번 코드를 OOP로 작성하면서 확실하게 개념을 잡아보자 라는 생각으로 진행했다.

참고로 OOP의 기본 원칙은 추상화(Abstraction), 캡슐화(Encapsulation), 상속(Inheritance), 다형성(Polymorphism)이다.


1.

보통 VS에서 처음 프로젝트랑 파일을 만들면 클래스(Program라는 이름의...)를 하나 자동으로 만들어주는데 난 그동안 이게 뭔지 몰랐다...ㄷㄷ

이번에 다른 클래스들을 만들어보면서 클래스라는게 사실 일종의 도안(청사진)같은거고, 

기본적으로 그 클래스 안의 함수들을 사용하려면 클래스를 기반으로하는 객체를 만들어줘야 사용가능하다는걸 알았다.

static을 쓰는 이유도 몰랐는데, 

static을 클래스 안의 함수앞에 붙여주면 후에 생성해줄 객체들이 그 함수를 가져가서 작동하는게 아니라

클래스가 그 함수를 가지게 되어 객체를 만들지 않아도 클래스를 바로 불러서 직접 사용이 가능하다.

main 클래스가 static인건 위의 이유에서다.


2.

그리고 한 클래스당, 한 개의 파일을 두는게 일반적이다.

이게 어찌보면 캡슐화의 한 종류인듯하다. A클래스에서 B클래스로 접근이 자유로우면 정보은닉이 힘드므로...

(Enum(열거형식) 도 마찬가지)


3.

클래스들은 나중에 객체가 될 정보(변수나 함수)들을 가지고 있다.

클래스가 연필 도안이라면 객체는 연필이다.

연필 도안에는 연필 크기(변수)가 얼만큼일지, 연필 색(변수)은 무엇인지, 연필이 수행해야 할 기능(함수)등이 들어있다.

이게 추상화다. 일반적으로 작동하는 것들을 프로그래밍화 시키는것.


4.

근데 만약에 후에 내가 지우개달린 연필을 만들고 싶어졌다면? 기존에 있는 클래스(도안)을 수정할것인가?

물론 수정해도 되겠지만 그럼 다시는 지우개가 없는 연필을 만들긴 어려울것이다.

이 때 사용하는게 상속. ( class 내클래스 : 부모클래스 이런식으로 쓴다)

지우개연필 클래스에, 연필 클래스(도안)을 상속받으면 내가 따로 정해주지 않아도 

이미 연필클래스의 크기나 기능은 지우개연필 클래스 안에 모두 가져와진다.


5.

근데 또 만약에 다시 연필 색을 빨간색으로 바꾸고 싶어졌다. 기존 클래스를 수정하면 다시는 검은 연필을 만들수가 없다.

그럼 어떻게 할까?

원래 연필 클래스로 돌아가서 "나중에 바꿀수 있게 해줘"라고 표시해준 후,

"바꿀 수 있게 된"연필 클래스를 상속받아 색깔 정보를 "덮어씌워서" 색연필 클래스를 만들면 된다.

여기 쓰이는 키워드가 (바꿀 수 있게)virtual과 (덮어씌우는)override다. 이게 다형성.


6.

내코드에서 다른 도형클래스들이 상속받은 클래스(shape)는 객체 생성을 해도 할수있는게 없다. 

그래서 아예 처음부터 순수가상클래스(absract)로 만들었다. 가상클래스는 객체 생성이 불가능하다. 그리고 후에 override가 가능하다.


7.

근데 아무 기능도 없는데 왜 상속을 받냐고? 

상속을 받으면 부모클래스의 하위 타입(Type)이 되어서 나중에 한꺼번에 관리하기가 편하다.

triangle과 circle은 서로 다른 클래스고 객체가 만들어져도 각각 triangle타입, circle타입이라 관리하기가 복잡한데,

shape을 상속받게되면 triangle 객체도 shape, circle 객체도 shape 타입으로 관리가 가능해진다.


8.

그리고 "팩토리 패턴"은 사실 OOP랑은 좀 거리가 있는 디자인 패턴의 한 종류라고 하는데,

어쨌든, 연필 만들고 싶을 때 마다 매번 사용자가 만들어주는게 아니라, 찍어내는 공장을 만들어서

원할때마다 그 공장을 가동시키기만 하면 연필이 나오는(...) 걸 만드는게 목적이라고 할 수 있겠다. 


이번 코드에서는 static을 쓰지 않고 팩토리를 만들었는데, 굳이 공장이 여러개일 필요가 없다면

객체들(공장들)을 따로 만들지 않고 static으로 코드를 짜도 무방하겠다.(하지만 여러개가 될 수도 있지!!캬캬)


길게도 적었네...

여기까지가 이번 코딩에서 배운점이고.(빼먹은게 있을 수 있음 ㅠㅠ)

몇몇 참고로 생각나는 부분은 각주로.


아래는 이제 코드들.


코드를 간략히 설명하면, 

1. 5개의 입력을 차례로 받은 후,

2. 도형을 그려주는 팩토리에게 넘긴 후

3. 다섯번 팩토리가 도형을 골라서 만들어 저장한 후

4. 그려주자.



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

using System;
 
namespace drawshapefactory
{
    class Program
    {
 
        static void PrintInstruction(ShapeType shape)
        {
            Console.WriteLine(shape.ToString() + ": " + (int)shape);
        }
        static void Main(string[] args)
        {
            PrintInstruction(ShapeType.Triangle);
            PrintInstruction(ShapeType.Circle);
            PrintInstruction(ShapeType.Rectangle);
            PrintInstruction(ShapeType.Square);
 
            Shape[] inputShape = new Shape[5];
 
            int length = inputShape.Length;
            ShapeFactory shapefactory = new ShapeFactory();    //
 
            for (int i=0; i < length; i++)
            {
                Console.Write("Please input number :");
                int inputnumber = Int32.Parse(Console.ReadLine());
                inputShape[i] = shapefactory.CreateShape((ShapeType)inputnumber);
            }
 
            foreach (Shape i in inputShape)
            {
                i.Draw();
            }
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
 
namespace drawshapefactory
{
    public enum ShapeType [각주:2]
    {
        Triangle,
        Circle,
        Rectangle,
        Square
    };
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
namespace drawshapefactory
{
    public abstract class Shape
    {
        protected int Size { get; private set; }[각주:3]
 
        public Shape(int size)
        {
            Size = size;
        }
        public virtual void Draw()
        {}
    }
}
 
cs


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
 
using System;
 
namespace drawshapefactory
{
    class Triangle : Shape
    {
        public Triangle(int size) : base(size)
        {}
 
        public override void Draw()
        {
            for (int i = 1; i < Size; i++)
            {
                for (int k = Size/2; k > i / 2; k--)
                {
                    Console.Write(" ");
                }
                for (int j = i; j > 0; j--)
                {
                    Console.Write("#");
                }
                Console.WriteLine();
            }
            Console.WriteLine();
        }
    }
}
 
cs
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
 
using System;
 
namespace drawshapefactory
{
    class Rectangle : Shape
    {
        protected int Height { get; private set; }
 
        public Rectangle(int size, int height) : base(size)
        {
            Height = height;
        }
        
        public override void Draw()
        {
            base.Draw();
 
            for (int i = 0; i < Height; i++)
            {
                for (int j = 0; j < Size; j++)
                {
                    Console.Write("#");
                }
                Console.WriteLine();
            }
            Console.WriteLine();
        }
    }
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
namespace drawshapefactory
{
    class Square : Rectangle
    {
        public Square(int size) : base(size)
        {}
 
        public override void Draw()
        {
            base.Draw();
        }
    }
}
 
cs
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
 
using System;
 
namespace drawshapefactory
{
    class Circle : Shape
    {
        public Circle(int size) : base(size)
        {}
 
        public override void Draw()
        {
            base.Draw();
 
            int radial = Size / 2;      
            for (int i = 0; i < Size; i++)
            {
                for (int j = 0; j < Size; j++)
                {
                    if (radial * radial > (i - radial) * (i - radial) + (j - radial) * (j - radial))
                    {
                        Console.Write("#");
                    }
                    else
                    {
                        Console.Write(" ");
                    }
                }
                Console.WriteLine();
            }
            Console.WriteLine();
        }
    }
}
 
cs
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
namespace drawshapefactory
{
    public class ShapeFactory
    {
        public Shape CreateShape(ShapeType s)
        {
            const int size = 16;                 //basic size.
            const int rectangleheight = 10;      //
 
            switch (s)
            {
                case ShapeType.Triangle:
                    return new Triangle(size);
 
                case ShapeType.Circle:
                    return new Circle(size);
 
                case ShapeType.Rectangle:
                    return new Rectangle(size, rectangleheight);
 
                case ShapeType.Square:
                    return new Square(size);
 
                default:
                    return null;
            }
        }
    }
}
cs

아 이제 직원 관리 시스템 코딩 한것도 분석하러가야됨 ㅠㅠ 헉헉 바쁘다 바빠.

근데 왜 티스토리 에디터에는 consola 폰트가 없지?



  1. OOP 한글위키 : https://goo.gl/pYKp6i [본문으로]
  2. Enum : https://msdn.microsoft.com/ko-kr/library/sbbt4032(v=vs.120).aspx [본문으로]
  3. 프로퍼티 : http://mrw0119.tistory.com/15 [본문으로]
c#


이번엔 코드보다 일단 설명


뭔가(문자열로) 입력을 받고 그걸 뒤집는걸 구현해보자는게 이번 취지.

밴쿠버 불꽃놀이를 5시에 가서(....) 10시까지 기다리기 지루해서 

아이패드 앱으로 코딩했다가 집에와서 다시 코딩.


7번 줄에 보면,

나는 ReverseStr()클래스가 char[]행렬을 받는다.

나는 string형을 받아서 함수 내에서 string을 char[]행렬로 바꾸는게 더 깔끔하다고 생각했는데

포프님 생각은 완전 반대. 왜 굳이 함수에서 바꿔서 메모리를 더 잡아먹게 하느냐는것.

(별 차이 없는거 같은데 엉엉 ㅠㅠ)

그래서  Main() 함수에서 받자마자 바로 변환시킨후에 함수로 넘겨줬다.


사실 이게 버전 2.5쯤 되는데, 처음 1.0버전은 입력받은걸 거꾸로 출력만(...)하는게 목적이었는데

출력보단 아예 스트링을 뒤집는게 더 좋을꺼라고(반협박) 하셔서 고쳤다.

2.0버전은 ReverseStr()클래스가 string형을 받는것, 그리고 아래 코드가 최종본이다.


20번 줄에서 입력받은 string 

21번 줄에서 char[]행렬로 바꿔주고

22번 줄에서 ReverseStr()함수호출

그리고 24번부터 출력 순이다.


-----------------------

 

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
using System;
 
namespace ReverseString
{
    class Program
    {
        static void ReverseStr(char[] str)      
{
            int length = str.Length;
            for (int i = 0; i < length/2;  i++)
            {
                char temp = str[i];
                str[i] = str[length - i - 1];
                str[length - i - 1= temp;
            }
        }
 
        static void Main(string[] args)
        {
            string input = Console.ReadLine();
            char[] str = input.ToCharArray();
            ReverseStr(str);
 
            foreach(char s in str)
            {
                Console.Write(s);
            }
            Console.WriteLine();
        }
    }
}
 
cs

-------------------------








c#




 최종코드---

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace pachinkogame
{
    class pachinko
    {
 
        /////////////////////////////
 
        static int money = 100;    //first money
        static int score = 0;
        static char a, b, c;
 
        static Random r = new Random();
        ///////////////////////////////
 
        static char createcharacter()
        {
            System.Threading.Thread.Sleep(50);    
            int random = r.Next(06);
 
            char character;
            switch (random)              //  0 ~ 4 (A, #, V, $, %)
            {
                case 0:
                    character = 'A';
                    break;
                case 1:
                    character = '#';
                    break;
                case 2:
                    character = 'V';
                    break;
                case 3:
                    character = '$';
                    break;
                default:
                    character = '%';
                    break;
            }
            return character;
        }
 
        static void printresult()
        {
            Console.SetCursorPosition(106);
            Console.WriteLine("STOP!");
 
            if (a == b && b == c)
            {
                score = 30;
                Console.SetCursorPosition(108);
                Console.WriteLine("WIN! +30");
            }
            else
            {
                score = -5;
                Console.SetCursorPosition(108);
                Console.WriteLine("LOSE -5");
            }
 
            money = money + score;
 
            System.Threading.Thread.Sleep(1000);
        }
 
        static void play()
        {
            while (money > 0)
            {
                if (Console.KeyAvailable == true)
                {
                    printresult();
 
                    Console.ReadKey(true);      //erase key insert
                }
 
                else if (Console.KeyAvailable == false)
                {
                    while (Console.KeyAvailable == false)
                    {
                        Console.SetCursorPosition(106);
                        Console.WriteLine("---------    NOW MONEY : {0}  ", money);
                        Console.SetCursorPosition(108);
                        Console.WriteLine("---------");
 
                        Console.SetCursorPosition(107);
                        Console.Write("- ");
 
                        a = createcharacter();
                        b = createcharacter();
                        c = createcharacter();
 
                        Console.Write("{0} {1} {2}", a, b, c);
                        Console.WriteLine("-");
                    }
                }
            }
        }
 
        static void Main(string[] args)
        {
            play();                 // if money is 0, game is end.
 
            Console.SetCursorPosition(1010);
            Console.WriteLine("Thank you for playing!");
 
            System.Threading.Thread.Sleep(1500);
 
        }
    }
}
 
 
cs



-------------------------------------


1. 하노이의 탑을 만들라고 했었는데, 결국 뭘 만들라는건지 질문 자체를 이해못해서 파칭코 게임으로 만들게 됐다.


2. 이번엔 사람의 도움이 아니라, 필요한 코드들은 직접 짜고

막히는 부분은 인터넷에서 찾고 찾아서 얼기설기 코드를 만들었더니

왜 여기서 이렇게 하면 버그가 나는걸까 싶은 부분도 아직 그대로 있다ㅜㅜ 

해결은 해서(자리를 바꾼다거나 해서) 버그는 없이 돌아가지만 그냥 왜 거기서 버그가 났었는지 아직도 모름.....


3. 파칭코가 빙글빙글 돌아가는걸 보여주고 싶었음.

 while문 하나를 키 입력 받기 전까지 무한으로 돌게 하려고 

( while (Console.KeyAvailable == false) ) 이런것도 써봄 ㅋㅋ 

근데 한번 입력하니까 계속 입력된걸로 인식해서 진행이 안됨 ㅠㅠㅋ 찾다보니 

(Console.ReadKey(true);) 요렇게 해주면 왠지 입력이 리셋될것 같아서 해보니 진짜 리셋됨!! 올레!

(그럼 false 하면 어떻게 될까......?!)


4. if문 안의 무한 루프를 돌던 while에서, 입력을 받은 후 빠져나와, 다음 else if로 갈 줄 알았던 분기문이, 

if가 끝났다고 if else로 안가고 바로 다음 구문으로 넘어가 버려서 멘붕. 

(사실 방금까지 왜 그런건지 모르고 있었는데 블로그에 정리하면서 깨달았다.... 

if를 두개쓰면 되는 문제였는데..... 이걸 왜 몰랐었니 ㅇ<-< 으아)


5. 랜덤함수는 아무래도 시간의 영향을 받는거 같은데, 한 랜덤함수에서 한번에 3개의 글자를 "짠!" 하고 구해버리면

항상 같은 글자가 나온다는 문제점이 있어서(...) 글자 사이에 시간차를 준 후 랜덤 함수를 두개 구해서 곱해버림.

(글쓰다보니 두개 구할 필요가 없네? 내일 코드 고쳐야지.)

(글쓰다보니 나머지를 따로 구할 필요도 없잖아? 나 뭐니)


6. 4번의 이유 때문에 코드 사이에 약간의 텀을 주는 함수가 없을까 찾다가 

유용한 녀석(System.Threading.Thread.Sleep(MiliSec.)) 발견.


7. 한번 그려진 그래픽(이라기엔 좀 민망하지만ㅋ) 위에 새로운 그래픽을 그리기 위해

커서 위치를 조정하는 함수도 써봄(Console.SetCursorPosition(x,y);). 우오오

잼남 신남! 뭔가 실시간?으로 돌아가는 게임을 만든 느낌!!ㅋㅋ


8. 점수랑, 점수에 계산해줄 그 턴의 점수는 아예 전역변수로 선언해버림.

원랜 play 함수 안에 넣었는데, play 함수가 재귀로 한바퀴 돌때마다 리셋 되어버리길래

(리셋은 내가 할꺼야!! 누구맘대로!!) 걍 맨 첨으로 꺼내버렸다.... 이래도 되는걸까?ㄷㄷ


9. 정말 한글로 된 블로그들보단 영문 블로그가 훠어얼씬 방대하고 자료가 많다.

위의 함수들은 그나마 대중적이지만, 조금만 생소한 함수들로만 들어가도 (특히)네이버에선 전혀 찾을수가 없다.

그러니까 구글링합시다 여러분.


10. I wanna make different function 이라고 적어놓은 부분은

원래대로라면 따로 함수로 때고 싶었는데, 저 a, b, c 요녀석들이 문제여서 따로 떼질 못했다.

밤이 늦어서 머리가 제대로 안돌아간건지... 내일 다시 보고 따로 떼야지.

그래야 부가적인 다른 기능들도 넣을 수 있을듯.



흐으.. 벌써 자정이 넘었다 ㅠ


나중에 좀 더 물어보고 아쉬운 부분 몇 군데 더 고칠생각.

잘자용.


-----다음날 추가수정----


1. 랜덤 수를 매번 구해 줄 필요가 없어서, 전역변수로 뺌.


2. a, b, c도 비교하기위해 밖으로 뺌. 

근데 생각해보니 비교할때 char형을 int형으로 비교했는데도 비교가 되더라 ㄷㄷ지적받고 놀람.


3. 이전 코드에서 print()던 함수를 createcharacter()로 (지적받고)바꿨다.

일단 이름만으로 뭘 하는지 알아야 하는데, 그게 불가능했고, 이 함수가 하는 일과 정확히 매치되지도 않았고

그래서 함수 안에 프린트 하는 부분을 아예 함수밖으로 빼고, 캐릭터 생성하는 함수로 정리함.


4. 재귀로 돌던 함수는 몇만번을 돌게되면 뻑(크래쉬)이 날 수 있다는 이야길 듣고

while문으로 바꿨다. 동시에 돈이 0원이 되면 함수에서 나와서 게임이 종료되도록 바꿨다.


5. 그 외에 자잘하게, 이기면 WIN, 지면 LOSE 라고 출력하는걸 만들었다.



c#

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;


namespace quicksort

{

    class Program

    {

        static void swap(int[] numbers, int a, int b)

        {

            int temp = numbers[a];

            numbers[a] = numbers[b];

            numbers[b] = temp;

        }


        static void sort(int[] numbers, int left, int right)

        {

            if(right <= left)       //exit condition

            {

                return;

            }

            

            int pivot = right;      //rightest bececome a new pivot


            int i = left;

            int j = right-1;


            while(i<j)              //compare with i and j (left and right)

            {

                if(numbers[i]<=numbers[pivot])

                {

                    i++;

                }

                else if(numbers[j] >= numbers[pivot])

                {

                    j--;

                }

                else

                {

                    swap(numbers, i, j);

                    i++;

                }

            }

            int newpivot = j;       //j become a new pivot

            swap(numbers, pivot, newpivot);     //switch a old pivot value and a new pivot



            /////////////////// recursive function

            sort(numbers, newpivot + 1, right);

            sort(numbers, left, newpivot - 1);

            //////////////////

            

        }


        static void Main(string[] args)

        {

            int[] numberArray = { 1, 6, 352, 56, 3, 43, 57, 47, 5, 2, 63, 0, 96 };      //random input

            int length = numberArray.Length;

            sort(numberArray, 0, length - 1);



            ////////////////////print

            Console.WriteLine("Sort result::");

            for(int i = 0; i < length; i++)

            {

                Console.Write("{0} ", numberArray[i]);

            }

            ////////////////////

        }

    }

}





-----------------------------------------
완성하는데 한달 가까이 걸림....
한번 다 완성하고, 집에와서 첨부터 다시 짜보니 30분도 안걸림.....헉

구글에 퀵소트 검색해서 나온 위키페이지만 믿고(예제가 잘못되어 있다...틀린건 아닌데ㅜ)고생하다가
결국은 거의 도움으로 짠듯 ㅠㅠ

여기서 배운건
1. 나는 내가 하고 있는 일을 설명할 줄 모른다(논리력이 부조카다) *중요
2. 퀵소트는 재귀함수다. 재귀함수로만 할 수 있는 일도 있다.
3. 재귀함수를 나가는 조건은(exit condition) 함수의 제일 처음에 있는게 (무조건)좋다.
4. 두 위치을 비교하면서 진행할땐, 한번에 한쪽 위치만 바꿔주는게 좋다. 안그러면 두 위치가 뒤집힐 수 있다.
5. 조금이라도 고쳤으면 디버깅을 하자.
6. 버그가 10개건 100개건 일단 당장 고치려고 하는 버그 하나에만 집중하자. 안그러면 절대 못고친다.
7. 심플하게 만들 수 있는걸 굳이 복잡하게 만들지 말자. 함수 하나만 거치면 될껄 두개 세개를 거치게 하면 더 복잡해진다.
8. 함수를 만들었으면 그 함수를 믿어라. 내가 만든 함수는 내가 넣은 값을 받아서 결과값을 도출해준다. 
일단 만들어진거라면 내부에서 어떻게 값을 도출해 내는지는 중요하지 않다.
9. sort 함수는 "숫자가 들어있는 행렬과 (왼쪽 오른쪽)위치값을 받아서 그 위치사이의 행렬이 가진 값을 정렬"해준다. 





http://bugacg.net/

부가씨지라는곳을 알게되었습니다.


컴터그래픽 전문 강의사이트인데, 강의 질이 괜찮고 폭넓어서 지금 정회원 가입을 고려중에 있습니다 ㅋㅋ

위의 스샷은 강의중 하나 따라해본것인데, 참 맥스에는 기능이 많군요 'ㅇ'ㅋㅋ



'ETC(미분류)' 카테고리의 다른 글

일기 : the whining  (0) 2015.11.05
일기  (0) 2015.11.05
파티클과 플로우, 그리고 부가씨지  (0) 2012.08.27



강좌 : ShaderFX를 이용한, 그래픽 디자이너를 위한 기초 쉐이더 강좌 14강





넹, 꾸준히 하고있습니다.


정신없이 좇아오다보니 벌써 14강이네요, ㅎㅎ

매달 한개씩 올려주신다고 하셨으니

다음 강의를 보려면 꼼짝없이 9월초까지는 기다려야 할 듯 싶습니다 ^^;;;


해야할 것, 하고싶은 것이 참 많습니다.

지치지 않고 꾸준히 해 나갈 수 만 있다면 좋겠네요^ㅂ^







꾸준히 따라가는 중입니다 ㅎㅎ

대마왕님의 ShaderFX를 이용한, 그래픽 디자이너를 위한 기초 쉐이더 강좌 9강 까지 듣고 해본 실습입니다.


진짜! 완전! 재미있어요!

대마왕님은 천재인거 같아요....

진짜 감사드리는 맘 뿐이네요 ㅎㅎ


예전에 언리얼을 다룰때 조금 해봤던 노드이기에 적응하는건 어렵지 않았었고

앞으로도 더 열심히, 이제 점점더 어려운게 나와도 꾸준히 해 나갈 수 있기를 바랄 뿐입니다 :)


아자아자!



*이건 9강의 숙제!

(재미삼아 넣어본 하늘, 아 정말 신기하네요 ㅋㅋ)



  1. 대마왕J 2013.01.13 06:52 신고

    훌륭하십니다. 숙제검사 완료. 짝짝짝








몇달전에 지인한테 보여주려고 급히 만들었던 튜토입니다 ㅋㅋ
일단 참고용으로 올려봅니다.









  1. 바닐라 2012.01.31 01:06

    잊어버려갖구... 어디서 다시 배워야 하나.. 하고 찾아다녔는데!! 감사합니다:D

+ Recent posts