===Sprite demo: Arcade=== {{ :migratedattachments:mmbasic_original:amods.zip?linkonly}} //This module is part of the original MMBasic library. It is reproduced here with kind permission of Hugh Buckle and Geoff Graham. Be aware it may reference functionality which has changed or is deprecated in the latest versions of MMBasic.// **Arcade**: Arcade game where you have to shoot enemies until you die 3 times. It shows how to use multi-sprite enemies, audio modules as sound effects and ADC input for moving your ship Right/Left with a potentiometer + a Button to fire. **ARCATST.BAS**: 'Arcade game test for Colour Maximite v4.0 'Fabrice Muller 2012 'All music modules have to be copied to a: 'The sprites are read from b: 'Joystick connections are : 'Pin 2 = 10Kohm Potentiometer ' ' Pin 2 ' | ' | ' / \ ' +3v3 ----------| o |---------- GND ' \___/ ' ' 10Kohm Potentiometer ' ' 'Pin 15 = Button connected to GND , 10Kohm pullup resistor to pin 15 ' ' __|__ ' ' 10 Kohm | | ' +3v3 ---------/\/\/\/\-----|-------| |-------- GND ' | ' | Button ' Pin 15 ' 'All arrays start at index 1 Option Base 1 'Erase all variables values from memory Clear 'Load the Sprites Drive "b:" Sprite Load "arcade01.spr" Drive "a:" 'Arrays declaration Dim ShootSpr(5) Dim ShowShoot(5) Dim ShootPos(5,2) Dim EnnemySpr(10) Dim EnnemyPos(10,2) Dim EnnemyShow(10) Dim EnnemyDir(10) Dim EnnemySpeed(10) Dim EnnemyKilled(10) Dim EnnemyShootSpr(10) Dim EnnemyShootPos(10,2) Dim EnnemyShowShoot(10) Dim Sprite_to_Show(26) Dim Cx(26) Dim Cy(26) 'Main ship sprite number is 1 ShipSpr = 1 'Global Variables declaration Max_Shoot = 5 Max_Ennemy = 10 Max_Ennemy_Shoot = 10 Max_Sprite = 26 Shoot_Speed = -5 Ennemy_Shoot_Speed = 5 SpriteFlip = 0 OutsideX = 0 OutsideY = 0 ShipX = 0 ShipY = 0 Audio_is_playing = 0 Fire = 0 Lives = 0 Score = 0 'Joystick declaration 'Pin 2 as ADC input for a 10Kohm potentiometer SetPin 2,1 'PIN 15 = Fire Button 1 SetPin 15,2 'Initialise the sprites and screen Initialise 'General game loop Do While 1 'Here we check if we fire every 300mS If (Timer Mod 200) >= 100 Then fire = Check_Fire(15) 'Put a new fire if possible If fire = 0 Then Put_New_Fire EndIf 'Here we move the Ship ShipX = Pot_Read(2) 'Here we move all Ennemys Move_Ennemy 'Here we move the Shoots we have fired Move_Shoot 'Here we move the Ennemys Shoots they have fired Move_Ennemy_Shoot 'Here we check if we have kill a Ennemy Check_Ennemy_Dead 'Here we Check if the Ennemys kill us Check_Player_Dead 'We Random the Ennemy Shoots If Int(Rnd * 100) > 80 Then Put_New_Enenmy_Fire 'Here we redraw all Sprites every 100mS Show_All_Sprites Print @(60,0) "Lives : ";Lives;" " Print @(150,0) "Score : ";Score;" " Loop Sub Initialise Local a 'Set all the Sprite first For a = 1 To Max_Shoot 'Shoot Sprites start at 2 ShootSpr(a) = a + 1 ShowShoot(a) = 0 Next a For a = 1 To Max_Ennemy 'Ennemy Sprites start at 7 EnnemySpr(a) = a + 6 'Don't show the ennemys now EnnemyShow(a) = 1 'Reset Ennemys Directions EnnemyDir(a) = 0 'Reset the Ennemys Speed EnnemySpeed(a) = 2 'Put all Ennemy as not Killed EnnemyKilled(a) = 0 Next a For a = 1 To Max_Ennemy_Shoot 'Ennemy Shoot Sprites start at 17 EnnemyShootSpr(a) = a + 16 EnnemyShowShoot(a) = 0 Next a SpriteFlip = 0 'Set Lives ans Score Lives = 3 Score = 0 ' Set the graphics mode Mode 4 'Erase the screen Cls 'Wait for a key to start Print @(80 , 100) "Press a key to start" Do While Inkey$ = "" : Loop Cls 'Initialise the random number generator Randomize Timer 'Place the ship ShipX = Pot_Read(2) ShipY = 198 'Set the Ennemys Positions and directions For a = 1 To Max_Ennemy EnnemyPos(a,1) = Set_Ennemy_Pos_X(1) EnnemyPos(a,2) = Set_Ennemy_Pos_Y(1) EnnemyDir(a) = Set_Ennemy_Dir(1) EnnemySpeed(a) = Set_Ennemy_Speed(1) Next a OutsideX = -20 OutsideY = -20 Start_All_Sprite 'Reset the timer for the game loop Timer = 0 End Sub Sub Start_All_Sprite 'We start all sprite here outside the screen 'for not have to look at on/off status 'This improve the performance. 'Sprite order: 'Sprite 1 Sprite On ShipSpr,OutsideX,OutsideY 'Sprite 2 to 6 For a = 1 To Max_Shoot Sprite On ShootSpr(a),OutsideX,OutsideY Next a 'Sprite 7 to 16 For a = 1 To Max_Ennemy Sprite On EnnemySpr(a),OutsideX,OutsideY Next a 'Sprite 17 to 26 For a = 1 To Max_Ennemy_Shoot Sprite On EnnemyShootSpr(a),OutsideX,OutsideY Next a End Sub Sub Show_All_Sprites 'Here we show all sprite in respecting the 'Order needed for the Sprite function 'We record the Ship info Sprite_to_Show(ShipSpr) = ShipSpr Cx(ShipSpr) = ShipX Cy(ShipSpr) = ShipY 'Check if Sprites have to be Moved or 'pushed out of the screen For a = 1 To Max_Shoot If ShowShoot(a) = 1 Then Sprite_to_Show(ShootSpr(a)) = 1 Cx(ShootSpr(a))=ShootPos(a,1) Cy(ShootSpr(a))=ShootPos(a,2) Else Sprite_to_Show(ShootSpr(a)) = 0 Cx(ShootSpr(a))=OutsideX Cy(ShootSpr(a))=OutsideY EndIf Next a For a = 1 To Max_Ennemy If EnnemyShow(a) = 1 Then Sprite_to_Show(EnnemySpr(a)) = 1 Cx(EnnemySpr(a))=EnnemyPos(a,1) Cy(EnnemySpr(a))=EnnemyPos(a,2) Else Sprite_to_Show(EnnemySpr(a)) = 0 Cx(EnnemySpr(a))=OutsideX Cy(EnnemySpr(a))=OutsideY EndIf Next a For a = 1 To Max_Ennemy_Shoot If EnnemyShowShoot(a) = 1 Then Sprite_to_Show(EnnemyShootSpr(a)) = 1 Cx(EnnemyShootSpr(a))=EnnemyShootPos(a,1) Cy(EnnemyShootSpr(a))=EnnemyShootPos(a,2) Else Sprite_to_Show(EnnemyShootSpr(a)) = 0 Cx(EnnemyShootSpr(a))=OutsideX Cy(EnnemyShootSpr(a))=OutsideY EndIf Next a If SpriteFlip = 0 Then 'Sprites was drawn 1st to last , we erase or move 'then Last to 1st 'Drawing Order was : 'Ship 'Shoot 'Ennemy 'Ennemy_Shoot ' 'Here we move the Sprite or put them out of the screen For a = Max_Sprite To 1 Step - 1 Sprite Off a Next a For a = Max_Sprite To 1 Step - 1 If Sprite_to_Show(a) = 0 Then Sprite On a,OutsideX,OutsideY Else Sprite On a,Cx(a),Cy(a) EndIf Next a SpriteFlip = 1 Else 'Sprites was drawn last to 1st , we erase or move 'then 1st to last 'Drawing Order was : 'Ennemy_Shoot 'Ennemy 'Shoot 'Ship ' 'Here we move the Sprite or put them out of the screen For a = 1 To Max_Sprite Sprite Off a Next a For a = 1 To Max_Sprite If Sprite_to_Show(a) = 0 Then Sprite On a,OutsideX,OutsideY Else Sprite On a,Cx(a),Cy(a) EndIf Next a SpriteFlip = 0 EndIf End Sub Sub Move_Ennemy 'Move all ennemy Ship Local a For a = 1 To Max_Ennemy If EnnemyShow(a) = 1 Then EnnemyPos(a,1) = EnnemyPos(a,1) + EnnemyDir(a) 'We look if the Ennemy bump at a screen border 'If so , we reverse his direction If EnnemyPos(a,1) < 1 Then EnnemyDir(a) = 1 If EnnemyPos(a,1) > MM.HRes - 18 Then EnnemyDir(a) = -1 'We made the Ennemy go down EnnemyPos(a,2) = EnnemyPos(a,2) + EnnemySpeed(a) 'If the ennemy go outside the screen or if we kill 'then we put it at new place If (EnnemyPos(a,2) >= (MM.VRes - 40)) Or (EnnemyKilled(a) = 1) Then EnnemyPos(a,1) = Set_Ennemy_Pos_X(1) EnnemyPos(a,2) = Set_Ennemy_Pos_Y(1) EnnemyDir(a) = Set_Ennemy_Dir(1) EndIf 'Update the score if we kill a Ennemy If EnnemyKilled(a) = 1 Then EnnemyKilled(a) = 0 Score = Score + 10 EndIf EndIf Next a End Sub Sub Move_Shoot 'Move the player shoots Local a For a = 1 To Max_Shoot If ShowShoot(a) = 1 Then ShootPos(a,2) = ShootPos(a,2) + Shoot_Speed 'If the Shoot go outside the screen we put it 'as not showed If ShootPos(a,2) < 18 Then ShowShoot(a) = 0 EndIf Next a End Sub Sub Move_Ennemy_Shoot 'Move the ennemys shoots Local a For a = 1 To Max_Ennemy_Shoot If EnnemyShowShoot(a) = 1 Then EnnemyShootPos(a,2) = EnnemyShootPos(a,2) + Ennemy_Shoot_Speed 'If the Shoot go outside the screen we put it 'as not showed If EnnemyShootPos(a,2) >= MM.VRes Then EnnemyShowShoot(a) = 0 EndIf Next a End Sub Sub Check_Ennemy_Dead 'Check if we have kill one of the Ennemy Local a,b Local px,py For a = 1 To Max_Ennemy px = EnnemyPos(a,1) + 15 py = EnnemyPos(a,2) + 15 For b = 1 To Max_Shoot If ShowShoot(b) = 1 Then If (ShootPos(b,1) >= EnnemyPos(a,1)) And (ShootPos(b,1) <= px) Then If (ShootPos(b,2) >= EnnemyPos(a,2)) And (ShootPos(b,2) <= py) Then 'We have killed this ennemy EnnemyKilled(a) = 1 Score = Score + 10 ShowShoot(b) = 0 If Audio_is_playing = 1 Then PlayMOD stop PlayMOD "Explode.mod" , 6000 Else PlayMOD "Explode.mod" , 6000 EndIf Exit For EndIf EndIf EndIf Next b Next a End Sub Sub Check_Player_Dead 'Check if the Ennemys kill us Local a,px,py px = ShipX + 15 py = ShipY + 15 For a = 1 To Max_Ennemy_Shoot If EnnemyShowShoot(a) = 1 Then If (EnnemyShootPos(a,1) >= ShipX) And (EnnemyShootPos(a,1) <= px) Then If (EnnemyShootPos(a,2) >= ShipY) And (EnnemyShootPos(a,2) <= py) Then 'The Ennemy Kill us ! '............... to continue ............ Lives = Lives - 1 If Lives = 0 Then Drive "b:" Print @(100,80) "Game Over" Print @(80,120) "press a key to restart" Do While Inkey$ = "" : Loop End Else Exit Sub EndIf EndIf EndIf EndIf Next a End Sub Sub Put_New_Fire 'Here we check if we can add a new fire Local a For a = 1 To Max_Shoot If ShowShoot(a) = 0 Then 'we can add a shoot 'Record the the Actual Show Shoot status ShootPos(a,1) = ShipX + 6 ShootPos(a,2) = ShipY - 8 ShowShoot(a) = 1 If Audio_is_playing = 1 Then PlayMOD stop PlayMOD "Shoot.mod" , 6000 Else PlayMOD "Shoot.mod" , 6000 EndIf Exit For EndIf Next a End Sub Sub Put_New_Enenmy_Fire 'Here we check if the Ennemy can add a new fire Local a For a = 1 To Max_Ennemy_Shoot If EnnemyShowShoot(a) = 0 Then 'Ennemy can add a shoot EnnemyShootPos(a,1) = EnnemyPos(a,1) + 6 EnnemyShootPos(a,2) = EnnemyPos(a,2) + 16 EnnemyShowShoot(a) = 1 Exit For EndIf Next a End Sub Function Pot_Read(ADC_Pin) 'Read the potentiometer value for place 'the X coordinate from the Ship 'ADC_Pin is the pin number we have define for ADC input Local CalcPot , tmppos CalcPot = 3 / MM.HRes tmppos = Int((Pin(ADC_Pin) -0.1) / CalcPot) If tmppos > (MM.HRes - 17) Then tmppos = MM.HRes - 17 Pot_Read = tmppos End Function Function Check_Fire(Fire_Button) 'Return the value from the Fire Button 'Fire_Button is the pin number we have define as fire button Check_Fire = Pin(Fire_Button) End Function Function Set_Ennemy_Dir(dummy) 'Return -1 or 1 for the Ennemy direction Local a a = 0 Do While a = 0 If (Int(Rnd * 100) + 1 ) > 50 Then a = 1 Else a = -1 EndIf Loop Set_Ennemy_Dir = a End Function Function Set_Ennemy_Pos_X(dummy) 'Set Ennemy Pos X Set_Ennemy_Pos_X = Int(Rnd * (MM.HRes - 30)) + 15 End Function Function Set_Ennemy_Pos_Y(dummy) 'Set Ennemy Pos X Set_Ennemy_Pos_Y = Int(Rnd * 30) + 15 End Function Function Set_Ennemy_Speed(dummy) 'Set the Ennemy Speed in Y Set_Ennemy_Speed = Int(Rnd * 5) + 1 End Function