Hi Virtual Nomad!
Thats really smart, I think I will start using some of your techniques in my coding style.
For the collision I dont think its a floating point error.
I can get it so that the character slides, but when they get too a part of the wall that is adjacent to another wall (i,e colliding 2 walls at once) I cant get it so that the slide continues, it awlays stops.
I've attached my current code which works, but it doesnt slide.
If you have time want to have a look?
// Project: Elixir
// Created: 20-08-12
// show all errors
SetErrorMode(2)
// set window properties
SetWindowTitle( "Elixir" )
SetWindowSize( 640, 480, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 640, 480 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 )
Loadimage(1,"Scientist.png")
type playerdata
id as integer
idle as integer
statechange as integer
state as integer
facing as integer
name as string
x as integer
y as integer
oldx as integer
oldy as integer
collision as integer
endtype
Dim player[1] as playerdata
player[1].id=1
player[1].x=1
player[1].y=1
player[1].idle=0
player[1].facing=1
player[1].statechange=0
player[1].state=0
player[1].collision=0
player[1].name="Name"
createsprite (1,1)
setspritedepth(1,1)
setspriteanimation (1,32,32,12)
playsprite(1,10,1,1,1)
setspriteshape(1,3)
// load the floor tile
loadimage(2,"floor.png")
Loadimage(3,"roof.png")
Loadimage(4,"wall.png")
//the floordata is held in this array. 18 tiles across, and 13 down.
Dim Floordata [18,13]
// randomize the position of the start hatch and the escape, they must be 5 tiles away along the x and y
type door
x as integer
y as integer
endtype
dim hatch[3] as door
loadimage(5,"hatch.png")
buildlevel()
loadimage(6,"zombie.png")
type zombie
id as integer
x as integer
y as integer
oldx as integer
oldy as integer
idle as integer
facing as integer
state as integer
statechange as integer
endtype
Global level=1
populate()
do
input()
enemies()
collision ()
playeranimation()
Print( ScreenFPS() )
print(totalzombies)
Sync()
loop
// Input function
function input ()
// record the old x and y for collision.
player[1].oldx=player[1].x
player[1].oldy=player[1].y
// set the player to idle animation and set the statechange to the current state.
player[1].idle=1
player[1].statechange=player[1].state
// KEY_LEFT 37
// KEY_UP 38
// KEY_RIGHT 39
// KEY_DOWN 40
if getrawkeystate(37)=1
player[1].x=player[1].x-2
player[1].idle=0
player[1].facing=4
player[1].state=1
endif
// keyup
if getrawkeystate(38)=1
player[1].y=player[1].y-2
player[1].idle=0
player[1].facing=1
player[1].state=2
endif
// keyright
if getrawkeystate(39)=1
player[1].x=player[1].x+2
player[1].idle=0
player[1].facing=3
player[1].state=3
endif
//keydown
if getrawkeystate(40)=1
player[1].y=player[1].y+2
player[1].idle=0
player[1].facing=2
player[1].state=4
endif
if player[1].idle=1
player[1].state=5
endif
print (player[1].state)
print (player[1].statechange)
setspriteposition(1,player[1].x,player[1].y)
endfunction
// function animates the player
function playeranimation()
//checks whether the animation state has changed. Animates based on idle and facing.
if player[1].statechange<>player[1].state
if player[1].idle=0
if player[1].facing=3 then playsprite(1,10,1,8,9)
if player[1].facing=4 then playsprite(1,10,1,11,12)
if player[1].facing=2 then playsprite(1,10,1,5,6)
if player[1].facing=1 then playsprite(1,10,1,2,3)
endif
if player[1].idle=1
if player[1].facing=3 then playsprite(1,10,1,7,7)
if player[1].facing=4 then playsprite(1,10,1,10,10)
if player[1].facing=2 then playsprite(1,10,1,4,4)
if player[1].facing=1 then playsprite(1,10,1,1,1)
endif
endif
Endfunction
// level building function
function buildlevel ()
//randomize the hatch locations
hatch[1].x=random(2,17)
hatch[1].y=random(2,12)
// this code places the second hatch at least 5 away from the x value, not more than 8 away, and it cant equal a border position.
if hatch[1].x>9
hatch[2].x=hatch[1].x-random(5,8)
else
hatch[2].x=hatch[1].x+random(5,8)
endif
// same for y value but 5 or 6
if hatch[1].y>7
hatch[2].y=hatch[1].y-random(5,6)
else
hatch[2].y=hatch[1].y+random(5,6)
endif
if hatch[2].y<2 then hatch[2].y=2
if hatch[2].y>12 then hatch[2].y=12
if hatch[2].x<2 then hatch[2].x=2
if hatch[2].x>17 then hatch[2].x=17
//set all the floordata to roof
for i=1 to 18
for o =1 to 13
floordata[i,o]=2
next o
next i
// create a worm of floor tiles, starting at hatch position and repeat until it hits the other hatch. it wont go over border.
// also the worm should never go backwards
wormx=hatch[1].x
wormy=hatch[1].y
exitx=hatch[2].x
exity=hatch[2].y
repeat
floordata[wormx,wormy]=1
chance=random(1,4)
if chance =1
chance2=random(1,2)
if chance2=1 then wormx=wormx+1
if chance2=2 then wormx=wormx-1
endif
if chance =2
chance2=random(1,2)
if chance2=1 then wormy=wormy+1
if chance2=2 then wormy=wormy-1
endif
if wormx>17 then wormx=17
if wormy>12 then wormy=12
if wormx<2 then wormx=2
if wormy<2 then wormy=2
until wormx=exitx and wormy=exity
// this is a function that decides whether to draw roofs or walls
for i=2 to 17
for o=1 to 12
// if roof then check to see if should be wall
if floordata[i,o]>1
if floordata[i,o+1]=1 then floordata[i,o]=3
endif
next o
next i
// this is a repeat of the two fors to draw the sprites. Maxtiles is a variable name for the current sprite index of the tile.
// maxtiles gets incremented to 2 so it doenst take the player position of 1.
maxtiles=1
for i=1 to 18
for o=1 to 13
inc maxtiles
createsprite (maxtiles,floordata[i,o]+1)
if floordata[i,o]>1 then setspritedepth(maxtiles,0)
if floordata[i,o]=1 then setspritedepth(maxtiles,2)
if i=hatch[1].x
if o=hatch[1].y
setspriteimage(maxtiles,5)
setspriteanimation(maxtiles,32,32,2)
hatch_spr=maxtiles
endif
endif
if i=hatch[2].x
if o=hatch[2].y
setspriteimage(maxtiles,5)
setspriteanimation(maxtiles,32,32,2)
hatch2_spr=maxtiles
endif
endif
setspriteposition (maxtiles,i*32,o*32)
next o
next i
// set the player position to the hatch position
player[1].x=getspritex(hatch_spr)
player[1].y=getspritey(hatch_spr)
endfunction
function collision()
// this function checks for player collision with walls and roofs. It also checks the y value and determines which should be drawn first.
// lets use maxtiles and the same i and o loop.
maxtiles=1
for i=1 to 18
for o=1 to 13
inc maxtiles
// checks for collision with walls and roofs
if floordata[i,o]>1
if getspritecollision(1,maxtiles)=1
// check the y values and draw the correct sprite on top
if player[1].y<getspritey(maxtiles)
setspritedepth(maxtiles,1)
else
setspritedepth(maxtiles,3)
endif
// if colliding with wall, check y offset
if floordata[i,o]=3
print ("wall")
if player[1].y>getspritey(maxtiles)-20
if player[1].y<getspritey(maxtiles)+20
player[1].y=player[1].oldy
player[1].x=player[1].oldx
endif
endif
endif
if floordata[i,o]=2
print ("roof")
if player[1].y>getspritey(maxtiles)-20
if player[1].y<getspritey(maxtiles)+32
player[1].x=player[1].oldx
player[1].y=player[1].oldy
endif
endif
endif
endif
endif
next o
next i
endfunction
function enemies()
// check whether the zombie should idle or move
for i=1 to totalzombies
chance=random(1,30)
//set the zombie statechange
zombie[i].statechange=zombie[i].state
// set the oldzombie pos
zombie[i].oldx=zombie[i].x
zombie[i].oldy=zombie[i].y
if zombie[i].idle=1 then zombie[i].state=2
if zombie[i].idle=0 then zombie[i].state=1
// idle is state 2, moving is state 1
if chance=1
if zombie[i].idle=0
zombie[i].idle=1
chance=random(1,3)
if chance=1
zombie[i].facing=random(1,4)
endif
else
zombie[i].idle=0
endif
endif
if zombie[i].idle=1 then zombie[i].state=2
if zombie[i].idle=0 then zombie[i].state=1
// if not idling then move in a direction based on facing
if zombie[i].idle=0
if zombie[i].facing=1 then zombie[i].y=zombie[i].y+1
if zombie[i].facing=2 then zombie[i].y=zombie[i].y-1
if zombie[i].facing=3 then zombie[i].x=zombie[i].x-1
if zombie[i].facing=4 then zombie[i].x=zombie[i].x+1
endif
setspriteposition(zombie[i].id,zombie[i].x,zombie[i].y)
//checks whether the zombie state has changed. Animates based on idle and facing.
if zombie[i].statechange<>zombie[i].state
if zombie[i].idle=0
if zombie[i].facing=4 then playsprite(zombie[i].id,10,1,8,9)
if zombie[i].facing=3 then playsprite(zombie[i].id,10,1,11,12)
if zombie[i].facing=1 then playsprite(zombie[i].id,10,1,5,6)
if zombie[i].facing=2 then playsprite(zombie[i].id,10,1,2,3)
endif
if zombie[i].idle=1
if zombie[i].facing=4 then playsprite(zombie[i].id,10,1,7,7)
if zombie[i].facing=3 then playsprite(zombie[i].id,10,1,10,10)
if zombie[i].facing=1 then playsprite(zombie[i].id,10,1,4,4)
if zombie[i].facing=2 then playsprite(zombie[i].id,10,1,1,1)
endif
endif
// check for colliding with walls and draw the correct sprite on top
maxtiles=1
for p=1 to 18
for o=1 to 13
inc maxtiles
//check y offset
if floordata[p,o]>1
if getspritecollision(maxtiles,zombie[i].id)=1
// check the y values and draw the correct sprite on top
if zombie[i].y<getspritey(maxtiles)
setspritedepth(maxtiles,1)
else
setspritedepth(maxtiles,3)
endif
if zombie[i].y>getspritey(maxtiles)-20
if zombie[i].y<getspritey(maxtiles)+20
zombie[i].y=zombie[i].oldy
zombie[i].x=zombie[i].oldx
endif
endif
setspriteposition(zombie[i].id,zombie[i].x,zombie[i].y)
endif
endif
next o
next p
next i
endfunction
function populate()
// set a random amout of zombies based on level number
global totalzombies
totalzombies=level+random(1,3)
for i=1 to totalzombies
createsprite(300+i,6)
setspritedepth(300+i,2)
setspriteanimation (300+i,32,32,12)
playsprite(300+i,10,1,1,1)
setspriteshape(300+i,3)
dim zombie[i] as zombie
zombie[i].id=300+i
zombie[i].x=1
zombie[i].y=1
zombie[i].state=1
zombie[i].statechange=1
zombie[i].facing=1
zombie[i].idle=1
repeat
for p=2 to 17
for o=2 to 12
if floordata[p,o]=1
chance=random(1,30 )
if chance=1
zombie[i].x=p*32
zombie[i].y=o*32
setspriteposition(zombie[i].id,zombie[i].x,zombie[i].y)
endif
endif
next o
next p
until zombie[i].x>1
next i
endfunction