Pyörivä tilekartta

Oletko tehnyt jotain, mistä muut voisivat hyötyä. Postita vinkit tänne.
Post Reply
User avatar
MetalRain
Active Member
Posts: 188
Joined: Sun Mar 21, 2010 11:17 am
Location: Espoo

Pyörivä tilekartta

Post by MetalRain »

Tyhmät kysymykset aiheessa tiedusteltiin josko kartan pyörittäminen on mahdollista. Muutama epäluuloinen vastaus ja Jonezin ideat saivat minut tekemään tälläisen helppokäyttöisen kartanpyörityssysteemin. LoadRotatedMap() lataa kuvat kartassa käytetyistä tileistä ja pyörittää ne valmiiksi, DrawRotatedMap() piirtää tilekuvat haluttuun paikkaan halutussa kulmassa. Törmäystarkistusta eikä kartan muokkausta (ainakaan vielä) tueta, mutta eivät olisi kyllä mahdottomia toteuttaa. Latausaika saattaa olla hieman pitkä, valitan.

Esimerkissä vasen- ja oikea nuolinäppäin kääntää karttaa. Wasd liikuttaa kameraa.

Code: Select all

SCREEN 1024,768

// global variables often needed for other calculations
Global AmountOfRotation  As integer
Global RotationPrecision As Float
Global RotatedMapTileSize As integer
Dim RotatedMapTiles( 1, 1) As integer
Dim RotatedMapData( 1, 1) As integer 
Global UnrotatedTileset As integer 
Global UnrotatedMap As integer
Global RotatedMapWidth, RotatedMapHeight

SetWindow "Loading.. please wait"

LoadRotatedMap("media\cdm2.til","media\tileset.bmp")

SetWindow "Loaded!"

