游戏案例C#飞行棋

飞行棋案例

一.基本方案

游戏规则:

  1. 两个人轮流掷骰子红人和绿人

  2. 投掷出2,4,6点出门,投掷出6点可以在出门后再次投掷行走

  3. 地图长度共100步

  4. 地图中除过普通地板之外,另设六种特殊功能地板

    1. 踩到香蕉皮,退6步

    2. 踩到时空,前进6步

    3. 踩到陷阱,暂停一回合

    4. 踩到星星,可以再投掷一次

    5. 踩到移魂大法,可以做出选择与对方互换位置

    6. 踩到手枪,可以击退对方3步

    7. 踩到大炮,可以直接将对方轰炸回家(需要重新出门)

  5. 如果踩到对方,则对方直接回到起点,

二.游戏策划

  1. 地图面积30*13

  2. 每个格子30像素

  3. 地面的代号=0,普通地板=1,香蕉皮=2,时空=3,陷阱=4,星星=5,大挪移=6,手枪=7

    红人=8,绿人=9

    起点=10,终点=11

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 WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        Panel map = new Panel();
        //这个数组是所有的地板的一个数组,游戏逻辑全部取决于数字数组
        int[] mapList = new int[390];
        //这个数组是所有的图片,根据maplist决定每个元素的内容
        PictureBox[] mapImg = new PictureBox[390];
        const int size = 30;
        //这个数组用来记录所有的路的索引位置
        int[] road = new int[100];
        private void Form1_Load(object sender, EventArgs e)
        {
            this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
            this.BackColor = Color.FloralWhite;
            this.Width = 1300;
            this.Height = 700;
            this.Left = Screen.PrimaryScreen.Bounds.Width / 2 - this.Width / 2;
            this.Top = Screen.PrimaryScreen.Bounds.Height / 2 - this.Height / 2;

            //获取维度
            map.Width = 30 * size;
            map.Height = 13 * size;

            this.Controls.Add(map);
            map.Location = new Point(50, 250);
            map.BorderStyle = BorderStyle.FixedSingle;
            //调用方法
            InitialGame();

            //红色玩家home生成
            redplayHome.Size = new Size(100, 100);
            redplayHome.BackgroundImage = Image.FromFile("../../img/select_circle.png");
            redplayHome.Location = new Point(50, map.Top - 120);
            redplayHome.BackgroundImageLayout = ImageLayout.Stretch;
            this.Controls.Add(redplayHome);

            //绿色玩家home生成
            greenplayHome.Size = new Size(100, 100);
            greenplayHome.BackgroundImage = Image.FromFile("../../img/select_circle.png");
            greenplayHome.Location = new Point(170, map.Top - 120);
            greenplayHome.BackgroundImageLayout = ImageLayout.Stretch;
            this.Controls.Add(greenplayHome);

            //红色玩家生成
            PictureBox redPlayer = new PictureBox();
            redPlayer.Size = new Size(80, 80);
            redPlayer.Image = Image.FromFile("../../img/red.png");
            redPlayer.Location = new Point(10, 10);
            redPlayer.SizeMode = PictureBoxSizeMode.StretchImage;
            redplayHome.Controls.Add(redPlayer);
            redPlayer.BackColor = Color.Transparent;

            //绿色玩家生成
            PictureBox greenPlayer = new PictureBox();
            greenPlayer.Size = new Size(80, 80);
            greenPlayer.Image = Image.FromFile("../../img/green.png");
            greenPlayer.Location = new Point(10, 10);
            greenPlayer.SizeMode = PictureBoxSizeMode.StretchImage;
            greenplayHome.Controls.Add(greenPlayer);
            greenPlayer.BackColor = Color.Transparent;

            //创建游戏步骤框
            msg.Size = new Size(260, 600);
            msg.Location = new Point(map.Right + 20, 50);
            msg.ReadOnly = true;
            this.Controls.Add(msg);

            //生成骰子
            dice.Size = new Size(100, 100);
            dice.Image = Image.FromFile("../../img/roll.png");  
            dice.Location = new Point(msg.Left - 100, 50);
            dice.SizeMode = PictureBoxSizeMode.StretchImage;
            this.Controls.Add(dice);
            //添加骰子鼠标点击事件
            dice.MouseClick += Dice_MouseClick;

            //设置游戏开始弹框
            string startmsg = "请两个人先轮流掷骰子,点大的先行一步,红方先手";
            //步骤框消息记录
            ResultTell(startmsg);
        }
        //玩家home实例化
        Panel redplayHome = new Panel();
        Panel greenplayHome = new Panel();
        //实例化一个 RichTextBox,记录游戏步骤
        RichTextBox msg = new RichTextBox();
        Random r = new Random();

        //记录谁可以投掷
        //索引为0代表红方,索引为1代表绿方
        bool[] whoCan = new bool[2] { true, false };
        //轮流投掷筛子
        private void PlayDice()
        {
            //红方先投掷
            if (whoCan[0])
            {
                startNum[0] = r.Next(1, 7);
                ResultTell(String.Format("红方投掷出【{0}】点", startNum[0]));
                whoCan[0] = !whoCan[0];
            }
            else
            {
                whoCan[0] = !whoCan[0];
            }
            //绿方投掷
            if (whoCan[1])
            {
                startNum[1] = r.Next(1, 7);
                ResultTell(String.Format("绿方投掷出【{0}】点", startNum[1]));
                whoCan[1] = !whoCan[1];
            }
            else
            {
                whoCan[1] = !whoCan[1];
            }
        }
      


        //1.轮流投掷筛子决定谁先出门,//骰子 鼠标点击事件
        private void Dice_MouseClick(object sender, MouseEventArgs e)
        {
            //鼠标点击一次,摇一次骰子
            PlayDice();
            PlayGame();
        }
        //双方投掷出的点数
        int[] startNum = new int[2];
        string[] playName = new string[2] { "红方", "绿方" };
        //记录双方当前的位置
        int[] playPostion = new int[2] { -1, -1 };
        int[] playStand = new int[2] { -1, -1 };
        //游戏逻辑处理部分

        //控制游戏刚开始决定谁先行
        bool start = true;
        private void PlayGame()
        {
            //先判断是否是游戏刚开始比点数确定先行
            if (start)
            {
                OutDoor();
                if (!whoCan[0] && whoCan[1])
                {
                    ResultTell("请绿方投掷");
                }
                else if (whoCan[0] && !whoCan[1])
                {
                    ResultTell("请红方投掷");
                }
            }
            else
            {
                //判断谁这次变成了false上次是谁投掷的
                if (whoCan[0] && !whoCan[1])//绿方
                {
                    PlayeReturnGame(1);
                }
                else if (!whoCan[0] && whoCan[1])//红方
                {
                    PlayeReturnGame(0);
                }
            }
        }
        bool[] reclick = new bool[2] { false, false };
       
        /// <param name="playIndex">双方索引,0是红方,1是绿方</param>
        private void PlayeReturnGame(int playIndex)
        {
            //判断这次执行方的位置还是-1证明没出门,判断能否出门
            if (playPostion[playIndex] == -1)
            {
                switch (startNum[playIndex])
                {
                    //如果投掷出的是2,4则可以出门
                    case 2:
                    case 4:
                        ResultTell(String.Format("{0}可以起步!", playName[playIndex]));
                        playPostion[playIndex] = 0;
                        playStand[playIndex] = 0;
                        if (playPostion[1] == playPostion[0])
                        {
                            mapImg[road[playPostion[playIndex]]].Image = imageList1.Images[2];
                        }
                        else
                        {
                            mapImg[road[playPostion[playIndex]]].Image = imageList1.Images[playIndex];
                        }
                        break;
                    case 6:
                        whoCan[playIndex] = true;
                        whoCan[1 - playIndex] = false;
                        ResultTell(String.Format("{0}可以起步!", playName[playIndex]));
                        playPostion[playIndex] = 0;
                        playStand[playIndex] = 0;
                        if (playPostion[1] == playPostion[0])
                        {
                            mapImg[road[playPostion[playIndex]]].Image = imageList1.Images[2];
                        }
                        else
                        {
                            mapImg[road[playPostion[playIndex]]].Image = imageList1.Images[playIndex];
                        }
                        ResultTell(string.Format("请{0}投掷骰子", playName[playIndex]));
                        break;
                    default:
                        ResultTell(String.Format("很遗憾,{0}投掷出{1}点无法起步!轮到{2}投掷", playName[playIndex], startNum[playIndex], playName[1 - playIndex]));
                        break;
                }
                if (playPostion[0] != -1)//红色出门
                {
                    redplayHome.Controls.Clear();
                }
                if (playPostion[1] != -1)
                {
                    greenplayHome.Controls.Clear();
                }
            }
            else//出门之后,按照你的点数计算位置
            {
                //在其位置改变之前记录好原本站立的位置索引
                playStand[playIndex] = playPostion[playIndex];
                playPostion[playIndex] += startNum[playIndex];
                if (playPostion[playIndex] >= 99)
                {
                    MessageBox.Show(playName[playIndex] + "获胜!");
                    playPostion[playIndex] = 99;
                    ChangeImg(playIndex);
                    return;
                }
                ResultTell(string.Format("{0}移动{1}步", playName[playIndex], startNum[playIndex]));
                ChangeImg(playIndex);

                //判断移动完成之后的位置是如何
                if (playPostion[playIndex] == playPostion[1 - playIndex])
                {
                    playPostion[1 - playIndex] = 0;
                    playStand[1 - playIndex] = playPostion[1 - playIndex];
                    ResultTell(string.Format("厉害!{0}精准踩到{1}将其踩回原点!{0}当前位置是{2},{1}当前的位置是{3}", playName[playIndex], playName[1 - playIndex], playPostion[playIndex], playPostion[1 - playIndex]));
                    mapImg[road[playPostion[playIndex]]].Image = imageList1.Images[playIndex];
                    mapImg[road[playPostion[1 - playIndex]]].Image = imageList1.Images[1 - playIndex];
                    ResultTell(string.Format("{0}开始投掷。", playName[1 - playIndex]));
                }

                switch (mapList[road[playPostion[playIndex]]])
                {
                    case 1:
                        ResultTell(string.Format("{0}安全到达!当前位置是{1}", playName[playIndex], playPostion[playIndex]));
                        ResultTell(string.Format("{0}开始投掷。", playName[1 - playIndex]));
                        break;
                    case 2:
                        if (playPostion[playIndex]>=6&&playPostion[playIndex]>=6)
                        {
                        ResultTell(string.Format("很不幸,{0}踩中香蕉皮,后退6步!当前位置是{1}", playName[playIndex], playPostion[playIndex]));
                        playStand[playIndex] = playPostion[playIndex];
                        playPostion[playIndex] -= 6;
                        ChangeImg(playIndex);
                        ResultTell(string.Format("{0}当前位置是{1}", playName[playIndex], playPostion[playIndex]));
                        ResultTell(string.Format("{0}开始投掷。", playName[1 - playIndex]));

                        }
                        else
                        {
                            ResultTell(String.Format("离起点位置小于7,无法被退回"));
                        }
                        break;
                    case 3:
                        ResultTell(string.Format("恭喜!{0}踩中时空隧道,前进6步!当前位置是{1}", playName[playIndex], playPostion[playIndex]));
                        playStand[playIndex] = playPostion[playIndex];
                        playPostion[playIndex] += 6;
                        ChangeImg(playIndex);
                        ResultTell(string.Format("{0}当前位置是{1}", playName[playIndex], playPostion[playIndex]));
                        ResultTell(string.Format("{0}开始投掷。", playName[1 - playIndex]));
                        break;
                    case 4:
                        ResultTell(string.Format("可惜!{0}踩中陷阱,暂停一回合!", playName[playIndex]));
                        //0=false  1=true;  0踩中了4
                        //下一回合0不能执行
                        reclick[1 - playIndex] = true;
                        reclick[playIndex] = false;
                        break;
                    case 5:
                        ResultTell(string.Format("真好!{0}踩中幸运星,再玩一回合!当前位置是{1}", playName[playIndex], playPostion[playIndex]));
                        whoCan[playIndex] = true;
                        whoCan[1 - playIndex] = false;
                        ResultTell(string.Format("{0}继续投掷。", playName[playIndex]));
                        break;
                    case 6:
                        if (playStand[0] != -1 && playStand[1] != -1)
                        {
                            ResultTell(string.Format("真好!{0}踩中秘籍,请选择措施!当前位置是{1}", playName[playIndex], playPostion[playIndex]));
                            DialogResult dr = MessageBox.Show("是否选择与对方更换位置!", "移魂大法!", MessageBoxButtons.YesNo);
                            if (dr == DialogResult.Yes)
                            {

                                int temp = playPostion[playIndex];
                                playPostion[playIndex] = playPostion[1 - playIndex];
                                playPostion[1 - playIndex] = temp;
                                playStand[playIndex] = playPostion[playIndex];
                                playStand[1 - playIndex] = playPostion[1 - playIndex];
                                mapImg[road[playPostion[playIndex]]].Image = imageList1.Images[playIndex];
                                mapImg[road[playPostion[1 - playIndex]]].Image = imageList1.Images[1 - playIndex];
                            }
                            ResultTell(string.Format("{0}当前位置是{1},{2}的位置是{3}", playName[playIndex], playPostion[playIndex], playName[1 - playIndex], playPostion[1 - playIndex]));
                            ResultTell(string.Format("{0}开始投掷。", playName[1 - playIndex]));

                        }
                        else
                        {
                            ResultTell(string.Format("对方飞机还没出门,不能交换位置"));
                        }
                        break;
                    case 7:
                        if (playPostion[playIndex]>=3&&playStand[1-playIndex]>=3)
                        {
                            ResultTell(string.Format("幸运!{0}获得手枪,可选择击退对方3步!当前位置是{1}", playName[playIndex], playPostion[playIndex]));
                            DialogResult re = MessageBox.Show("是否选择击退对方三步!", "手枪!", MessageBoxButtons.YesNo);
                            if (re == DialogResult.Yes)
                            {
                                playStand[1 - playIndex] = playPostion[1 - playIndex];
                                playPostion[1 - playIndex] -= 3;
                                mapImg[road[playPostion[1 - playIndex]]].Image = imageList1.Images[1 - playIndex];
                                ChangeImg(1 - playIndex);
                            }
                            ResultTell(string.Format("{0}被击退对方3步!当前位置是{1}", playName[1 - playIndex], playPostion[1 - playIndex]));
                            ResultTell(string.Format("{0}开始投掷。", playName[1 - playIndex]));
                        }
                        else
                        {
                            ResultTell(string.Format("一方飞机离起点位置小于三,无法被击退"));
                        }
                            break;
                    default:
                        break;
                }
                //判断对方现在处于暂停回合状态
                if (reclick[playIndex] && !reclick[1 - playIndex])
                {
                    whoCan[playIndex] = true;
                    whoCan[1 - playIndex] = false;
                    reclick[playIndex] = false;
                    reclick[1 - playIndex] = false;
                }
            }
        }

        private void ChangeImg(int playIndex)
        {
            //如果某个玩家移动完成之后在同一位置
            if (playPostion[1] == playPostion[0])
            {
                mapImg[road[playPostion[playIndex]]].Image = imageList1.Images[2];
            }
            else//移动完成之后显示对应的玩家图片
            {
                mapImg[road[playPostion[playIndex]]].Image = imageList1.Images[playIndex];
            }

            //原本位置的图片显示,如果原来两人在同一个位置站着,并且都在路上,自己移动离开之后,留下对方的图片还在原地
            if (playStand[0] == playStand[1] && playStand[0] != -1 && playStand[1] != -1 && playPostion[1 - playIndex] == 0)
            {
                mapImg[road[playStand[playIndex]]].Image = imageList1.Images[1 - playIndex];
                mapImg[road[playPostion[playIndex]]].Image = imageList1.Images[playIndex];
            }
            else//如果两人原来不在同一个位置
            {
                //判断原来脚下站的格子是什么
                switch (mapList[road[playStand[playIndex]]])
                {
                    case 0:
                        mapImg[road[playStand[playIndex]]].Image = Image.FromFile("../../img/water.gif");
                        break;
                    case 1:
                        mapImg[road[playStand[playIndex]]].Image = Image.FromFile("../../img/floor.png");
                        break;
                    case 2:
                        mapImg[road[playStand[playIndex]]].Image = Image.FromFile("../../img/xj.jpg");
                        break;
                    case 3:
                        mapImg[road[playStand[playIndex]]].Image = Image.FromFile("../../img/sk.jpg");
                        break;
                    case 4:
                        mapImg[road[playStand[playIndex]]].Image = Image.FromFile("../../img/xianjing.jpg");
                        break;
                    case 5:
                        mapImg[road[playStand[playIndex]]].Image = Image.FromFile("../../img/xx.jpg");
                        break;
                    case 6:
                        mapImg[road[playStand[playIndex]]].Image = Image.FromFile("../../img/jh.jpg");
                        break;
                    case 7:
                        mapImg[road[playStand[playIndex]]].Image = Image.FromFile("../../img/sq.jpg");
                        break;
                    case 10:
                        mapImg[road[playStand[playIndex]]].Image = Image.FromFile("../../img/start.png");
                        break;
                    case 11:
                        mapImg[road[playStand[playIndex]]].Image = Image.FromFile("../../img/end.bmp");
                        break;
                    case 12:
                        mapImg[road[playStand[playIndex]]].Image = Image.FromFile("../../img/double.jpg");
                        break;
                }
            }
        }

        //决定游戏谁先手
        private void OutDoor()
        {
            //满足这种情况两人投掷完成一个回合
            //0=true,1=false
            if (whoCan[0] && !whoCan[1] && (startNum[0] != 0 || startNum[1] != 0))
            {
                if (startNum[0] == startNum[1])
                {
                    ResultTell("双方点数相同,请重新投掷!");
                }
                else
                {
                    start = false;
                    if (startNum[0] > startNum[1])
                    {
                        ResultTell("红方点数较大,先行一步,红方投掷");
                        whoCan[0] = true;
                        whoCan[1] = false;
                    }
                    else
                    {
                        ResultTell("绿方点数较大,先行一步,绿方投掷");
                        whoCan[0] = false;
                        whoCan[1] = true;
                    }
                }
            }
        }
        //实例化一个骰子
        PictureBox dice = new PictureBox();
        //初始化游戏:计算地图,计算道路,计算关卡,并绘制出完整地图
        //创建一个方法,游戏格式化
        void InitialGame()
        {
            //调用方法
            CreateMap();
            CreateGear();
            for (int i = 0; i < mapImg.Length; i++)
            {
                PictureBox picture = new PictureBox();
                picture.Size = new Size(size, size);
                switch (mapList[i])
                {
                    case 0:
                        picture.Image = Image.FromFile("../../img/water.gif");
                        break;
                    case 1:
                        picture.Image = Image.FromFile("../../img/floor.png");
                        break;
                    case 2:
                        picture.Image = Image.FromFile("../../img/xj.jpg");
                        break;
                    case 3:
                        picture.Image = Image.FromFile("../../img/sk.jpg");
                        break;
                    case 4:
                        picture.Image = Image.FromFile("../../img/xianjing.jpg");
                        break;
                    case 5:
                        picture.Image = Image.FromFile("../../img/xx.jpg");
                        break;
                    case 6:
                        picture.Image = Image.FromFile("../../img/jh.jpg");
                        break;
                    case 7:
                        picture.Image = Image.FromFile("../../img/sq.jpg");
                        break;
                    case 8:
                        picture.Image = Image.FromFile("../../img/red.png");
                        break;
                    case 9:
                        picture.Image = Image.FromFile("../../img/green.png");
                        break;
                    case 10:
                        picture.Image = Image.FromFile("../../img/start.png");
                        break;
                    case 11:
                        picture.Image = Image.FromFile("../../img/end.bmp");
                        break;
                    case 12:
                        picture.Image = Image.FromFile("../../img/double.jpg");
                        break;
                }
                picture.SizeMode = PictureBoxSizeMode.StretchImage;
                picture.Left = i % 30 * size;
                picture.Top = i / 30 * size;
                mapImg[i] = picture;
                map.Controls.Add(picture);
            }
        }
        //创建地图土地
        void CreateMap()
        {
            CreateRoed();
            for (int i = 0; i < road.Length; i++)
            {
                mapList[road[i]] = 1;
            }
            mapList[0] = 10;//起点
            mapList[mapList.Length - 1] = 11;//终点
        }
        //创建道路
        void CreateRoed()
        {
            for (int i = 0; i < 30; i++)//0~29的索引,获取第1~30的地板
            {
                road[i] = i;
            }
            for (int i = 30; i <= 35; i++)//30~35的索引,获取59,89,119,149,179五个地板
            {
                road[i] = road[i - 1] + 30;
            }
            for (int i = 36; i < 65; i++)//*36~64的索引,获取第209~180的地板*/
            {
                road[i] = road[i - 1] - 1;
            }
            for (int i = 65; i <= 70; i++)//65~70的索引,获取240,270,300,330,360,五个地板
            {
                road[i] = road[i - 1] + 30;
            }
            for (int i = 71; i < 100; i++)//71~99的索引,获取第361~389的地板
            {
                road[i] = road[i - 1] + 1;
            }

        }
        //定义机关的位置
        int[] back = {17, 28, 45, 71, 85 };
        int[] forword = { 3, 20, 35, 50, 60, 70, };
        int[] stop = { 90, 25, 33, 65, 80, 88 };
        int[] star = { 7, 27, 42, 62, 73, 96 };
        int[] change = { 11, 32, 66, 83 };
        int[] gun = {  18, 55, 75, 44 };
        //创建关卡,玩的是索引, //创建一个方法提取机关数组
        void CreateGear()
        {
            for (int i = 0; i < back.Length; i++)
            {
                mapList[road[back[i]]] = 2;
            }
            for (int i = 0; i < forword.Length; i++)
            {
                mapList[road[forword[i]]] = 3;
            }
            for (int i = 0; i < stop.Length; i++)
            {
                mapList[road[stop[i]]] = 4;
            }
            for (int i = 0; i < star.Length; i++)
            {
                mapList[road[star[i]]] = 5;
            }
            for (int i = 0; i < change.Length; i++)
            {
                mapList[road[change[i]]] = 6;
            }
            for (int i = 0; i < gun.Length; i++)
            {
                mapList[road[gun[i]]] = 7;
            }
        }

        //每次需要记录本次操作及操作结果时需要调用
        void ResultTell(string str)
        {
            MessageBox.Show(str);
            //步骤框文本换行
            msg.AppendText(str + "\r\n");
        }
    }
}


发布了16 篇原创文章 · 获赞 24 · 访问量 1741

猜你喜欢

转载自blog.csdn.net/Cocksuck/article/details/103456676
今日推荐