Jatkoin näkyvyyskoodin tutkimista. Ei siitä vieläkään hyvä tullut, mutta ainakin pahimmat vilkkumiset korjautuivat.
Kuvaan on merkitty nykyiset ongelmakohdat joissa tilejen kulmat peittyvät tietyistä suunnista katsottuna.
Itse pelissä kartan OVER-kerros piirretään kuitenkin tummennuksen päälle, joten nämä ongelmat eivät välttämättä näytä kovin pahoilta käytännössä. Lisäksi näkyvyysalue on vain tummennettu eikä esim. täysin musta, joten pienet virheet eivät välttämättä pistä silmään.
Code: Select all
// #define TIC __timerstart = timer()
// #define TOC (timer() - __timerstart)
const COORD_X = 0
const COORD_Y = 1
dim mapCornerPositions(0,0,1)
dim mapCorners(0,0)
const CORNER_NW = 0
const CORNER_NE = 1
const CORNER_SE = 2
const CORNER_SW = 3
function find_map_corners(map, tilesize)
mapw = mapWidth()
maph = mapHeight()
mapx = objectX(map)
mapy = objectY(map)
reDim mapCorners(mapw, maph)
reDim mapCornerPositions(mapw, maph, 2)
for ty=1 to maph
for tx=1 to mapw
A = getMap2(2, tx-1, ty-1)
B = getMap2(2, tx , ty-1)
C = getMap2(2, tx-1, ty)
D = getMap2(2, tx , ty)
' the tiles are in the following arrangement:
' A B
' C D
' 0,0 1,0
' 0,1 1,1
corner = true
' X X
' Y Y
if (A = B) and (C = D) then corner = false
' X Y
' X Y
if A = C and B = D then corner = false
ofs_x = 0
ofs_y = 0
amt = 1
' push the corner point away from the tile
if corner then
if A then ofs_x = ofs_x + amt : ofs_y = ofs_y + amt
if B then ofs_x = ofs_x - amt : ofs_y = ofs_y + amt
if C then ofs_x = ofs_x + amt : ofs_y = ofs_y - amt
if D then ofs_x = ofs_x - amt : ofs_y = ofs_y - amt
'ofs_x + 10
endif
sx = ofs_x + (tx-1)*32 - objectSizeX(map)/2.0 + objectX(map)
sy = ofs_y + (ty-1)*32 - objectSizeY(map)/2.0 + objectY(map)
mapCornerPositions(tx, ty, COORD_X) = sx
mapCornerPositions(tx, ty, COORD_Y) = sy
mapCorners(tx, ty) = corner
next tx
next ty
endFunction
const MAX_CORNER_COUNT = 150
'global losCornerCount // done at runtime
dim losCornerAngles(MAX_CORNER_COUNT) as float
'! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
'Aja tämä ohjelma painamalla F5.
'Lopeta ohjelma painamalla ESC.
'! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
SCREEN 640,480
'frameLimit 40 'rajoita nopeutta
kartta = LoadMap("Media\cdm2.til","Media\tileset.bmp")
PlayObject kartta,0,0,1
ukko = LoadObject ("Media\guy.bmp",72)
'setupCollision ukko, kartta, 1, 4, 2
dummy = makeObject()
objectPickable kartta, ON
translateObject kartta, 16, 0
__timerstart = timer()
find_map_corners(kartta, 32)
setWindow " took " + (timer() - __timerstart) + " ms"
corner_max = 0
draw_triangles = true
repeat
if keyHit(cbKeySpace) then draw_triangles = not draw_triangles
'Ukon ohjaus
If LeftKey() Then TurnObject ukko,5
If RightKey() Then TurnObject ukko,-5
If UpKey() Then MoveObject ukko,2*2
If DownKey() Then MoveObject ukko,-2*2
updateGame
CloneCameraPosition ukko
drawGame
color 255,255,255
drawToWorld ON,ON,ON
mapw = mapWidth()
maph = mapHeight()
mapx = objectX(kartta)
mapy = objectY(kartta)
map_bound_x = max(0, ((cameraX()-320) - (-objectSizeX(kartta)/2.0 + objectX(kartta)))/32)
map_bound_y = max(0, ((-cameraY()-240) - (-objectSizeY(kartta)/2.0 - objectY(kartta)))/32)
' piirtoa varten ei flipata kameran y:tä, kiitos vaan zerppa
map_bound_y2 = max(0, ((cameraY()+240) - (-objectSizeY(kartta)/2.0 + objectY(kartta)))/32) + 2
map_bound_x_end = min(mapw-1, map_bound_x + roundUp(640/32.0)) + 1 ' +1 is needed to handle rightmost corners
map_bound_y_end = min(maph-1, map_bound_y + roundUp(480/32.0)) + 2
setWindow map_bound_x + ", " + map_bound_y
box map_bound_x, map_bound_y ,10, 10, 1
' static corners
'const MAX_CORNER_COUNT = 150
'dim losCornerAngles(MAX_CORNER_COUNT)
color cbwhite
corner_count = 0
for ty=map_bound_y to map_bound_y_end
for tx=map_bound_x to map_bound_x_end
if mapCorners(tx, ty) then
'sx = (tx)*32 - objectSizeX(kartta)/2.0 + objectX(kartta)
'sy = (ty)*32 - objectSizeY(kartta)/2.0 + objectY(kartta)
sx = mapCornerPositions(tx, ty, COORD_X)
sy = mapCornerPositions(tx, ty, COORD_Y)
ang# = getAngle(objectX(ukko), -objectY(ukko), sx, sy)
losCornerAngles(corner_count) = ang
corner_count = corner_count + 1
box sx-1,-sy+1,3,3,1
if corner_count >= MAX_CORNER_COUNT then
exit
endif
endif
next tx
if corner_count >= MAX_CORNER_COUNT then
exit
endif
next ty
solid = getMap2(2, map_bound_x + 1, map_bound_y + 1)
for y_index = 0 to 1
'ty = (map_bound_y - 4) * (1-y_index) '+ (map_bound_y_end-2) * y_index
ty = (map_bound_y - 1) * (1 - y_index) + (map_bound_y_end-1) * y_index
for tx = map_bound_x to map_bound_x_end
hit = getMap2(2, tx + 1, ty + 1)
if not hit = solid then
' spawn corners here
sx = (tx)*32 - objectSizeX(kartta)/2.0 + objectX(kartta)
sy = (ty)*32 - objectSizeY(kartta)/2.0 + objectY(kartta)
'sy2 = (ty)*32 - objectSizeY(kartta)/2.0 - objectY(kartta)
' if we came from air to solid, move the new point slightly to left etc.
if hit then
sx = sx - 1
else
sx = sx + 1
endif
color 255,0,255
box sx,-sy,6,6,1
ang# = getAngle(objectX(ukko), -objectY(ukko), sx, sy)
losCornerAngles(corner_count) = ang
corner_count = corner_count + 1
endif
solid = hit
next tx
next y_index
' vertical additional corners
solid = getMap2(2, map_bound_x + 1, map_bound_y + 1)
for x_index = 0 to 1
'ty = (map_bound_y - 1) * (1 - y_index) + (map_bound_y_end-1) * y_index
tx = (map_bound_x - 1) * (1 - x_index) + (map_bound_x_end) * x_index
for ty = map_bound_y to map_bound_y_end
hit = getMap2(2, tx + 1, ty + 1)
if not hit = solid then
' spawn corners here
sx = (tx)*32 - objectSizeX(kartta)/2.0 + objectX(kartta)
sy = (ty)*32 - objectSizeY(kartta)/2.0 + objectY(kartta)
'sy2 = (ty)*32 - objectSizeY(kartta)/2.0 - objectY(kartta)
if hit then
'sy = sy - 1
else
'sy = sy + 1
endif
color 255,0,255
box sx,-sy,6,6,1
ang# = getAngle(objectX(ukko), -objectY(ukko), sx, sy)
losCornerAngles(corner_count) = ang
corner_count = corner_count + 1
endif
solid = hit
next ty
next x_index
/*
' dynamic corners
last_hit = -1 'always hit ON first
for x=0 to 20 '640/32
xx = map_bound_x + x
yy = map_bound_y + 1
hit = getMap2(2, xx, yy)
if (last_hit <> hit) or x=20 then
xx=xx-1 'the last tile is the corner
sx = (xx)*32 - objectSizeX(kartta)/2.0 + objectX(kartta)
sy = (map_bound_y2-1)*32 - objectSizeY(kartta)/2.0 + objectY(kartta)
color cbred
box sx, sy+8, 8, 8, 1
last_hit = hit
ang# = getAngle(objectX(ukko), -objectY(ukko), sx, sy)
losCornerAngles(corner_count) = ang
corner_count = corner_count + 1
endif
next x
*/
iters = 0
repeat
sorted = true
for i = 0 to corner_count-1-1
if losCornerAngles(i) > losCornerAngles(i+1) then
temppi# = losCornerAngles(i)
losCornerAngles(i) = losCornerAngles(i+1)
losCornerAngles(i+1) = temppi
sorted = false
iters + 1
endif
next i
until sorted
corner_max = max(corner_count, corner_max)
steps = 30
a# = 360.0/float(steps)
cloneObjectPosition dummy, ukko
ox = objectX(dummy)
oy = objectY(dummy)
px = 0
py = 0
px2 = 0
py2 = 0
lock(SCREEN())
for i = 0 to corner_count
ang# = losCornerAngles(i mod corner_count)
if ang > 179 and ang < 181 then ang = 180
if ang > -1 and ang < 1 then ang = 0
dist# = 9999999.0
rotateObject dummy, ang
objectPick dummy
px = pickedX()
py = pickedY()
' we round the (px , py) coordinate to a multiple of 32 to
' align it with the underlying tile grid so the triangles won't
' cross tiles so often
'px = (px/32)*32
'py = (py/32)*32
if i > 0 then
color 255,255,255
if draw_triangles then drawtri(ox, oy, px, py, px2, py2)
color 0,255,0
line ox, oy, px, py
color 255,255,0
'circle px-4,py-4,16,1
endif
px2 = px
py2 = py
next i
unlock(SCREEN())
drawToWorld OFF,OFF,OFF
color 255,0,0
text 0,0,"FPS: " + FPS()
text 0,12,"corner count: " + corner_count
text 0,12*2,"corner max: " + corner_max
text 0,12*3,"sort iters: " + iters
text 0,12*4,"space: toggle fill"
text 0,12*5,"bounds: " + map_bound_x + ", " + map_bound_y + " -> " + map_bound_x_end + ", " + map_bound_y_end
text 0,12*6,"mouse: " + mouseWX() + ", " + mouseWY()
for i = 0 to corner_count-1
text 200,12*i,i+": " + losCornerAngles(i)
next i
drawScreen
forever
function drawtri(x1,y1,x2,y2,x3,y3) 'by atomimalli
'line x1,y1,x2,y2
'line x2,y2,x3,y3
'line x3,y3,x1,y1
If y2<y1 Then 'jos p2 on ylempänä kuin p1 vaihdetaan niiden paikkaa
tmp=y1
y1=y2
y2=tmp
tmp=x1
x1=x2
x2=tmp
EndIf
If y3<y1 Then 'jos p3 on ylempänä kuin p1 vaihdetaan niiden paikkaa
tmp=y1
y1=y3
y3=tmp
tmp=x1
x1=x3
x3=tmp
endif
if y3<y2 Then 'jos p3 on ylempänä kuin p2 vaihdetaan niiden paikkaa
tmp=y2
y2=y3
y3=tmp
tmp=x2
x2=x3
x3=tmp
endif
'pisteet ovat nyt järjestyksessä
'ylhäältä alas p1(x1,y1), p2(x2,y2), p3(x3,y3)
dy1=y2-y1'pystysuora matka p1:sta p2:seen
dx1=x2-x1'vaakasuora matka p1:sta p2:seen
dy2=y3-y1'pystysuora matka p1:sta p3:meen
dx2=x3-x1'vaakasuora matka p1:sta p3:meen
If dy1 Then 'jos kolmion yläosa on pidempi kuin 0
'käydään läpi kaikki vaakaviivat kolmion yläosassa(p1-p2)
for i = y1 To y2
'lasketaan seuraava x-koordinaatti p1:stä p2:seen
ax=x1+((i-y1)*dx1)/dy1
'lasketaan seuraava x-koordinaatti p1:stä p3:meen
bx=x1+((i-y1)*dx2)/dy2
Line ax,i,bx,i 'piirretään viiva kolmion reunojen välille
Next i
endif
dy1=y3-y2'pystysuora matka p2:sta p3:meen
dx1=x3-x2'vaakasuora matka p2:sta p3:meen
If dy1 Then 'jos kolmion alaosa on pidempi kuin 0
'käydään läpi kaikki vaakaviivat kolmion alaosassa(p2-p3)
For i = y2 To y3
'lasketaan seuraava x-koordinaatti p2:stä p3:meen
ax=x2+((i-y2)*dx1)/dy1
'lasketaan seuraava x-koordinaatti p1:stä p3:meen
bx=x1+((i-y1)*dx2)/dy2
Line ax,i,bx,i 'piirretään viiva kolmion reunojen välille
next i
endif
endFunction