이번에는 맵을 불러오는 것 까지 해보겠습니다.

맵을 불러오는 것은 간단합니다.

메모장으로 텍스트 파일을 입력후 해당 입력 값을 차례로 불러와서
타일 그림을 로드 할 것입니다.
예로 0이면 바위 1이면 빈공간 2면 악당 이런식으로 불러온다는 것이죠
000010022  < 이런식의 글씨면 바위 4개에 빈공간 하나에 바위 두개에 악당 2마리라는 뜻이죠 -_-;; 헉헉

가장먼저 Tile 클래스를 생성해보도록 합시다.

사용자 삽입 이미지

Tile에서는 충돌하는 녀석인지 충돌하지 않는 녀석인지와 이미지 정보를 가지고 있을 것 입니다.
상단 부분에
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

이렇게 바꿔주시구용~
Tile 클래스를 작성해보도록 합시다.

     enum TileCollision//타일의 충돌정보
    {
        Passable = 0,//빈공간의 타일이라고 생각하시면 됩니다. 케릭터나 몬스터가 자유롭게 이동가능함.
        Impassable = 1,//상하좌우 충돌이 나는 타일입니다. 돌덩어리죠ㅋ
        Platform = 2,//위에서 아래로만 충돌이 일어납니다. 하단에서 위로는 그냥 지나칠수있죠
     }
    class Tile
    {
        public Texture2D Texture;//타일 그림
        public TileCollision Collision;//위에 충돌정보

        public const int Width = 64;//가로크기
        public const int Height = 48;//세로크기
        public static readonly Vector2 Size = new Vector2(Width, Height);

        public Tile(Texture2D texture, TileCollision collision)//타일 생성자
        {
            Texture = texture;//그림 초기화
            Collision = collision;//충돌정보 초기화
        }
    }
자 Tile 클래스 작성이 끝났습니다.
TileCollision는 레벨에서도 사용할거기때문에 빼놨습니다. 타일관련이라 해당부분에 작성하였습니다.
namespace WindowsGame1 내부 어디에 작성하셔도 됩니당~

이제 맵의 정보를 가져와보도록 합시다.
먼저 컨텐츠에 txt 파일과 블럭이미지를 추가하도록 합시다.


사용자 삽입 이미지

일단 저는 맵 하나의 정보만을 가져 왔습니다.

사용자 삽입 이미지
txt 파일 속성을 위와 같이 바꿔줍니다.

자 이제~ 기본적으로 준비사항은 끝났습니다.

오늘 한 내용은 기본적으로 타일클래스를 생성했구요~
txt파일 맵 정보데이터를 컨텐츠에 추가했습니다.

다음 시간에 해당 정보들을 가지고 타일이미지를 불러와 그려보도록 합시다.



해당 블로깅은 -_-예제파일이 완성 된 상태에서존재하는데 따로 적으면서 하는게
별의미가 없어서 여기서 그만 종료하겠습니다. 혹 궁금한점있으시면 메일이나 방명록에 남겨주세요^^




오랜만에 작성을 합니다. 예제파일 튜토리얼을 간단하게 만들어달라는 사람들이 있어서 작성합니다.

사용자 삽입 이미지


xna 설치 후 프로젝트 생성을 누르면 해당 샘플 파일이 존재합니다.
해당 샘플 파일을 따라서 제작해보는 시간을 가져보려고 합니다.

새로 프로젝트를 생성 후 가장먼저 사이즈부터 맞게 조정합시다.

        private const int BackBufferWidth = 1280;
        private const int BackBufferHeight = 720;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = BackBufferWidth;//사이즈 가로
            graphics.PreferredBackBufferHeight = BackBufferHeight;//사이즈 세로
            Content.RootDirectory = "Content";
        }

생성 자 부분에 작성 합니다.

가장 먼저 배경화면부터 만들어보겠습니다.
새 클래스를 하나 만들어 줍시다. 이름은 샘플 파일과 같게 Level 로 작성하도록 하죠
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using System.IO;

상단부분에 해당 부분을 작성해주세요~ c의 include 라고 보시면됩니다.

다음으로는 배경으로 쓸 녀석들을 우리 프로젝트에 추가해보도록 합시다.


사용자 삽입 이미지

컨텐츠를 누르고 오른쪽 마우스 클릭 추가-새폴더랑 기존항목 추가로 해당 그림처럼 만들어 줍니다.
Backgrounds 입니다. n이 빠졌네요-_-;;

다음으로 Level 에 추가로 작성해보겠습니다.
Level 클래스가 로드 및 드로우 업데이트 게임의 거의 모든 부분이라고 생각하셔도 됩니다.

먼저 작성에 앞서 필요한 변수들을 선언합니다.

    class Level
    {
        public ContentManager Content//레벨클래스에서 그림을 로드하기 위해 작성
        {
            get { return content; }
        }
        ContentManager content;

        private Texture2D[] layers;//배경이미지를 저장할 배열
        private const int EntityLayer = 2;//배경화면 그릴 갯수(0,1,2 이렇게 3가지)
        private Random random = new Random(354668);//랜덤 생성

이렇게 추가 하시고 생성자를 작성해봅시다.

        public Level(IServiceProvider serviceProvider, string path)//생성자 스트링은 다음 강의때 사용
        {
            content = new ContentManager(serviceProvider, "Content");//컨텐츠 매니저 생성

            layers = new Texture2D[3];//배경으로 3개가 들어감
            for (int i = 0; i < layers.Length; ++i)//위에 선언한 이미지 크기만큼 로드
            {
                int segmentIndex = random.Next(3);//레이어 안에 이미지 중 0, 1, 2, 각 3가지들 중 한가지씩
                                                           //로드함 레이어0_0~2 중하나, 1_0~2 중하다, 2_0~2중 하나
                layers[i] = Content.Load<Texture2D>("Backgrounds/Layer" + i + "_" + segmentIndex);
            }     //로드
        }

생성자를 작성해서 그림 로드 했으니 실제적으로 그려줄 Draw 함수를 작성합시다.
 
        public void Draw(GameTime gameTime, SpriteBatch spriteBatch)//이렇게 그립니다.
        {
            for (int i = 0; i <= EntityLayer; ++i)//총 0 1 2 이녀석들을 0,0에 그려라
                spriteBatch.Draw(layers[i], Vector2.Zero, Color.White);
        }

자 이렇게 Level 클래스 작성을 마쳤으니 메인클래스로 돌아가서 Level을 생성 및 적용하도록 합시다.

        private Level level;//선언하시구요~


        protected override void LoadContent()//로드 부분에
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            LoadNextLevel();//해당 함수부분을 추가합니다.
            // TODO: use this.Content to load your game content here
        }

LoadNextLevel() 이 함수 녀석이 Level을 생성하는 역할을 하게 됩니다.

        private void LoadNextLevel()//로드 넥스트
        {
            string levelPath;//아직 요녀석은 상관하지마세용~
            levelPath = null;//일단 널로 처리해 둡시다.
            level = new Level(Services, levelPath);//레벨 생성
        }

레벨 생성을 마쳤으니 그려주도록 합시다.

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();
            level.Draw(gameTime, spriteBatch);//해당 부분을 추가해주록 합시다
            spriteBatch.End();
            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }

자이제 F5를 눌러보도록 하죠

사용자 삽입 이미지


다들 잘되셨나요~
레벨클래스를 생성하여 메인 클래스에서 생성 및 그려줬습니다.
다음 시간은 맵을 그려보도록 합시다.

이번 기회에 시리얼 통신을 사용하게 되었다.
압력센서에서 값을 받아오기 위해서
C#이다보니 C#시리얼 통신이랑 똑같이 하면된다. -_ -...난 XNA라고 괜히 겁먹었음 ㅠ

        public void Serial_open()
        {
            try
            {
                sss.PortName = "COM6";
                sss.DataBits = 8;
                sss.Parity = Parity.None;
                sss.BaudRate = 9600;
                sss.StopBits = StopBits.One;
                sss.Open();
                CreateThread();
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Alter", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }
        }

이부분은 시리얼 포트를 열때 사용한다 멀티 쓰레드로 돌리지 않으면 게임이랑 같이 느려진다-_-(당연한걸..)

쓰레드를 만드는 부분 함수

        public void CreateThread()
        {

            Thread thRun = new Thread(new ThreadStart(SerialPort_DataReceived));
            thRun.Start();
        }

쓰레드를 생성하고 스타드 안에 값을 받는 함수를 돌려준다

        public void SerialPort_DataReceived()
        {

            while(true)
            {
                try
                {
                    if (Mode == mode.sens)
                    {
                        string strtmp = this.sss.ReadLine();
                     }
                }
            }
         }

센서쪽에서 \n 을 넣어서 보내달라그랬다. 엔터가 들어올때까지 버퍼에 쌓아두다가
값이 넘어오게 된다. 이 넘어온 값을 적절하게 짤라서 게임에 사용하였다.

궁금한점 있으면 댓글 남겨주세요

네트워크도 되긴하지만 이부분은 다음에 작성하겠다.
         


사용자 삽입 이미지


흑흑 부루마블 같이 나왔다 그래두 ㅠ ^ ㅠ

일주일만에 후다닥 - _ -일주일넘었나?;;하핫;;;
using System.Diagnostics;
추가하시고

아래창 처럼 입력하시고
Debug.WriteLine("X?"+X);


사용자 삽입 이미지

잘 나오는군요 *-_-*
간단한 퍼즐게임을 하나 만들어 보겠습니다.^^

조각 맞추기 퍼즐게임을 다들 잘 아시죠^^?
이미지는 이걸로 하겠습니다
가로 6칸 세로 4칸으로 구현하겠습니다.
사용자 삽입 이미지

게임을 어떻게 구현할지 간단하게 생각해보겠습니다.
1. 그림파일을 가져와 일정한 크기로 나열합니다.
2. 각 그림들을 내열할때 다중배열로 저장합니다.
3. Rectangle, vector2, int[][] 만 잘사용하면 금방 끝납니다^^

시작 하겠습니다.

가장먼저 초기 선언을 하겠습니다.

public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; Texture2D bk;//배경그림 const int bw = 40;//각 셀 사이즈 40*40 int[,] data = new int[4, 6];//가로 6 세로 4사이즈 int count = 0;//data배열에 값을 저장할 변수 KeyboardState stopkeyboard;//키보드 중복 인식 방지


주석 참고 해주시구요~
가로 셀 6개 세로 셀 4개의 조각 퍼즐을 만들 생각입니다.
data[0,0] = 0; data[0,1] = 1;.... 이런식으로 지정할 생각입니다.


protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); bk = Content.Load("bk"); // TODO: use this.Content to load your game content here }
위와 같이 그림파일 불러와 주세요

