游戏开始界面

游戏开始

共有两条蛇,吃到红色食物加1分,吃到绿色毒食物减1分,知道0不减;

碰到墙壁游戏结束,碰到对方游戏结束,碰到自己游戏结束

此游戏通过Canvas画布布局,通过C#代码实现

游戏主界面大小为1200*1000
<Window x:Class="贪吃蛇__.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:贪吃蛇__"
mc:Ignorable="d"
Title="贪吃蛇" Loaded="Window_Loaded" Height="700" Width="900">
<Canvas Name="BG" Width = "1200" Height = "1000"></Canvas>
</Window>
全局声明:
       Random ran = new Random();// 随机对象
int size = 20; // 边框距离BG距离,格子数
Canvas gameArea = new Canvas(); // 游戏区对象
Border food = new Border(); //食物对象
Border dufood = new Border(); // 毒食物对象
List<Border> snakeList1 = new List<Border>(); // 存储蛇1的泛型
List<Border> snakeList2 = new List<Border>(); // 存储蛇2的泛型
DispatcherTimer moveTimer1 = new DispatcherTimer(); // 蛇1移动定时器
DispatcherTimer moveTimer2 = new DispatcherTimer(); // 蛇2移动定时器
SoundPlayer EatFm = new SoundPlayer(@"../../music/EatFood.wav"); // 吃食物音乐
SoundPlayer EatDuFm = new SoundPlayer(@"../../music/EatDufood.wav");// 吃毒食物音乐
SoundPlayer Overm = new SoundPlayer(@"../../music/Over.wav"); // 游戏结束音乐
SoundPlayer BGm = new SoundPlayer(@"../../music/BGmusic.wav"); // 背景音乐
int score = 0; //记录分数
Label feng = new Label(); // 分数对象
bool Pand = true; // 游戏开始和暂停判断
加载事件:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.Background = Brushes.Cyan;
this.WindowState = WindowState.Maximized; // 屏幕最大化
BG.Background = new LinearGradientBrush(Colors.Yellow, Colors.Pink, 10);
// 边框
Border bianKuang = new Border();
bianKuang.Width = 1040;
bianKuang.Height = 840;
Canvas.SetLeft(bianKuang, size);
Canvas.SetTop(bianKuang, size);
bianKuang.BorderThickness = new Thickness(20); // 边框厚度
bianKuang.CornerRadius = new CornerRadius(10); // 画圆
bianKuang.BorderBrush = Brushes.Green;
BG.Children.Add(bianKuang);
Image map = new Image();
map.Source = new BitmapImage(new Uri("../../img/BGimg.png",UriKind.Relative));
ImageBrush mp = new ImageBrush();
mp.ImageSource = map.Source; // 显示图片 // 游戏区
gameArea.Width = 1000;
gameArea.Height = 800;
gameArea.Background = mp;
mp.Stretch = Stretch.Fill;
Canvas.SetLeft(gameArea, 2 * size);
Canvas.SetTop(gameArea, 2 * size);
BG.Children.Add(gameArea);
// 得分对象
feng.Width = 120;
feng.Height = 50;
Canvas.SetLeft(feng, 1060);
Canvas.SetTop(feng, 100);
feng.Background = Brushes.Coral;
feng.Foreground = Brushes.DeepSkyBlue;
feng.FontFamily = new FontFamily("楷体");
feng.Content = " 得分:" + score + "分";
feng.FontSize = 20;
BG.Children.Add(feng);
// 蛇1移动定时器
moveTimer1.Tick += MoveTimer1_Tick; ;
moveTimer1.Interval = TimeSpan.FromMilliseconds(100);
// 蛇2移动定时器
moveTimer2.Tick += MoveTimer2_Tick;
moveTimer2.Interval = TimeSpan.FromMilliseconds(100);
// 开始按钮
Button Kaise = new Button();
Kaise.Cursor = Cursors.Hand; // 鼠标移动到按钮处变成手型
Kaise.Width = 120;
Kaise.Height = 50;
Canvas.SetLeft(Kaise, 1060);
Canvas.SetTop(Kaise, 160);
Kaise.Content = "开始游戏";
Kaise.FontFamily = new FontFamily("楷体");
Kaise.BorderBrush = Brushes.Cyan; // 边框颜色
Kaise.Foreground = Brushes.DarkRed; // 字体颜色
Kaise.FontSize = 20;
Kaise.Background = Brushes.DarkKhaki;
Kaise.Click += Kaise_Click;
BG.Children.Add(Kaise);
// 暂停按钮
Button Zanting = new Button();
Zanting.Cursor = Cursors.Hand; // 鼠标移动到按钮处变为手型
Zanting.Width = 120;
Zanting.Height = 50;
Canvas.SetLeft(Zanting, 1060);
Canvas.SetTop(Zanting, 220);
Zanting.Content = "暂停游戏";
Zanting.FontFamily = new FontFamily("楷体");
Zanting.BorderBrush = Brushes.Cyan;
Zanting.Foreground = Brushes.DarkRed;
Zanting.FontSize = 20;
Zanting.Background = Brushes.BurlyWood;
Zanting.Click += Zanting_Click;
BG.Children.Add(Zanting);
// 背景音乐播放
BGm.Play();
}
开启游戏按钮
// 开启游戏
private void Kaise_Click(object sender, RoutedEventArgs e)
{
BGm.Stop(); // 背景音乐停止
this.KeyDown += MainWindow_KeyDown;
if (Pand == true)
{
CreateSnake1(); // 生成蛇1方法
CreateSnake2(); // 生成蛇2方法
CreateFood(); // 生成食物
CReateDufood();// 生成毒食物
}
moveTimer1.Start(); // 蛇1移动
moveTimer2.Start();// 蛇2移动
Pand = false;
}
暂停按钮
        // 暂停游戏
private void Zanting_Click(object sender, RoutedEventArgs e)
{
this.KeyDown -= MainWindow_KeyDown;
moveTimer1.Stop(); // 蛇1移动
moveTimer2.Stop();// 蛇2移动
Pand = false;
}
创建食物方法:
// 创建食物
private void CreateFood()
{
food.Width = food.Height = size;
food.Background = Brushes.Red;
food.CornerRadius = new CornerRadius(20);
Canvas.SetLeft(food, ran.Next(1, 50) * size);
Canvas.SetTop(food, ran.Next(1, 40) * size);
// 判断食物在蛇位置上
for (int i = 0; i < snakeList1.Count; i++)
{
for (int j = 0; j < snakeList2.Count; j++)
{
if (Canvas.GetLeft(food)==Canvas.GetLeft(snakeList1[i])&&Canvas.GetTop(food)==Canvas.GetTop(snakeList1[i])||Canvas.GetLeft(food)==Canvas.GetLeft(snakeList2[j])&&Canvas.GetTop(food)==Canvas.GetTop(snakeList2[j]))
{
Canvas.SetLeft(food, ran.Next(1, 50) * size);
Canvas.SetTop(food, ran.Next(1, 40) * size);
}
}
}
gameArea.Children.Add(food);
}
创建毒食物方法:
 // 创建毒食物
private void CReateDufood()
{
dufood.Width = dufood.Height = size;
dufood.Background = Brushes.GreenYellow;
dufood.CornerRadius = new CornerRadius(20);
Canvas.SetLeft(dufood, ran.Next(1, 50) * size);
Canvas.SetTop(dufood, ran.Next(1, 40) * size);
// 毒食物与食物位置重合
if (Canvas.GetLeft(dufood)==Canvas.GetLeft(food)&&Canvas.GetTop(dufood)==Canvas.GetTop(food))
{
Canvas.SetLeft(dufood, ran.Next(1, 50) * size);
Canvas.SetTop(dufood, ran.Next(1, 40) * size);
}
// 毒食物在蛇身上
for (int i = 0; i < snakeList1.Count; i++)
{
for (int j = 0; j < snakeList2.Count; j++)
{ if (Canvas.GetLeft(dufood) == Canvas.GetLeft(snakeList1[i]) && Canvas.GetTop(dufood) == Canvas.GetTop(snakeList1[i]) || Canvas.GetLeft(dufood) == Canvas.GetLeft(snakeList2[j]) && Canvas.GetTop(dufood) == Canvas.GetTop(snakeList2[j]))
{
Canvas.SetLeft(dufood, ran.Next(1, 50) * size);
Canvas.SetTop(dufood, ran.Next(1, 40) * size);
}
}
}
gameArea.Children.Add(dufood);
}
蛇1创建方法:
 // 创建蛇1方法
