用Excel制作贪吃蛇

本文介绍如何使用Excel的VBA编程制作贪吃蛇游戏。通过讲解核心函数和关键类的实现,包括初始化、画布、贪吃蛇、食物以及游戏主循环,详细阐述了游戏的运作原理。玩家需要了解VBA基础知识,如Range对象的使用,以及如何控制游戏帧率。通过游戏实例,深入理解Excel VBA编程。
摘要由CSDN通过智能技术生成

此文章最先发布于我的博客
废话不多说,先放成果。在GitHub上查看源代码

点击查看图片

开始编写

阅读此教程,你需要了解

  • 什么是VBA,对VBA初步了解

  • 如何在Excel中编辑VBA,并启用它

否则请另行百度。

##最重要的两个函数

RangeCells是整个游戏程序中的核心,它们都能返回一个 表示一个单元格、一行、一列、一个包含单个或若干连续单元格区域的选定单元格范围,或者一个三维区域。(摘自https://docs.microsoft.com/zh-cn/office/vba/api/excel.range(object)

简单来说姐是能帮助我们获取到Excel中的每一个格子,以便我们操作他们的属性。

如以下代码:

Cells(2, 22) = "贪吃蛇撞墙过猛,游戏结束"

获取了y坐标为2x坐标为22的单元格,并设置它的文本。(这里可能和我们平时的认知不太一样,Cells函数是y在前x在后的)

初始化

游戏初始化过程的代码如下:

Option Explicit

'定义贪吃蛇坐标变量
Dim snackX(400) As Integer
Dim snackY(400) As Integer
'定义贪吃蛇坐标引索
Dim snackIndex As Integer
'定义贪吃蛇移动变量
Dim snackMoveX As Integer
Dim snackMoveY As Integer
'苹果坐标
Dim appleX As Integer
Dim appleY As Integer
'游戏是否运行
Dim isGameRunning As Integer

'导入win32API模块
#If VBA7 And Win64 Then
  Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
  Private Declare Function GetTickCount Lib "kernel32" () As Long
#End If

'工具类函数
Private Sub Sleep(numa As Double)
    Dim num1 As Double
    Dim num2 As Double
    Dim numb As Double
    
    numb = 0
    num1 = GetTickCount
    
    Do While numa - numb > 0
      num2 = GetTickCount
      numb = num2 - num1
      DoEvents
    Loop
End Sub

其中,第一行规定全局的变量必须定义后才可以使用,当然取消后代码也能正确运行,但会存在许多潜在的漏洞。

之后,是贪吃蛇和苹果位置信息的定义,以便我们可以全局使用它。需要注意的是,贪吃蛇坐标变量定义了两个长度为400的整形数组,这是经过了计算的,即贪吃蛇沾满格子的长度。

最后,我们导入了kernel32模块。又利用其中的GetTickCount定义了一个Sleep函数,用于延时,以控制游戏帧数。

游戏基础——画布类

'画布类
Public Sub CanvasClean()
    With Range("B2:S19").Interior
        .Pattern = xlNone
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
End Sub

Public Sub CanvasReLoad()
    With Range("A1:T20").Interior
        .PatternColorIndex = xlAutomatic
        .ThemeColor = xlThemeColorLight1
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
End Sub

CanvasClean函数,顾名思义,我们用其清理画布的区域。其中,使用Range("B2:S19")获取了Excel中的格子区域(图中框选区域),并将它清空。点击查看图片

CanvasReLoad中,我们将整个黑框区域恢复原样,及在CanvasClean的基础上,将黑框也重新绘制。

为什么要这么做,给你看个图就知道了:

点击查看图片

主角——贪吃蛇类

'贪吃蛇类
Private Sub TextBox1_Change()
    Select Case TextBox1.Text
        Case Is = "w"
            If snackMoveY <> 1 Then
                snackMoveY = -1
                snackMoveX = 0
            End If
        Case Is = "s"
            If snackMoveY <> -1 Then
                snackMoveY = 1
                snackMoveX = 0
            End If
        Case Is = "a"
            If snackMoveX <> 1 Then
                snackMoveX = -1
                snackMoveY = 0
            End If
        Case Is = "d"
            If snackMoveX <> -1 Then
                snackMoveX = 1
                snackMoveY = 0
            End If
    End Select
    TextBox1.Text = ""
End Sub

Public Sub snackCreate()
    snackIndex = 3
    Dim i As Integer
    Dim x As Integer
    Dim y As Integer
    x = Int(Rnd * 13) + 3
    y = Int(Rnd * 13) + 3
    For i = 0 To snackIndex
        snackX(i) = x
        snackY(i) = y + i
    Next
End Sub

Public Sub snackMove()
    Dim i As Integer
    For i = snackIndex To 1 Step -1
        snackX(i) = snackX(i - 1)
        snackY(i) = snackY(i - 1)
    Next
    snackX(0) = snackX(0) + snackMoveX
    snackY(0) = snackY(0) + snackMoveY
End Sub

Public Sub snackDraw()
    Dim i As Integer
    For i = 0 To snackIndex
        Cells(snackY(i), snackX(i)).Interior.Color = 255
    Next
End Sub

Public Sub snackHitWall()
    If snackX(0) = 1 Or snackX(0) = 20 Or snackY(0) = 1 Or snackY(0) = 20 Then
        Cells(2, 22) = "贪吃蛇撞墙过猛,游戏结束"
        isGameRunning = 0
    End If
End Sub

Public Sub snackEatApple()
    If snackX(0) = appleX And snackY(0) = appleY Then
        appleCreate
        snackIndex = snackIndex + 1
        Cells(4, 22) = Int(Cells(4, 22).Value) + 1
    End If
End Sub

Public Sub snackHitHimself()
    Dim i As Integer
    For i = 1 To snackIndex
        If snackX(0) = snackX(i) And snackY(0) = snackY(i) Then
            Cells(2, 22) = "贪吃蛇把自己吃了,游戏结束"
            isGameRunning = 0
        End If
    Next
End Sub

如果你熟悉VB,那你一定看出来了,TextBox1_Change是TextBox1中的文本改变时自动调用的一个过程。我们在这里进行判断,已根据WASD的方向键调整贪吃蛇的移动量,最后再将其内容清空,以便下一次检测

其次,就是故名思意了:

  • snackCreate——创建贪吃蛇
  • snackMove——根据贪吃蛇的移动量移动贪吃蛇
  • snackDraw——绘制贪吃蛇
  • snackHitWall——检测贪吃蛇是否撞到墙
  • snackEatApple——检测贪吃蛇是否吃到苹果
  • snackHitHimself——检测贪吃蛇是否把自己吃了

食物——苹果类

'苹果类
Public Sub appleCreate()
    appleX = Int(Rnd * 15) + 3
    appleY = Int(Rnd * 15) + 3
End Sub

Public Sub appleDraw()
    Cells(appleY, apple
Excel下实现贪吃蛇游戏 上次我们在Excel下实现了一个华容道式的小游戏,使用了Excel中的小部分属性和功能,不到100行语句就完成了。这次我们要把贪吃蛇搬到Excel中,就不那么容易了。 首先要解决游戏显示的问题。对我们来说,小游戏最好的平台是Excel的工作区,由于大小可调、颜色可填的单元格操作方便,我们完全可以把它们当像素来使用。于是我们的贪吃蛇游戏就有了以单元格为基础的像素形式的显示方式了。 其次是游戏的控制方法。在这里我摸索了好久,其中走了弯路不说,我最后的结论是在Excel中要实现按键事件的方法是引入窗体,然后在窗体中响应Keydown与Keypress事件。这样的话,既可以快速响应还可以根据情况修改对应按键。 最后是游戏的定时问题。所有的游戏事实上都是在一个时间大循环里面定时接收输入信息更新状态的程序,我们的小游戏都不例外。老实说,我写这个游戏大部分的思考时间就浪费在如何实现游戏定时这里。Excel的VBA中与定时有关的只有onTime函数,没有其他相关函数提供了,onTime函数可以实现某一事件在指定时间发生,但只能以秒为最小单位,对我们要在一秒内更新数十次信息的小游戏不适合,我们只能另找方法。用过VB的人都知道VB控件中有个定时控件,用它来实现游戏定时是最好的,但在Excel中却没有,难道我要把VB中的定时控件移植到VBA中?这也是个很值得研究的课题,但是我想到了另外的方法。VB的程序员都知道要想VB程序发挥大作用一定离不开调用系统的API,于是我查看了系统相关API的帮助,发现系统API中实现相应功能的有settimer与killtimer函数,具体定义和用法大家可以参考相关帮助,但从字面大家都已经可以知道它们就是我们要找的东西了。那么现在的问题就是如何在vba环境下调用系统API。心想微软称vba就是office中的vb,那么在vba中调用系统API应该也与在VB中的一样。一试,呵呵,果然非虚,这微软真不是盖的(后在msdn中发现ms office vba从2000版本开始支持调用系统API,大家可以拓展office应用了)。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值