Repeat

    ang# = WrapAngle( ang# + LeftKey() - RightKey() )

    //hotspot used to rotate map from center
    DrawRotatedMap(0,0,ang#,RotatedMapWidth*RotatedMapTileSize/2,RotatedMapheight*RotatedMapTileSize/2)
    
    //camera moves with wasd
    TranslateCamera (KeyDown(cbkeyd)-KeyDown(cbkeya))*5,(KeyDown(cbkeyw)-KeyDown(cbkeys))*5
    
    Text 0,0,Str(FPS())

    DrawScreen
Forever

Function DrawRotatedMap(x#,y#,ang#,hotspotx=0,hotspoty=0)

    DrawToWorld OFF,ON 
    
    rang = RoundDown( ang# / RotationPrecision + 0.5) Mod (AmountOfRotation+1)

    //these don't require tile coordinates, so lets calculate them before loop
    cx# = Cos( ang# ) * RotatedMapTileSize
    cy# = Cos( ang# + 90.0) * RotatedMapTileSize
    
    sx# = Sin( ang# ) * -RotatedMapTileSize
    sy# = Sin(ang#+90) * -RotatedMapTileSize 
    
    hcx# = Cos( ang# ) * -hotspotx
    hcy# = Cos( ang# +90.0) * -hotspoty
    
    hsx# = Sin( ang# ) * hotspotx 
    hsy# = Sin( ang# +90.0) * hotspoty 

    //draw tiles if image is available
    For tx=1 To RotatedMapWidth
        For ty=1 To RotatedMapHeight
        
            tile = RotatedMapTiles( RotatedMapData(tx,ty), rang)

            If tile Then 
                DrawImage tile, x# + cx# * tx  + cy# * ty + hcx + hcy,  y# + sx * tx + sy * ty + hsx + hsy
            EndIf 
        Next ty
    Next tx

End Function 

Function LoadRotatedMap(mappath$,tilesetpath$,rotation=50)

    AmountOfRotation = rotation

    UnrotatedMap = LoadMap(mappath$,tilesetpath$)
    
    ShowObject UnrotatedMap,OFF
    
    RotatedMapWidth = MapWidth()
    RotatedMapHeight = MapHeight()
    
    RotatedMapTileSize = ObjectSizeX(UnrotatedMap)/MapWidth()

    UnrotatedTileset = LoadImage(tilesetpath$)
    
    tilesetw = ImageWidth(UnrotatedTileset)/RotatedMapTileSize
    tileseth = ImageHeight(UnrotatedTileset)/RotatedMapTileSize
    
    ReDim RotatedMapTiles( tilesetw*tileseth+1, AmountOfRotation )

    RotationPrecision = 360.0 / Float( AmountOfRotation + 1 ) 
    
    ReDim RotatedMapData( MapWidth(), MapHeight())
    
    
    //check map for used tiles
    For x=1 To RotatedMapWidth
        For y=1 To RotatedMapHeight
            
            RotatedMapData(x,y) = GetMap2(1,x,y)
            If RotatedMapData(x,y)=0 Then RotatedMapData(x,y) = GetMap2(0,x,y)

            value = RotatedMapData(x,y)
            
            //only loads tiles not loaded before
            If value<>0 Then 
                If RotatedMapTiles( value, 0)=0 Then 

                    //get the right tile coordinates
                    tx = ((value-1) Mod tilesetw) 
                    ty = RoundDown((value-1) / tilesetw) 
                    
                    //copy tile from tileset
                    RotatedMapTiles( value, 0 ) = MakeImage( RotatedMapTileSize , RotatedMapTileSize)
                    CopyBox tx * RotatedMapTileSize , ty * RotatedMapTileSize , RotatedMapTileSize , RotatedMapTileSize , 0, 0, Image( UnrotatedTileset ), Image( RotatedMapTiles( value, 0 ) )
                    ResizeImage RotatedMapTiles( value, 0 ),RotatedMapTileSize,-RotatedMapTileSize
                    RotateImage RotatedMapTiles( value, 0 ), -0 * RotationPrecision
                    
                    //tile rotation
                    For a = 1 To AmountOfRotation
                        RotatedMapTiles( value, a ) = CloneImage( RotatedMapTiles( value, 0 ))
                        RotateImage RotatedMapTiles( value, a ), -a * RotationPrecision 
                    Next a
                EndIf 
            EndIf 
            
        Next y
    Next x
End Function
MaGetzUb
Guru
Posts: 1715
Joined: Sun Sep 09, 2007 12:35 pm
Location: Alavus

Re: Pyörivä tilekartta

Post by MaGetzUb »

Juu ihan hieno, joskus tämmöistä moottoria olen MavMaggotille vääntänyt, mutta 256 tileä oli turhan raskas pyörittää 360:n asentoon. :D Joten innostus sitten lopahti.
Solar Eclipse
Meneillä olevat Projektit:
We're in a simulation, and God is trying to debug us.
User avatar
Jonez
Devoted Member
Posts: 575
Joined: Mon Aug 27, 2007 8:37 pm

Re: Pyörivä tilekartta

Post by Jonez »

Aika näppärä systeemi. Vielä kun lisäisi mahdollisuuden päästä mappiin jo ennen kuin tilejen visuaalinen data on ladattu. Näiden tilejen kohdalla olisi vaikka jokin väliaikainen kuva. Ja jotta ei mene liian helpoksi, olisi käytännöllistä ladata ensimmäisenä ruudulla olevat kuvat.

Myös itse tilejen loopin voisi säätää sellaiseksi, että vain ruudulla olevat tilet piirretään.
-Vuoden 2008 aloittelijan ystävä -palkinnon voittaja-
Image <- protestipelikilpailun voittaja.
Space War
DJ-Filbe
Devoted Member
Posts: 854
Joined: Sat Feb 20, 2010 2:18 pm

Re: Pyörivä tilekartta

Post by DJ-Filbe »

Juuri tällaista systeemiä tarkoitin kun kysyin voiko karttaa "oikeasti" pyöritellä! Thanks!
EDIT:

Tosin tarkoitin lähinnä ei-tilekartan pyöritystä, eli kameran pyöritystä, mutta lienee mahdoton toteuttaa... tai sitten pitäis tehä omat objektisysteemit yms...

Post Reply