private void CreateSnake1()
{
int lenght = 4; // 默认蛇长度
for (int i = 0; i < lenght; i++)
{
Border sna1 = new Border(); // 蛇对象
sna1.Width = sna1.Height = size; // 蛇宽度,高度
sna1.Tag = "Right";// 默认方法存储到Tag中
if (i == 0)
{
sna1.Background = Brushes.Thistle;
}
else
{
sna1.Background = Brushes.Purple;
}
Canvas.SetLeft(sna1, gameArea.Width / 2 - (size * i));
Canvas.SetTop(sna1, gameArea.Height / 2);
sna1.CornerRadius = new CornerRadius(20);
gameArea.Children.Add(sna1);
snakeList1.Add(sna1);
}
}
蛇2创建方法:
// 创建蛇2方法
private void CreateSnake2()
{
int length = 4;
for (int i = 0; i < length; i++)
{
Border sna2 = new Border();
sna2.Width = sna2.Height = size;
sna2.Tag = "Left";
if (i == 0)
{
sna2.Background = Brushes.Thistle;
}
else
{
sna2.Background = Brushes.Orange;
}
sna2.CornerRadius = new CornerRadius(20);
Canvas.SetLeft(sna2, gameArea.Width / 2 + (i * size));
Canvas.SetTop(sna2, gameArea.Width / 2);
gameArea.Children.Add(sna2);
snakeList2.Add(sna2); }
}
蛇1移动
// 蛇1移动定时器
private void MoveTimer1_Tick(object sender, EventArgs e)
{
for (int i = 0; i < snakeList1.Count; i++)
{
if (snakeList1[i].Tag.ToString() == "Right") // 向右移动
{
Canvas.SetLeft(snakeList1[i], Canvas.GetLeft(snakeList1[i]) + size);
}
else if (snakeList1[i].Tag.ToString() == "Left") // 向左移动
{
Canvas.SetLeft(snakeList1[i], Canvas.GetLeft(snakeList1[i]) - size);
}
else if (snakeList1[i].Tag.ToString() == "Up") // 向上移动
{
Canvas.SetTop(snakeList1[i], Canvas.GetTop(snakeList1[i]) - size);
}
else if (snakeList1[i].Tag.ToString() == "Down") // 向下移动
{
Canvas.SetTop(snakeList1[i], Canvas.GetTop(snakeList1[i]) + size);
}
}
for (int i = snakeList1.Count - 1; i > 0; i--)
{
// 蛇身跟随蛇头,占蛇头位置
snakeList1[i].Tag = snakeList1[i - 1].Tag;
}
// 蛇碰到墙
if (Canvas.GetTop(snakeList1[0]) <= -1 || Canvas.GetTop(snakeList1[0]) == gameArea.Height || Canvas.GetLeft(snakeList1[0]) <= -1 || Canvas.GetLeft(snakeList1[0]) == gameArea.Width)
{
GameOver();
}
// 蛇1碰到蛇2
for (int x = 0; x < snakeList2.Count; x++)
{
if (Canvas.GetLeft(snakeList1[0]) == Canvas.GetLeft(snakeList2[x]) && Canvas.GetTop(snakeList1[0]) == Canvas.GetTop(snakeList2[x]))
{
GameOver();
}
}
// 吃到食物
if ( snakeList1.Count>0&&Canvas.GetTop(snakeList1[0]) == Canvas.GetTop(food) && Canvas.GetLeft(snakeList1[0]) == Canvas.GetLeft(food))
{
gameArea.Children.Remove(food); //删除吃的食物
CreateFood(); // 重新创建食物
EatFm.Play(); // 吃食物的音乐
//新创建的蛇身
Border Slimuse = new Border();//增添蛇身
Slimuse.Width = Slimuse.Height = size;
Slimuse.Tag = " ";
Slimuse.Background = Brushes.Purple;
Slimuse.CornerRadius = new CornerRadius(20); // 变圆
Canvas.SetLeft(Slimuse, Canvas.GetLeft(snakeList1[snakeList1.Count - 1])); // 获取到蛇尾的Left位置
Canvas.SetTop(Slimuse, Canvas.GetTop(snakeList1[snakeList1.Count - 1])); // 获取到蛇尾的Top位置
gameArea.Children.Add(Slimuse);
snakeList1.Add(Slimuse);
score++;
feng.Content = " 得分:" + score + "分";
}
//吃到毒食物
if (snakeList1.Count > 0 && Canvas.GetTop(snakeList1[0]) == Canvas.GetTop(dufood) && Canvas.GetLeft(snakeList1[0]) == Canvas.GetLeft(dufood))
{
EatDuFm.Play(); // 吃毒食物音乐
gameArea.Children.Remove(dufood);// 删掉吃的毒食物
CReateDufood(); // 重新创建毒食物
if (score > 0)
{
score--;
feng.Content = " 得分:" + score + "分";
}
gameArea.Children.Remove(snakeList1[snakeList1.Count - 1]); // 清除蛇身最后一节
snakeList1.Remove(snakeList1[snakeList1.Count - 1]); // 清除集合最后一节
}
// 蛇头碰到蛇身体
for (int i = 1; i < snakeList1.Count; i++)
{
// 蛇头碰到蛇身
if (Canvas.GetTop(snakeList1[0]) == Canvas.GetTop(snakeList1[i]) && Canvas.GetLeft(snakeList1[0]) == Canvas.GetLeft(snakeList1[i]))
{
GameOver();
}
}
}
蛇2移动
// 蛇2移动定时器
private void MoveTimer2_Tick(object sender, EventArgs e)
{
for (int i = 0; i < snakeList2.Count; i++)
{
if (snakeList2[i].Tag.ToString() == "Left") // 向左移动
{
Canvas.SetLeft(snakeList2[i], Canvas.GetLeft(snakeList2[i]) - size);
}
else if (snakeList2[i].Tag.ToString() == "Right") // 向右移动
{
Canvas.SetLeft(snakeList2[i], Canvas.GetLeft(snakeList2[i]) + size);
}
else if (snakeList2[i].Tag.ToString() == "Up") // 向上
{
Canvas.SetTop(snakeList2[i], Canvas.GetTop(snakeList2[i]) - size);
}
else if (snakeList2[i].Tag.ToString() == "Down") // 向下
{
Canvas.SetTop(snakeList2[i], Canvas.GetTop(snakeList2[i]) + size);
}
}
for (int i = snakeList2.Count - 1; i > 0; i--)
{
// 蛇身跟随蛇头移动
snakeList2[i].Tag = snakeList2[i - 1].Tag;
} // 蛇2碰到墙
if (Canvas.GetLeft(snakeList2[0]) <= -1 || Canvas.GetLeft(snakeList2[0]) >= gameArea.Width || Canvas.GetTop(snakeList2[0]) <= -1 || Canvas.GetTop(snakeList2[0]) >= gameArea.Height)
{
GameOver();// 调用游戏结束方法
}
// 蛇2碰到蛇1
for (int x = 0; x < snakeList1.Count; x++)
{
if (Canvas.GetLeft(snakeList2[0]) == Canvas.GetLeft(snakeList1[x]) && Canvas.GetTop(snakeList2[0]) == Canvas.GetTop(snakeList1[x]))
{
GameOver();// 调用游戏结束方法
}
}
// 吃到食物
if (snakeList2.Count>0&& Canvas.GetLeft(snakeList2[0]) == Canvas.GetLeft(food) && Canvas.GetTop(snakeList2[0]) == Canvas.GetTop(food))
{
gameArea.Children.Remove(food); // 删除食物
CreateFood(); // 创建新食物
EatFm.Play();// 吃食物音乐
Border Slom = new Border();// 添加的蛇身 创建新蛇身
Slom.Tag = " ";
Slom.Width = Slom.Height = size;
Slom.Background = Brushes.Orange;
Slom.CornerRadius = new CornerRadius(20);
Canvas.SetLeft(Slom, Canvas.GetLeft(snakeList2[snakeList2.Count - 1]));
Canvas.SetTop(Slom, Canvas.GetTop(snakeList2[snakeList2.Count - 1]));
snakeList2.Add(Slom);
gameArea.Children.Add(Slom);
score++;
feng.Content = " 得分:" + score + "分";
}
// 吃到毒食物
if (snakeList2.Count > 0&&Canvas.GetLeft(snakeList2[0])==Canvas.GetLeft(dufood)&&Canvas.GetTop(snakeList2[0])==Canvas.GetTop(dufood))
{
EatDuFm.Play(); // 吃毒食物音乐
gameArea.Children.Remove(dufood); // 消除毒食物
CReateDufood(); // 创建新毒食物
if (score>0)
{
score--;
feng.Content = " 得分:" + score + "分";
}
gameArea.Children.Remove(snakeList2[snakeList2.Count - 1]);
snakeList2.Remove(snakeList2[snakeList2.Count - 1]);
}
// 蛇头碰到蛇身
for (int i = 1; i < snakeList2.Count; i++)
{
if (Canvas.GetLeft(snakeList2[0]) == Canvas.GetLeft(snakeList2[i]) && Canvas.GetTop(snakeList2[0]) == Canvas.GetTop(snakeList2[i]))
{
GameOver();// 调用游戏结束方法
}
}
}
游戏结束方法:
// 游戏结束方法
private void GameOver()
{
this.KeyDown -= MainWindow_KeyDown;
moveTimer1.Stop();
moveTimer2.Stop();
gameArea.Children.Clear(); // 清除游戏区子级
// Overm.Play(); // 游戏结束音乐
MessageBoxResult Out = MessageBox.Show("游戏结束,得分为:" + score + ",是否重新开始游戏", "游戏结束", MessageBoxButton.YesNo, MessageBoxImage.Asterisk);
if (Out == MessageBoxResult.Yes)
{
snakeList1.Clear(); // 清除存储蛇1的泛型
snakeList2.Clear(); // 清除存储蛇2的泛型
Pand = true;
score = 0;
feng.Content = " 得分:" + score + "分";
}
else
{
this.Close();
}
}
键盘事件
// 键盘事件
private void MainWindow_KeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Left:
snakeList1[0].Tag = "Left";
break;
case Key.Right:
snakeList1[0].Tag = "Right";
break;
case Key.Up:
snakeList1[0].Tag = "Up";
break;
case Key.Down:
snakeList1[0].Tag = "Down";
break;
case Key.A:
snakeList2[0].Tag = "Left";
break;
case Key.D:
snakeList2[0].Tag = "Right";
break;
case Key.W:
snakeList2[0].Tag = "Up";
break;
case Key.S:
snakeList2[0].Tag = "Down";
break;
default:
break;
}
}

基于C# WPF框架的贪吃蛇的更多相关文章

  1. 基于NABCD评论探路者团队贪吃蛇作品及改进建议

    1.根据(不限于)NABCD评论作品的选题 N:随着人们生活压力越来越大,需要去去缓解压力,并且也需要不断进步,学习英语知识. A:它是基于java开发的一款软件,采用逐个吃字母,加长蛇身,增强记忆的 ...

  2. 基于spec评论作品 - 探路者 贪吃蛇

    基于spec评论作品,试用(并截图)所有其他小组的Alpha作品,与软件功能说明书对比,评论Alpha作品对软件功能说明书的实现. 首先通过命令行进入到游戏主页面中. 因为软件没有编译为exe程序,所 ...

  3. 基于C#WPF框架——动画

    WPF提供了一个更高级的模型,通过该模型可以只关注动画的定义,而不必考虑它们的渲染方式.这个模型基于依赖项属性基础架构.本质上,WPF动画只不过是在一段时间间隔内修染方式.这个模型基于依赖项属性基础架 ...

  4. 小项目特供 贪吃蛇游戏(基于C语言)

    C语言写贪吃蛇本来是打算去年暑假写的,结果因为ACM集训给耽搁了,因此借寒假的两天功夫写了这个贪吃蛇小项目,顺带把C语言重温了一次. 是发表博客的前一天开始写的,一共写了三个版本,第一天写了第一版,第 ...

  5. AI贪吃蛇前瞻——基于Dijkstra算法的最短路径问题

    在贪吃蛇流程结构优化之后,我又不满足于亲自操刀控制这条蠢蠢的蛇,干脆就让它升级成AI,我来看程序自己玩,哈哈. 一.Dijkstra算法原理 作为一种广为人知的单源最短路径算法,Dijkstra用于求 ...

  6. 基于React的贪吃蛇游戏的设计与实现

    代码地址如下:http://www.demodashi.com/demo/11818.html 贪吃蛇小游戏(第二版) 一年半前层用react写过贪吃蛇小游戏https://github.com/ca ...

  7. 一个基于Net Core3.0的WPF框架Hello World实例

    目录 一个基于Net Core3.0的WPF框架Hello World实例 1.创建WPF解决方案 1.1 创建Net Core版本的WPF工程 1.2 指定项目名称,路径,解决方案名称 2. 依赖库 ...

  8. 基于AT89C51单片机的贪吃蛇电子游戏(仿真)

    有关贪吃蛇的历史发展可以看一下这个网址,贪吃蛇最初的设计和现在并不相同..http://www.techweb.com.cn/internet/2013-02-21/1278055.shtml 该项目 ...

  9. 基于EasyX库的贪吃蛇游戏——C语言实现

    接触编程有段时间了,一直想学习怎么去写个游戏来练练手.在看了B站上的教学终于可以自己试试怎么实现贪吃蛇这个游戏了.好了,废话不多说,我们来看看如何用EasyX库来实现贪吃蛇. 一.准备 工具vc++6 ...

随机推荐

  1. 扛把子 选题 Scrum立会报告+燃尽图 03

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/8680 一.小组情况组长:迟俊文组员:宋晓丽 梁梦瑶 韩昊 刘信鹏队名:扛 ...

  2. .NET Core 3.0 使用Nswag生成Api文档和客户端代码

    摘要 在前后端分离.Restful API盛行的年代,完美的接口文档,成了交流的纽带.在项目中引入Swagger (也称为OpenAPI),是种不错的选择,它可以让接口数据可视化.下文将会演示 利用N ...

  3. AppBoxFuture: 集成第三方Sql数据库

      框架设计之初是不准备支持第三方数据库的,但最近几个朋友都提到需要将旧的基于传统Sql数据库的应用迁移到框架内,主要是考虑到一方面目前框架内置的分布式数据库尚未完善,另一方面是希望能逐步迭代旧应用替 ...

  4. 探索 IPv6 网络

    目录 0x00 前言 0x01 探索 服务器配置 IPv6 地址 服务器部署网络代理 客户端配置网络代理 测试访问 IPv6 地址 给博客添加 IPv6 地址 0x00 前言 IPv4 地址枯竭的事情 ...

  5. 并发编程--greenlet与gevent

    什么是greenlet? 虽然CPython(标准Python)能够通过生成器来实现协程,但使用起来还并不是很方便. 与此同时,Python的一个衍生版 Stackless Python实现了原生的协 ...

  6. JavaScript算法实现之汉诺塔(Hanoi)

    目前前端新手,看到的不喜勿喷,还望大神指教. 随着Node.js,Angular.js,JQuery的流行,点燃了我学习JavaScript的热情!以后打算每天早上跟晚上抽2小时左右时间将经典的算法都 ...

  7. 【Android - 组件】之Activity生命周期的全面分析

    Activity是Android四大组件之首,其重要性不言而喻,Activity的生命周期更是我们了解Android工作机制的重中之重.我们一般将Activty的生命周期做两种情况下的理解,即正常情况 ...

  8. 使用 Flask 和 Vue.js 来构建全栈单页应用

    在这个教程中,我将向你展示如何将 Vue 的单页面应用和 Flask 后端连接起来. 简单的来说,如果想在 Flask 中使用 Vue 框架是没有什么问题的. 但在实际中存在一个明显的问题就是 Fla ...

  9. PHP 获取服务器详细信息的原生方法

    获取系统类型及版本号:    php_uname()     (例:Windows NT PCA15130 6.1 build 7601 (Windows 7 Ultimate Edition Ser ...

  10. 10个常见的HTTP状态码

    目录 500 内部服务器错误 404 文件未找到 403 禁止访问 400 错误请求 401 未经授权 200 请求成功 206 部分内容 301 永久重定向 302 临时重定向 502 无效网关 H ...