I changed the collision subroutine a bit, combining a couple of elements from Pizzaman's code with some of my own, and it
almost works. The left collsion works like it should, but only in certain places, and I haven't been able to get the right collision to work. Top collision works well, but only in certain places as with before, and bottom collision... Well, it almost works, but Mario usually doesn't collide until he reaches the bottom of the tile, as opposed to colliding with the top of the tile as he should. And after scrolling for a bit it says "array accessed out of bounds". What am I doing wrong?
sync on:sync rate 150
Gosub setup
Gosub vars
Gosub loadimages
Gosub readmap
Do
cls
gosub dispmap
gosub dispsprite
gosub tilecollision
sync
Loop
setup:
set display mode 400,300,32
set window on
`I find that the window sometimes leaves out text at the top of the screen, so I increase the window size a bit.
set window size 400,307
set window title "Mario Ghost House"
return
vars:
`map array
Dim Tilemap(25,15)
tilesizeX=35
tilesizeY=35
centerx=200
centery=150
`map coordinates
Xscroll=-40
Yscroll=-262
StartX=Xscroll
StartY=Yscroll
OldXscroll=Xscroll
OldYscroll=Yscroll
Marioani=51
`Mario's position relative to the screen
MarioX=50
MarioY=223
Oldmariox=MarioX
Oldmarioy=MarioY
`speed for Mario and scrolling
speedX=2
speedY=3
xfocus=1
return
loadimages:
load image "sprites/Gblock.bmp",1
load image "sprites/GWall.bmp",2
load image "sprites/GWallb.bmp",3
load image "sprites/Mb1.bmp",51
load image "sprites/Mb2.bmp",52
load image "sprites/Mb3.bmp",53
load image "sprites/Mbj.bmp",54
cls rgb(255,0,0)
get image 599,0,0,10,10
cls rgb(0,0,0)
return
readmap:
restore map1
level=1
If level=1 then level$="Level 1"
set window title "Mario Ghost house-" + level$
set window size 400,307
For y=1 to 15
For x=1 to 25
read Tilemap(x,y)
next x
next y
return
dispmap:
For y=1 to 15
For x=1 to 25
paste image Tilemap(x,y),((x*tilesizeX)+Xscroll),((y*tilesizeY)+Yscroll)
`debug way of scrolling the map, for testing purposes.
If keystate(77)=1
inc scrollcounterx
If scrollcounterx=500 then dec Xscroll,speedx:scrollcounterx=0
endif
If keystate(75)=1
inc scrollcounterx
If scrollcounterx=500 then inc Xscroll,speedx:scrollcounterx=0
endif
If keystate(72)=1
inc scrollcountery
If scrollcountery=500 then inc Yscroll,speedy:scrollcountery=0
endif
If keystate(80)=1
inc scrollcountery
If scrollcountery=500 then dec Yscroll,speedy:scrollcountery=0
endif
If keystate(77)=0 and keystate(75)=0 then scrollcounterx=0
If keystate(72)=0 and keystate(80)=0 then scrollcountery=0
If Xscroll>-40 then Xscroll=-40
If Xscroll<-506 then Xscroll=-506
If Yscroll<-262 then Yscroll=-262
next x
next y
return
dispsprite:
If leftkey()=0 and rightkey()=0 then moving=0
`The dec and inc commands are used to break Mario out of the center.
If Xscroll>=startx and xfocus=2 then dec mariox:xfocus=1
If Xscroll<=-506 and xfocus=2 then inc mariox:xfocus=3
`Following sets viewpoints: 1=Leftmost of map and non-scrolling, 2=Scrolling view, 3=Rightmost of map and non-scrolling.
If mariox<=centerx and xfocus=3 then xfocus=2
If mariox>=centerx and xfocus=1 then xfocus=2
If rightkey()=1
moving=1
`Following says Mario moves when the view point is set to 1 or 3.
If xfocus=1 or xfocus=3 then inc mariox,speedx
`Says if the view point is set to 2 then mario is locked at the center of the screen while the map scrolls around him.
If xfocus=2
mariox=centerx
dec Xscroll,speedx
endif
If dirflag=1 then mirror sprite 50:dirflag=0
endif
If leftkey()=1
moving=1
If xfocus=1 or xfocus=3 then dec mariox,speedx
If xfocus=2
mariox=centerx
inc Xscroll,speedx
endif
If dirflag=0 then mirror sprite 50:dirflag=1
endif
`Animation timer
If moving=0 then aniA=0
If moving=1 then inc aniA
If aniA=0 or aniA<=5 then marioani=51
If aniA=7 then marioani=52
If aniA=14 then marioani=53
If aniA=21 then marioani=52
If aniA=28 then aniA=0
sprite 50,marioX,marioY,marioani
return
tilecollision:
For y=1 to 15
For x=1 to 25
leftpos=int((MarioX+abs(Xscroll))/TilesizeX)
rightpos=int(((MarioX+abs(Xscroll))+(TilesizeX-1))/TilesizeX)
toppos=int((MarioY+abs(Yscroll))/TilesizeY)
bottompos=int(((MarioY+abs(Xscroll))+(TilesizeY-1))/TilesizeY)
oldleftpos=leftpos
oldrightpos=rightpos
oldtoppos=toppos
oldbottompos=bottompos
If tilemap(leftpos,oldtoppos)<=2 then mariox=oldmariox:xscroll=oldxscroll:else:oldmariox=mariox:oldxscroll=xscroll
If tilemap(oldleftpos,toppos)<=2 then marioy=oldmarioy:yscroll=oldyscroll:else:oldmarioy=marioy:oldyscroll=yscroll
If tilemap(rightpos,oldtoppos)<=2 then mariox=oldmariox:xscroll=oldxscroll:else:oldmariox=mariox:oldxscroll=xscroll
If tilemap(oldrightpos,toppos)<=2 then marioy=oldmarioy:yscroll=oldyscroll:else:oldmarioy=marioy:oldyscroll=yscroll
If tilemap(leftpos,oldbottompos)<=2 then mariox=oldmariox:xscroll=oldxscroll:else:oldmariox=mariox:oldxscroll=xscroll
If tilemap(oldleftpos,bottompos)<=2 then marioy=oldmarioy:yscroll=oldyscroll:else:oldmarioy=marioy:oldyscroll=yscroll
If tilemap(rightpos,oldbottompos)<=2 then mariox=oldmariox:xscroll=oldxscroll:else:oldmariox=mariox:oldxscroll=xscroll
If tilemap(oldrightpos,bottompos)<=2 then marioy=oldmarioy:yscroll=oldyscroll:else:oldmarioy=marioy:oldyscroll=yscroll
next x
next y
return
`map data starts here
map1:
Data 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
Data 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
Data 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
Data 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
Data 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
Data 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3
Data 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
Data 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,3,3
Data 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
Data 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,3,3,3
Data 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
Data 2,3,3,3,3,3,3,3,3,1,1,1,3,3,3,1,1,1,1,1,1,3,3,3,3
Data 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
Data 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
Data 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
`Image 3 is the background, 2 the walls, 1 the floor and platforms.