본문 바로가기
공부,일/C#

소코반게임 만들기

by fromnothing1 2021. 6. 8.

배운점 

 

1. 스트링은 readonly 속성으로 수정이 불가능하다. 

2. paint이벤트의  의 draw 기능은 함수 내에서 바로 구현 되지 않고 윈도우에 요청만 한 상태이다. 

함수가 끝나고 나서야 그려진다. 

 

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Socoban_Game
{
    public partial class Form1 : Form
    {
        Bitmap aPeatchF;
        Bitmap aPeatchB;
        Bitmap aPeatchL;
        Bitmap aPeatchR;
        Bitmap aPeatch;
        Bitmap Goal;
        Bitmap GBox;
        Bitmap Box;
        Bitmap Road;
        Bitmap Wall;
        Bitmap aPeatchOld;
        int aPeatchX;
        int aPeatchY;
        int aPeatchOldX; // @ 의 이전 위치
        int aPeatchOldY; // @ 의 이전 위치
        int stage;
        const int MaxStage = 2;
        int KeyCount;
        bool Endstage; // 게임 클리어 여부 확인 

        //string[,] =  char[][][]   초기 화 쉽게 할라고 string[,] 형태 사용
        static string[,] Map1 = {
            {
                "################",
                "#   #      ##  #",
                "#  @##         #",
                "#   BG         #",
                "################",
            },
            {
                "################",
                "#   #      ##  #",
                "#  @##    B  G #",
                "#       B B  GG#",
                "################",
            }
        };
        // string 은 수정 불가능하다 읽기만 가능하다.
        char[][] Map;

        int TileXNum = Map1[0,0].Length;
        int TileYNum = Map1.Length / MaxStage;
        int TileXSize = Properties.Resources.Back.Width;
        int TileYSize = Properties.Resources.Back.Height;

        void LoadMap()
        {
            for (int i = 0; i < TileYNum; i++)
            {
                Map[i] = Map1[stage, i].ToCharArray();
            }
            KeyCount = 0;
        }
        void NextStage()
        {
            ++stage;
            if(stage >= MaxStage)
            {
                if (MessageBox.Show("마지막 판입니다. 종료할 까요", "게임 올 클리어", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    Close();
                }
                else
                {
                    stage = 0;
                }
            }
            LoadMap();
            Refresh();
        }
        void PrevStage()
        {
            --stage;
            if (stage < 0)
            {
                MessageBox.Show("첫판입니다..");
                stage = 0;
               
            }
            LoadMap();
            Refresh();

        }
            public Form1()
        {
            InitializeComponent();
            StartPosition = FormStartPosition.Manual;
            Location = new Point(0, 0); // 생성위치 
            Text = "소코반";
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Location = new Point(0, 0);
            aPeatchF = new Bitmap(Properties.Resources.Front);
            aPeatchB = new Bitmap(Properties.Resources.Back);
            aPeatchL = new Bitmap(Properties.Resources.Left);
            aPeatchR = new Bitmap(Properties.Resources.Right);
            aPeatch = aPeatchF;
            aPeatchOld = aPeatchF;
            Box = new Bitmap(Properties.Resources.box);
            GBox = new Bitmap(Properties.Resources.Gbox);
            Road = new Bitmap(Properties.Resources.road);
            Wall = new Bitmap(Properties.Resources.wall);
            Goal = new Bitmap(Properties.Resources.goal);

            ClientSize = new System.Drawing.Size(TileXNum * TileXSize, TileYNum * TileYSize);
            Map = new char[Map1.Length][];
            stage = 0;
            LoadMap();

            //for (int i = 0; i < Map1.Length; i++)
            //{
            //    Map[i] = new char[Map1[i].Length]; c 언어랑 달리 주소값을 계속 넣어 줘야한다.
            //    for (int j = 0; j < Map1[i].Length; j++)
            //    {
            //        Map[i][j] = Map1[i][j];
            //    }
            //}
        }

        void aPeatchMove(Bitmap TempBitmap)
        {
            int NextX = 2 * aPeatchX - aPeatchOldX; // 3번째 위치 
            int NextY = 2 * aPeatchY - aPeatchOldY;

            if (Map[aPeatchY][aPeatchX] == '#') {return;}
            else if (Map[aPeatchY][aPeatchX] == 'B')
            {
                if (TempBitmap == aPeatchOld)
                {
                    if (Map[NextY][NextX] == ' ' || Map[NextY][NextX] == 'G')
                    {
                        Map[NextY][NextX] = 'B';
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    return;
                }
            }
            Map[aPeatchY][aPeatchX] = '@';
            Map[aPeatchOldY][aPeatchOldX] = ' ';
            KeyCount++;
            return;
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            aPeatchOldX = aPeatchX;
            aPeatchOldY = aPeatchY;
            aPeatchOld = aPeatch;
            switch (e.KeyCode)
            {
                case Keys.Up:
                    aPeatch = aPeatchB;
                    --aPeatchY;
                    break;
                case Keys.Down:
                    aPeatch = aPeatchF;
                    ++aPeatchY;
                    break;
                case Keys.Left:
                    aPeatch = aPeatchL;
                    --aPeatchX;
                    break;
                case Keys.Right:
                    aPeatch = aPeatchR;
                    ++aPeatchX;
                    break;
                case Keys.Home:
                    aPeatch = aPeatchF;
                    LoadMap();
                    Refresh();
                    return;
                case Keys.PageUp:
                    NextStage();
                    return;
                case Keys.PageDown:
                    PrevStage();
                    return;
                default:
                    return;
            }
            aPeatchMove(aPeatch);
            Refresh();
            
            if (Endstage) // 게임 끝난으면 출력됨 
            {
                if (MessageBox.Show("다음레벨을 도전하시겠습니까 ?", "게임 클리어 ", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    NextStage();
                }
                else
                {
                    Close();
                }
            }
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            
            Bitmap MapImage;
            Endstage = true; 

            for (int iy = 0; iy < TileYNum; iy++)
            {
                for (int ix = 0; ix < TileXNum ; ++ix)
                {
                    switch (Map[iy][ix])
                    {
                        case '#':
                            MapImage = Wall;
                            break;
                        case ' ':
                            if (Map1[stage,iy][ix] == 'G')
                            {
                                MapImage = Goal;
                                break;
                            }
                            MapImage = Road;
                            break;
                        case '@':
                            MapImage = aPeatch;
                            aPeatchX = ix;
                            aPeatchY = iy;
                            break;
                        case 'B':
                            if (Map1[stage,iy][ix] == 'G')
                            {
                                MapImage = GBox;
                            }
                            else
                            {
                                MapImage = Box;
                                Endstage = false;
                            }
                            break;
                        case 'G':
                            MapImage = Goal;
                            break;
                        default:
                            MapImage = Road;
                            break;
                    }
                    e.Graphics.DrawImage(MapImage, ix * MapImage.Width, iy * MapImage.Height);
                }
            }

            Text = string.Format($"소코반 : [{KeyCount}]");
        }

    }
}

'공부,일 > C#' 카테고리의 다른 글

enum 열거형 다중지정 방식  (0) 2021.06.10
210608  (0) 2021.06.08
210607  (0) 2021.06.07
window forms  (0) 2021.06.04
210604  (0) 2021.06.04

댓글