二十多年前写的一款游戏

今天整理邮件时,偶然发现了我在二十多年前,上小学时写的一个类似《小蜜蜂》的游戏,大概是小学五年级或者六年级,用的 QBasic。

因为我没有配置 QBasic 的环境,所以也不确定还能不能用。但看这个程序,真的恍如隔世。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
DECLARE SUB Initialize ()
DECLARE SUB DrawPlayer ()
DECLARE SUB MovePlayer (direction AS INTEGER)
DECLARE SUB Shoot ()
DECLARE SUB CheckInput ()
DECLARE SUB InitializeEnemies ()
DECLARE SUB MoveEnemies ()
DECLARE SUB EnemyShoot ()
DECLARE SUB MoveEnemyBullets ()
DECLARE SUB DrawEnemies ()
DECLARE SUB CheckCollisions ()
DECLARE SUB GameOver ()
DECLARE SUB DrawGame ()

CONST screenWidth = 80
CONST screenHeight = 25
CONST playerChar = "A"
CONST bulletChar = "^"
CONST enemyBulletChar = "*"
CONST enemyChar = "V"
CONST maxEnemies = 5
CONST maxEnemyBullets = 10

TYPE Enemy
x AS INTEGER
y AS INTEGER
dx AS INTEGER
active AS BOOLEAN
END TYPE

TYPE Bullet
x AS INTEGER
y AS INTEGER
active AS BOOLEAN
END TYPE

DIM SHARED playerX AS INTEGER, playerY AS INTEGER
DIM SHARED playerBullet AS Bullet
DIM SHARED enemies(maxEnemies) AS Enemy
DIM SHARED enemyBullets(maxEnemyBullets) AS Bullet
DIM SHARED score AS INTEGER
DIM SHARED gameRunning AS BOOLEAN

RANDOMIZE TIMER
Initialize

DO WHILE gameRunning AND NOT INKEY$ = CHR$(27)
CALL CheckInput
CALL MoveEnemies
CALL EnemyShoot
CALL MoveEnemyBullets
CALL CheckCollisions
CALL DrawGame
SLEEP 1
LOOP

IF NOT gameRunning THEN
CALL GameOver
END IF

SUB Initialize
playerX = screenWidth / 2
playerY = screenHeight - 1
playerBullet.active = FALSE
score = 0
gameRunning = TRUE
CALL InitializeEnemies
END SUB

SUB InitializeEnemies
FOR i = 1 TO maxEnemies
enemies(i).x = INT(RND * (screenWidth - 2)) + 2
enemies(i).y = INT(RND * 5) + 1
enemies(i).dx = IIF(RND > 0.5, 1, -1)
enemies(i).active = TRUE
NEXT i
END SUB

SUB DrawGame
CLS
LOCATE playerY, playerX
PRINT playerChar;
IF playerBullet.active THEN
LOCATE playerBullet.y, playerBullet.x
PRINT bulletChar;
END IF
FOR i = 1 TO maxEnemies
IF enemies(i).active THEN
LOCATE enemies(i).y, enemies(i).x
PRINT enemyChar;
END IF
NEXT i
FOR i = 1 TO maxEnemyBullets
IF enemyBullets(i).active THEN
LOCATE enemyBullets(i).y, enemyBullets(i).x
PRINT enemyBulletChar;
END IF
NEXT i
LOCATE 1, 1
PRINT "Score: "; score
END SUB

SUB MovePlayer (direction AS INTEGER)
IF direction = -1 AND playerX > 1 THEN
playerX = playerX - 1
ELSEIF direction = 1 AND playerX < screenWidth THEN
playerX = playerX + 1
END IF
END SUB

SUB Shoot
IF NOT playerBullet.active THEN
playerBullet.x = playerX
playerBullet.y = playerY - 1
playerBullet.active = TRUE
END IF
END SUB

SUB CheckInput
DIM key AS STRING
key = INKEY$
SELECT CASE key
CASE CHR$(75) ' left
CALL MovePlayer(-1)
CASE CHR$(77) ' right
CALL MovePlayer(1)
CASE " " ' space
CALL Shoot
END SELECT
END SUB

SUB MoveEnemies
FOR i = 1 TO maxEnemies
IF enemies(i).active THEN
enemies(i).x = enemies(i).x + enemies(i).dx
IF enemies(i).x <= 1 OR enemies(i).x >= screenWidth THEN
enemies(i).dx = -enemies(i).dx
enemies(i).y = enemies(i).y + 1
END IF
IF enemies(i).y >= screenHeight THEN
enemies(i).y = 1
END IF
END IF
NEXT i
END SUB

SUB EnemyShoot
FOR i = 1 TO maxEnemies
IF enemies(i).active AND INT(RND * 10) < 2 THEN
FOR j = 1 TO maxEnemyBullets
IF NOT enemyBullets(j).active THEN
enemyBullets(j).x = enemies(i).x
enemyBullets(j).y = enemies(i).y + 1
enemyBullets(j).active = TRUE
EXIT FOR
END IF
NEXT j
END IF
NEXT i
END SUB

SUB MoveEnemyBullets
FOR i = 1 TO maxEnemyBullets
IF enemyBullets(i).active THEN
enemyBullets(i).y = enemyBullets(i).y + 1
IF enemyBullets(i).y > screenHeight THEN
enemyBullets(i).active = FALSE
END IF
END IF
NEXT i
END SUB

SUB CheckCollisions
IF playerBullet.active THEN
FOR i = 1 TO maxEnemies
IF enemies(i).active THEN
IF playerBullet.x = enemies(i).x AND playerBullet.y = enemies(i).y THEN
playerBullet.active = FALSE
enemies(i).active = FALSE
score = score + 10
EXIT FOR
END IF
END IF
NEXT i
END IF

FOR i = 1 TO maxEnemyBullets
IF enemyBullets(i).active THEN
IF enemyBullets(i).x = playerX AND enemyBullets(i).y = playerY THEN
gameRunning = FALSE
END IF
END IF
NEXT i
END SUB

SUB GameOver
CLS
LOCATE screenHeight / 2, (screenWidth / 2) - 5
PRINT "Game Over! Score: "; score
SLEEP 5
END SUB