2024年3月21日发(作者:)

吃豆子游戏详解一

这两天找到了一个非常好玩的小游戏,叫吃豆子,这个游戏附有vb代码。这个代码真的很

难,我研究了很长的时间,现在才略知一二。吃豆子这个游戏也是值得一提的,为什么呢?

吃豆子这游戏我在1987年就玩过,有一次,我在部队里的一个计算机的房间里玩的这个小

游戏,因为以前没有玩过,所以印象就很深,那时的计算机很大,不像现在的电脑叫微机,

当时吃豆子叫吃苹果,豆子都画成了苹果的形状,比现在的吃豆子还要复杂一些,一个大嘴

怪喀碴喀碴的在吃苹果,我还觉得特别的好玩。

现在玩起来也觉得好玩,试玩一下吃豆子游戏,就会发现

1.游戏开始之前有一个倒计时,而且有一段音乐,屏幕上还有准备两个字在闪烁

2.吃豆子吃,大嘴怪的嘴巴会张会闭,每吃掉一个豆子,玩家就会获得一定的积分,如果

大嘴怪把屏幕上的所有的豆子吃掉后,就会自动进入下一关。

3.幽灵们被大嘴怪吃掉后如何自动找到自己的家,好象会找到最近的路,到自己的家后就

会恢复到以前的样子,而且幽灵们好象会往大会嘴怪的方向去找大嘴怪似的,如果幽灵遇到

大嘴怪,就会把大嘴怪吃掉。幽灵的眼睛会转动的。

4.因为吃豆子算是一个很老的游戏,所以它还有一个投币的程序,如果一个人玩,就投一

个硬币,如果两个人玩,就投两个硬币,就像我们原来用游戏币玩游戏一样。

5.大嘴怪吃掉一颗红色的豆子,幽灵们就会变成深蓝色,这个时候,幽灵们不具有战斗力,

大嘴怪反而会把幽灵吃掉了,幽灵吃掉后,就会只剩下两只眼情,它们会尽快找到自己的家,

而且到家以后,它们就会恢复原来的样子。

图一

此图为吃豆子的游戏画面

图二

此图是游戏中的幽灵、大嘴怪的画法,还有

游戏中出现的其它的物品,包括白豆子和红

豆子,这个图在vb代码中名称为pctTiles

如何从一个图片中分离出幽灵和大嘴怪来

我研究了一个整个游戏中的vb代码,和图二,发现了有几处难点

第一点:图二实际名称为,在vb代码中

