📄 invaders.bas
字号:
' Experimental software to reproduce the classic Space Invaders game
' For version 2.1 of the PROTON+ BASIC Compiler
' Written by Les Johnson 2003.
'
' This version uses the LCDWRITE and PLOT commands to produce the graphics
' Which allows smooth movements on a pixel by pixel basis
'
' Use an 8MHz crystal
'
' BUTTON CONNECTIONS
' LEFT Button connects to PORTB.0
' RIGHT Button connects to PORTB.1
' FIRE Button connects to PORTB.2
'
' SOUND CHANNEL CONNECTIONS
' Each channel is output from PORTA.0,1,2
' Channel 1. PORTA.0 is the INVADER noise
' Channel 2. PORTA.1 is the MISSILE noise
' Channel 3. PORTA.2 is the SAUCER noise
' Each pin should have a current limiting resistor in order to stop pin to pin shorts.
'
' 1uF
' 220 +| |-
' PORTA.0 --/\/\/\----| |--- To SPEAKER
' | | |
' 330 |
' PORTA.1 --/\/\/\--|
' |
' 330 |
' PORTA.2 --/\/\/\--|
'
'
Include "PROTON18_G8.INT" ' Game created on the PROTON board
' Set up some Variables
' Interrupt driven sound channel variables
Dim NOTE_STATUS as Byte SYSTEM
Dim INVADER_SOUND_ENABLE as NOTE_STATUS.0
Dim MISSILE_SOUND_ENABLE as NOTE_STATUS.1
Dim SAUCER_SOUND_ENABLE as NOTE_STATUS.2
Dim INTERNAL_INVADER_SOUND_ENABLE as NOTE_STATUS.4
Dim INTERRUPT_COUNTER1 as Byte SYSTEM
Dim INVADER_SOUND_COUNTER as Byte SYSTEM
Dim INVADER_FREQ as Byte SYSTEM
Dim INVADER_SOUND_DURATION as Byte SYSTEM
Dim INVADER_SOUND_DURATION_COUNTER as Byte SYSTEM
Dim MISSILE_SOUND_COUNTER as Byte SYSTEM
Dim MISSILE_FREQ as Byte SYSTEM
Dim SAUCER_SOUND_COUNTER as Byte SYSTEM
Dim SAUCER_FREQ as Byte SYSTEM
' Space invader variables
Dim BASE_ENABLED[9] as Byte ' Whether or not the section of the BASE is enabled
Dim BASE_HITS[9] as Byte ' Holds the amount of hits each part of the bases has had
Dim INVADER_XPOS[18] as Byte' at 400 ' Array to hold the space invader's X position
Dim INVADER_YPOS[18] as Byte' at 418 ' Array to hold the space invader's Y position
Dim INVADER_ENABLED[18] as Byte' at 436 ' Array to hold the space invader' config. i.e. hit or active
Dim SHIP_XPOS as Byte ' X position of BASE ship
Dim MISSILE_YPOS as Byte ' Y position of Ship's MISSILE
Dim MISSILE_XPOS as Byte ' X position of Ship's MISSILE
Dim MISSILE_STATUS as Byte SYSTEM
Dim MISSILE_FIRED as MISSILE_STATUS.0 ' TRUE if Ship's MISSILE in the air
Dim MISSILE_HIT as MISSILE_STATUS.1 ' Set if Ship's missile has hit something
Dim TIME_TO_MOVE_INVADERS as MISSILE_STATUS.7 ' Indicate time to move the invaders
Dim BASE_HIT as MISSILE_STATUS.2 ' Indicates whether a BASE has been hit by a missile
Dim TIME_TO_MOVE_SHIP_MISSILE as MISSILE_STATUS.3 ' Indicate time to move the ship's missile
Dim TIME_TO_MOVE_BASE as Bit
Dim SHIP_SPEED as Byte
Dim INVADER_TICK as Byte ' Constant tick within program
Dim INVADER_LOOP as Byte SYSTEM ' Scans the invader arrays
Dim INVADER_MISSILE_TICK as Byte
Dim SHIP_MISSILE_TICK as Byte
Dim TEMP_LOOP as Byte
Dim INVADERS_DIRECTION as Bit
Dim INVADERS_ENABLED as Byte ' Count the INVADERS enabled
Dim INVADER_SPEED as Byte ' The speed of the invaders
Dim BASE_XPOS_TEST as Byte ' Used for detecting a missile hit on a BASE
Dim SHIP_HIT as Bit ' TRUE if ship hit by missile
Dim INVADER_MISSILE_YPOS as Byte ' Y position of Invader's MISSILE
Dim INVADER_MISSILE_XPOS as Byte ' X position of Invader's MISSILE
Dim TIME_TO_MOVE_INV_MISSILE as MISSILE_STATUS.4 ' Indicate time to move the invader's missile
Dim INVADER_MISSILE_FIRED as MISSILE_STATUS.5 ' TRUE if Invader's MISSILE in the air
Dim INVADER_MISSILE_HIT as MISSILE_STATUS.6 ' Set if Invader's missile has hit something
Dim TIME_TO_MOVE_INVADERS_DOWN as Bit ' Signal that the invaders need to move down
Dim INVADERS_REACHED_BOTTOM as Bit ' Set if the invaders reach the botton of the screen
Dim INVADER_MISSILE_SPEED as Byte ' The speed of the invader's missile. This slows down as invader near the bottom of the screen
Dim DEFAULT_INVADER_SPEED as Byte ' Saves the initial speed of the invaders
Dim INVADER_CHARACTER as Bit ' Determines the character to use for the invader
Dim INVADER_MISSILE2_TICK as Byte
Dim INVADER_MISSILE2_YPOS as Byte ' Y position of Invader's second MISSILE
Dim INVADER_MISSILE2_XPOS as Byte ' X position of Invader's second MISSILE
Dim TIME_TO_MOVE_INV_MISSILE2 as Bit ' Indicate time to move the invader's second missile
Dim INVADER_MISSILE2_FIRED as Bit ' TRUE if Invader's second MISSILE in the air
Dim INVADER_MISSILE2_HIT as Bit ' Set if Invader's second missile has hit something
Dim INVADER_MISSILE2_SPEED as Byte ' The speed of the invader's second missile. This slows down as invader near the bottom of the screen
Dim SAUCER_XPOS as Byte
Dim SAUCER_HIT as Bit
Dim TIME_TO_MOVE_SAUCER as Bit
Dim SAUCER_SPEED as Byte
Dim SAUCER_ENABLED as Bit
Dim SCORE as Dword ' Holds the games score
Dim LEVEL as Word ' Game level
Dim LIVES as Byte ' Amount of lives left for the base
' Define some constants and alias's
Symbol L_BUTTON = PORTB.0
Symbol R_BUTTON = PORTB.1
Symbol FIRE_BUTTON = PORTB.2
Symbol SPEAKER = PORTB.3
Symbol SHIP_WIDTH = 9 ' The width of the ship in pixels. This does not include the two blanks
Symbol INVADER_WIDTH = 10 ' The width of the invaders. minus the two outside blanks
Symbol INVADER_RIGHT_LIMIT = 127 - INVADER_WIDTH ' The right most limit for the invaders before they need to move down
Symbol SAUCER_WIDTH = 14
Symbol TRUE = 1
Symbol FALSE = 0
Symbol FORWARD = 1
Symbol BACKWARD = 0
Symbol T0IF = INTCON.2 ' Timer0 Overflow Interrupt Flag
Symbol GIE = INTCON.7 ' Global Interrupt Enable
'ON_INTERRUPT Goto NOTE_INT
'----------------------------------------------------------------------------
Input L_BUTTON
Input R_BUTTON
Input FIRE_BUTTON
Delayms 200 ' Wait for the PICmicro to stabilise
PORTB_PULLUPS = ON
Cls ' Clear the LCD
Goto MAIN_PROGRAM_LOOP ' Jump over any subroutines
'----------------------------------------------------------------------------
' Draw or clear the Invader's missile
CLEAR_INVADER_MISSILE:
UnPlot INVADER_MISSILE_YPOS, INVADER_MISSILE_XPOS
UnPlot INVADER_MISSILE_YPOS, INVADER_MISSILE_XPOS + 1
UnPlot INVADER_MISSILE_YPOS + 1, INVADER_MISSILE_XPOS
UnPlot INVADER_MISSILE_YPOS + 1, INVADER_MISSILE_XPOS + 1
UnPlot INVADER_MISSILE_YPOS + 2, INVADER_MISSILE_XPOS
UnPlot INVADER_MISSILE_YPOS + 2, INVADER_MISSILE_XPOS + 1
Return
DRAW_INVADER_MISSILE:
UnPlot INVADER_MISSILE_YPOS, INVADER_MISSILE_XPOS
UnPlot INVADER_MISSILE_YPOS, INVADER_MISSILE_XPOS + 1
Plot INVADER_MISSILE_YPOS + 1, INVADER_MISSILE_XPOS
Plot INVADER_MISSILE_YPOS + 1, INVADER_MISSILE_XPOS + 1
Plot INVADER_MISSILE_YPOS + 2, INVADER_MISSILE_XPOS
Plot INVADER_MISSILE_YPOS + 2, INVADER_MISSILE_XPOS + 1
Return
'----------------------------------------------------------------------------
' Draw or clear the second Invader's missile
CLEAR_INVADER_MISSILE2:
UnPlot INVADER_MISSILE2_YPOS, INVADER_MISSILE2_XPOS
UnPlot INVADER_MISSILE2_YPOS, INVADER_MISSILE2_XPOS + 1
UnPlot INVADER_MISSILE2_YPOS + 1, INVADER_MISSILE2_XPOS
UnPlot INVADER_MISSILE2_YPOS + 1, INVADER_MISSILE2_XPOS + 1
UnPlot INVADER_MISSILE2_YPOS + 2, INVADER_MISSILE2_XPOS
UnPlot INVADER_MISSILE2_YPOS + 2, INVADER_MISSILE2_XPOS + 1
Return
DRAW_INVADER_MISSILE2:
UnPlot INVADER_MISSILE2_YPOS, INVADER_MISSILE2_XPOS
UnPlot INVADER_MISSILE2_YPOS, INVADER_MISSILE2_XPOS + 1
Plot INVADER_MISSILE2_YPOS + 1, INVADER_MISSILE2_XPOS
Plot INVADER_MISSILE2_YPOS + 1, INVADER_MISSILE2_XPOS + 1
Plot INVADER_MISSILE2_YPOS + 2, INVADER_MISSILE2_XPOS
Plot INVADER_MISSILE2_YPOS + 2, INVADER_MISSILE2_XPOS + 1
Return
'----------------------------------------------------------------------------
' Re-Draw the bases
UPDATE_BASES:
Print at 6,2,2 + BASE_HITS#0,8 + BASE_HITS#1,14 + BASE_HITS#2,_
at 6,9,2 + BASE_HITS#3,8 + BASE_HITS#4,14 + BASE_HITS#5,_
at 6,15,2 + BASE_HITS#6,8 + BASE_HITS#7,14 + BASE_HITS#8
Return
'----------------------------------------------------------------------------
' Check if BASE hit by a missile
' Each base is built from three elements (characters)
' Returns with BASE_HIT set if a hit was detected
CHECK_BASE_HIT:
BASE_HIT = FALSE ' Default to no hit detected
Select BASE_XPOS_TEST
Case 12 to 17 ' Has the missile XPOS hit BASE 1, ELEMENT 0
If BASE_HITS#0 < 5 AND BASE_ENABLED#0 = TRUE Then ' Is the base element enabled, and has had less than 5 hits ?
Inc BASE_HITS#0 ' Increment the amount of hits the base element has sustained
BASE_HIT = TRUE ' Indicate a missile has hit a target
Else
BASE_ENABLED#0 = FALSE ' Disable the base element
Endif
Case 18 to 23 ' Has the missile XPOS hit BASE 1, ELEMENT 1
If BASE_HITS#1 < 5 AND BASE_ENABLED#1 = TRUE Then ' Is the base element enabled, and has had less than 5 hits ?
Inc BASE_HITS#1 ' Increment the amount of hits the base element has sustained
BASE_HIT = TRUE ' Indicate a missile has hit a target
Else
BASE_ENABLED#1 = FALSE ' Disable the base element
Endif
Case 24 to 29 ' Has the missile XPOS hit BASE 1, ELEMENT 2
If BASE_HITS#2 < 5 AND BASE_ENABLED#2 = TRUE Then ' Is the base element enabled, and has had less than 5 hits ?
Inc BASE_HITS#2 ' Increment the amount of hits the base element has sustained
BASE_HIT = TRUE ' Indicate a missile has hit a target
Else
BASE_ENABLED#2 = FALSE ' Disable the base element
Endif
Case 54 to 59 ' Has the missile XPOS hit BASE 2, ELEMENT 3
If BASE_HITS#3 < 5 AND BASE_ENABLED#3 = TRUE Then ' Is the base element enabled, and has had less than 5 hits ?
Inc BASE_HITS#3 ' Increment the amount of hits the base element has sustained
BASE_HIT = TRUE ' Indicate a missile has hit a target
Else
BASE_ENABLED#3 = FALSE ' Disable the base element
Endif
Case 60 to 65 ' Has the missile XPOS hit BASE 2, ELEMENT 4
If BASE_HITS#4 < 5 AND BASE_ENABLED#4 = TRUE Then ' Is the base element enabled, and has had less than 5 hits ?
Inc BASE_HITS#4 ' Increment the amount of hits the base element has sustained
BASE_HIT = TRUE ' Indicate a missile has hit a target
Else
BASE_ENABLED#4 = FALSE ' Disable the base element
Endif
Case 66 to 71 ' Has the missile XPOS hit BASE 2, ELEMENT 5
If BASE_HITS#5 < 5 AND BASE_ENABLED#5 = TRUE Then ' Is the base element enabled, and has had less than 5 hits ?
Inc BASE_HITS#5 ' Increment the amount of hits the base element has sustained
BASE_HIT = TRUE ' Indicate a missile has hit a target
Else
BASE_ENABLED#5 = FALSE ' Disable the base element
Endif
Case 90 to 95 ' Has the missile XPOS hit BASE 3, ELEMENT 6
If BASE_HITS#6 < 5 AND BASE_ENABLED#6 = TRUE Then ' Is the base element enabled, and has had less than 5 hits ?
Inc BASE_HITS#6 ' Increment the amount of hits the base element has sustained
BASE_HIT = TRUE ' Indicate a missile has hit a target
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -