基于WPF实现用户头像选择器的示例代码

目录
  • 实现思路
  • 核心代码
  • 参考资料

实现思路

制作一个用户头像选择器仿 WeGame

制作一个用户头像选择Canvas为父控件所实现,展示图片使用ImagePath当作上方的蒙版;

Canvas:主要用途方便移动Image,设置ClipToBounds="True"裁剪为一个正方形200x200做为主要展示区域;

Image:展示需要裁剪的图片;

Path:CombinedGeometry[1]绘制蒙版大小200x200效果如下;

当选择一个本地图片的时候判断宽与高谁更大,谁小就将它更改为200 ,另一边做等比缩放后给到DrawingVisual绘制一个新的BitmapFrame[2]给Image控件做展示;

当移动图片的时候右侧展示当前区域使用CroppedBitmap[3]进行裁剪并显示;

源码Github[4] Gitee[5]

核心代码

1)CropAvatar.xaml 代码如下;

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:controls="clr-namespace:WPFDevelopers.Controls">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
    </ResourceDictionary.MergedDictionaries>

    <Style TargetType="controls:CropAvatar" BasedOn="{StaticResource ControlBasicStyle}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type controls:CropAvatar}">
                    <Canvas x:Name="PART_Canvas" ClipToBounds="True">
                        <Image x:Name="PART_Image" Cursor="SizeAll" ></Image>
                        <Path x:Name="PART_Layout" 
                              Fill="{DynamicResource BlackSolidColorBrush}" 
                              Width="200" Height="200" 
                              Opacity=".5">
                            <Path.Data>
                                <CombinedGeometry GeometryCombineMode="Xor">
                                    <CombinedGeometry.Geometry1>
                                        <RectangleGeometry Rect="0,0,200,200"/>
                                    </CombinedGeometry.Geometry1>
                                    <CombinedGeometry.Geometry2>
                                        <EllipseGeometry Center="100,100" RadiusX="100" RadiusY="100"/>
                                    </CombinedGeometry.Geometry2>
                                </CombinedGeometry>
                            </Path.Data>
                        </Path>
                        <Grid x:Name="PART_Grid" Width="200" Height="200">
                            <Button x:Name="PART_ReplaceButton" Style="{StaticResource PathButton}"
                                    HorizontalAlignment="Right"
                                    VerticalAlignment="Top"
                                    Width="40" Height="40" ToolTip="更换图片"
                                    Visibility="Collapsed">
                                <Button.Content>
                                    <Path Data="{StaticResource PathReplace}"
                                          Fill="{StaticResource PrimaryNormalSolidColorBrush}"
                                          Height="15"
                                          Width="15"
                                          Stretch="Fill" />
                                </Button.Content>
                            </Button>
                            <Button x:Name="PART_AddButton" Style="{StaticResource PathButton}"
                                    Width="40" Height="40" ToolTip="选择图片">
                                <Button.Content>
                                    <Path Data="{StaticResource PathAdd}"
                                          Fill="{StaticResource PrimaryNormalSolidColorBrush}"
                                          Height="20"
                                          Width="20"
                                          Stretch="Fill" 
                                          RenderTransformOrigin="0.5,0.5" IsHitTestVisible="False">
                                        <Path.RenderTransform>
                                            <RotateTransform Angle="45"/>
                                        </Path.RenderTransform>
                                    </Path>
                                </Button.Content>
                            </Button>
                        </Grid>
                    </Canvas>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>

2)CropAvatar.cs 代码如下;

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using WPFDevelopers.Helpers;