다음으로는 초기화 부분입니다 각 셀의 정보를 가지고 있을 data 녀석에게 수치를 부여합시다.
각 수치에 따라 그림 위치가 정해질 것 입니다.



protected override void Initialize() { // TODO: Add your initialization logic here for (int i = 0; i < 4; i++) { for (int j = 0; j < 6; j++) { if (i == 3 && j == 5) data[i, j] = -1; else data[i, j] = count++; } } setdivise();//화면크기 변경 무시하셔도 됩니다. base.Initialize(); }
이중 for문을 이요해서 data[0,0]~data[3,5] 까지 0~22 의 수치와
마지막 셀에는 -1의 수치를 넣어주도록 합시다.
-1을 넣은 이유는 나중에 그릴때 빈 블럭(퍼즐조각의경우 빈블럭있음)을
그리기 위함입니다.

네 키보드 입력을 받아 이동할 MoveBlock(int x, int y)는 두번째 블로깅에서
올리도록 하고 이번에는 일단 지금 까지 작성한걸 출력해보도록 하겠습니다.
>

protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(); for(int n=0; n<4; n++) { for(int m=0; m<6; m++) { if(data[n,m] < 0)//-1은 그리지않음(빈블럭) { } else{ int cx = data[n,m]%6;(x셀의 좌표는 0~5까지) int cy = data[n,m]/6;(y셀의 좌표는 0,1,2,3까지) Rectangle Clip = new Rectangle(cx * bw, cy *bw ,bw, bw); spriteBatch.Draw(bk, new Vector2(m * bw,n *bw), Clip, Color.White); } } } spriteBatch.End(); }
draw 부분에 위와같이 작성하도록 합시다.
for문으로 각 셀의 데이터를 조사합니다
-1 일 경우 아무것도 하지 않고 else 일 경우에 그리도록합니다.
x좌표는 총 0~5까지니 6으로 나눈 나머지가 되겠구요
y좌표는 몫이 0~3 까지 나오게 합니다.
그림내부에 그릴 영역을 설정합니다(rectangle)
bw 는 각 셀의 크기 입니다.
cx,cy 좌표에 bw크기만큼 곱합니다. 그림의 좌표 값이 되겠구요 이미지 영역은 bw,bw 만큼 설정합니다.
마지막 이제 그리도록 하겠씁니다
spriteBatch.Draw(bk, new Vector2(m * bw,n *bw), Clip, Color.White);

아까 저장한 bk의 이미지에 위치는 각 셀의 data[n,m] 값을 가져와 설정하고
그림 영역은 셀이 저장하고있는 수치정보로 Clip(rectangle)을 설정합니다.

자 위와 같이 입력하셨으면 출력해보도록 하겠습니다.

사용자 삽입 이미지
다음은 키보드 입력을 받아 이동하는 함수를 하나 제작해보도록 하겠습니다.
3#에서는 랜덤으로 퍼즐을 나열하도록 해보겠습니다.

+ Recent posts