VB.NET实现人物2D行走(wpf向)
这篇文章我主要介绍如何,控制一个人物行走。达到小游戏中很常见的简单的功能。
通常小游戏的资源文件中通常包含下面这样的四方位行走图,百度搜索人物四方位行走图,这样的图片很多。可以直接拿来用。
那么问题出现了,怎么用?当然是一张一张的替换啊,比如说第一张图的第一排的四个图轮流播放,就完成了人物向前行走的动画。
那么第一步,首先要把这些图片给分开。有同学说了,用PS分一下。想象一个游戏好多角色,好多动作,单单这个行走的动作你就要分16张存储,你跑动又来16张,攻击又来,你不觉得图片太多太乱了么。当然应该在游戏里面分一下图片。划分的方式很多,我以WPF为例,剪裁一下这些资源图片。
Dim path = "Images\1111.png" Dim bitmap As BitmapSource = New BitmapImage(New Uri(path, UriKind.Relative)) Dim ImageList(4, 4) As ImageSource Private Delegate Sub mydelegate1(ByVal i As Integer, ByVal j As Integer) Private Delegate Sub mydelegate2() Dim image1 As New Image Dim width = bitmap.PixelWidth Dim height = bitmap.PixelHeight Dim bytePerPixel = bitmap.Format.BitsPerPixel / 8 Dim stride = width * bytePerPixel Dim pixls(stride * height + 1) As Byte Dim dpix = bitmap.DpiX Dim dpiy = bitmap.DpiY Dim format = bitmap.Format Dim palette = bitmap.Palette
Dim cut(4, 4) As Int32Rect For i = 1 To 4 For j = 1 To 4 cut(i, j) = New Int32Rect((j - 1) * width * 0.25, (i - 1) * height * 0.25, width * 0.25, height * 0.25) bitmap.CopyPixels(cut(i, j), pixls, stride, 0) ImageList(i, j) = BitmapSource.Create(width * 0.25, height * 0.25, dpix, dpiy, format, palette, pixls, stride) Next Next
上面这段代码是图片处理的核心代码,很值得收藏,是这篇文章的第一个精华。针对像素的处理,可以做的工作很多,比如黑化等等,放在这里划分图片确实是大材小用。经过上面的处理,我们把资源图片划分存储进入ImageList(i, j)数组中,4x4正好16张。虽然实际是5x5的数组,但是个人使用vb的习惯,数组的第一项0向来是不用的。
好了,现在划分完了资源图片。接下来就是播放行走动画了。有同学说无非就是循环播放那么简单,放一个timer里面就可以了。下面我们看看是不是这么简单。
我们用一个image控件来做人物的动作。
image1.Source = ImageList(1, 1) image1.Width = ImageList(1, 1).Width image1.Height = ImageList(1, 1).Height grid1.Children.Add(image1)
这篇文章我先介绍第一种效果:键盘方向键触发和解除timer的方式。当然先把timer注册了。
Dim WithEvents timer1 As New System.Timers.Timer
时间间隔设为200毫秒
timer1.Interval = 200
然后再keydown事件中写下
Private Sub Window_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Input.KeyEventArgs) Handles MyBase.KeyDown If e.Key = Key.Down Then If timer1.Enabled = False Then timer1.Start() End If Image_i = 1 Call ChangePIC1() End If ··· End Sub
Timer1的事件触发更换图片,因为WPF里面的timer的线程不属于这个程序,这里使用了托管线程,回到程序本身。(如果winform应该不用)
Sub ChangePIC1() Handles timer1.Elapsed Image_j += 1 If Image_j > 4 Then Image_j = 1 End If Dim d As New mydelegate1(AddressOf ChangePIC) Dispatcher.BeginInvoke(d, Image_i, Image_j) End Sub Sub ChangePIC(ByVal i As Integer, ByVal j As Integer) image1.Source = ImageList(i, j) End Sub
到这里确实很简单,这样就完成了4个方位人物行走的效果,按下方向键就可以走了。试一下效果,看起来好像不错。但是。。。。
生活总是有很多的但是。切换方向键的时候,人物的切换动作比较慢。快速的点击左右方向键,人物基本不动的。游戏做完了,别人玩后的评价,手感太僵硬!这时候我们就要在keyup里面处理一下了。
Private Sub Window_KeyUp(ByVal sender As System.Object, ByVal e As System.Windows.Input.KeyEventArgs) Handles MyBase.KeyUp If e.Key = Key.Down Then If timer1.Enabled = True Then 'timer1.Stop() End If Call ChangePIC1() End If If e.Key = Key.Up Then Call ChangePIC1() End If If e.Key = Key.Left Then Call ChangePIC1() End If If e.Key = Key.Right Then Call ChangePIC1() End If End Sub
我们在keyup里面绕过了timer,直接调用ChangePIC1。大大提升了反映速度,不受限制于timer。这里算是一个小技巧。
这样做的结果就是人物会一直走下去。松开按键还是会走,因为timer没有停止。这样做一下坦克大战,贪吃蛇那样的没什么问题,要是做动作操纵的,不给人控制可不行。
有同学说在keyup里面停止下timer.stop就好了,是个办法。但是问题又来了,停在哪一张图片上面呢?停在中间伸一条腿呆在那,有点违和啊。
下面就是我的第二篇内容了,按键行走。本片结束
前文回顾:使用timer做人物四方位行走图。
下文介绍:按键触发的太快了,人物的动作动那么快,更加违和啊,怎么办?且听下文分解