namespace WPFDevelopers.Controls
{
    [TemplatePart(Name = CanvasTemplateName, Type = typeof(Canvas))]
    [TemplatePart(Name = ImageTemplateName, Type = typeof(Image))]
    [TemplatePart(Name = PathTemplateName, Type = typeof(Path))]
    [TemplatePart(Name = GridTemplateName, Type = typeof(Grid))]
    [TemplatePart(Name = ReplaceButtonTemplateName, Type = typeof(Button))]
    [TemplatePart(Name = AddButtonTemplateName, Type = typeof(Button))]
    public partial class CropAvatar : Control
    {
        private const string CanvasTemplateName = "PART_Canvas";
        private const string ImageTemplateName = "PART_Image";
        private const string PathTemplateName = "PART_Layout";
        private const string GridTemplateName = "PART_Grid";
        private const string ReplaceButtonTemplateName = "PART_ReplaceButton";
        private const string AddButtonTemplateName = "PART_AddButton";
        private Point point;
        private const int _size = 200;
        private bool isDown;
        private bool isLeft;
        private CroppedBitmap crop;
        private Canvas canvas;
        private Image image;
        private Path path;
        private Grid grid;
        private Button replaceButton, addButton;
        private int initialX, initialY, voffsetX, voffsetY;
        private double vNewStartX, vNewStartY, _StartX, _StartY, centerX, centerY;
        private BitmapFrame bitmapFrame;

        public ImageSource OutImageSource
        {
            get { return (ImageSource)GetValue(OutImageSourceProperty); }
            set { SetValue(OutImageSourceProperty, value); }
        }

        public static readonly DependencyProperty OutImageSourceProperty =
            DependencyProperty.Register("OutImageSource", typeof(ImageSource), typeof(CropAvatar), new PropertyMetadata(null));

