제 3장에서는 클래스에 관한 개념을 배웠다.

사실 c에서 c++로 넘어올때 무엇때문에 공부해야되는지 차라리 게임제작에 필요한

언어를 더 빨리 배우면 안되는 것인지 -_-궁금하던차에 객체지향언어라는 이야기때문에

배우게 되었는데 제 3강에서 그 내용이 나왔다.

게임을 제작하기 위해 케릭터의 설정을 만든다고 하면은

그 케릭터가 하는 행동, 자료, 이 것들을 한 클래스로 지정해놓으면

많은 수의 케릭터를 불러올수도있고 메인코딩 자체가 짧아 질 것 같다.

뭉칠수 있는 덩어리를 하나의 덩어리로 모아서 사용에 보다 용이하게 만드는 작업?
내가 이해한 클래스는 이러하다 .
구조체와 다른 점은 함수도 클래스로 뭉칠수 있다는 것인데 기능 자체도 넣을 수있다는 점이
내가 정의한 자료형보다는 내가 정의한 함수 + 자료형의 느낌이다.

class 클래스이름 {
}
이런식으로 선언을 하고~
private: 내부 접근만 용이하다 클래스 내에서만 지정된 함수
public: 이녀석은 내부 , 외부 접근 모드 용이하다

그리고 하나 더있었는데-_-;;;뭐드라...

아무튼   클래스 내에서도 내부 외부 접근을 막아줄수 있는 기능이있다.

내부 접근은 한마디로 클래스 내에서 접근하는 방식
즉 class Door{
 int state
 void Open(){
  state=2
}}
이경우 state 라는 변수를 open함수에서 2로 초기화 시켜주었다.
이때는 내부접근이다 클래스 내에서 움직이는건 다 내부접근이다.
외부접근은 한마디로 다른 함수나 main 함수에서 불러오는 형태이다.

Door.state  < 도트 형태로 메인함수에서 불러올수있다.
액션스크립트에서 경로를 찾아 들어가는것과 비슷한 형태라서 금방이해했다.

슈팅게임의 움직임과 배경 그리고 총알까지만 구현하겠습니다.

추후에 충돌이나 이런쪽으로 좀더 문법을 알아야 하기때문에 이 게임은 여기서 잠시 중단하고

XNA자체에서 나오는 듀토리얼을 공부한 후 적기 출현과 충돌에 대해서 제작하겠습니다.

그럼 오늘 배경을 마지막으로 다음 강의는 XNA 2D게임제작을 올리겠습니다.


배경을 제작하려면 일단 배경이 있어야겠죠
미스터백님의 배경을 가져와서 다중스크롤 배경에 대해서 작성하고 마치도록하겠습니다.
두개의 배경을 다른속도로 스크롤 시키면서 좀더 역동적인 배경을 제작합시다.

사용자 삽입 이미지
사용자 삽입 이미지

전 이 두개를 배경으로 사용하겠습니다.
사용자 삽입 이미지








자 저렇게 선언 하시구요
back1 back2 가 그림의 좌표값으로 사용될것입니다.

사용자 삽입 이미지













자 이부분에 추가된 것은
back1, back2 의 간단한 if문입니다.
배경 크기가 500 x 600 입니다.

back1 이 먼저 출력될 그림입니다 속도는 10만큼씩 움직일거구요
back2 는 그위에 출력될 그림입니다. 속도는 15만큼 움직일겁니다.
당연히 그림크기가 600이니 다되면 다시 아래로 가게 되야 스크롤되겠죠 간단한 if문입니다.

자 이제 준비는 끝났습니다 Draw 에 가서 출력합시다

사용자 삽입 이미지



















그림 출력관련해서는 강의 #4 를 참고 해주시기 바랍니다.
Draw(이미지이름, 이미지이동좌표, 그림이미지크기, 색)
new Rectangle( x ,y , 이미지x, 이미지y)

그럼 이제 디버깅 해보도록 하겠습니다.



이제 xna 스튜디오에 익숙해지는 작업이 완료되었다고 생각합니다.
다음은 본격적인 2D게임 듀토리얼을 따라하겠습니다.
이 게임은 2D게임 듀토리얼이 끝나는대로 다시 진행하겠습니다.

수고하셨습니다^^
이번시간은 비행기에서 미사일이 발사되는 것까지 구현하도록 하겠습니다.

사용자 삽입 이미지

요놈이 미사일입니다. 이미지 컨텐츠에 추가해주세용~

사용자 삽입 이미지
















선언부분 입니다. 추가된 것은
   Texture2D cong;//총알이미지저장
   Vector2[] congtruepo;//총알 움직임
    bool[] coungpan;//총알발사여부
    int misailnumber = 0;//현재 미사일번호
    int maxmisail = 30;// 미사일 맥스수치
    float delay = 0.0f;// 딜레이시간저장
    float delatnum = 0.1f;//딜레이 한계시간

가장 맨위는 총알의 이미지를 저장할 곳이구요
다음은 총알의 위치정보를 담을 곳입니다. [] 많은수의 미사일을 조정해야함으로 배열로 선언했구요
bool형으로 총알이 발사되었는지 안되었는지 알기위해 선언했습니다. 물론 배열선언해야되구요
현재 미사일 번호와 맥스수치의 미사일 번호를 알아야 합니다.
그리고 어느정도 간격을 가지고 미사일을 발사해야함으로 지나가는 시간을 저장하는 곳과
어느정도 지난후 발사하라는 딜레이 한계시간을 지정했습니다.

컨텐츠에서 cong 에 이미지를 저장해주시구요

사용자 삽입 이미지






초기화 하는 부분입니다.
총의 위치정보를 배열을 사용할 만큼 선언해줍니다.
그리고 bool형도 사용할 만큼 배열을 선언해줍니다.
그리고 현재 마시일 넘버는 당연히 0이겠죠. 초기화 끝났습니다.
다음은 마시일을 움직여 봅시다.

사용자 삽입 이미지

 protected override void Update(GameTime gameTime)
        {
이부분 안에 작성한 코드입니다.
가장먼저 delay += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f; 현재시간을
delay 에 저장합니다. 그리고
if (delay >= delatnum) 어느정도 시간이 지났으면 실행합니다.
                    coungpan[misailnumber] = true;// 미사일 발사되었다고 해주시구요~
                    congtruepo[misailnumber] = pengmove;// 위치는 비행기와 같은 위치에 와야겠쬬?
                    congtruepo[misailnumber].X = (pengmove.X + pengs.Width / 2) - (cong.Width / 2) -100;
                    비행기에 미사일이 발사되는 곳으로 좌표를 이동시켜줍니다.
                   (케릭터 위치값 + 케릭터그림/2) - (총의 이미지/2) -100 < 임의 적으로 작성 한것
케릭터그림/2 하는 이유는 정확하게 가운데로 옮기기 위해서 입니다 총도 마찬가지구요~
-100은 계속 실행해보면서 위치값을 조절한것입니다. 비행기의 총이 약간 왼쪽에 있어서 -100을 했습니다.~

  misailnumber++;
계속해서 미사일넘버를 바꿔주시구요~
 if (misailnumber >= maxmisail)
 misailnumber = 0;
현재 마사일이 맥스수치에 도달 했을 경우 0으로 초기화합니다.
delay = 0.0f;
그리고 저장되어 있는 시간도 초기화 해주시구요~
발사 되었으니 다음 미사일은 새로 시간을 잡아야합니다.
 else
 delay = 0.0f;
또 z키를 누르지 않았으면 계속 딜레이 값은 0입니다.

사용자 삽입 이미지
 
그럼 미사일을 비행기 가운데로 옮겼으면 위로 움직이게 합시다.
   float misailmove =400* (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f;
마시일의 속도를 지정해주시구요~ 400수치값이 올라갈수록 빨라집니다.

   for (int misailnumber = 0; misailnumber < maxmisail; misailnumber++)// 마시일의 수치만큼 for반복
            {
                if (coungpan[misailnumber] == true)//만약에 미사일이 발사되었다면~
                    congtruepo[misailnumber].Y -= misailmove;//y축으로 마사일 무브 만큼 움직여라.

그 아래 부분은 미사일이 화면 밖으로 나가면 계산하지 않기 위해 false값으로 바꿔버리는 역할입니다.

            int screenga = graphics.PreferredBackBufferWidth;
            int screense = graphics.PreferredBackBufferHeight;
화면의 크기를 screenga , se 로 저장했습니다.

     if (congtruepo[misailnumber].X > screenga || congtruepo[misailnumber].Y > screense||
                    congtruepo[misailnumber].X < 0.0f || congtruepo[misailnumber].Y <0.0f)
                {
                    coungpan[misailnumber] = false;
                }

미사일의 위치가 화면 밖으로 나가게 되면 false값으로 바꿔줍니다. 그럼 더이상 계산 안하겠죠?

자이제 모든 코딩이 끝났습니다. 이제 화면상에 출력만 하면 끝입니다.
   protected override void Draw(GameTime gameTime)
        {
이곳에 작성해줍시다~
사용자 삽입 이미지
for반복문 만약 미사일이 발사 되었다면 그려라

자이제 디버깅해봅시다^^;
이번에는 스프라이트 애니메이션이 적용된 케릭터에게 움직임을 주도록합니다.
좌우위아래로 자연스럽게 움직이는 케릭터를 `ㅡ` ㅋ

사용자 삽입 이미지

비행기 의 모습입니다. 이상하게 생겼지만 팽귄입니다..-_-...(어딜봐서...)

자 시작합니다.

가장 먼저 비행기를 화면상으로 나타내야합니다.

사용자 삽입 이미지

일단 가장먼저 비행기(펭귄)을 불러올 2D이미지를 선업합니다.
Texture 2D pengs;
그리고 이 펭귄을 움직임을 줄 벡터를 선업합니다.
Vector2 pengmove;

사용자 삽입 이미지







컨텐트에 Flight 의 비행기를 불러와주시구요 ( 불러오는 방법은 컨텐트>오른쪽마우스>추가 >기존항목)
불러오셨으면 로드 하도록합시다 앞에서 선언안 pengs에 이미지를 넣어봅시다.

사용자 삽입 이미지
  pengs = Content.Load<Texture2D>("Flight"); 자 그림파일을 pengs 에 저장했구요
다음으로는 케릭터의 움직임을 지정해줍시다.
사용자 삽입 이미지

 protected override void Update(GameTime gameTime)
게임실행시 계속해서 실행하라는 곳입니다.

일단 현재 키보드상태의 정보를 가지고있는 녀석을 지정해주시구요
 KeyboardState currentKeyState = Keyboard.GetState();
currentKeyState 요놈이 사용자가 키보드에 무엇을 입력했는지 저장하고 있습니다.
이제 수치값을 지정해봅시다 매초마다 얼만큼 움직이게 할것인가 입니다.

 float move = 200 * (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f;
float 형태의 move를 지정합니다. float형태는 소수점까지 저장할수있는 형태입니다.
앞에 수치값의 변화에 따라 움직임의 속도가 달라집니다. 높을수록 빠르겠죠?

if (currentKeyState.IsKeyDown(Keys.Right))
                pengmove.X += move;
            if (currentKeyState.IsKeyDown(Keys.Left))
                pengmove.X -= move;
            if (currentKeyState.IsKeyDown(Keys.Up))
                pengmove.Y -= move;
            if (currentKeyState.IsKeyDown(Keys.Down))
                pengmove.Y += move;

만약 키보드 오른쪽 키를 눌렀다면 pengmove를 x축의 +방향으로 move 만큼 이동시켜라.
나머지 좌 위 아래도 같은 방법으로 코딩해줍니다.

자 모든 준비가 끝났습니다. 이제 상콤하게 움직여 봅시다.

화면상에 출력하는 부분으로 가봅시다.

사용자 삽입 이미지

Draw 가 화면상에 그리는 부분입니다.
   spriteBatch.Draw(pengs, pengmove, flightangle[anim], Color.White);
그립시다. ( 이미지명, 움직임 , 이미지변경애니메이션 , 색 )
flightangle[anim] < 이부분은 스프라이트 이미지 입니다. 앞에 강의 참조하시구요~ㅎ

자 이제 디버깅해봅시다.



다음시간에는 미사일을 발사 시키도록 합시다.

제 2강 공부한 내용입니다.

const 키워드란?
한마디루 변수를 상수화 시켜주는 것 입니다.
움직이는 값이 아닌 정해진 하나의 값으로 만들어주는 키워드죵
const int i = 10;
i=20;
이런식으로 하면 에러가 나겠쬬? 움직이지 못하는 값이니까요~ ㅎ

stack 이란 ?
메모리 공간에 나오는 개념
흠...스택이라함은 메인 함수가아닌 호출함수에 쓰이는 매개변수나 지역변수를 저장하는 공간이라고
설명하면 되겠다. 일회용으로 한번 사용하고 그 값을 지워버리는 공간? 이다.

heap 이란 ?
힙이라고 함은 프로그래머가 직접 할당하는 영역인데 여기서 사용하는것이 c에서는 말록과 프리함수였다.
만약 배열의 크기를 입력받는다고하면 거기에 몇바이트를 줘야 할지 컴파일러는 알수없다. 한마디로 사용자가 입력하는 값자체를 메모리 크기로 할당해야되는데 그걸 컴파일러는 알수없고 프로그래머도 알수없다. 그래서 말록 함수로 그 받은 크기만틈 메모리를 할당해준 곳이 힙이란 영역이다. 힙의 영역에 할당된 메모리는 프로그래머가 삭제하기 전에는 사라지지 않기 떄문에 꼭 프리함수를 써서 삭제 시켜줘야한다.
int* arr=(int*)malloc(sizeof(int)*size);
free(arr);

위 두문장이 한세트로 다녀야 한다. arr이라는 동적배열의 메모리 선언과 프리함수로 arr의 메모리를 삭제해주는 구문이다.

bool 이란?
다음은 bool의 자료형에 대해서 배웠다 한마디로 true false의 값을 반환해주는 자료형인데..
흠......뭐 c에서 일일이 선언하는 것보다 이거에 관한 자료형이 있으니 편한거 말고는..확실히
필요한지는 잘모르겠따 - _- ;;;물론 int값으로 bool형을 반환하면 1(true),0(false)이 나온다

래퍼런스란 ?
무지무지 c++에서 중요하다고 말하는 래퍼런스를 배웠다.
int b;
int& a=b;
b라는 놈에게 a라는 이름을 중복으로 설정해주는 것이다.
한마디로 b의 이름이 두개가 생긴것이다.

래퍼런스의 활용은 정말 많을 듯 싶다.
일단 데이터를 확실하게 줄일수 있다. 한 데이터에 이름만 여러게 만들어줘서 하기때문에
데이터 관리에 용이하다는 점.

메인함수의 있는 것들 함수로 받아서 처리할때도 래퍼런스를 활용하면된다.

함수에서도 메인함수의 데이터에 접근이 가능하니 편리하다
물론 메인함수의 영향을 안미치기 위해서는 const 키워드를 사용하면된다
이것을 상수화하여 더이상 값이 변하지 못하게 하는것이다. 참조를 할때
사용하면 될듯 하다.

제2강에서는 래퍼런스가 가장 중요할 듯..


제가 공부하기 위해서 블로깅 하는 것이므로-_-;;전혀 도움안되는 내용을 가지고 있습니다 ㅠ
-------------------------------------------------------------------------------------
c++ 입력 및 출력

cout , cin, endl
printf , scanf, \n

두개가 같은 뜻으로 사용됨

c++은 함수 오버로딩이 가능한데 오버로딩이란 같은이름의 함수지정이 가능 하다는 것이다.

void function(void){
}
void function(int i){
i=0;
}

c에서는 불가능햇지만 c++에서는 매개변수의 수에 따라 같은 함수 지정이 가능하다.
이유는 컴파일시에 매개변수의 차이까지 정보로 가지고 있기때문에 아예 다른 함수로 인식한다.

매개변수의 경우 void function(int 1=0){
} 이라고 했을 경우 매개변수가 들어오지 않으면 0으로 초기화 시킨다.

c의 #define 매크로의 경우도 다른 개념을 배웠다.
inline이라는 함수 인데 이 함수자체가 디파인과 같은 기능을 지닌다고한다.
하지만 인라인의 경우 함수를 매크로처럼 지정할수 있어서 c에서 매크로로 코딩하기 어려웠던 것을
아주 편하게 함수처럼 지정할수있다.

오버로딩에서 문제점은 같은 함수의 이름을 지정시에

function()이란 함수를 호출했다고하자

void function(void){
}
void function(int i=0){
i=0;
}

자 그럼 위에 두함수는 어떻게 되겠는가?
분명 둘다 호출이 될것이다. 아무것도 매개변수로 전달되지 않았다면
처음 매개변수가 보이드인 놈도 호출될것이고 전달안됐을때 0을 매개변수 초기화하라는 놈도
실행될 것이다 이 문제를 해결하기 위해서 등장한 것이 이름공간이란다.

공간에 이름을 지정한다.

namespace A{
void function(void){
}
}

namespace이놈이 바로 공간을 지정하는 놈인데 그뒤에 따라오는 변수가 그 공간 이름이 된다.
A라는 이름공간을 마련한 셈이다 그안에 fucntion이라는 함수가 들어있다
그럼 이놈을 출력할때에는 A::function(); 요런식으로 실행해준다
에이란 이름공간안에 펀션이라는 함수를 실행하라 이뜻이다.

네임스페이스가 확실히 편리하고 도움이 되지만 그 호출할때 이름이 길어지기때문에
조금 불편할수도 있다 그래서 이것을 해결하기 위해 사용하는 것이 using이다.

using A::fucntion(); 으로 선언하면
fucntion으로 바로 호출이 가능하다.

using A::function;

int main(void)
{
 function();
 return 0;
}

간단하게 이런식인데 이름공간안에있는 함수를 쉽게 불러오기 위함이다.

헷갈리는 것은 굳이 이름공간으로 두함수를 주었다고 하자...

그것을 편하게 불러오기위해 function();으로 넣는다면..
오버로딩시 에러가나는 두함수가 함께 불러올때를 해결할수 있는가?

#include <iostream>

namespace A_COM
{
 void function(int i=0)
 {
  std::cout<<i<<std::endl;
 }
}
namespace B_COM
{
 void function(void)
 {
  std::cout<<"A.com에서 정의한 함수"<<std::endl;
 }
}
using A_COM::function;
using B_COM::function;

int main(void)
{
 int a=10;
 function();
 return 0;
}

한마디로 이런고민인데 메인 함수에서 펀션을 불러왔을때와 펀션(a)를 불러왔을때
쉽게 사용하기 위해 유징을 사용한다면 똑같은 문제가 다시 발생하는건 아닌가?
...사용이 안되겠지?당연히-_-?;; 이름공간을 없애버리는게 유징아닌가?;;;
그럼 왜 유징을 사용하는거지-_-;;편리하기위해? 아무튼 오버로딩에서 이름공간에 유징까지
세가지가 혼합되니까 상당히 헷갈린다;;;;;;;;;;

오버로딩때문에 이름공간을 나누었더니 유징으로 없애서 다시 원상태?-_-;;

뭐 이해하기로는 대충 유징은 필요한 함수에게만 사용해서 그것을 편리하게 사용한다 이정도로
이해해둬야겠따..더생각하다간 더 뒤죽박죽이 될듯..

ㅡ_-뭐 틀린점있으면 댓글좀 달아주세용 ㅠㅠㅠ 열심히공부할게염 ㅋㅋ





+ Recent posts