为:e=LoadPicture(&”/

这是一个bmp图片,里面包含着游戏大嘴怪嘴巴一张一闭的动画,大嘴怪朝上下左右行走

的四下个方向的模样,还有四个幽灵不同颜色的,幽灵的眼睛会上下左右转动的动画,图的

左边为彩图,黑色背景,右边为黑白图,白色背景。仅一张图,就可以表现出如此多的内容,

对于像我这样的初级水平的vb学员来说,确实有些难以理解

第二点:大嘴怪在游戏代码中的名称为pacman,幽灵在vb代码中的名称为Ghost,吃的白

色的豆子在游戏中的代码为pill,红色豆子在游戏中的代码为powerpills

我从一个很复杂的吃豆子的代码中首先重新组成一个新的小游戏,是这个吃豆子的游戏的一

部分,就是从一个包含着大嘴怪(嘴巴张开的动画)和四个幽灵还有一些相它的游戏中的物

品中分离出来游戏中的幽灵来,代码也是从原来游戏的代码改编出来的,因为他可以单独运

行的,就像一个新的游戏一样

这是Form1窗体,它包含着三个pictureBox图片和两个按钮

Form1的尺寸要能够装下这三个图片控件和两个按钮按件,另外Form1属性中的ScaleMode

设为3Pixel像素模式,这样pctBack图片的尺寸才会与下面的宽和高相同

为了和原来吃豆子游戏中的代码相同,所以这三个pictureBox的名称完全与原来吃豆子游戏

中我名称一样分别为

pctScreen图片,AutoSize = True 属性中的picture为下图,图片名为LevelOld,注意在代

码中图片名是不出现的,只出现的是pctScreen ,因为此图片在Form1中,又可称为

e

pctStats图片

这个图片属性中的Picture不设,它仅显示背景色&H00404080

名称和原游戏相同pctStats

BackColor &Hoo404080

AutoSize: False

W(宽):32

H(高):192

pctBack图片

它的属性中的picture设为:

AutoSize=True,尺寸与图片相同

另外还有一个开始按钮,在代码中的名称为Command1,而结束按钮没有在代码中出现

在游戏中有大嘴怪,它的名称为PacMan,它在游戏中也是一个UDTPacman类型的变量

四个幽灵(不同颜色的)它的名称为Ghost(1 To 4) 它在游戏中是一个UDTGhost类型的变

量,大嘴怪因为可以死亡,如果大嘴怪死亡后,游戏就结束了,所以它的变量类型UDTPacman

要复杂一些,所以本篇代码中我们只讲如何把幽灵从一个图片中分离出来,在代码中,幽灵

即Ghost(1 To 4)定义为UDTGhost类型的变量,然后再定义UDTGhost这个类型包括哪些变

量,即,幽灵有哪些属性,幽灵的全部动作都会出现在UDTGHost这个类型中

还有一个函数BitBlt 要在代码中声明一下,格式挺复杂的,换行时要注意程序出错,或者

就不换行一直写下去就行了

Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer

Declare Function sndPlaySound Lib "" Alias "sndPlaySoundA" (ByVal

lpszSoundName As String, ByVal uFlags As Long) As Long

Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As

Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As

Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

游戏代码为

Form1的代码为

Private Sub Command1_Click()

DefaultPositions

End Sub

然后添加一个模块,Module1代码为:

Option Explicit

Public Enum BitbltOps ' For bitblt function

SRCCOPY = &HCC0020 ' Dest = Source

SRCAND = &H8800C6 ' Dest = Dest AND Source

SRCINVERT = &H660046 ' Dest = Dest XOR Source

SRCPAINT = &HEE0086 ' Dest = Dest OR Source

SRCERASE = &H4400328 ' Dest = (XOR Dest) AND Source

WHITENESS = &HFF0062 ' Dest = vbWhite

BLACKNESS = &H42 ' Dest = vbBlack

End Enum

Public Type UDTGhost

InGame As Boolean ' if ghost is in the game (true) or in the box (false)

Eyesonly As Boolean ' if ghost is eyes only (true)

Xpos As Integer ' x position of the ghost

Ypos As Integer ' y position of the ghost

Direction As Integer ' direction the ghost is currently moving

Offset As Integer ' y offset until the next square to be flush with it

Xcounter As Integer ' not used

Ycounter As Integer ' counts how many times ghost has bounced up and down in the box

Speed As Integer ' speed the ghost moves at

PPTimer As Integer ' how long the ghost stays in eaten mode for

DelayTime As Integer ' this is to slow the ghost down in eaten mode by half

End Type

Public Ghost(1 To 4) As UDTGhost

Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer

Declare Function sndPlaySound Lib "" Alias "sndPlaySoundA" (ByVal

lpszSoundName As String, ByVal uFlags As Long) As Long

Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As

Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As

Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

Sub ShowBlit(ByVal X As Integer, ByVal Y As Integer, _

ByVal XP As Integer, ByVal YP As Integer, ByVal pos As Integer)

Dim maskOffset As Integer

With Form1

maskOffset = 135

BitBlt ., 0, pos * 32, 32, 32, ., X, Y, Y

If pos = 0 Or pos = 5 Then

maskOffset = XP + 128

Else

If Ghost(pos).Eyesonly = False Then

maskOffset = 192

Else

maskOffset = 224

End If

End If

BitBlt ., X, Y, 32, 32, ., maskOffset, YP,

BitBlt ., X, Y, 32, 32, ., XP, YP, NT

End With

End Sub

Sub DefaultPositions()

With Ghost(1) ' outside the starting box

.Xpos = 224

.Ypos = 184

.Direction = 2 + Rnd

.Offset = 8

.Speed = 1

.InGame = False

.Eyesonly = False

.PPTimer = 0

ShowBlit .Xpos - 16, .Ypos - 16, 0, .Direction * 32, 1

End With

With Ghost(2) ' inside starting box on the left

.Xpos = 192

.Ypos = 224

.Direction = 0

.Offset = 8

.InGame = False

.Eyesonly = False

.Ycounter = 0

.Speed = 1

.PPTimer = 0

ShowBlit .Xpos - 16, .Ypos - 16, 32, .Direction * 32, 2

End With

With Ghost(3) ' inside middle

.Xpos = 224

.Ypos = 240

.Direction = 1

.Offset = 8

.InGame = False

.Eyesonly = False

.Ycounter = 0

.Speed = 1

.PPTimer = 0

ShowBlit .Xpos - 16, .Ypos - 16, 64, .Direction * 32, 3

End With

With Ghost(4) ' inside right

.Xpos = 256

.Ypos = 224

.Direction = 0

.Offset = 0

.InGame = False

.Eyesonly = False

.Ycounter = 0

.Speed = 1

.PPTimer = 0

ShowBlit .Xpos - 16, .Ypos - 16, 96, .Direction * 32, 4

End With

End Sub

运行程序,画面如下: