桌面人偶

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。

本篇博文主要讲述如何用VB.Net实现桌面人偶程序。

一、准备工作
1.1、人偶图片的准备
本文中将使用到两张人物行走的png图片,均来源于网络。

图1、男性图片

图2、女性图片

图片大小为280*992,实际包含32张人物行走动作的图片,从上到下分别为:
向下行走、向左行走、向右行走、向上行走、左下行走、右下行走、左上行走、右上行走
共8个方向的行走动作图。
根据图片内容可以均分为4*8区域,每个区域对应大小为70*124。
1.2、窗体和控件设置
打开VB.Net,新建工程,工程名称为Actor,窗体名称为FormMain。
根据1.1节分析的内容,设置FormMain的高宽属性为70*124;
为使人偶显示在所有窗体最上面,设置TopMost属性为True;
为使人偶窗体不显示系统多拽栏、系统菜单(包含关闭按钮),设置FormBorderStyle 为None;
窗体出现位置为屏幕中央,设置StartPosition为CenterScreen。

在窗体上添加快捷菜单,名称为ContextMenuStrip1。
菜单项如下图:

图3、快捷菜单菜单项
作用分别是调节人偶走动速度、设置人偶性别、退出程序。

在窗体上放置一个图片框,名称为picActor。
picActor的高宽属性为70*124,和窗体边框重合;
picActor的ContextMenuStrip 属性设置为ContextMenuStrip1,确保在图片上点击鼠标右键出来快捷菜单

在窗体上放置一个Timer组件,名称为tmActor。
tmActor时间间隔Interval 属性为150。
tmActor的作用是每隔一段时间控制人偶移动一定距离。

1.3、使用资源文件
为了方便调用人偶图片,向工程添加资源文件Resource1.resx,将1.1节中的两张人物行走的图片添加到资源文件中,分别命名为f1和m1。

图4、资源文件中包含的图片

二、动起来吧,小可爱
在代码中已经添加了详细注释,这里不再作说明。
1、人偶类

'人偶类
Public Class clsActor
    '方向
    Public Enum Direction
        down = 0
        left
        right
        up
        downleft
        downright
        upleft
        upright
    End Enum

    '人偶的宽度和高度
    Const Width As Integer = 70
    Const Height As Integer = 124

    '当前方向
    Property currentdirection As Direction
    '当前动作
    Property currentAct As Integer

    '数组用以保存拆分的图像,包含每张人偶行走动作的图像
    '8个方向,每个方向4张图像,一共32张图像
    Private bmpPerson(31) As Bitmap

    '参数为资源中的人偶图片
    Public Sub New(ByVal bmpActor As Bitmap)
        '当前动作为第一张图片
        currentAct = 0

        Call loadActor(bmpActor)
    End Sub

    '载入人偶图像,将图像拆分到数组中
    Public Sub loadActor(ByVal bmpActor As Bitmap)
        'bmp是资源中的图像,它是一个固定宽高的图像,宽280、高992
        Dim bmp As Bitmap
        '按照4*8区域,将资源图片中的每一个行走动作图保存到图像数组中
        For i As Integer = 0 To 7
            For j As Integer = 0 To 3
                bmp = New Bitmap(Width, Height)
                Dim g As Graphics = Graphics.FromImage(bmp)
                g.DrawImage(bmpActor, 0, 0, New Rectangle(70 * j, 124 * i, Width, Height), GraphicsUnit.Pixel)
                bmpPerson(i * 4 + j) = bmp
                g.Dispose()
            Next
        Next
    End Sub

    '人偶移动
    Public Sub moveActor(ByVal g As Graphics)
        '使用RGB(255, 255, 254)清除之前的graphics
        '注意:使用的颜色应和窗体透明索引(TransparencyKey)一致,确保背景透明
        g.Clear(Color.FromArgb(255, 255, 254))
        '绘制行走的图像
        g.DrawImage(bmpPerson(currentdirection * 4 + currentAct), New Point(0, 0))
        '设置为下一个动作
        currentAct += 1
        If currentAct = 4 Then currentAct = 0
    End Sub
End Class

2、窗体上的代码


Public Class FormMain
    Dim actor As clsActor

    '图片数组,用于保存资源文件中的图片
    Dim actorImg(1) As Bitmap

    '上下左右直线运动时的位移量
    Dim moveStraightLine As Integer = 10
    '斜向运动时的x、y方向上的位移量
    Dim moveObliqueLine As Integer = 7

    Dim screenWidth As Integer
    Dim screenHeight As Integer

    '用于产生随机数
    Dim rnd As Random

    '按下鼠标左键时鼠标位置
    Dim mousePoint As Point

    Private Sub FormMain_Load(sender As Object, e As EventArgs) Handles Me.Load
        Me.Width = 70
        Me.Height = 124
        '设置窗体需要透明的颜色
        Me.TransparencyKey = Color.FromArgb(255, 255, 254)
        '设置背景颜色
        Me.BackColor = Color.FromArgb(255, 255, 254)
        '获得屏幕宽度和高度
        screenWidth = Screen.PrimaryScreen.WorkingArea.Width
        screenHeight = Screen.PrimaryScreen.WorkingArea.Height
        '将资源文件中的图片保存到数组
        actorImg(0) = My.Resources.Resource1.f1
        actorImg(1) = My.Resources.Resource1.m1
        '创建新人偶
        actor = New clsActor(actorImg(0))

        '设置初始随机行走方向
        rnd = New Random()
        actor.currentdirection = rnd.Next(8)

        '启动定时器
        tmActor.Start()
    End Sub

    Private Sub tmActor_Tick(sender As Object, e As EventArgs) Handles tmActor.Tick

        '根据方向移动窗体
        Select Case actor.currentdirection
            Case clsActor.Direction.down
                Me.Top += moveStraightLine
            Case clsActor.Direction.left
                Me.Left -= moveStraightLine
            Case clsActor.Direction.right
                Me.Left += moveStraightLine
            Case clsActor.Direction.up
                Me.Top -= moveStraightLine
            Case clsActor.Direction.downleft
                Me.Top += moveObliqueLine
                Me.Left -= moveObliqueLine
            Case clsActor.Direction.downright
                Me.Top += moveObliqueLine
                Me.Left += moveObliqueLine
            Case clsActor.Direction.upleft
                Me.Top -= moveObliqueLine
                Me.Left -= moveObliqueLine
            Case clsActor.Direction.upright
                Me.Top -= moveObliqueLine
                Me.Left += moveObliqueLine
        End Select

        '方向数组,保存与现有方向相反的方向
        Dim chooseDirection() As Integer
        '是否需要改变方向
        Dim changeDirection As Boolean = False

        '判断人偶行走是否到达屏幕边缘
        Select Case True
            Case Me.Left <= 0  '屏幕左边缘
                '如果到达左边缘,则方向数组中保存 向右、右下、右上 这三个方向,下同。
                chooseDirection = New Integer() {clsActor.Direction.right, clsActor.Direction.downright, clsActor.Direction.upright}
                changeDirection = True
            Case Me.Top <= 0    '屏幕上边缘
                chooseDirection = New Integer() {clsActor.Direction.down, clsActor.Direction.downleft, clsActor.Direction.downright}
                changeDirection = True
            Case (Me.Left + Me.Width) >= screenWidth    '屏幕右边缘
                chooseDirection = New Integer() {clsActor.Direction.left, clsActor.Direction.downleft, clsActor.Direction.upleft}
                changeDirection = True
            Case (Me.Top + Me.Height) >= screenHeight   '屏幕下边缘
                chooseDirection = New Integer() {clsActor.Direction.up, clsActor.Direction.upleft, clsActor.Direction.upright}
                changeDirection = True
            Case Else
                changeDirection = False
        End Select
        rnd = New Random()
        '如果人偶到达边缘
        If changeDirection = True Then
            '设置人偶方向为方向数组中的随机一个方向
            actor.currentdirection = chooseDirection(rnd.Next(3))
        End If

        '从图片框创建Graphics
        Dim g As Graphics
        g = picActor.CreateGraphics

        '移动人偶
        actor.moveActor(g)

        '释放当前的Graphics
        g.Dispose()
    End Sub

    '设置定时器间隔
    Private Sub 速度100ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 速度100ToolStripMenuItem.Click
        tmActor.Interval = 100
    End Sub
    Private Sub 速度150ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 速度150ToolStripMenuItem.Click
        tmActor.Interval = 150
    End Sub
    Private Sub 速度200ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 速度200ToolStripMenuItem.Click
        tmActor.Interval = 200
    End Sub

    '设置人偶性别
    Private Sub 男性角色ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 男性角色ToolStripMenuItem.Click
        actor.loadActor(actorImg(0))
    End Sub
    Private Sub 女性角色ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 女性角色ToolStripMenuItem.Click
        actor.loadActor(actorImg(1))
    End Sub

    '退出程序
    Private Sub 退出ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 退出ToolStripMenuItem.Click
        Application.Exit()
    End Sub

    '当在图片框上按下鼠标时
    Private Sub picActor_MouseDown(sender As Object, e As MouseEventArgs) Handles picActor.MouseDown
        '暂停人偶移动
        tmActor.Stop()
        '在图片框上按下时,记录当前鼠标位置
        If e.Button = MouseButtons.Left Then
            mousePoint = New Point(e.X, e.Y)
        End If
    End Sub

    '当在图片框上移动鼠标时
    Private Sub picActor_MouseMove(sender As Object, e As MouseEventArgs) Handles picActor.MouseMove
        '实现人偶随鼠标移动
        If e.Button = MouseButtons.Left Then
            tmActor.Stop()
            Me.Left -= mousePoint.X - e.X
            Me.Top -= mousePoint.Y - e.Y
        End If
    End Sub

    '当在图片框上释放鼠标时
    Private Sub picActor_MouseUp(sender As Object, e As MouseEventArgs) Handles picActor.MouseUp
        '启动定时器
        tmActor.Start()
    End Sub


End Class

三、最终效果

图5、行走的人偶

图6、更换人偶性别

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值