        static CropAvatar()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CropAvatar), new FrameworkPropertyMetadata(typeof(CropAvatar)));
        }
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            canvas = GetTemplateChild(CanvasTemplateName) as Canvas;
            canvas.Loaded += Canvas_Loaded;
            grid = GetTemplateChild(GridTemplateName) as Grid;
            image = GetTemplateChild(ImageTemplateName) as Image;
            image.MouseDown += Image_MouseDown;
            image.MouseMove += Image_MouseMove;
            image.MouseUp += Image_MouseUp;
            image.MouseLeave += Image_MouseLeave;
            path = GetTemplateChild(PathTemplateName) as Path;
            replaceButton = GetTemplateChild(ReplaceButtonTemplateName) as Button;
            replaceButton.Click += ReplaceButton_Click;
            addButton = GetTemplateChild(AddButtonTemplateName) as Button;
            addButton.Click += AddButton_Click;
        }

        private void Canvas_Loaded(object sender, RoutedEventArgs e)
        {
            if (sender is Canvas canvas)
            {
                var width = canvas.ActualWidth;
                var height = canvas.ActualHeight;
                centerX = (width - path.Width) / 2.0d;
                centerY = (height - path.Height) / 2.0d;
                canvas.Clip = new RectangleGeometry(new Rect(centerX, centerY, 200, 200)); 
                Canvas.SetLeft(path, centerX);
                Canvas.SetTop(path, centerY);
                Canvas.SetLeft(grid, centerX);
                Canvas.SetTop(grid, centerY);
            }
        }

        private void Image_MouseLeave(object sender, MouseEventArgs e)
        {
            isDown = false;
            if (isLeft)
                _StartX = Canvas.GetLeft(image);
            else
                _StartY = Canvas.GetTop(image);
        }

        private void Image_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (isDown)
            {
                var vPoint = e.GetPosition(this);
                if (isLeft)
                {
                    _StartX = Canvas.GetLeft(image);
                    initialX = voffsetX;
                }

                else
                {
                    _StartY = Canvas.GetTop(image);
                    initialY = voffsetY;
                }
            }
        }

        private void Image_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed && isDown)
            {
                var vPoint = e.GetPosition(this);
                if (isLeft)
                {
                    var voffset = vPoint.X - point.X;
                    vNewStartX = _StartX + voffset;
                    var xPath = Canvas.GetLeft(path);
                    if (vNewStartX <= xPath && vNewStartX >= -(bitmapFrame.Width - 200 - xPath))
                    {
                        Canvas.SetLeft(image, vNewStartX);
                        voffsetX = initialX - (int)voffset;
                        voffsetX = voffsetX < 0 ? 0 : voffsetX;
                        crop = new CroppedBitmap(bitmapFrame, new Int32Rect(voffsetX, 0, _size, _size));

                    }
                }
                else
                {
                    var voffset = vPoint.Y - point.Y;
                    vNewStartY = _StartY + voffset;
                    var yPath = Canvas.GetTop(path);
                    if (vNewStartY <= yPath && vNewStartY >= -(bitmapFrame.Height - 200 - yPath))
                    {
                        Canvas.SetTop(image, vNewStartY);
                        voffsetY = initialY - (int)voffset;
                        voffsetY = voffsetY < 0 ? 0 : voffsetY;
                        crop = new CroppedBitmap(bitmapFrame, new Int32Rect(0, voffsetY, _size, _size));
                    }
                }
                OutImageSource = crop;
            }
        }

        private void Image_MouseDown(object sender, MouseButtonEventArgs e)
        {
            isDown = true;
            point = e.GetPosition(this);
        }

        private void ReplaceButton_Click(object sender, RoutedEventArgs e)
        {
            InitialImage();
        }

        private void AddButton_Click(object sender, RoutedEventArgs e)
        {
            InitialImage();
        }

        void InitialImage()
        {
            vNewStartX = 0;
            vNewStartY = 0;
            var uri = ControlsHelper.ImageUri();
            if (uri == null) return;
            var bitmap = new BitmapImage(uri);
            if (bitmap.Height > bitmap.Width)
            {
                double scale = (double)bitmap.Width / (double)path.Width;
                image.Width = _size;
                image.Height = (double)bitmap.Height / scale;
                isLeft = false;
            }
            else if (bitmap.Width > bitmap.Height)
            {
                double scale = (double)bitmap.Height / (double)path.Height;
                image.Width = (double)bitmap.Width / scale;
                image.Height = _size;
                isLeft = true;
            }
            bitmapFrame = ControlsHelper.CreateResizedImage(bitmap, (int)image.Width, (int)image.Height, 0);
            image.Source = bitmapFrame;
            if (image.Source != null)
            {
                replaceButton.Visibility = Visibility.Visible;
                addButton.Visibility = Visibility.Collapsed;
            }
            Canvas.SetLeft(grid, centerX);
            Canvas.SetTop(grid, centerY);
            _StartX = (canvas.ActualWidth - image.Width) / 2.0d;
            _StartY = (canvas.ActualHeight - image.Height) / 2.0d;
            Canvas.SetLeft(image, _StartX);
            Canvas.SetTop(image, _StartY);        
            if (isLeft)
            {
                initialX = (int)(image.Width - 200) / 2;
                initialY = 0;
                crop = new CroppedBitmap(bitmapFrame, new Int32Rect(initialX, 0, _size, _size));

            }
            else
            {
                initialY = (int)(image.Height - 200) / 2;
                initialX = 0;
                crop = new CroppedBitmap(bitmapFrame, new Int32Rect(0, initialY, _size, _size));
            }
            OutImageSource = crop;
        }
       
    }
}

3)CropAvatarWindow.xaml使用如下;

<ws:Window x:Class="WPFDevelopers.Samples.ExampleViews.CropAvatarWindow"
        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:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers"
        xmlns:ws="https://github.com/WPFDevelopersOrg.WPFDevelopers.Minimal"
        mc:Ignorable="d"  WindowStyle="ToolWindow" ResizeMode="NoResize"
        WindowStartupLocation="CenterScreen"
        Title="WPF 开发者-头像选择器" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <wpfdev:CropAvatar x:Name="MyCropAvatar"/>
        <Image Grid.Column="1" Name="CropAvatarImage" Source="{Binding ElementName=MyCropAvatar,Path=OutImageSource}" 
               Stretch="Fill" Width="200" Height="200">
            <Image.Clip>
                <EllipseGeometry Center="100,100" RadiusX="100" RadiusY="100"/>
            </Image.Clip>
        </Image>
        <UniformGrid Grid.Row="1" Grid.ColumnSpan="2" 
                     HorizontalAlignment="Center" 
                     VerticalAlignment="Center">
            <Button  Content="保存" Click="btnSave_Click" Style="{StaticResource PrimaryButton}" Margin="4,0"/>
            <Button  Content="关闭" Click="btnClose_Click" Margin="4,0"/>
        </UniformGrid>
    </Grid>
</ws:Window>

4) CropAvatarWindow.xaml.cs 代码如下;

using System.Windows;

namespace WPFDevelopers.Samples.ExampleViews
{
    /// <summary>
    /// CropAvatarWindow.xaml 的交互逻辑
    /// </summary>
    public partial class CropAvatarWindow 
    {
        public CropAvatarWindow()
        {
            InitializeComponent();
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = true;
        }

        private void btnClose_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = false;
        }
    }
}

5) CropAvatarExample.xaml 使用如下;

<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.CropAvatarExample"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers"
             xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Button Content="图像选择器" VerticalAlignment="Center" HorizontalAlignment="Center" Click="Button_Click"/>
        <Image Grid.Column="1" Name="MyImage"
               Stretch="Fill" Width="200" Height="200">
            <Image.Clip>
                <EllipseGeometry Center="100,100" RadiusX="100" RadiusY="100"/>
            </Image.Clip>
        </Image>
    </Grid>
</UserControl>

6) CropAvatarExample.xaml.cs 代码如下;

using System.Windows.Controls;

namespace WPFDevelopers.Samples.ExampleViews
{
    /// <summary>
    /// CropAvatarExample.xaml 的交互逻辑
    /// </summary>
    public partial class CropAvatarExample : UserControl
    {
        public CropAvatarExample()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            var cropAvatarWindow = new CropAvatarWindow();
            if (cropAvatarWindow.ShowDialog() == true)
            {
                MyImage.Source = cropAvatarWindow.CropAvatarImage.Source;
            }
        }
    }
}

参考资料

[1]CombinedGeometry

[2]BitmapFrame

[3]CroppedBitmap

[4]Github

[5]Gitee

到此这篇关于基于WPF实现用户头像选择器的示例代码的文章就介绍到这了,更多相关WPF头像选择器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • c# WPF实现Windows资源管理器(附源码)

      今天我来写一篇关于利用WPF来实现Windows的资源管理器功能,当然只是局部实现这个功能,因为在很多时候我们需要来实现对本机资源的管理,当然我们可以使用OpenFileDialog dialog = new OpenFileDialog()这个Microsoft.Win32命名空间下的这个类来实现一些资源查找和导入的功能,但是在很多时候我们可能需要更多的功能,并且希望能够集成到我们自己的项目中,但是我们这个时候就不得不自己来写一套来集成到我们的软件中去了,因为OpenFileDialog这

  • c# 基于wpf,开发OFD电子文档阅读器

    前言 OFD是国家标准版式文档格式,于2016年生效.OFD文档国家标准参见<电子文件存储与交换格式版式文档>.既然是国家标准,OFD随后肯定会首先在政务系统使用,并逐步推向社会各个方面.OFD是在研究当下各类文件格式后,推出的标准,有如下优点: 1 产权属于自主产权 2 具有便携性:文件小,可压缩比率大.测试显示生成的文件体量比PDF还要小. 3 具有开放性:易于入门,对于使用者来说更具开放性. 4 具有扩展性:预留了可扩展入口和自定义标引,设置了非接触式引用机制,为特性化提供支持. 5 呈

  • WPF自定义选择年月控件详解

    本文实例为大家分享了WPF自定义选择年月控件的具体代码,供大家参考,具体内容如下 封装了一个选择年月的控件,XAML代码: <UserControl x:Class="SunCreate.CombatPlatform.Client.DateMonthPicker" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.micr

  • 利用WPF窗口程序设计简单计算器

    本文中设计的计算器仅支持单次双目运算,可连续计算. 实验要求: 1.在wpf项目中编程实现一个简单计算器,具体要求如下: 1)实现+,-,*,/运算 2)可以连续进行计算. 效果如图: *该程序中数字通过点击对应按钮输入,运算符包含四种常用运算,除此之外还有退格以及清空操作,输入以及运算结果在上方文本框内显示 1.首先,该程序中只涉及单次运算,所以我们可以在隐藏文件里声明两个全局变量来相应的保存operation前后两个数(字符串). string num1 = null; //运算符之前的数

  • WPF实现多运算符表达式计算器

    WPF实现一个简单的多运算符表达式计算器 1.先看下效果图在这里插入图片描述 首先外围给了一个grid 把他分成了两行 第一行用来显示文本框给了一个低于第二行的高度 第二行用来存按钮 窗体的大小自己去调就好了 我这里给的是380x268 <Grid.RowDefinitions> <RowDefinition Height="0.7*"></RowDefinition> <RowDefinition></RowDefinition&

  • WPF制作一个简单的倒计时器实例附源码

    实例一: 早上起来后闲的无事,于是想到前些日子学院的某个老师让大家给他找个什么倒计时的小软件,当时大家忙于复习所以也懒得搭理这件事,囧~.既然早上没事干,何不写个玩玩~既然要写,就用以前没怎么捣鼓过的WPF写一个吧,也算是一次学习WPF的初探吧(感觉自己很落后了)! 在Vs2008和Vs2010之间徘徊了许久之后,最终还是选择了Vs2008做开发IDE.在Vs2008中建了个WPF工程后,浏览了下默认生成的工程文件结构,一个App.xaml(当然还有App.xaml.cs)和一个Windows1

  • WPF ComboBox获取当前选择值的实例详解

    WPF下给ComboBox设置绑定字段时可通过如下设置: combobox.SelectedValuePath = "编号" ;//为隐藏的一个字段 combobox .DisplayMemberPath = "名称" ;//为显示的字段 获得隐藏字段方式: combobox .SelectedValue.ToString (); 获得显示的字段: combobox.Text 补充:WPF中的ComboBox框赋值 WPF中的ComboBox框不能直接赋值给实体(选

  • 基于WPF实现用户头像选择器的示例代码

    目录 实现思路 核心代码 参考资料 实现思路 制作一个用户头像选择器仿 WeGame 制作一个用户头像选择Canvas为父控件所实现,展示图片使用Image,Path当作上方的蒙版; Canvas:主要用途方便移动Image,设置ClipToBounds="True"裁剪为一个正方形200x200做为主要展示区域; Image:展示需要裁剪的图片: Path:CombinedGeometry[1]绘制蒙版大小200x200效果如下: 当选择一个本地图片的时候判断宽与高谁更大,谁小就将它

  • 基于Java实现扫码登录的示例代码

    目录 基本介绍 原理解析 1. 身份认证机制 2. 流程概述 代码实现 1. 环境准备 2. 主要依赖 3. 生成二维码 4. 扫描二维码 5. 确认登录 6. PC 端轮询 7. 拦截器配置 效果演示 1. 工具准备 2. 数据准备 3. 扫码登录流程展示 结语 基本介绍 相信大家对二维码都不陌生,生活中到处充斥着扫码登录的场景,如登录网页版微信.支付宝等.最近学习了一下扫码登录的原理,感觉蛮有趣的,于是自己实现了一个简易版扫码登录的 Demo,以此记录一下学习过程. 实际上是面试的时候被问到

  • Django用户身份验证完成示例代码

    在这篇Django文章中,wom 将讨论Django User 验证,Django附带了一个用户认证系统. 它处理用户帐户,组,权限和基于cookie的用户会话. Django身份验证系统同时处理身份验证和授权. 简要地说,身份验证将验证用户是他们声称的身份,而授权则确定允许经过身份验证的用户执行的操作. 基本上,我们将创建登录,注销,忘记密码和重置密码功能. 身份验证支持在django.contrib.auth中为Django contrib模块.默认情况下,所需的配置已包含在django-a

  • spring cloud oauth2 实现用户认证登录的示例代码

    需求 在微服务架构中,我们有很多业务模块,每个模块都需要有用户认证,权限校验.有时候也会接入来自第三方厂商的应用.要求是只登录一次,即可在各个服务的授权范围内进行操作.看到这个需求,立马就想到了这不就是单点登录吗?于是基于这样的需求,作者使用spring-cloud-oauth2去简单的实现了下用户认证和单点登录. 相关介绍 OAuth2 OAuth2是一个关于授权的网络标准,他定制了设计思路和执行流程.OAuth2一共有四种授权模式:授权码模式(authorization code).简化模式

  • Python基于React-Dropzone实现上传组件的示例代码

    目录 实例演示 1. axios上传普通文件: 2. 大文件导入: 结语 这次我要讲述的是在React-Flask框架上开发上传组件的技巧.我目前主要以React开发前端,在这个过程中认识到了许多有趣的前端UI框架--React-Bootstrap.Ant Design.Material UI.Bulma等.而比较流行的上传组件也不少,而目前用户比较多的是jQuery-File-Upload和Dropzone,而成长速度快的新晋有Uppy和filepond.比较惋惜的是Fine-Uploader

  • SQL实现筛选出连续3天登录用户与窗口函数的示例代码

    目录 还原试题 SQL窗口函数 一.窗口函数有什么用 二.什么是窗口函数 三.如何使用 1.专用窗口函数rank 2.其他专业窗口函数 3.聚合函数作为窗口函数 4.注意事项 四.总结 1.窗口函数语法 2.窗口函数有以下功能: 3.注意事项 解题思路 代码实现 其他解法与延展 还原试题 首先新建一张表来还原一下试题: CREATE TABLE last_3_day_test_table ( user_id varchar(300), login_date date ); INSERT INTO

  • 基于Python编写微信清理工具的示例代码

    目录 主要功能 运行环境 核心代码 完整代码 前几天网上找了一款 PC 端微信自动清理工具,用了一下,电脑释放了 30GB 的存储空间,而且不会删除文字的聊天记录,很好用,感觉很多人都用得到,就在此分享一下,而且是用 Python 写的,喜欢 Python 的小伙伴可以探究一下. 主要功能 它可以自动删除 PC 端微信自动下载的大量文件.视频.图片等数据内容,释放几十 G 的空间占用,而且不会删除文字的聊天记录,可以放心使用. 工作以后,微信的群聊实在太多了,动不动就被拉入一个群中,然后群聊里大

  • 基于C语言实现迷宫游戏的示例代码

    目录 C语言迷宫游戏 定义地图 打印地图方法一 打印地图方法二 定义起点和终点位置 实现读取按键 实现小球下向下移动一步 总结小球移动规律 实现重新打印地图 实现连续移动 实现小球下向上下左右移动 实现小球走到终点就胜利 C语言迷宫游戏 这篇文章是给学完并学懂了C语言的分支(选择和循环)结构和二维数组的朋友看的. 要做一个游戏或者程序先要想好有那些要求,以下是我认为一个迷宫必带的要求: 迷宫要先打印出来(要设置墙.空气.小球的起点),是墙就不能,是空气就可以走. 每次输入'w'.'a'.'s'.

  • 基于mysql乐观锁实现秒杀的示例代码

    目录 说明 具体实现 代码实现 说明 如果你的项目流量非常小,完全不用担心有并发的购买请求,那么做这样一个系统意义不大.但如果你的系统要像12306那样,接受高并发访问和下单的考验,那么你就需要一套完整的流程保护措施,来保证你系统在用户流量高峰期不会被搞挂了. 进阶redis+mq实现:参考springboot + rabbitmq + redis实现秒杀 严格防止超卖保证用户体验:高并发下,别网页打不开了,支付不成功了,购物车进不去了,地址改不了了防止黑产:防止不怀好意的人群通过各种技术手段把

  • WPF实现绘制扇形统计图的示例代码

    扇形统计图 绘制一个扇形原理也是基于Canvas进行绘制; ArcSegment[1]绘制弧形; 绘制指示线: 绘制文本: 鼠标移入动画: 显示详情Popup: 源码Github[2] Gitee[3] 示例代码 1)SectorChart.cs代码如下; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Win

随机推荐