• 用C#写的方块赛车


    实际上根据是以前网上流传的VB版本的思路改编的,设计的非常巧妙,本人可没这原创思路。非常短小的一个游戏,将数组玩的得心应手,还包含碰撞检测等等。。。

    下面是我设计的界面:

    别小看它,玩起来难度很大,坚持60秒都难。点我下载!

      1 using System;
      2 using System.Drawing;
      3 using System.Drawing.Drawing2D;
      4 using System.Windows.Forms;
      5 
      6 namespace 方块赛车
      7 {
      8     public partial class Form1 : Form
      9     {
     10         const int Unit = 20;     // 一个方格单元的大小,单位像素
     11         const int Road = 20;     // 跑道的长度,单位方块;路面宽7个方格,小车占用3个
     12         const int Wall = 20;     // 墙的厚度,单位像素
     13         float OriginX;    // 作图的原点X轴坐标,小车位于正中时左下角(车身)的坐标
     14         float OriginY;    // 作图的原点Y轴坐标,也就是跑道最底部y轴的坐标
     15         int[] LeftWay = new int[Road];    // 左边每段跑道的障碍物的大小,也就是方格的数量
     16         int[] RightWay = new int[Road];   // 右边每段跑道的障碍物的大小,也就是方格的数量
     17         float CarX;       // 赛车左下角X轴的坐标(赛车只做水平移动,不需记录Y轴坐标)
     18         int Second;       // 记录已玩秒数
     19         Graphics g;
     20         Random random = new Random();
     21 
     22         public Form1()
     23         {
     24             InitializeComponent();
     25             g = this.CreateGraphics();
     26             OriginX = (this.ClientSize.Width - 3 * Unit) / 2;
     27             OriginY = Road * Unit;
     28         }
     29 
     30         private void button1_Click(object sender, EventArgs e)
     31         {
     32             this.Refresh();
     33             CarX = OriginX;    // 小车复位
     34             DrawWall();
     35             for (int i = 0; i < Road; i++)    // 障碍复位
     36             {
     37                 LeftWay[i] = 0;
     38                 RightWay[i] = 0;
     39                 DrawWay(i);
     40             }
     41             DrawCar();
     42             Second = 0;
     43             timer1.Enabled = true;
     44             button1.Enabled = false;
     45             checkBox1.Enabled = true;
     46             checkBox1.Focus();
     47             Console.WriteLine(this.CanSelect);    // True
     48             Console.WriteLine(this.Focus());    // False
     49         }
     50 
     51         private void DrawWall()
     52         {
     53             Brush brickBrush = new HatchBrush(HatchStyle.HorizontalBrick, Color.Black, Color.Gray);
     54             Pen penLine = new Pen(brickBrush, Wall);
     55             float x1 = OriginX - 2 * Unit - Wall / 2, x2 = OriginX + 5 * Unit + Wall / 2;
     56             g.DrawLine(penLine, x1, 0, x1, OriginY);    // 画路的左边线
     57             g.DrawLine(penLine, x2, 0, x2, OriginY);    // 画路的右边线
     58         }
     59 
     60         private void DrawCar()    // 车可以不擦,擦跑道的时候就把车全擦了
     61         {
     62             Brush brushCar = Brushes.Green;
     63             g.FillRectangle(brushCar, CarX, OriginY - Unit, 3 * Unit, Unit);    // 车身
     64             g.FillRectangle(brushCar, CarX + Unit, OriginY - 2 * Unit, Unit, Unit);    // 车头
     65         }
     66 
     67         private void DrawWay(int index)    // 画一层跑道(含障碍)
     68         {
     69             SolidBrush brushBack = new SolidBrush(Color.LightGray);
     70             Brush brushWay = Brushes.Black;
     71             float x1 = OriginX - 2 * Unit, x2 = OriginX + 5 * Unit - RightWay[index] * Unit;
     72             float y = OriginY - (index + 1) * Unit;
     73             g.FillRectangle(brushBack, x1, y, 7 * Unit, Unit);    // 擦除所有障碍
     74             g.FillRectangle(brushWay, x1, y, LeftWay[index] * Unit, Unit);    // 画左边障碍
     75             g.FillRectangle(brushWay, x2, y, RightWay[index] * Unit, Unit);    // 画右边障碍
     76         }
     77 
     78         private void timer1_Tick(object sender, EventArgs e)
     79         {
     80             for (int i = 0; i < Road - 1; i++)    // 每一层跑道往下移
     81             {
     82                 LeftWay[i] = LeftWay[i + 1];
     83                 RightWay[i] = RightWay[i + 1];
     84                 DrawWay(i);
     85             }
     86             do
     87             {
     88                 LeftWay[Road - 1] = random.Next(5);    // 最上层的路段设置随机值[0,4]
     89                 RightWay[Road - 1] = random.Next(5);
     90             } while ((LeftWay[Road - 1] + RightWay[Road - 1] > 4) ||
     91                      (LeftWay[Road - 2] + RightWay[Road - 1] > 4) || (LeftWay[Road - 1] + RightWay[Road - 2] > 4) ||
     92                      (LeftWay[Road - 3] + RightWay[Road - 1] > 5) || (LeftWay[Road - 1] + RightWay[Road - 3] > 5));
     93             // 条件必须满足:第一行满足路面能够容纳车身,第二行满足往前走一步时车身能通过;第三行满足往前走一步时车头能通过
     94             DrawWay(Road - 1);
     95             DrawCar();
     96             CrashDetection();
     97             Second = Second + 1;
     98             label1.Text = "时间:" + Second * timer1.Interval / 1000 + "";
     99         }
    100 
    101         private void CrashDetection()
    102         {
    103             Brush brushCrash = Brushes.Yellow;
    104             if (CarX < OriginX - 2 * Unit + LeftWay[0] * Unit)    // 车身左侧发生碰撞
    105             {
    106                 g.FillRectangle(brushCrash, CarX, OriginY - Unit, Unit, Unit);
    107                 GameOver();
    108             }
    109             if (CarX + 3 * Unit > OriginX + 5 * Unit - RightWay[0] * Unit)    // 车身右侧发生碰撞
    110             {
    111                 g.FillRectangle(brushCrash, CarX + 2 * Unit, OriginY - Unit, Unit, Unit);
    112                 GameOver();
    113             }
    114             if (CarX + Unit < OriginX - 2 * Unit + LeftWay[1] * Unit ||       // 车头与左侧障碍发生碰撞
    115                 CarX + 2 * Unit > OriginX + 5 * Unit - RightWay[1] * Unit)    // 车头与右侧障碍发生碰撞
    116             {
    117                 g.FillRectangle(brushCrash, CarX + Unit, OriginY - 2 * Unit, Unit, Unit);
    118                 GameOver();
    119             }
    120         }
    121 
    122         private void GameOver()
    123         {
    124             g.DrawString("Game Over", new Font("微软雅黑", 40), Brushes.Red, 50, 200);
    125             timer1.Enabled = false;
    126             button1.Enabled = true;
    127             checkBox1.Enabled = false;
    128             button1.Focus();
    129         }
    130 
    131         private void Form1_KeyDown(object sender, KeyEventArgs e)
    132         {
    133             Console.WriteLine("KeyCode: {0}", e.KeyCode);    // 因窗体上控件焦点导致箭头键无法使用
    134             if (e.KeyCode == Keys.Left) CarX -= Unit;
    135             if (e.KeyCode == Keys.Right) CarX += Unit;
    136             if (e.KeyCode == Keys.A) CarX -= Unit;
    137             if (e.KeyCode == Keys.D) CarX += Unit;
    138         }
    139 
    140         private void checkBox1_Click(object sender, EventArgs e)
    141         {
    142             timer1.Enabled = !checkBox1.Checked;
    143         }
    144 
    145         private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    146         {
    147             if (comboBox1.SelectedIndex == 0) timer1.Interval = 350;
    148             if (comboBox1.SelectedIndex == 1) timer1.Interval = 250;
    149             if (comboBox1.SelectedIndex == 2) timer1.Interval = 150;
    150         }
    151 
    152         private void Form1_KeyPress(object sender, KeyPressEventArgs e)
    153         {
    154             Console.WriteLine("KeyChar: {0}", e.KeyChar);
    155             e.Handled = true;
    156         }
    157 
    158         // 把窗体上所有子控件的IsInputKey属性设置为true后,箭头键终于可以用了
    159         private void button1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    160         {
    161             e.IsInputKey = true;
    162         }
    163 
    164         private void checkBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    165         {
    166             e.IsInputKey = true;
    167         }
    168     }
    169 }
  • 相关阅读:
    Android开发开源一款结合databinding写的用于RecyclerView的简单高效MultiTypeAdapter
    Android开发databinding和RecyclerView.ViewHolder的完美结合
    Android开发华为手机不弹出Toast,报HwRTBlurUtils: check blur style for HwToast-Toast...的原因
    android开发Toolbar标题居中显示的解决方法
    记录使用xshell通过ssh方式连接Linux机器的步骤
    同一局域网内手机访问电脑本地localhost网页的方法
    Gradle里面的依赖implementation和api的真正理解
    Android开发使用kotlin编写的泛型模式的MVP框架
    nyoj-3-多边形重心问题(求多边形面积和中心)
    nyoj-1132-promise me a medal(求线段交点)
  • 原文地址:https://www.cnblogs.com/chengyb/p/13844261.html
Copyright © 2020-2023  润新知