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
| ' Gambas module file
' TODO: Make real setup for playing ' TODO: There is an occasional flickering when shooting and the ships are already near the player and few
PUBLIC X AS INTEGER PUBLIC Y AS INTEGER ' Hardcoded corresponding to the strings in Draw() below! PUBLIC Width AS INTEGER = 3 PUBLIC Height AS INTEGER = 2
PRIVATE $hEnemies AS Timer PRIVATE $hMissiles AS Timer
PUBLIC SUB Main() ' Debug aid. Watch /tmp/pipe with "tail -f" ' Dim hPipe As Stream ' ' hPipe = Pipe "/tmp/pipe" For Write ' Error To #hPipe
Screen.Cursor = Cursor.Hidden Screen.Echo = FALSE Window.Attributes = Attr.Bold Object.Attach(Window, ME, "Window") Window.SetFocus()
X = (Window.Width - Width) \ 2 Y = Window.Height - Height
Object.Attach(Enemies, ME, "Enemies")
Draw() ' Populate ca. 1/3 of the screen with enemies. It will actually look more ' because of the enemy arrangement. But that's good :-) Enemies.Init(Window, Window.Width * Window.Height / 3 / Enemy.AverageWidth) Missiles.Init(Window) Window.Buffered = TRUE
$hEnemies = NEW Timer AS "Enemies" ' TODO: The Timers are made for a 80*24 terminal. ' Make it 100 and you'll likely win, 75 really depends on the amount of Borg for me... $hEnemies.Delay = 75 $hMissiles = NEW Timer AS "Missiles" $hMissiles.Delay = 50
$hEnemies.Start() $hMissiles.Start()
END
PUBLIC SUB Window_Read()
SELECT Window.Read() ' Navigate left/right CASE Key.Left IF X = 0 THEN RETURN Undraw() DEC X Draw() CASE Key.Right IF X + Width >= Window.Width THEN RETURN Undraw() INC X Draw() ' Navigate up/down CASE Key.Up IF Y <= 0 THEN RETURN Undraw() DEC Y Draw() CASE Key.Down IF Y >= Window.Height - Height THEN RETURN Undraw() INC Y Draw() ' Shoot normal missile CASE Key[" "] Missiles.Shoot(Missile.Normal, X, Y - 1) 'If Not $hMissiles.Enabled Then $hMissiles.Start() ' Shoot super missile CASE Key["v"] Missiles.Shoot(Missile.Super, X, Y - 1) 'If Not $hMissiles.Enabled Then $hMissiles.Start ' Of course, manipulate the timers CASE Key["+"] $hEnemies.Delay -= 10 $hMissiles.Delay -= 5 CASE Key["-"] $hEnemies.Delay += 10 $hMissiles.Delay += 5 END SELECT
END
PUBLIC SUB Enemies_Triumph()
End("TRIUMPH!", Color.Yellow)
END
PUBLIC SUB Enemies_GameOver()
End("GAME OVER!", Color.Blue)
END
PRIVATE SUB End(sMessage AS STRING, iColor AS INTEGER)
$hEnemies.Stop() $hMissiles.Stop() '' TODO: The message display is glitchy Window.Buffered = FALSE Window.PrintCenter(sMessage,, Pair[iColor, Window.Background]) '' TODO: What now? Note that the user can still interact at this point...
END
PRIVATE SUB Draw()
Window.Print(" | ", X, Y) Window.Print("^'^", X, Y + 1)
END
PRIVATE SUB Undraw()
Window.Print(Space$(Width), X, Y) Window.Print(Space$(Width), X, Y + 1)
END
PUBLIC SUB Enemies_Timer()
Enemies.Move() IF NOT $hMissiles.Enabled THEN Enemies.Draw() Screen.Refresh() ENDIF
END
PUBLIC SUB Missiles_Timer()
IF Missiles.Move() AND Missiles.Count = 0 THEN '$hMissiles.Stop() RETURN ENDIF ' Missiles draw at a higher rate so we can safely redraw everything ' here. Note that, thanks to ncurses' buffering, only the changed ' parts are redrawn so that there is no overhead in more frequent ' Screen.Refresh()es here. Enemies.Draw() Screen.Refresh()
END
|