The sprite collision command seems to be behaving erratically for me. I have a chunk of code that has been working great to detect when the explosion sprite from an exploding bullet is colliding with an incoming missile sprite.
Then, I added one more collision detection to check and see when the bullet hits another target on screen, but this command seems to be completely ignored and I cannot explain why. Any help would be greatly appreciated! The problem command is in the moveBullets() function on line 417 (if sprite collision (bulletSprite, bogieSprite))
I am very sorry for posting my complete source code here, but I didn't know how to extract the problem command without the rest of the code as context.
REM ***** ********************************** *****
REM ***** Tin Dome Missile Defense *****
REM ***** ********************************** *****
REM ***** ********************************** *****
REM ***** ** Display Settings ** *****
REM ***** ********************************** *****
set window on
set display mode 1024,768,32
sync rate 60
sync on
backdrop on
color backdrop 0
hide mouse
REM ***** ********************************** *****
REM ***** ** Special Types ** *****
REM ***** ********************************** *****
type projectile
id as byte
xOrigin as float
yOrigin as float
xPosition as float
yPosition as float
xTarget as float
yTarget as float
tracers as byte `(tracers on = 1, tracers off = 0)
isActive as byte `(Projectile lifecycle is 0=UNUSED, 1=ACTIVE, 2=SPENT)
endtype
type level
xCity1 as word
yCity1 as word
statusCity1 as byte `Each city should have 6 stages 1=Perfect ... 6=Totally Destroyed
xCity2 as word
yCity2 as word
statusCity2 as byte
xCity3 as word
yCity3 as word
statusCity3 as byte
xCity4 as word
yCity4 as word
statusCity4 as byte
xCity5 as word
yCity5 as word
statusCity5 as byte
xCity6 as word
yCity6 as word
xCannon as word
yCannon as word
bulletsCannon as byte
statusCity6 as byte
totalMissiles as byte
totalBullets as byte
missileSpeed as float
bulletSpeed as float
missilesInflight as byte
missilesDestroyed as byte
missilesAllowed as byte
bulletsUsed as byte
missileTracers as byte `0=tracers off ... 1=tracers on
bulletTracers as byte `0=tracers off ... 1=tracers on
cannonDamaged as byte
bogiePositionX as word
bogiePositionY as word
bogieSpeed as float
bogieActive as byte `0=not active, 1=active, 2=already passed
bogieTrigger as word
endtype
REM ***** ********************************** *****
REM ***** ** Main Execution Commands ** *****
REM ***** ********************************** *****
initGame()
runTitleScreen()
runIntro()
runGame()
runEndSequence()
wait key
end
REM ***** ********************************** *****
REM ***** ** Game Functions ** *****
REM ***** ********************************** *****
function initGame()
load image "media\hud.bmp", 1, 1 `image numbers 1-8 are taken
load image "media\bullet.bmp", 2, 1
load image "media\chicago1.png", 3, 1
`load image "media\missile_city2.bmp", 4, 1
`load image "media\missile_city3.bmp", 5, 1
`load image "media\missile_city4.bmp", 6, 1
`load image "media\missile_city5.bmp", 7, 1
load image "media\title.png", 8, 1
load sound "media\Cannon.wav",1 `sound numbers 1-16 are taken
load sound "media\Air raid siren 2.wav",2
load sound "media\explosions2b.wav",3
load sound "media\fmwoods_intro.ogg",4
load sound "media\pvtlee_taunt1.ogg",5
load sound "media\pvtlee_taunt2.ogg",6
load sound "media\pvtlee_taunt3.ogg",7
load sound "media\pvtlee_taunt4.ogg",8
load sound "media\pvtlee_taunt5.ogg",9
load sound "media\pvtlee_taunt6.ogg",10
load sound "media\pvtlee_taunt7.ogg",11
load sound "media\pvtlee_taunt8.ogg",12
load sound "media\pvtlee_taunt9.ogg",13
load sound "media\pvtlee_taunt10.ogg",14
load sound "media\empty_click.wav",15
load sound "media\JewelBeat - Drums Of Doom.wav",16
create bitmap 11, 40, 25
set current bitmap 11
ink rgb(255,0,0),0
box 0,0,40,25
get image 12, 0, 0, 40, 25
delete bitmap 11
global gametime=timer()
global runLevel=0 `0=Title, 1=Intro, 2=Game, 3=EndSequence....necessary?
global currentLevel=1
global barrelLength=15
global lastshot=gametime
global bulletSprite=150
global missileSprite=170
global bogieSprite=5
dim levels(6) as level
levels(1).xCity1=77
levels(1).yCity1=668
levels(1).statusCity1=1
levels(1).xCity2=231
levels(1).yCity2=668
levels(1).statusCity2=1
levels(1).xCity3=385
levels(1).yCity3=668
levels(1).statusCity3=1
levels(1).xCity4=639
levels(1).yCity4=668
levels(1).statusCity4=1
levels(1).xCity5=793
levels(1).yCity5=668
levels(1).statusCity5=1
levels(1).xCity6=947
levels(1).yCity6=668
levels(1).xCannon=512
levels(1).yCannon=630
levels(1).statusCity6=1
levels(1).totalMissiles=30
levels(1).totalBullets=60
levels(1).missileSpeed=1.5
levels(1).bulletSpeed=10.0
levels(1).missilesInflight=0
levels(1).missilesDestroyed=0
levels(1).missilesAllowed=3
levels(1).bulletsUsed=0
levels(1).missileTracers=1
levels(1).bulletTracers=1
levels(1).cannonDamaged=0
levels(1).bogiePositionX=0
levels(1).bogiePositionY=0
levels(1).bogieSpeed=2
levels(1).bogieActive=0
`levels(1).bogieTrigger=(rnd(29)+1)
levels(1).bogieTrigger=2 `for testing
endfunction
function runTitleScreen()
sync
endfunction
function runIntro()
sync
endfunction
function runGame()
dim missiles(levels(currentLevel).totalMissiles) as projectile
dim bullets(levels(currentLevel).totalBullets) as projectile
initializeMissiles()
initializeBullets()
do
handlePlayerInput()
drawCities()
drawCannon()
triggerMissiles()
moveBullets()
moveMissiles()
moveBogies()
playExplosions()
printPlayerStats()
triggerLeeResponse()
sync
loop
endfunction
function runEndSequence()
endfunction
REM ***** ********************************** *****
REM ***** ** Supporting Functions ** *****
REM ***** ********************************** *****
function initializeMissiles() `sprites 20-80
dim possibleTargets(7,2)
possibleTargets(1,1)=levels(currentLevel).xCity1
possibleTargets(1,2)=levels(currentLevel).yCity1
possibleTargets(2,1)=levels(currentLevel).xCity2
possibleTargets(2,2)=levels(currentLevel).yCity2
possibleTargets(3,1)=levels(currentLevel).xCity3
possibleTargets(3,2)=levels(currentLevel).yCity3
possibleTargets(4,1)=levels(currentLevel).xCity4
possibleTargets(4,2)=levels(currentLevel).yCity4
possibleTargets(5,1)=levels(currentLevel).xCity5
possibleTargets(5,2)=levels(currentLevel).yCity5
possibleTargets(6,1)=levels(currentLevel).xCity6
possibleTargets(6,2)=levels(currentLevel).yCity6
possibleTargets(7,1)=levels(currentLevel).xCannon
possibleTargets(7,2)=levels(currentLevel).yCannon
for i=1 to levels(currentLevel).totalMissiles
selectedTarget = (rnd(6)+1)
missiles(i).id = i + 20
missiles(i).xPosition = rnd(1024)
if missiles(i).xPosition = 0 then inc missiles(i).xPosition
missiles(i).yPosition = 0
missiles(i).xOrigin = missiles(i).xPosition
missiles(i).yOrigin = missiles(i).yPosition
missiles(i).xTarget = possibleTargets(selectedTarget,1)
missiles(i).yTarget = possibleTargets(selectedTarget,2)
missiles(i).tracers=levels(currentLevel).missileTracers
missiles(i).isActive = 0
next i
endfunction
function initializeBullets() `sprites 80-140
for b=1 to levels(currentLevel).totalBullets
bullets(b).id = b + 80
bullets(b).xPosition=0
bullets(b).yPosition=0
bullets(b).xTarget=0
bullets(b).yTarget=0
bullets(b).tracers=levels(currentLevel).bulletTracers
bullets(b).isActive=0
next b
endfunction
function handlePlayerInput() ` sprite 1
sprite 1,mousex(),mousey(),1
offset sprite 1,15,15
set sprite priority 1, 1
endfunction
function drawCities() `sprites 2-7
ink rgb(255,0,0),0
line 0,668,1024,668 ` building the cannon platform
line 462,668,462,656
line 462,656,487,656
line 487,656,487,644
line 487,644,537,644
line 537,644,537,656
line 537,656,562,656
line 562,656,562,668
box 500,630,525,644 ` building the cannon housing
ink 0,0
box 501,631,524,643
ink rgb(255,0,0),0
sprite 2,levels(currentLevel).xCity1,levels(currentLevel).yCity1,3
sprite 3,levels(currentLevel).xCity2,levels(currentLevel).yCity2,3
sprite 4,levels(currentLevel).xCity3,levels(currentLevel).yCity3,3
sprite 5,levels(currentLevel).xCity4,levels(currentLevel).yCity4,3
sprite 6,levels(currentLevel).xCity5,levels(currentLevel).yCity5,3
sprite 7,levels(currentLevel).xCity6,levels(currentLevel).yCity6,3
for t=2 to 7
offset sprite t,37,24
next t
endfunction
function drawCannon()
if levels(currentLevel).cannonDamaged = 1
exitfunction
endif
ink rgb(255,0,0),0
mousePositionX#=mousex()
mousePositionY#=mousey()
barrelOriginX=levels(currentLevel).xCannon
barrelOriginY=levels(currentLevel).yCannon
rem if mouse goes below the height of the barrel, let it go no further
if mousePositionY# > barrelOriginY
mousePositionY# = barrelOriginY
endif
rem avoid zero
if mousePositionX# = 0
mousePositionX# = 1
endif
rem avoid zero
if mousePositionY# = 0
mousePositionY# = 1
endif
bigTriangleHeight=(barrelOriginY - mousePositionY#)
bigTriangleBase=abs(barrelOriginX - mousePositionX#)
distanceToMouse#=sqrt((bigTriangleBase*bigTriangleBase) + (bigTriangleHeight * bigTriangleHeight))
rem avoid zero
if distanceToMouse#=0
distanceToMouse#=1
endif
smallTriangleHeight#=(bigTriangleHeight * barrelLength) / distanceToMouse#
bulletOriginY#=smallTriangleHeight# + (smallTriangleHeight# / 2)
smallTriangleWidth#=sqrt((barrelLength * barrelLength) - (smallTriangleHeight# * smallTriangleHeight#))
bulletOriginX#=smallTriangleWidth# + (smallTriangleWidth# / 2)
if mousex() < barrelOriginX
line barrelOriginX,barrelOriginY,(barrelOriginX-smallTriangleWidth#),(barrelOriginY-smallTriangleHeight#)
else
line barrelOriginX,barrelOriginY,(barrelOriginX+smallTriangleWidth#),(barrelOriginY-smallTriangleHeight#)
endif
if mouseclick()=1
curtime=timer()
if curtime >= lastshot+300
if mousey() > barrelOriginY
play sound 15
else
if levels(currentLevel).bulletsUsed < levels(currentLevel).totalBullets
play sound 1
for i=1 to levels(currentLevel).totalBullets
if bullets(i).isActive = 0
if mousex() < barrelOriginX
bullets(i).xPosition=(barrelOriginX-bulletOriginX#)
bullets(i).yPosition=(barrelOriginY-bulletOriginY#)
bullets(i).xOrigin=(barrelOriginX-bulletOriginX#)
bullets(i).yOrigin=(barrelOriginY-bulletOriginY#)
else
bullets(i).xPosition=(barrelOriginX+bulletOriginX#)
bullets(i).yPosition=(barrelOriginY-bulletOriginY#)
bullets(i).xOrigin=(barrelOriginX+bulletOriginX#)
bullets(i).yOrigin=(barrelOriginY-bulletOriginY#)
endif
bullets(i).xTarget=mousePositionX#
bullets(i).yTarget=mousePositionY#
bullets(i).isActive=1
exit
endif
next i
lastshot = curtime
inc levels(currentLevel).bulletsUsed
else
play sound 15
endif
endif
endif
endif
endfunction
function triggerMissiles()
for z=1 to levels(currentLevel).totalMissiles
if missiles(z).isActive=0
if levels(currentLevel).missilesInflight < levels(currentLevel).missilesAllowed
missiles(z).isActive=1
inc levels(currentLevel).missilesInflight
endif
endif
next z
endfunction
function moveBullets()
for b=1 to levels(currentLevel).totalBullets
if bullets(b).isActive=1
height#=abs(bullets(b).yTarget - bullets(b).yPosition)
width# =abs(bullets(b).xTarget - bullets(b).xPosition)
hyp# =sqrt((height# * height#) + (width# * width#))
smheight# = ((levels(currentLevel).bulletSpeed * height#) / hyp#)
smwidth# = ((levels(currentLevel).bulletSpeed * width#) / hyp#)
if (bullets(b).xPosition > bullets(b).xTarget)
bullets(b).xPosition = bullets(b).xPosition - smwidth#
bullets(b).yPosition = bullets(b).yPosition - smheight#
if bullets(b).xPosition <= bullets(b).xTarget
bullets(b).isActive = 2
endif
if bullets(b).yPosition <= bullets(b).yTarget
bullets(b).isActive = 2
endif
else
bullets(b).xPosition = bullets(b).xPosition + smwidth#
bullets(b).yPosition = bullets(b).yPosition - smheight#
if bullets(b).xPosition >= bullets(b).xTarget
bullets(b).isActive = 2
endif
if bullets(b).yPosition <= bullets(b).yTarget
bullets(b).isActive = 2
endif
endif
if bullets(b).isActive = 2
play sound 3
create animated sprite bulletSprite, "media\smboom1.bmp", 6, 1, 9 `image 9 taken
offset sprite bulletSprite, 16, 16
set sprite frame bulletSprite, 1
sprite bulletSprite, bullets(b).xTarget, bullets(b).yTarget, 9
if sprite exist(bogieSprite)
if sprite collision (bulletSprite, bogieSprite)
inc levels(currentLevel).bogieActive
endif
endif
for k=1 to levels(currentLevel).totalMissiles
if missiles(k).isActive = 1
if sprite exist (missiles(k).id)
if sprite collision (bulletSprite, missiles(k).id)
missiles(k).isActive = 2
inc levels(currentLevel).missilesDestroyed
dec levels(currentLevel).missilesInflight
delete sprite missiles(k).id
endif
endif
endif
next k
inc bulletSprite
if sprite exist(bullets(b).id)
delete sprite bullets(b).id
endif
else
if levels(currentLevel).bulletTracers = 1
ink rgb(255,255,255),0
line bullets(b).xOrigin, bullets(b).yOrigin, bullets(b).xPosition, bullets(b).yPosition
ink rgb(255,0,0),0
endif
sprite bullets(b).id, bullets(b).xPosition, bullets(b).yPosition, 2
offset sprite bullets(b).id, sprite width(bullets(b).id)/2, sprite height(bullets(b).id)/2
endif
endif
next b
endfunction
function moveMissiles()
for b=1 to levels(currentLevel).totalMissiles
if missiles(b).isActive = 1
set cursor 0,0
height#=abs(missiles(b).yTarget - missiles(b).yPosition)
width# =abs(missiles(b).xTarget - missiles(b).xPosition)
hyp# = sqrt((height# * height#) + (width# * width#))
smheight# = ((levels(currentLevel).missileSpeed * height#) / hyp#) `taking a ratio of the larger triangle to find the smaller height
smwidth# = ((levels(currentLevel).missileSpeed * width#) / hyp#) `taking a ratio of the larger triangle to find the smaller width
if (missiles(b).xPosition < missiles(b).xTarget) `this is for missiles coming from the near side of the town
missiles(b).xPosition = missiles(b).xPosition + smwidth#
missiles(b).yPosition = missiles(b).yPosition + smheight#
if missiles(b).xPosition >= missiles(b).xTarget `registers a hit on the town because the xPosition exceeds the town's
missiles(b).isActive = 2
endif
if missiles(b).yPosition >= missiles(b).yTarget `registers a hit on the town because the yPosition exceeds the town's
missiles(b).isActive = 2
endif
else
missiles(b).xPosition = missiles(b).xPosition - smwidth# `this is for missiles coming from the far side of the town
missiles(b).yPosition = missiles(b).yPosition + smheight#
if missiles(b).xPosition <= missiles(b).xTarget `registers a hit on the town because the xPosition is smaller than the town's
missiles(b).isActive = 2
endif
if missiles(b).yPosition >= missiles(b).yTarget `registers a hit on the town because the yPosition exceeds the town's
missiles(b).isActive = 2
endif
endif
if missiles(b).isActive = 2
play sound 3
create animated sprite missileSprite, "media\smboom1.bmp", 6, 1, 10 `image 10 taken
offset sprite missileSprite, 16, 16
set sprite frame missileSprite, 1
sprite missileSprite, missiles(b).xTarget, missiles(b).yTarget, 2
inc missileSprite
inc levels(currentLevel).missilesDestroyed
dec levels(currentLevel).missilesInflight
if ((missiles(b).xTarget = levels(currentLevel).xCannon) OR (missiles(b).yTarget = levels(currentLevel).yCannon))
if sprite exist(145) = 0
inc levels(currentLevel).cannonDamaged
create animated sprite 145, "media\repairing.png", 9, 1, 15
offset sprite 145, 34, 34
set sprite frame 145, 1
sprite 145, levels(currentLevel).xCannon, levels(currentLevel).yCannon-34, 15
endif
endif
if missiles(b).xTarget = levels(currentLevel).xCity1 then inc levels(currentLevel).statusCity1
if missiles(b).xTarget = levels(currentLevel).xCity2 then inc levels(currentLevel).statusCity2
if missiles(b).xTarget = levels(currentLevel).xCity3 then inc levels(currentLevel).statusCity3
if missiles(b).xTarget = levels(currentLevel).xCity4 then inc levels(currentLevel).statusCity4
if missiles(b).xTarget = levels(currentLevel).xCity5 then inc levels(currentLevel).statusCity5
if missiles(b).xTarget = levels(currentLevel).xCity6 then inc levels(currentLevel).statusCity6
`inc levels(currentLevel).cityHit
`leeTaunt()
if sprite exist(missiles(b).id)
delete sprite missiles(b).id
endif
else
if levels(currentLevel).missileTracers = 1
ink rgb(255,255,255),0
line missiles(b).xOrigin, missiles(b).yOrigin, missiles(b).xPosition, missiles(b).yPosition
ink rgb(255,0,0),0
endif
sprite missiles(b).id, missiles(b).xPosition, missiles(b).yPosition, 2
offset sprite missiles(b).id, sprite width(missiles(b).id)/2, sprite height(missiles(b).id)/2
endif
endif
next b
if sprite exist(145)=1 AND levels(currentLevel).cannonDamaged=1
play sprite 145, 1, 9, 500
if sprite frame(145)=9
hide sprite 145 : delete sprite 145 : dec levels(currentLevel).cannonDamaged
endif
endif
endfunction
function moveBogies()
if levels(currentLevel).missilesDestroyed = levels(currentLevel).bogieTrigger AND levels(currentLevel).bogieActive = 0
levels(currentLevel).bogiePositionX = 0
levels(currentLevel).bogiePositionY = rnd(50)+25
levels(currentLevel).bogieActive=1
endif
if levels(currentLevel).bogieActive=1
levels(currentLevel).bogiePositionX = levels(currentLevel).bogiePositionX + levels(currentLevel).bogieSpeed
sprite bogieSprite, levels(currentLevel).bogiePositionX, levels(currentLevel).bogiePositionY, 12
if levels(currentLevel).bogiePositionX >= 1024
inc levels(currentLevel).bogieActive
endif
endif
if levels(currentLevel).bogieActive=2
if sprite exist(bogieSprite)=1
delete sprite bogieSprite
endif
endif
endfunction
function playExplosions()
for i=150 to 190
if sprite exist(i)
play sprite i, 1, 6, 100
if sprite frame(i) = 6 then hide sprite i : delete sprite i
if bulletSprite > 170 then bulletSprite = 150
if missileSprite > 190 then missileSprite = 170
endif
next i
endfunction
function printPlayerStats()
` just using for debugging right now
set cursor 0,0
print "Bogie Trigger: " + str$(levels(currentLevel).bogieTrigger)
print "Missiles Destroyed: " + str$(levels(currentLevel).missilesDestroyed)
print "Bogie Position X: " + str$(levels(currentLevel).bogiePositionX)
print "Bogie Status: " + str$(levels(currentLevel).bogieActive)
endfunction
function checkWinCondition()
endfunction
function triggerLeeResponse()
endfunction