'' '' Cabezóóón by The Mojon Twins '' A game for the CSSCGC 2010 '' Big-headed platforming action! '' '' Copyleft 2010 by the Mojon Twins '' http://www.mojontwins.com '' '' Compiles using Boriel's ZX Basic v. 1.2.6 r 1564 '' http://www.boriel.com/software/the-zx-basic-compiler/ '' ' ----------------------------------------------------------------------------- ' Compiling: just type this in a command prompt from where this source is: ' zxb -O3 -T -B -a cabezooon.bas ' Some disclaimers: ' I use random screen generators quite often. Those rely on a properly ' placed Randomize which makes those random generated patters always the same. ' The game is playable with the actual random number generator code included ' in the compiler runtime. If this changes, patterns won't be the same. ' If you want to build this game from this source code, and you get some ' unplayable situations, the random number generator may have changed. In ' such case, build this using ZX Basic v. 1.2.6. ' ----------------------------------------------------------------------------- ' Stuff I use: #include once #include once '' ============ '' Declarations '' ============ ' TYPEs are not yet implemented in ZX Basic as of v. 1.2.6, so I'll be using ' some kind of naming convention for variables. Variables which a common prefix ' are supposed to be related, for example pl* are for the player, con* for ' connections, fly* for the fly, es* for the extra stuff, etc. ' I don't usually use many global variables, but they are somewhat faster and ' not having TYPEs would make function calls rather tedious. And slow. Dim plSal As Integer ' Player, True if jump is active Dim plNu As Integer ' Player, jump counter Dim plFacing As Integer ' Player, 0 faces right, 1 faces left Dim plFrame As Integer ' Player, walk animation frame Dim plX As UByte ' Player, X coordinate Dim plY As UByte ' Player, Y coordinate Dim plXorg As UByte ' Player, X coordinate when entering current screen Dim plYorg As UByte ' Player, Y coordinate when entering current screen Dim plLives As UByte ' Player, lives. Dim nPant As Byte ' Current screen Dim conU As Byte ' screen connection up. -1 = N/A Dim conD As Byte ' screen connection down. -1 = N/A Dim conL As Byte ' screen connection left. -1 = N/A Dim conR As Byte ' screen connection right. -1 = N/A Dim cambiaPantalla As Byte ' flag used during gameplay to activate a full screen redraw Dim gameOver As Byte ' flag used during gameplay to tell the engine the game is over Dim win As Byte ' flag used during gameplay to tell the engine the game is won Dim key As String ' temp variable used to store the latest keypress (menu/password) Dim pass As String ' temp variable used to store the password the player enters. Dim terminado As Byte ' flag variable. Dim extraStuff as Byte ' If <> 0, there's extra stuff happenning during gameplay ' This is DA FLY. It's only there to waste some time and make ' the game more playable. I hate dummy delays. This is more ' beautiful Dim flyX As Byte ' The fly X coordinate Dim flyY As Byte ' The fly Y coordinate Dim flyCX As UByte ' The fly former X coordinate Dim flyCY As UByte ' The fly former Y coordinate Dim flyChar As String ' Used to store the background char Dim flyAttr As UByte ' Used to store the background attr Dim flyM As Byte ' temp variable to decide in which direction the fly will move Dim flyCt As Byte ' counter variable. ' Yet slower... We draw a banner which will make everything even slower ' Funny how sometimes you have to WASTE cycles. Dim bogusMessage As String ' Stupid banner Dim bogusPointer As Integer ' Stupid banner position Dim bogusCt As Byte ' Stupid banner counter bogusMessage = " THIS MAKES THE GAME RUN SLOWER YEAH I NEEDED A SLOWER PACED GAME SO I PLACED THE FLY AND THEN THIS BOGGUS BANNER AND INDEED THIS MAKES THE GAME LOOK EVEN WEIRDER THAN IT ORIGINALLY WAS ONLY THE MOJON TWINS COULD DO IT HEHEHE ALL HAIL ME " bogusPointer = 0 bogusCt = 0 ' extraStuff section: general variables to perform extraStuff activities. ' for example, the serpent duchess/queen/king and stuff like that. Dim esX (31) As Byte ' Array of 32 X coordinates (0 to 31) Dim esY (31) As Byte ' Array of 32 Y coordinates (0 to 31) Dim esMX As Byte ' movement in the X axis (usually -1, 0 or 1) Dim esMY As Byte ' movement in the Y axis (usually -1, 0 or 1) Dim esCt As Byte ' Counter Dim esGeneral As Byte ' General value. '' ==================== '' Inizialization stuff '' ==================== ' Chars (straight from SevenuP, with added "_" so ZXBasic doesn't complain :) ). Dim chars (767) As uByte => { _ 0, 0, 0, 0, 0, 0, 0, 0, _ 21, 32, 64, 64, 0, 64, 32, 21, _ 85, 0, 0, 56,124,108, 60, 95, _ 85, 0, 0, 7, 31, 63, 63,255, _ 85, 0, 0,255,247,247,255,254, _ 84, 2, 1,255,239,239,254,124, _ 0, 94,214,218,230,124, 16, 28, _ 0, 94,190,182,206,124,133,195, _ 42, 64,128,255,247,247,127, 62, _ 170, 0, 0,255,239,239,255,127, _ 170, 0, 0,224,248,252,252,255, _ 170, 0, 0, 28, 62, 54, 60,250, _ 168, 4, 2, 2, 0, 2, 4,168, _ 0,122,107, 91,103, 62, 8, 56, _ 0,122,125,109,115, 62,161,195, _ 85, 0, 0, 0, 0, 0, 0, 85, _ 85, 0, 0,255,255,255,255,255, _ 15, 33, 12,214,204,225,127,124, _ 192,240,192, 24, 44,153,195, 63, _ 113,116,112, 57, 28, 15, 7, 0, _ 79, 44, 12, 92, 56,240,224, 0, _ 60,126,255,255,255,255,126, 60, _ 60,126,219,219,255,231, 90, 60, _ 0, 0, 68,255, 58,229, 28,255, _ 1, 0, 1, 3, 1, 57, 5, 85, _ 5,117, 13,117, 5, 41, 71,129, _ 167,165,165,189, 61, 37, 37,109, _ 7, 8, 16, 16, 32, 33, 35, 33, _ 240, 12, 2, 0,169,170,248,240, _ 32, 71, 45, 24, 19, 7, 2, 3, _ 0,248,244, 2,248,252, 16, 24, _ 60,126,219,255,219,231,126, 60, _ 0, 60, 74, 86, 94, 64, 60, 0, _ 0, 8, 28, 52,100,254,130, 0, _ 0,248, 76, 76,126, 70, 78,120, _ 0, 62, 96, 64, 64, 96, 60, 0, _ 0,120, 76, 70, 66, 70,124, 0, _ 0,126, 96,124, 96, 96,126, 0, _ 0, 0,127, 96,124, 96, 96, 0, _ 0, 62, 96, 76, 68,124, 56, 0, _ 64, 66, 66,114,126, 66, 66, 2, _ 0, 32, 0, 32, 32, 48, 28, 0, _ 0, 8, 0, 8, 8,136,112, 0, _ 0, 66, 68, 72,112, 88, 68, 0, _ 0, 16, 32, 32, 96,178, 76, 0, _ 64, 70,102,126, 90, 66, 66, 64, _ 0, 98,114,122, 78, 70, 66, 0, _ 0, 56,108, 68, 68,108, 56, 0, _ 0,124, 70, 70,126,120, 64, 0, _ 62, 99, 65, 65,107, 62, 8, 8, _ 0,124, 66, 70,124, 76,102, 0, _ 0, 60, 96, 96, 60, 6,238, 56, _ 0,126, 82, 16, 16, 24, 56, 0, _ 0, 66, 66, 66, 66,102, 60, 0, _ 0,195, 66,102, 60, 24, 24, 0, _ 0, 66, 74, 74, 74, 62, 28, 0, _ 0, 68,108, 56, 24, 44,100, 0, _ 0,102,102, 62, 6, 12, 56, 0, _ 0, 62, 12, 24, 48, 96,126, 0, _ 24, 16, 16, 16, 16, 16, 24, 0, _ 128, 64, 32, 16, 8, 4, 2, 0, _ 48, 16, 16, 16, 16, 16, 48, 0, _ 0, 16, 56, 84, 16, 16, 16, 0, _ 0, 0, 0, 0, 0, 0, 0,255, _ 0, 0, 0, 0, 0, 0, 0, 0, _ 238,119,187,221,238,119,187,221, _ 164,165,149, 93,138, 85,170,255, _ 56,124, 14,166,215,230,213,106, _ 28, 44, 28, 40, 0, 94, 62, 86, _ 28, 44, 28, 44, 28, 44, 28, 44, _ 170,255,255, 0,102, 60, 0, 60, _ 170,255,255, 0, 0, 0, 0, 0, _ 0, 32, 34, 34, 51,115,119,119, _ 95, 53, 75,166,127,183, 78, 17, _ 117,222, 60,154, 7,174,221,116, _ 255,193,226,212,200,212,226,193, _ 124,190,126,190, 94, 60, 80,170, _ 0,170,170,170, 0,170,170,170, _ 254,146,146,254,146,146,254, 0, _ 0, 0, 0, 16, 0, 0, 0, 0, _ 0, 0, 0, 0, 0, 40, 16, 40, _ 0,254,254,254, 0,247,247,247, _ 128,192,224,240,240,224,192,128, _ 24, 60, 60, 90, 66, 66, 36, 0, _ 127, 63, 30, 28, 24, 48, 96,128, _ 128, 64, 2, 33, 16,128, 64, 0, _ 85, 85, 82, 82,178,178,172,168, _ 64, 32, 24, 23, 13, 11, 5, 3, _ 1, 2, 13,250,202,180,248,224, _ 32, 96,232,220,220,220, 88, 16, _ 8, 26, 59, 59, 59, 23, 6, 4, _ 0, 0, 0, 0, 0, 0, 0, 0, _ 0, 0, 0, 0, 0, 0, 0, 0, _ 0, 0, 0, 0, 0, 0, 0, 0, _ 0, 0, 0, 0, 0, 0, 0, 0, _ 0, 0, 0, 0, 0, 0, 0, 0 _ } Poke uInteger 23606, (@chars (0)) - 256 ' Sprites. Facing = 1 => left, 0 => right Dim SprHead (1) As String SprHead (0) = "!" + Chr (34) + "#$%" SprHead (1) = "()*+," Dim SprWalk (3) As String SprWalk (0) = "&" SprWalk (1) = "'" SprWalk (2) = "-" SprWalk (3) = "." ' Well... Let's go. Main loop, main inner loop, and general stupidity ahead. ' And then, afterwards, the SUBs and FUNCTIONs. '' ========= '' Main loop '' ========= start: Border 0: Paper 0: Ink 7: Cls Do ' Pantalla de título cutre Cls ' From Blocky Graphs by Mojon Twins: Print At 0,0; "\{p3}\{i3}\::\::\::\::\::\::\::\::\::\{i1}\.:\{p1}\::\{i3}\ '\{p3}\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\{i1}\ :\{p1}\::\::\::\{i3}\ '\{p3}\::\::\::\{i1}\.:\. \{i3}\::\::\::\::\::\{p0}\:'\''\''\''\{p3}\::\::\::\::\::\::\{i1}\ :\:.\{i3}\::\::\::\::\::\{p1}\{i1}\::\::\::\::\::\{i3}\ '\{p3}\::\{i1}\.:\{p1}\::\::\{i3}\''\{p0}\''\''\{i0}\::\::\{p7}\''\' \{i7}\::\::\{i0}\''\{p3}\. \..\{i3}\::\::\{p1}\:'\{i1}\::\::\{i3}\ '\{p3}\::\::\::\{i1}\ :\{p1}\::\::\::\::\::\::\::\{p0}\:'\''\{i0}\::\::\{p7}\:'\''\{i7}\::\::\::\::\::\::\::\{i0}\ :\{p3}\:.\..\{i3}\::\{p1}\{i1}\::\::\::\::\{i3}\ '\{p3}\::\{p1}\:'\{i1}\::\::\::\::\::\::\{p0}\:'\' \{i0}\::\::\{p7}\''\' \{i7}\::\::\::\::\::\::\::\::\::\::\{i0}\':\{p3}\' \{i3}\::\{p1}\{i1}\::\::\::\::\::\{i3}\ :\' \{i1}\::\::\::\::\{p0}\''\{i0}\::\::\{p7}\:'\''\{i7}\::\::\::\::\::\::\::\::\::\::\::\::\::\{i0}\ :\{p3}\: \{i3}\::\{p1}\{i1}\::\::\::\::\::\::\::\::\::\{p0}\''\{i0}\::\::\{p7}\''\' \{i7}\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\{i0}\ :\{p3}\{i3}\::\::\{p1}\{i1}\::\::\::\::\::\::\::\{p0}\''\{i0}\::\{p7}\:'\' \{i7}\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\{p0}\{i0}\::\{p3}\{i3}\::\::\{p1}\{i1}\::\::\::\::\::\{p0}\''\{i0}\::\{p7}\''\{i7}\::\::\::\::\::\::\::\::\{i0}\.'\' \{i7}\::\::\::\::\::\::\::\::\::\{p0}\:'\' \{i1}\.:\{p3}\:.\{i3}\::\{p1}\{i1}\::\::\::\::\{i0}\.:\{p7}\''\{i7}\::\::\::\::\::\::\{i0}\ '\'.\{i7}\::\{i0}\ '\ .\. \{i7}\::\::\::\::\::\::\::\{p0}\:'\' \{i1}\..\{p1}\::\::\::\::\::\::\::\{i0}\.:\{p7}\' \{i7}\::\::\::\::\::\::\::\{p0}\:'\':\':\{p7}\::\{i0}\ '\' \{i7}\::\::\::\::\::\{p0}\''\{i1}\..\.:\{p1}\::\::\::\::\::\::\::\::\{i0}\.:\{p7}\' \{i7}\::\::\::\::\::\::\::\::\{i0}\ '\' \'.\' \..\{i7}\::\::\::\{p0}\''\' \{i1}\..\{p1}\::\::\::\::\::\::\::\::\::\::\{p0}\:'\{i0}\::\{p7}\{i7}\::\::\::\::\::\::\::\::\::\::\::\{p0}\''\..\{p7}\::\{p0}\''\' \{i1}\..\{i0}\::\{p1}\{i1}\::\::\::\{p4}\':\':\{p1}\::\::\::\::\::\::\::\{i0}\ :\{p0}\::\{p7}\{i7}\::\::\::\::\::\::\::\::\::\::\::\{p0}\''\' \{i0}\::\::\{i1}\':\: \{i0}\::\{p1}\{i1}\::\{i4}\ '\. \.'\{i1}\::\::\::\::\{p4}\:'\{p1}\::\::\{p4}\':\{p1}\::\{i0}\':\{p7}\:.\{i7}\::\::\::\::\::\::\::\{p0}\:'\''\{i1}\..\{i0}\::\::\::\{p1}\:'\{p0}\::\::\{i1}\.:\{p1}\::\::\{i4}\ '\. \{i1}\::\::\{p4}\':\.'\.:\{p1}\::\::\{p4}\{i4}\::\{i1}\''\{p1}\::\{i0}\''\{p0}\::\{i7}\''\''\''\''\''\{i1}\..\.:\:'\{i0}\::\::\::\::\{i1}\ :\{p1}\::\::\::\::\{p4}\:'\' \ '\':\{p1}\::\{i4}\ '\':\. \{i1}\::\{p4}\':\{i4}\::\::\::\::\::\{i0}\ '\''\''\{i4}\::\::\::\::\{i0}\ :\{p0}\::\{p4}\:'\''\{p0}\::\::\{i4}\''\''\{p4}\::\::\::\::\::\::\::\{p6}\':\{p4}\::\::\::\::\{i6}\ '\{i4}\::\::\{p6}\':\{p4}\::\::\::\::\::\{p6}\':\{p4}\::\{p0}\''\{i0}\::\::\{p4}\{i4}\::\::\::\{i0}\''\''\{p0}\::\{p4}\{i4}\::\{p6}\:'\{p4}\::\::\::\::\::\::\::\::\{p6}\':\{p4}\::\::\::\{p6}\':\{p4}\::\::\::\{p6}\.:\{p4}\::\::\::\{p6}\:'\{p4}\::\::\{i0}\''\{i4}\::\::\{p6}\.:\{p4}\::\::\::\::\::\::\::\{i6}\ '\{i4}\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\{p6}\.:\{p4}\::\::\::\::\::\::\{p6}\':\{p4}\::\::\{i6}\ '\{i4}\::\::\::\::\::\::\::\::\{i6}\ '\{i4}\::\::\::\{p6}\.:" plX=1 plY=21 manolitoDraw () nPant = -1 ' Cheesy menu code. While nPant = -1 centra (21, " G PLAY GAME ") centra (22, " P PASSWORD ") key = Inkey () If key ="G" or key ="g" Then nPant = 0 ElseIf key = "P" or key = "p" Then checkPassword () End If Wend ' Game loop Cls playerInit () win = 0 gameOver = 0 While Not gameOver scrDraw () plXorg = plX plYorg = plY manolitoDraw () cambiaPantalla = 0 While Not cambiaPantalla ' This moves the main character playerMove () ' This moves the fly, which is conceived to waste time. Only if there's ' no extra stuff... If extraStuff = 0 Then flyMove () End If ' This moves the banner, which is conceived to waste even more time. bogusDraw () ' Flick of the wris... screen cambiaPantalla = checkNewScreen () If (Not cambiaPantalla) Then ' If there's extra stuff to do, just do it If extraStuff = 1 Then cambiaPantalla = serpentMove () End If ' Suicidal. Check if 'S' is pressed... cambiaPantalla = cambiaPantalla Or checkIfSPressed () ' Fly attack. If extraStuff = 0 Then cambiaPantalla = cambiaPantalla Or checkFlyAttack () End If End If ' Game Over? gameOver = checkIfGameOver () Wend if nPant = 42 Then win = 1 gameOver = 1 End If Wend If win = 1 Then final () End If Loop End '' ======================= '' Subroutines & Functions '' ======================= Function attr (y As Integer, x As Integer) ' Reads an attribute value from screen. I know, I'm reinventing the ' wheel. ZXBasic already has one. But I didn't notice. Return Peek (Ubyte, 22528 + (y << 5) + x) End Function Sub setAttr (y As Integer, x As Integer, i As Integer) ' Paints a screen square with the provided attribute value. Poke 22528 + (y << 5) + x, i End Sub Sub playerInit () ' This sub initializes Manolito. Just that. plX = 1: plY = 8 plSal = 0: plNu = 0 plFacing = 0: plFrame = 0 plLives = 3 End Sub Sub presenta (y As Integer, t as String) ' Centers a text with fade in/fade out and a 2 seconds delay Dim i As Byte For i = 0 To 7 Print At y, 16 - Len (t) / 2; Ink i; Bright 1; t Pause 1 Next i Pause 100 For i = 7 To 0 Step -1 Print At y, 16 - Len (t) / 2; Ink i; Bright 1; t Pause 1 Next i End Sub Sub final () ' Secuencia final Dim i As Byte ' Clear keypress While Code(Inkey ()) <> 0 Wend Cls Print At 21, 0; Ink 4; "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" Print At 22, 0; Ink 5; "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" Print At 23, 0; Ink 5; "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" plX = 10 plY = 19 manolitoDraw () Print At 18, 16; Ink 2; "8"; At 19, 16; "9"; At 20, 16; ":" presenta (2, "I AM THE JIBARE GURU") presenta (2, "I CAN HELP YOU") presenta (2, "WITH YOUR PROBLEM") Pause 100 presenta (2, "CLOSE YOUR EYES") presenta (2, "AND WAIT") Pause 100 Paper 7: Cls: Pause 1 Paper 0: Cls: Pause 1 Paper 7: Cls: Pause 1 Paper 0: Cls: Pause 1 Paper 7: Cls: Pause 1 Paper 0: Cls: Pause 1 Print At 21, 0; Ink 4; "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" Print At 22, 0; Ink 5; "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" Print At 23, 0; Ink 5; "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" Print At plY, plX + 2; Ink 7; "?"; At plY + 1, plX + 2; Ink 4; "&" Print At 18, 16; Ink 2; "8"; At 19, 16; "9"; At 20, 16; ":" presenta (2, "SEE") presenta (2, "NOW YOUR BIG HEAD IS GONE") presenta (2, "YOU ARE FREE TO GO") Pause 100 Cls Print At 21, 0; Ink 4; "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" Print At 22, 0; Ink 5; "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" Print At 23, 0; Ink 5; "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" Print At 19, 10; Ink 4; ";<";At 20, 10; "=>" Pause 50 presenta (2, "MY LOVE") presenta (2, "IM COMMING") For i = 30 To 16 Step -1 Print At 19, i; Ink 7; "? "; Ink 4; At 20, i; "& "; Pause 20 Next i presenta (2, "SEE HOW MY BIG HEAD IS GONE") Pause 100 Ink 4 presenta (2, "OH MAN") Pause 50 presenta (2, "YOUR HEAD") Pause 50 presenta (2, "THATS DISGUSTING") presenta (2, "EWWWWWW") Pause 100 Ink 7 Cls centra (12, "THE END") Pause 1000 End Sub Sub playerMove () ' This sub reads the keyboard and stuff. Stuff is making Manolito ' move and interact with the background. Simple platforming engine ' ahead. I must have coded this like 1,000 times in several languages ' and platforms, and I still like doing it from scratch. It gets ' better, shorter and faster each time :-) ' If jump is active (plSal = TRUE) we skip the falling routine If Not plSal Then ' Rutina que hace que caigamos: If attr (plY + 1, plX) = 7 And _ attr (plY + 1, plX + 1) = 7 And _ attr (plY + 2, plX + 2) = 7 And _ attr (plY + 1, plX + 3) = 7 And _ attr (plY + 1, plX + 4) = 7 Then Print At plY, plX; Ink 7; Bright 0; " "; _ At plY + 1, plX; Bright 1; SprHead (plFacing); _ At plY + 2, plX + 2; Bright 0; Ink 4; SprWalk (plFacing + plFacing + plFrame) plY = plY + 1 Beep .01, 30 - plY End If End If ' Check for horizontal movement If In 57342 = 253 Or In 57342 = 189 Then ' Read "O" from issue 2/3 If plX > 0 Then If attr (plY, plX - 1) = 7 And _ attr (plY + 1, plX + 1) = 7 Then plX = plX - 1 plFacing = 1 plFrame = 1 - plFrame Print At plY, plX; Ink 7; Bright 1; SprHead (plFacing); Bright 0; " "; _ At plY + 1, plX + 2; Ink 4; SprWalk (plFacing + plFacing + plFrame); Ink 7; " " If attr (plY + 2, plX + 2) <> 7 Then Beep .01, -20: End If End If End If ElseIf In 57342 = 254 Or In 57342 = 190 Then ' Read "P" from issue 2/3 If plX < 27 Then If attr (plY, plX + 5) = 7 And _ attr (plY + 1, plX + 3) = 7 Then plFacing = 0 plFrame = 1 - plFrame Print At plY, plX; Ink 7; Bright 0; " "; Bright 1; SprHead (plFacing); _ At plY + 1, plX + 2; Bright 0; " "; Ink 4; SprWalk (plFacing + plFacing + plFrame); plX = plX + 1 If attr (plY + 2, plX + 2) <> 7 Then Beep .01, -20: End If End If End If End If ' Check if we jump (You can only jump if your feet are on a flatform, ' the huge head doesn't count. You are not a cephallopode). If Not plSal Then If In 32766 = 254 Or In 32766 = 190 Then ' Read "SPACE" from issue 2/3 If attr (plY + 2, plX + 2) <> 7 Then plSal = 1 plNu = 0 End If End If Else ' Simplest jump routine ever. Heck, ain't this a crap compo? Sheesh... If plY > 0 Then If attr (plY - 1, plX) = 7 And _ attr (plY - 1, plX + 1) = 7 And _ attr (plY - 1, plX + 2) = 7 And _ attr (plY - 1, plX + 3) = 7 And _ attr (plY - 1, plX + 4) = 7 Then plY = plY - 1 Print At plY, plX; Ink 7; Bright 1; SprHead (plFacing); _ At plY + 1, plX; Bright 0; " "; Ink 4; SprWalk (plFacing + plFacing + plFrame); Ink 7; " "; _ At plY + 2, plX + 2; " " Beep .01, 30 - plY End If End If plNu = plNu + 1 If plNu = 5 Then plSal = 0 End If End If End Sub Sub flyMove () ' A beautiful way to waste some cycles. This displays an odd bug ' we have named "the fly" which floats around. If it hits Manolito, ' you have to restart the screen (but you don't lose a life, don't ' worry). ' Move a bit, but only 1 out of 8 frames. ' That's why we check and update flyCt. If flyCt = 0 Then flyM = Int (Rnd * 3) - 1 ' -1, 0, 1 flyX = flyX + flyM If flyX < 0 Or flyX > 31 Then flyX = flyCX End If flyM = Int (Rnd * 3) - 1 ' -1, 0, 1 flyY = flyY + flyM If flyY < 0 Or flyY > 21 Then flyY = flyCY End If ' Restore previous backgrouns Print At flyCY, flyCX; flyChar; setAttr (flyCY, flyCX, flyAttr) ' Get new background flyChar = Screen (flyY, flyX) flyAttr = attr (flyY, flyX) End If flyCt = flyCt + 1 If flyCt = 8 Then flyCt = 0 End If ' Re-draw Print At flyY, flyX; Ink 4; "s"; flyCX = flyX flyCY = flyY End Sub Function checkNewScreen () ' This functions checks if we have to flick the screen. ' Basicly it checks if the player is at a screen boundary and ' there's movement to that direction. Dim newScreen As Integer newScreen = 0 If plX = 0 And _ (In 57342 = 253 Or In 57342 = 189) And _ conL >= 0 Then plX = 27 nPant = conL plFacing = 1 newScreen = 1 ElseIf plX = 27 And _ (In 57342 = 254 Or In 57342 = 190) And _ conR >= 0 Then plX = 0 nPant = conR plFacing = 0 newScreen = 1 ElseIf plY = 1 And plSal And conU >= 0 Then plY = 20 plNu = plNu - 1 ' Prolongamos el salto un paso más nPant = conU newScreen = 1 ElseIf plY = 20 And Not plSal And conD >= 0 Then plY = 1 nPant = conD newScreen = 1 End If Return newScreen End Function Sub die () ' Exploding head (death sequence). Funny and so crappy it rocks. Dim t As Integer Dim i As Byte Print At plY, plX; Bright 1; Ink 2; SprHead (plFacing); For i = 0 to 10 Beep .1, -10 + Int (Rnd * 5) Next i Print At plY, plX; Bright 0; Ink 2; "ijiji" beep .5, -15 Print At plY, plX; Bright 1; Ink 2; " h " beep .5, -30 t = 0 While Not t If attr (plY + 2, plX + 2) = 7 Then Print At plY, plX + 2; " "; _ At plY + 1, plX + 2; Ink 2; Bright 1; "h"; _ At plY + 2, plX + 2; Ink 4; Bright 0; SprWalk (plFacing + plFacing + plFrame); plY = plY + 1 Else t = 1 End If beep .01, 30 - plY Wend beep 1, -30 plX = plXorg plY = plYorg End Sub Sub restart () ' Displays Manolito with a cyan head crying "OUCHH". Dim i As Byte Print At plY - 2, plX; Paper 7; Ink 0; "OUCHH"; At plY - 1, plX + 2; Ink 7; Paper 0; "t"; Print At plY, plX; Bright 1; Ink 5; SprHead (plFacing); For i = 0 to 10 Beep .1, -10 + Int (Rnd * 5) Next i plX = plXorg plY = plYorg End Sub Function checkIfSPressed () ' This function checks if S is pressed. If so, Manolito suicides. ' This calls "die", which displays the dying animation. Dim suicide As Integer suicide = 0 If In (65022) = 189 Or In (65022) = 253 Then die () suicide = 1 plLives = plLives - 1 End If Return suicide End Function Function checkFlyAttack () ' This function checks if the fly attacks. If so, it Makes you ' start the current screen over, but it doesn't kill you. ' This calls "restart", which displays Manolito with a cyan head ' crying "OUCHH". Dim memuero As Integer memuero = 0 If (flyX >= plX And flyX <= plX + 4 And flyY = plY) Or _ (flyX = plX + 2 And flyY = plY + 1) Then restart () memuero = 1 End If Return memuero End Function Function checkIfGameOver () ' This function checks if the game is... over. This happens when ' plLives is -1. Dim gameIsOver As Integer gameIsOver = 0 If plLives = -1 Then Print at 11, 11; "\{p2}\{i4}\{b1} GAME OVER " beep 1, -10 gameIsOver = 1 End If Return gameIsOver End Function Sub manolitoDraw () ' Draws manolito (pretty self-explanatory). This is used when ' entering a new screen. Print At plY, plX; Bright 1; Ink 7; SprHead (plFacing); _ At plY + 1, plX + 2; Bright 0; Ink 4; SprWalk (plFacing + plFacing + plFrame) End Sub Sub terrainDraw (terrain As String) ' Draws a terrain based on heights in string terrain, which ' contains 32 numbers (0 - 9) indicating the height of each ' column, from bottom to top. Dim i As Byte Dim j As Byte Dim y As Byte For i = 0 To 31 y = asc (terrain, i) - 48 For j = 0 To y If j < y Then Print At 21-j, i; Ink 3; Chr (105 + Int (Rnd * 2)) Else Print At 21-j, i; Ink 4; "b" End If Next j Next i End Sub Sub houseDraw (x As Byte, y as Byte, hWidth as Byte, hHeight as Byte) ' Draws a house from (x, y) up and right. It generates ' windows and roof automaticly to fit. Cheesy but nice. Dim i As Byte Dim j As Byte ' Body For i = y To y - hHeight + 1 Step -1 For j = x To x + hWidth - 1 Print At i, j; Paper 6; Ink 2; "q" Next j Next i ' Windows For i = y - 1 To y - hHeight + 2 Step -2 For j = x + 1 To x + hWidth - 2 Step 2 Print At i, j; Paper 0; Ink 5; "n" Next j Next i ' Roof For j = x To x + hWidth - 1 Print At y - hHeight, j; Paper 0; Ink 2; "m" Next j End Sub Sub cityScapeDraw (cityScape as String) ' Draws a city scape based on cityScape, which is just a string of ' numeric values which indicate the height of 8 different buildings. Dim i As Byte Dim y As Byte bottomDraw () For i = 0 To 7 y = asc (cityScape, i) - 48 houseDraw (i * 4, 19, 4, 3 * y) Next i End Sub Sub bogusDraw () ' This sub displays the bogus banner you can see scrolling at the top ' of your screen. Its only purpose is to waste some cycles to make the ' game a little bit more playable. ' Below you can see the standard scrolling banner code you can find ' anywhere. Print Paper 3; Ink 4; At 0, 19; bogusMessage (bogusPointer To 9 + bogusPointer) bogusCt = bogusCt + 1 If bogusCt = 8 Then bogusCt = 0 bogusPointer = bogusPointer + 1 If bogusPointer = Len (bogusMessage) Then bogusPointer = 0 End If End If End Sub Sub forestTopDraw () ' This sub draws a pseudorandom forest top landscape. I say pseudorandom ' 'cause the RANDOMIZE used to nPant sort of certifies the random numbers ' will be the same everytime you enter each screen... Dim i As Byte Dim j As Byte Dim k As Byte Dim current As Byte Randomize nPant ' Ah, the joy of having a nice seed... ' This is what I call controlled randomness ' (or blatant treachery) current = Int (Rnd * 8) + 1 For i = 0 To 31 ' Draw current column For j = 0 To current Print At j + 1, i; Paper 4; Ink 2; "u" Next j ' A couple of nice leaves Print At 1 + Int (Rnd * current) , i; Paper 4; Ink 6; "y" Print At 1 + Int (Rnd * current) , i; Paper 4; Ink 6; "z" ' Calculate the length of the next column... k = Int (Rnd * 3) - 1 ' -1, 0, 1. current = current + k If current < 0 Then current = 0: End If If current > 7 Then current = 7: End If Next i End Sub Sub bottomDraw () ' This sub draws a plain boring floor Print At 20, 0; "\{i4}bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";_ "\{i5}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" End Sub Sub scrDraw () ' This sub just sets up a new screen. It basicly draws the frame, then ' looks in nPant and draws the correct background. For each screen, it ' defines the variables conL, conR, conU and conD, which are used by ' the engine to know which screens connect with the current one. If the ' value of one of such variables is -1, that means that there's no ' connection to that direction (L = left, R = right, U = up, D = down ' in case you didn't notice!). Otherwise, it contains the screen ID it ' connects to. Ñe. ' After doing everything, it initializes the fly, that tiny sprite which ' floats around. flyX = Int (Rnd * 16) + 8 flyY = Int (RNd * 20) + 2 ' Esto es una burracada, pero son pocas pantallas y bleh. Dim i As Byte Dim j As Byte Dim mj As Byte Dim x As Byte For i = 1 To 21 Print At i, 0; " " Next i ' Reset connections conL = -1: conR = -1: conU = -1: conD = -1 ' Draw frame (and lives, etc) Print At 22, 0; "\{p1}\{b1}\{i2}fggggggggggggggggggggggggggggggf"; _ At 23, 0; "\{b1}\{i2}d MOJONTWINS d"; _ At 0, 0; "\{b1}\{p1}\{i2}nkk\{i7}LIVES:\{i6}"; If plLives = 3 then Print "\{b1}\{p1}\{i6}XXX"; ElseIf plLives = 2 then Print "\{b1}\{p1}\{i6} XX"; ElseIf plLives = 1 then Print "\{b1}\{p1}\{i6} X"; Else Print "\{b1}\{p1}\{i6} "; End If Print "\{b1}\{p1}\{i2}kkkkkkkkkkkkkkkkkkn"; Print Paper 3; Ink 4; At 0, 31; Chr (65 + nPant) ' Draw some stars... For i = 0 To 20 Print At Int (Rnd * 20) + 1, Int (Rnd * 32); Ink 7; Bright 0; "o" If i < 10 Then Print At Int (Rnd * 20) + 1, Int (Rnd * 32); Ink 7; Bright 0; "p" End If Next i ' Extra stuff during gameplay: Some screens may have some extra stuff ' happenning during gameplay. Normally there's nothing happenning, so ' we define extraStuff = 0. It may get redefined depending on nPant. extraStuff = 0 ' Then draw the background depending on nPant. ' (I wish I could "SELECT CASE", but I'll have to wait for the ' next ZX BASIC version. Hint, hint, Boriel ;-) ) If nPant = 0 Then centra (2, "MANOLITO BEGINS") centra (3, "HIS JOURNEY") Print At 18, 0; "\{b0}\{i4}bbbb\{i7} \{i4}b\{i7} \{i4}bbb"; _ "\{b0}\{i5}aaaa\{i4}b\{i5}a\{i4}bb\{i7} \{i4}bbb\{i7} \{i4}b\{i7} \{i4}bbbb\{i7} \{i4}b\{i5}aaa"; _ "\{b0}\{i5}aaaaaaaa\{i7} \{i5}aaa\{i4}b\{i5}a\{i7} \{i4}b\{i5}aaaa\{i4}b\{i7} \{i4}bb\{i5}aaaa"; _ "\{b0}\{i5}aaaaaaaa\{i4}bb\{i5}aaaaa\{i4}b\{i5}aaaaaa\{i4}bbbb\{i5}aaaaaa" For i = 1 To 16 Print At i, 0; "\{b1}\{i6}e" Next i Print At 17, 0; "\{b1}\{i6}d" conR = 1 ElseIf nPant = 1 Then centra (2, "BEWARE") centra (3, "DONT GET TRAPPED") Print Bright 1; Ink 6; At 17, 6; "l"; At 16, 7; "l"; At 15, 8; "l"; At 14, 9; "l"; _ At 14, 11; "llll"; At 15, 15; "lllll"; At 15, 24; "lll"; At 16, 27; "lllll" Print At 18, 0; "\{b0}\{i4}bbbb\{i7} "; _ "\{b0}\{i5}aaaa\{i7} "; _ "\{i5}aaaa\{i7} "; _ "\{i5}aaaa\{i7} \{i4}bb\{i7} " conR = 2 conL = 0 ElseIf nPant = 2 Then centra (2, "GO DOWN FOR") centra (3, "YR FIRST PERIL") Print At 20, 0; "\{b0}\{i7} \{p6}\{i1}k\{p0}\{i7} \{p6}\{i1}k\{p0}\{i7} \{i6}d"; _ "\{b0}\{i7} \{i4}bbbb\{p6}\{i1}k\{p0}\{i7} \{p6}\{i1}k\{p0}\{i4}bbbbbbbb"; _ Paper 0; Ink 6; Bright 1; At 16,0; "lll"; At 17, 3; "l"; At 18, 3; "l"; At 19, 3; "l"; At 20, 3; "l"; For i = 1 To 19 Print At i, 31; "\{b1}\{i6}e"; Next i Print At 20, 31; "\{b1}\{i6}d"; conD = 3 ElseIf nPant >= 3 And nPant <= 10 Then ' This will make the rooms always the same, albeit random Randomize nPant For i = 1 To 21 Print At i, 0; "\{b0}\{i2}\{p1}ijijiji\{b1}\{i1}\{p6}k\{b0}\{p0}\{i7} \{p6}\{b1}\{i1}k\{b0}\{i2}\{p1}ijijiji"; Next i For i = 1 To 5 x = 8 + Int (Rnd * 13) Print Ink 6; At 5 + i + i + i + Int (Rnd * 2), x + Int (Rnd * 2); "l"; _ At 5 + i + i + i + Int (Rnd * 2), x + 2 + Int (Rnd * 2); "l"; Next i ' Trick to make tunnels with just 1 screen :-D conU = nPant - 1 conD = nPant + 1 ElseIf nPant = 11 Then Print At 10, 10; "\{p6}\{i2}\{b1}qqqqqqqqqqqqq"; _ At 11, 10; "\{p6}\{i2}\{b1}q\{p0}\{i7} WELL DONE \{p6}\{i2}\{b1}q"; _ At 12, 10; "\{p6}\{i2}\{b1}qqqqqqqqqqqqq"; For i = 1 To 16 Print At i, 0; "\{b1}\{i6}e" Next i Print At 17, 0; "\{b1}\{i6}d" Print At 18, 0; "\{b0}\{i4}bbbbbb\{i7} "; _ "\{b0}\{i5}aaaaaa\{i4}bbb\{i7} "; _ "\{b0}\{i5}aaaaaaaaa\{i4}bbb\{i7} \{i4}bbbb"; _ "\{b0}\{i5}aaaaaaaaaaaa\{i4}bbbbbbbbbbbbbbbb\{i5}aaaa"; conR = 12 ElseIf nPant = 12 Then centra (2, "ABRUPT") centra (3, "LANDSCAPE") Ink 6: centra (4, "PASS FPOL"): Ink 7 terrainDraw ("11111234555666665555543212341333") conL = 11 conR = 13 ElseIf nPant = 13 Then centra (2, "WATCH OUT") terrainDraw ("33333678005675000762666000127777") conL = 12 conR = 14 ElseIf nPant = 14 Then centra (2, "WHOOPSIE") centra (3, "HIGH PEAKS") terrainDraw ("77777888900098000870999000822222") conL = 13 conR = 15 ElseIf nPant = 15 Then terrainDraw ("22222111000023000670099900099000") conL = 14 conR = 16 ElseIf nPant = 16 Then centra (2, "ALMOST") centra (3, "DONE") terrainDraw ("99988888000007700008000001112222") conL = 15 conR = 17 ElseIf nPant = 17 Then centra (2, "AND NOW") centra (3, "DA CITY") Ink 6: centra (4, "PASS YTIC"): Ink 7 terrainDraw ("22233344455511111111111111111111") Print Bright 1; At 18,21; Paper 7; Ink 0; "CITY"; Paper 0; Ink 7; "r" Print At 19,22; Ink 2; "d" conL = 16 conR = 18 ElseIf nPant = 18 Then bottomDraw () houseDraw (7, 19, 5, 3) houseDraw (17, 19, 7, 5) Print At 10, 25; "\{i6}fggf"; Print At 18, 25; "\{i6}ff"; Print At 19, 25; "\{i6}dd"; conL = 17 conR = 19 ElseIf nPant = 19 Then terrainDraw ("11111122333300003332344444444555") houseDraw (6, 18, 4, 3) houseDraw (22, 16, 3, 5) houseDraw (7, 14, 3, 3) Print At 11, 18; "\{i6}gggg" conL = 18 conR = 20 ElseIf nPant = 20 Then cityScapeDraw ("11314132") Print At 14, 5; "\{i6}ff"; Print At 15, 5; "\{i6}dd"; conL = 19 conR = 21 ElseIf nPant = 21 Then cityScapeDraw ("21230030") conL = 20 conR = 22 ElseIf nPant = 22 Then cityScapeDraw ("00123003") conL = 21 conR = 23 ElseIf nPant = 23 Then cityScapeDraw ("32002002") conL = 22 conR = 24 ElseIf nPant = 24 Then cityScapeDraw ("22002023") conL = 23 conR = 25 ElseIf nPant = 25 Then centra (2, "PRETTY POINTLESS") centra (3, "WASNT IT") cityScapeDraw ("33322200") conL = 24 conR = 26 ElseIf nPant = 26 Then forestTopDraw () bottomDraw () Print At 19, 0; Ink 3; "lllllll" centra (2, " ENTERING ") centra (3, " DA FOREST ") Ink 6: centra (4, " PASS FORE "): Ink 7 conL = 25 conR = 27 ElseIf nPant = 27 Then forestTopDraw () terrainDraw ("11111230321111134043322222500555") conL = 26 conR = 28 ElseIf nPant = 28 Then forestTopDraw () terrainDraw ("55555580008800008000007000001111") conL = 27 conR = 29 ElseIf nPant = 29 Then forestTopDraw () terrainDraw ("11111222333444555700700700000000") centra (2, " THERES NO ") centra (3, " COMMING BACK ") conL = 28 conR = 30 ElseIf nPant = 30 Then forestTopDraw () terrainDraw ("00001111222233334444555566669999") centra (2, " GOING UP ") centra (3, " THAT HILL ") Ink 6: centra (4, " PASS SERP "): Ink 7 conL = 29 conR = 31 ElseIf nPant = 31 Then terrainDraw ("99900000000000000000000000000009") centra (1, "THE LAIR OF THE SERPENT DUCHESS") ' Activates the serpent duchess during gameplay! extraStuff = 1 esGeneral = 4 ' The duchess is GREEN serpentInit () ' OK conL = 30 conR = 32 Randomize 10 ElseIf nPant = 32 Then forestTopDraw () Ink 6: centra (4, " PASS TESA "): Ink 7 terrainDraw ("99999777755552220000000000001111") conL = 31 conR = 33 ElseIf nPant = 33 Then ' 0 4 8 12 16 20 24 28 31 ' 1 ································ ' ································ ' ································ ' ················xxxx············ ' 5 ···············O·O·xxxO·.······· ' ·····x·················xxx···O·· ' ····O·················O···xxx··· ' ············x············O···xxx ' ···········O··················O· ' 10································ ' ·················x·····x········ ' ············x·············x····· ' ············x·············x····· ' ····x·······x·············x····· ' 15···O········x·············x····· ' ···········xx·············xx···· ' ··········xxx·············xxx··· ' ·······xxxxx···············xxxxx ' ····xxxxxxx··················xxx ' 20xxxxxxxxx·····················xx Print Ink 2; At 4, 16; "w77x"; At 5, 19; "w7x"; At 6, 23; "w7x"; At 7, 26; "w7x"; At 8, 29; "w77"; _ At 6, 5; "7"; At 9, 9; "7"; At 11, 17; "7"; At 11, 23; "7"; At 14, 4; "7"; Print Ink 4; At 12, 12; "b"; At 12, 26; "b"; _ At 5, 15; "y"; At 5, 17; "z"; At 5, 22; "y"; At 6, 29; "z"; _ At 7, 4; "y"; At 10, 8; "z"; At 9, 30; "y"; _ At 15, 3; "z"; Print Ink 3; At 13, 12; "i"; At 13, 26; "j"; _ At 14, 12; "j"; At 14, 26; "i"; _ At 15, 12; "j"; At 15, 26; "i"; _ At 16, 11; "ij"; At 16, 26; "ji"; _ At 17, 10; "jij"; At 17, 26;"iji"; _ At 18, 7; "jijij"; At 18, 27; "ijiji"; _ At 19, 4; "jijijij"; At 19, 29; "jij"; _ At 20, 0; "ijijijijij"; At 20, 30; "ji" centra (2, "ANT PERIL") conL = 32 conR = 34 ElseIf nPant = 34 Then forestTopDraw () terrainDraw ("33333344445555666666666666666666") centra (1, "SO CLOSE NOW") conL = 33 conR = 35 ElseIf nPant = 35 Then forestTopDraw () terrainDraw ("66666666555555555544444003000333") centra (1, "CLOSER") conL = 34 conR = 36 ElseIf nPant = 36 Then forestTopDraw () terrainDraw ("33334500500055000650005666555555") centra (1, "EVEN CLOSER") conL = 35 conR = 37 ElseIf nPant = 37 Then forestTopDraw () terrainDraw ("55555444440022000200022000222222") centra (1, "ALMOST THERE") conL = 36 conR = 38 ElseIf nPant = 38 Then terrainDraw ("22222222222111111111111111111000") centra (1, "FINAL") centra (2, "PERIL") Ink 6: centra (4, " PASS FINA "): Ink 7 conL = 37 conR = 39 ElseIf nPant = 39 or nPant = 40 Then Randomize nPant If nPant = 39 Then For i = 0 To 7 For j = 0 To i Print At j + 1, i; Paper 4; Ink 2; "u"; Next j Next i For i = 1 To 20 Print At i, 24; Paper 4; Ink 2; "uuuuuuuu"; At i, 24 + Int (Rnd * 8); Ink 6; "y" Next i Print At 21, 0; Ink 4; "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" Else For i = 1 To 21 Print At i, 0; Paper 4; Ink 2; "uuuuuuuu"; At i, Int (Rnd * 8); Ink 6; "y"; Print At i, 24; Paper 4; Ink 2; "uuuuuuuu"; At i, 24 + Int (Rnd * 8); Ink 6; "y"; Next i If plY = 20 Then plY = 19 Print At 21, plX; Ink 5; Bright 1; "ccccc" End If End If j = 8 + 6 * Int (Rnd * 2) ' This should originate two kinds of screens. mj = 6 * (2 * Int (Rnd * 2) - 1) ' -6 or 6. Learn how to produce interesting randoms, dude ;) For i = 3 To 20 Step 3 Print At i, j; Ink 5; "c"; At i, j + 2; "c"; ' This IF makes some platforms (about 50% of them) fully solid. ' It also makes the top platform fully solid. Otherwise this would ' create a nice unplayable situation. If Int (Rnd * 2) = 1 Or i = 3 Then Print At i, j + 1; Ink 5; "c"; End If ' New horizontal placement. Common ping-pong algorythm. Yay. j = j + mj If j = 8 or j = 20 Then mj = -mj: End If Next i If nPant = 39 Then conL = 38 Else conD = nPant - 1 End If conU = nPant + 1 ElseIf nPant = 41 Then ' Pantalla 42. Final del juego. Secuencia tonta animada Print At 21, 0; Ink 4; "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" Print At 14, 16; Ink 6; "8"; At 15, 16; "9"; At 16, 16; ":"; Ink 2; At 17, 14; "ccccc"; centra (3, "GO TO THE RIGHT") centra (4, "I WILL HELP YOU") centra (5, "WITH YOUR HUGE HEAD") plX = 0 plY = 19 conR = 42 Else ' ERROR End If ' DA FLY. Initialization flyCX = flyX flyCY = flyY flyChar = Screen (flyY, flyX) flyAttr = attr (flyY, flyX) flyCt = 0 End Sub Sub serpentInit () ' Initializes the serpent duchess/queen/king. See next ' SUB for more info about how it works. Dim i as uByte For i = 0 To 31 esX (i) = 4 esY (i) = 2 Next i esCt = 0 esMX = 0 esMY = 0 End Sub Function serpentMove () ' Makes the serpent move. Dim t As Byte Dim i As Byte Dim auxX As Byte Dim auxY As Byte Dim hit As Byte ' Will become TRUE if the serpent hits the player! hit = 0 ' Let's imagine this nice grid: ' 4 8 12 16 20 24 28 ' OxxxOxxxOxxxOxxxOxxxOxxxO 2 ' x x x x x x x ' x x x x x x x ' x x x x x x x ' OxxxOxxxOxxxOxxxOxxxOxxxO 6 ' x x x x x x x ' x x x x x x x ' x x x x x x x ' OxxxOxxxOxxxOxxxOxxxOxxxO 10 ' x x x x x x x ' x x x x x x x ' x x x x x x x ' OxxxOxxxOxxxOxxxOxxxOxxxO 14 ' x x x x x x x ' x x x x x x x ' x x x x x x x ' OxxxOxxxOxxxOxxxOxxxOxxxO 18 ' The serpent head moves horizontally or vertically ' across the paths marked x. When it reaches an intersection ' (marked O), it decides a new direction. ' It's very easy, watch me: ' Counter, so it moves slower than Manolito If esCt = 0 Then ' First we check if we are in an intersection (marked O) ' This happens if both coordinates are multiples of four ' n is multiple of four if n = (n/4)*4. ' Additionally, we have to substract 2 from the Y axis, ' it's a very simple change of origin. If esX (0) = (esX (0) >> 2) << 2 And _ (esY (0) - 2) = ((esY (0) - 2) >> 2) << 2 Then ' First: clear directions esMX = 0 esMY = 0 ' We have to decide a new direction ' (0 = UP, 1 = RIGHT, 2 = DOWN, 3 = LEFT) t = Int (Rnd * 4) ' Some directions are illegal, we cannot escape ' from the grid! In such cases, we reverse the direction If t = 0 And esY (0) = 2 Then t = 2: End If If t = 1 And esX (0) = 28 Then t = 3: End If If t = 2 And esY (0) = 18 Then t = 0: End If If t = 3 And esX (0) = 4 Then t = 1: End If ' Now we check if the next move is legal. If the next ' intersection is NOT empty, we cancel the movement ' until the movement is possible. If t = 0 And attr (esY (0) - 4, esX (0)) <> 7 Then t = 5: End If If t = 1 And attr (esY (0), esX (0) + 4) <> 7 Then t = 5: End If If t = 2 And attr (esY (0) + 4, esX (0)) <> 7 Then t = 5: End If If t = 3 And attr (esY (0), esX (0) - 4) <> 7 Then t = 5: End If ' Now we modify esMX and esMY based upon t: If t = 0 Then esMY = -1: End If If t = 1 Then esMX = 1: End If If t = 2 Then esMY = 1: End If If t = 3 Then esMX = -1: End If ' And we are done. End If ' We just keep moving ' Erase tail, then erase head. This is a trick so we don't ' have to redraw the whole snake each frame. auxX = esX (31) auxY = esY (31) Print At esY (0), esX (0); Ink esGeneral; "5" ' First we move the head: esX (0) = esX (0) + esMX esY (0) = esY (0) + esMY ' Now we propagate this movement across the body For i = 31 To 1 Step -1 esX (i) = esX (i - 1) esY (i) = esY (i - 1) Next i ' Finally, we draw the head. And erase the tail if it moved If auxX <> esX (31) Or auxY <> esY (31) Then Print At auxY, auxX; Ink 7; Bright 0; " " End If Print At esY (0), esX (0); Bright 1; Ink esGeneral; "6" ' Check for collisions. If the serpent head hits the player, ' hit becomes 1, and we kill the player. If (esX (0) >= plX And esX (0) <= plX + 4 And esY (0) = plY) Or _ (esX (0) = plX + 2 And esY (0) = plY + 1) Then die () plLives = plLives - 1 hit = 1 End If End If esCt = esCt + 1: If esCt = 4 Then esCt = 0: End If Return hit End Function Sub centra (y As Integer, text As String) Print At y, 16 - Len (text) / 2; text End Sub Sub checkPassword () Dim i As Byte Dim j As Byte ' All caps: Poke 23658,8 nPant = -1 centra (21, "ENTER PASSWORD") centra (22, " ") ' Clear keypress While Code(Inkey ()) <> 0 Wend terminado = 0 pass = "" i = 0 centra (22, "_") While Not terminado key = Inkey () If key <> "" Then j = code (key) ' Check if ENTER was pressed If j = 13 Then terminado = 1 End If ' A-Z? If j > 64 And j < 91 And i < 4 Then pass = pass + key i = i + 1 centra (22, pass + "_") End If ' Backspace? If j = 12 And i > 0 Then if Len(pass) > 1 Then pass = pass (0 To Len (pass) - 2) Else pass = "" End If i = i - 1 centra (22, " ") centra (22, pass + "_") End If ' Wait until key is depressed While Inkey () = key Wend End If Wend ' Check if Password is correct If pass = "FPOL" Then nPant = 12 ElseIf pass = "ITYC" Then nPant = 17 ElseIf pass = "FORE" Then nPant = 26 ElseIf pass = "SERP" Then nPant = 30 ElseIf pass = "TESA" Then nPant = 32 ElseIf pass = "FINA" Then nPant = 38 ElseIf pass = "GRRR" Then nPant = 41 Else centra (22, "WRONG") Beep 1,0 End If End Sub ' Virtual squared paper ' ' 0 4 8 12 16 20 24 28 32 ' 1 ································· ' ································· ' ································· ' ································· ' 5 ································· ' ································· ' ································· ' ································· ' ································· ' 10································· ' ································· ' ································· ' ································· ' ································· ' 15································· ' ································· ' ································· ' ································· ' ································· ' 20································· '' And we are done! ' You know, I always end my sources with some nice rock poetry.