Needs help with my isometric map editor

Advanced game related topics
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Needs help with my isometric map editor

Post by Rook Zimbabwe »

I have been trying to rework my 2D map editor into an isometric map editor. I cannot get it to display the tiles correctly... there are gaps.

I know thi sis caused by my array but I cannot wrap my head around HOW to recode the array to place times correctly...

Code: Select all

; TILE MAP EDITOR
; Ralph Dunn
; many modifications by Jared {DEMIVEC}
;
; *********************************  TO DO
; * Integrate Jareds ZOOM feature
; * Integrate a screenshot feature for current map screen
; * Integrate OPEN MAP feature (for editing)
; * Integrate(?) ISO/HEX maps!
; * Other stuff yet to be named...
; *********************************
;
Enumeration
  #Window_0
EndEnumeration
;- ENUMERATION
Enumeration
  #CheckBox_HEX
  #CheckBox_ISO
  #Text_20
  #Text_19
  #String_YOFFSET
  #String_XOFFSET
  #Text_CTILE
  #Image_CURRENTTILE
  #Button_ADDTILE
  #Button_REMOVETILE
  #Button_SAVE
  #Button_OPENMAP
  #String_SAVE
  #ListIcon_SPRITES
  #Button_MAKENEW
  #Text_SPRY
  #Text_SPRX
  #Text_HIGH
  #Text_WIDE
  #Text_TID
  #Text_CDIT
  #Text_TRC
  #Text_AY
  #Text_LY
  #Text_AX
  #Text_LX
  #Text_MY
  #Text_YY
  #Text_MX
  #Text_XX
  #Text_LA
  #Text_LASTACTION
  #Text_MAP
  #String_SPRITEY
  #String_SPRITEX
  #String_HIGH
  #String_WIDE
  #ListIcon_TILE
  #ScrollBar_1
  #ScrollBar_0
  #MAPFILE
  #MAPIMAGE
  #BLANK
EndEnumeration

#LeftOffset = 200 ; these are used for the mouse cursor
#TopOffset = 49
#ScreenW = 722 ; 770 - cursor width
#ScreenH = 530 ; 578
#ZERO = 0
#Mouse = 1025
#MPoint = 1026

Structure VisualDesignerGadgets
  Gadget.l
  EventFunction.l
EndStructure

Structure Tile
  tid.l
  x.f
  y.f
  ax.f
  ay.f
EndStructure

Global NewList Tile.Tile()

;- VARIABLES
Global NewList EventProcedures.VisualDesignerGadgets()
Global Dim LAYER(20, 20) ; temp array to hold prites... will be resizable
Global Dim SPR(1024)

Global XWIDE ; x wide of map
Global YHIGH ; y wide of map
Global XW = 12
Global YH = 9
Global SPX ; x wide of sprite
Global SPY ; y wide of sprite
Global ScrollX
Global ScrollY ; variables for scrollbars
Global OffX ; offset X of array to assit in locating TILE in array
Global OffY ; ditto but for Y
Global sx.l = 0, sy.l = 0 ;index of top left tile to display from map [Demivec]

Global picoftile ; picture ID of current tile to show!
Global spritenumber ; used to ID spritte in our list of sprites
Global SPID = 1 ; starting number of spriteID

XWIDE = 19 ; map tiles wide and tall
YHIGH = 19

SPX = 256
SPY = 128

sx = 0
sy = 0

InitSprite()
InitMouse()
InitKeyboard()

DataSection
  Image0 : 
  IncludeBinary "Point1.bmp"
  Image1 : 
  IncludeBinary "Cursor0.bmp"
  Image2 : 
  IncludeBinary "floor005.bmp"
  Image3 : 
  IncludeBinary "floor002.bmp"
  ;Image4:
  ;    IncludeBinary "BLANKISO.bmp"
  ;Image5:
  ;    IncludeBinary "BLANKHEX.bmp"
EndDataSection
;-
Procedure DisplayMap(OffX, OffY)
  ; set the new values
  OFX$ = Str(OffX)
  OFY$ = Str(OffY)
  Debug "RCVD:: " + OFX$ + " / " + OFY$
  SetGadgetText(#Text_AX, OFX$)
  SetGadgetText(#Text_AY, OFY$)
  
  ResetList(Tile())
  
  For y = 0 To YHIGH
    For x = 0 To XWIDE
      AddElement(Tile())
      Tile() \tid = Val(GetGadgetItemText(#ListIcon_SPRITES, Layer(OffX, OffY) - 1, 2))
      Tile() \x = XXX
      Tile() \y = YYY
      Tile() \ax = xray
      Tile() \ay = yray
      xray = xray + 1
      XXX = XXX + SPX
      If xray > XWIDE
        xray = 0
        XXX = 0
      EndIf
    Next
    yray = yray + 1
    YYY = YYY + SPY
  Next
  
  ForEach Tile()
    If Tile() \ax < OffX
      DeleteElement(Tile())
    EndIf
    If Tile() \ax > OffX + 14
      DeleteElement(Tile())
    EndIf
    If Tile() \ay < OffY
      DeleteElement(Tile())
    EndIf
    If Tile() \ay > OffY + 11
      DeleteElement(Tile())
    EndIf
  Next
  ; list keeps growing... does not CAP
  Debug "LIST HAS " + Str(CountList(Tile()))
EndProcedure

Procedure OpenMAP(filename$)
  op = 1
  
  If OpenPreferences(filename$)   ; if the file could be read, we continue...
    PreferenceGroup("VERSION")
    Mapstyle$ = ReadPreferenceString("X1", "")
    PreferenceGroup("DATA")
    Layout$ = ReadPreferenceString("X1", "")
    XWIDE = ReadPreferenceLong("X2", 10)
    YHIGH = ReadPreferenceLong("X3", 10)
    SPX = ReadPreferenceLong("X4", 256)
    SPY = ReadPreferenceLong("X5", 128)
    PreferenceGroup("LEVEL")
    LNUM = ReadPreferenceLong("X1", 0)
    LVL$ = ReadPreferenceString("X2", "")
    longis = Len(LVL$) ; is it reporting 0 as 1?
    For X = 0 To XWIDE - 1 ; remember arrays start a 0 not 1
      For Y = 0 To YWIDE - 1
        tnum$ = Mid(LVL$, op, 1)
        num$ = Str(Asc(tnum$))
        numb = Val(num$)
        numb = numb - 33
        Layer(X, Y) = numb
        op = op + 1
      Next
    Next
    ClosePreferences()               ; close the previously opened file
  Else
    MessageRequester("Information", "Couldn't open the file: " + filename$ + "!!!")
  EndIf
  
  SetGadgetText(#String_SPRITEX, Str(SPX))
  SetGadgetText(#String_SPRITEY, Str(SPY))
  SetGadgetText(#String_HIGH, Str(XWIDE))
  SetGadgetText(#String_WIDE, Str(YWIDE))
  
EndProcedure

Procedure NewMap()
  ; get the vaues and whang it...
  ; clean all old crap
  SetGadgetState(#Scrollbar_0, #PB_ScrollBar_Minimum)
  SetGadgetState(#Scrollbar_1, #PB_ScrollBar_Minimum)
  
  XV$ = GetGadgetText(#String_WIDE)
  If XV$ = ""
    XV$ = "20"
  EndIf
  XVAL = Val(XV$)
  If XVAL < 11
    XVAL = 11
  EndIf
  YV$ = GetGadgetText(#String_HIGH)
  If YV$ = ""
    YV$ = "20"
  EndIf
  YVAL = Val(YV$)
  If YVAL < 8
    YVAL = 8
  EndIf
  
  SetGadgetText(#String_WIDE, Str(XVAL))
  SetGadgetText(#String_HIGH, Str(YVAL))
  
  Global Dim LAYER(XVal, YVal) ; remakes LAYER()
  
  XWIDE = XVAL
  YHIGH = YVAL
  
  For X = 0 To XVal  ; Fill with tile 0
    For Y = 0 To YVal
      LAYER(X, Y) = 0
    Next
  Next
  
  SPX$ = GetGadgetText(#String_SPRITEX)
  If SPX$ = ""
    SPX$ = "256"
    SetGadgetText(#String_SPRITEX, SPX$)
  EndIf
  SPX = Val(SPX$)
  
  SPY$ = GetGadgetText(#String_SPRITEY)
  If SPY$ = ""
    SPY$ = "128"
    SetGadgetText(#String_SPRITEY, SPY$)
  EndIf
  SPY = Val(SPY$)
  pw = XW - 2
  py = YH - 2
  SetGadgetAttribute(#Scrollbar_0, #PB_ScrollBar_Maximum, XWIDE - pw)
  SetGadgetAttribute(#Scrollbar_1, #PB_ScrollBar_Maximum, YHIGH - py)
  SetGadgetState(#Scrollbar_0, 0)
  SetGadgetState(#Scrollbar_1, 0)
  spritenumber = 1 ; reset sprite number
  ; clean tiles
  ; clean sprites
EndProcedure

Procedure ReadLayer(startx, starty, endx, endy)
  ; startx and starty are controlled by scroolbars
  ; probably need to reset all X and Y locs in the list to 0 first
  For X = startx To endx
    For Y = starty To endy
      piece = LAYER(X, Y)
      ; plop tiles into TILE list so we can show them
      Tile() \x = xloc
      Tile() \y = yloc
      Tile() \ax = X
      Tile() \ay = Y
      yloc = yloc + SPY ; add sprite Y width for redo
    Next
    xloc = xloc + SPX ; add sprite X wide
  Next
  
EndProcedure

Procedure DoScreenDisplay(inscreen)
  ;
  ; Display your screen stuff from Trond and NetMaestros help too!
  ; as well as extensive help from Demivec (Jared)
  If inscreen  ; manage mouse events only if mouse is inside screen
    ClearScreen(0)
    WindowEvent()
    ExamineMouse()
    
    MausX$ = Str(MouseX())
    MausY$ = Str(MouseY())
    SetGadgetText(#Text_MX, MausX$)
    SetGadgetText(#Text_MY, MausY$)
  EndIf
EndProcedure
;-
Procedure Image_CURRENTTILE_Event(Window, Event, Gadget, Type)
  Debug "#Image_CurrentTILE"
  ; open tile requester
EndProcedure
;-

Procedure CheckBox_HEX_Event(Window, Event, Gadget, Type)
  Debug "#CheckBox_HEX"
EndProcedure

Procedure CheckBox_ISO_Event(Window, Event, Gadget, Type)
  Debug "#CheckBox_ISO"
EndProcedure
;- *******************************
Procedure Button_SAVE_Event(Window, Event, Gadget, Type)
  Debug "#Button_SAVE"
  ; dump Level() Array to output file with image IDs constructed for easy entry into PB
  StandardFile$ = "MAP-0.rwd"   ; set initial file+path to display
  
  Pattern$ = "Ralph Map File (*.rwd)|*.rwd|All files (*.*)|*.*"
  Pattern = 0    ; use the first of the three possible patterns as standard
  File$ = SaveFileRequester("Please choose file to save", StandardFile$, Pattern$, Pattern)
  If File$
    fie$ = GetFilePart(File$)
    If Right(fie$, 4) = ".rwd"
      TRUBIE = 1
    Else
      fie$ = fie$ + ".rwd"
    EndIf
    foo = Len(fie$)
    foo = foo - 4
    gfile$ = Left(Fie$, foo)
    ; make the tilemap
    Result = CountGadgetItems(#ListIcon_SPRITES) + 2
    totsprites = spritenumber
    ; Result = CountGadgetItems(#ListIcon_SPRITES)
    
    Base = Round(Sqr(Result), #PB_Round_Up)
    IntBase = Int(Base)
    Base2 = IntBase
    If Base2 < Base
      IntBase + 1
    EndIf
    wide = IntBase * SPX
    high = IntBase * SPY
    
    CreateImage(#MAPIMAGE, wide, high, 24)
    
    SPnum = 0
    Result = CountGadgetItems(#ListIcon_SPRITES)
    Debug "SPRITE LIST HAS: " + Str(Result)
    
    StartDrawing(ImageOutput(#MAPIMAGE))
      For IY = 0 To IntBase ; DX Step 128 ; ***** I would love to figure out how to make these variable STEPS!
        For IX = 0 To IntBase - 1  ;DY Step 128 ; *****
          Debug "tile: " + Str(SPNUM) + "  --  LOCATION: " + Str(X) + " / " + Str(Y)
          DrawImage(SPR(SPnum), X, Y)
          SPnum + 1 ; = SPnum + 1
          X + SPX
          If X > wide - SPX ; this wraps it down
            X = 0
          EndIf
        Next
        Y + SPY
      Next
    StopDrawing()
    SaveImage(#MAPIMAGE, gfile$ + ".bmp")
    
    ; OK now do the work
    CreatePreferences(File$)
    PreferenceGroup("VERSION")
    WritePreferenceString("X1", "Ralph Map Editor 1.0")
    PreferenceGroup("DATA")
    WritePreferenceString("X1", "GRID")
    WritePreferenceLong("X2", XWIDE)
    WritePreferenceLong("X3", YHIGH)
    WritePreferenceLong("X4", SPX)
    WritePreferenceLong("X5", SPY)
    PreferenceGroup("LAYER")
    WritePreferenceLong("X1", 0)
    For X = 0 To XWIDE ; - 1 ; remember arrays start a 0 not 1
      For Y = 0 To YHIGH ; - 1
        lev = LAYER(X, Y)
        lev = lev + 35
        num$ = Chr(lev)
        layer$ = layer$ + num$
      Next
    Next
    WritePreferenceString("X2", layer$)
    PreferenceGroup("MAPDATA")
    WritePreferenceString("X1", gfile$ + ".bmp")
    WritePreferenceLong("X2", IntBase)
    WritePreferenceLong("X3", totsprites)
    ClosePreferences()               ; close the previously opened file
  Else
    MessageRequester("Information", "The requester was canceled.", 0)
  EndIf
  
EndProcedure

Procedure Button_REMOVETILE_Event(Window, Event, Gadget, Type)
  ; Debug "#Button_REMOVETILE"
EndProcedure

Procedure Button_ADDTILE_Event(Window, Event, Gadget, Type)
  Debug "#Button_ADDTILE"
  StandardFile$ = "*.bmp"   ; set initial file+path to display
  Pattern$ = "Bitmap (*.bmp|*.bmp|JPeG(*.jpg)|*.jpg ; *.jpeg|PNGraphics (*.png)|*.png|All files (*.*)|*.*"
  Pattern = 0    ; use the first of the three possible patterns as standard
  File$ = OpenFileRequester("Please choose Tile to load", StandardFile$, Pattern$, Pattern)
  If File$
    ; load the image
    Resultimage = LoadImage(#PB_Any, File$)
    SPR(SPID) = ImageID(ResultImage)
    SPID = SPID + 1
    ; ************************************************** does this NOT store the image ID?
    Resultsprite = LoadSprite(spritenumber, File$)
    ; get image id
    spriteisid$ = Str(Resultsprite)
    imageisid$ = Str(ResultImage)
    
    Filename$ = GetFilePart(File$)
    AddGadgetItem(#ListIcon_TILE, - 1, filename$, ImageID(ResultImage))
    addit$ = "" + Str(spritenumber) + Chr(10) + filename$ + Chr(10) + spriteisid$ + Chr(10) + imageisid$
    AddGadgetItem(#ListIcon_SPRITES, - 1, addit$)
    SetGadgetState(#Image_CURRENTTILE, ImageID(Resultimage))
    SetGadgetText(#Text_LASTACTION, "TILE: " + filename$ + "  -- ADDED")
    spritenumber = spritenumber + 1
  Else
    MessageRequester("Information", "The requester was canceled.", 0)
  EndIf
  
EndProcedure

Procedure Button_MAKENEW_Event(Window, Event, Gadget, Type)
  Debug "#Button_MAKENEW"
  NewMap()
EndProcedure

Procedure Button_OPENMAP_Event(Window, Event, Gadget, Type)
  Debug "#Button_OPENMAP"
  Path$ = GetCurrentDirectory()
  Pattern$ = "MAP FILE (*.rwd)|*.rwd|All files (*.*)|*.*"
  Pattern = 0    ; use the first of the three possible patterns as standard
  filename$ = OpenFileRequester("Please choose file to load", Path$, Pattern$, Pattern)
  If Filename$
    SetGadgetText(#String_SAVE, filename$)
    OpenMAP(filename$)
  Else
    MessageRequester("Information", "The requester was canceled.", 0)
  EndIf
  
EndProcedure
;- *******************************

Procedure ListIcon_TILE_Event(Window, Event, Gadget, Type)
  Debug "#ListIcon_TILE"
  ; list of possible tiles
  plucked = GetGadgetState(#ListIcon_TILE)
  Debug "TILE PICKED: " + Str(plucked)
  SetGadgetText(#Text_TID, Str(plucked))
  RImage$ = GetGadgetItemText(#ListIcon_SPRITES, plucked, 3)
  Resultimage = Val(RImage$)
  SetGadgetState(#Image_CURRENTTILE, ImageID(Resultimage))
EndProcedure

Procedure ListIcon_SPRITES_Event(Window, Event, Gadget, Type)
  ; Debug "#ListIcon_SPRITES"
  
EndProcedure
;-
Procedure ScrollBar_1_Event(Window, event, Gadget, Type) ; VERTICAL SHOULD BE ABLE TO GO TO 17
  Debug "#ScrollBar_1"
  OffY = GetGadgetState(#ScrollBar_1)
  SetGadgetText(#Text_AY, Str(OffY))
  sy = OffY ;update offset into LAYER() [Demivec]
EndProcedure

Procedure ScrollBar_0_Event(Window, event, Gadget, Type)
  Debug "#ScrollBar_0"
  OffX = GetGadgetState(#ScrollBar_0)
  SetGadgetText(#Text_AX, Str(OffX))
  sx = OffX ;update offset into LAYER() [Demivec]
EndProcedure
;-
Procedure RegisterGadgetEvent(Gadget, * Function)
  
  If IsGadget(Gadget)
    AddElement(EventProcedures())
    EventProcedures() \Gadget = Gadget
    EventProcedures() \EventFunction = * Function
  EndIf
  
EndProcedure

Procedure CallEventFunction(Window, Event, Gadget, Type)
  
  ForEach EventProcedures()
    If EventProcedures() \Gadget = Gadget
      CallFunctionFast(EventProcedures() \EventFunction, Window, Event, Gadget, Type)
      LastElement(EventProcedures())
    EndIf
  Next
  
EndProcedure
;-
Procedure Open_Window_MAIN()
  
  If OpenWindow(#Window_0, 0, 0, 1024, 768, "eD1t0r 1.0", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_TitleBar)
    If CreateGadgetList(WindowID(#Window_0))
      
      ScrollBarGadget(#ScrollBar_0, 200, 650, 800, 20, 0, XWIDE - XH, 1) ; XH + 1
      RegisterGadgetEvent(#ScrollBar_0, @ScrollBar_0_Event())
      ScrollBarGadget(#ScrollBar_1, 1000, 50, 20, 600, 0, YHIGH - YW, 1, #PB_ScrollBar_Vertical) ; YW + 1
      RegisterGadgetEvent(#ScrollBar_1, @ScrollBar_1_Event())
      
      ListIconGadget(#ListIcon_TILE, 5, 290, 185, 420, "TILES", 160, #PB_ListIcon_GridLines)
      RegisterGadgetEvent(#ListIcon_TILE, @ListIcon_TILE_Event())
      ListIconGadget(#ListIcon_SPRITES, 640, 675, 355, 80, "S#", 30, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
      AddGadgetColumn(#ListIcon_SPRITES, 1, "SPRITE NAME", 150)
      AddGadgetColumn(#ListIcon_SPRITES, 2, "SPRITE ID", 80)
      AddGadgetColumn(#ListIcon_SPRITES, 3, "", 1) ; image ID
      RegisterGadgetEvent(#ListIcon_SPRITES, @ListIcon_SPRITES_Event())
      
      StringGadget(#String_WIDE, 5, 10, 75, 20, "")
      StringGadget(#String_HIGH, 85, 10, 70, 20, "")
      StringGadget(#String_SPRITEX, 5, 45, 40, 20, "")
      StringGadget(#String_SPRITEY, 65, 45, 40, 20, "")
      StringGadget(#String_SAVE, 370, 675, 260, 20, "")
      StringGadget(#String_XOFFSET, 5, 85, 40, 20, "")
      StringGadget(#String_YOFFSET, 65, 85, 40, 20, "")
      
      ButtonGadget(#Button_MAKENEW, 205, 680, 150, 45, "CREATE NEW MAP", #PB_Button_MultiLine)
      RegisterGadgetEvent(#Button_MAKENEW, @Button_MAKENEW_Event())
      ButtonGadget(#Button_SAVE, 530, 700, 100, 25, "SAVE")
      RegisterGadgetEvent(#Button_SAVE, @Button_SAVE_Event())
      ButtonGadget(#Button_ADDTILE, 105, 720, 85, 35, "ADD A TILE")
      ButtonGadget(#Button_REMOVETILE, 10, 720, 85, 35, "REMOVE A TILE", #PB_Button_MultiLine)
      RegisterGadgetEvent(#Button_REMOVETILE, @Button_REMOVETILE_Event())
      RegisterGadgetEvent(#Button_ADDTILE, @Button_ADDTILE_Event())
      ButtonGadget(#Button_OPENMAP, 370, 700, 110, 25, "OPEN")
      RegisterGadgetEvent(#Button_OPENMAP, @Button_OPENMAP_Event())
      
      ImageGadget(#Image_CURRENTTILE, 5, 150, 180, 130, #PB_Image_Border)
      RegisterGadgetEvent(#Image_CURRENTTILE, @Image_CURRENTTILE_Event())
      
      TextGadget(#Text_WIDE, 5, 30, 30, 15, "WIDE")
      TextGadget(#Text_HIGH, 85, 30, 35, 15, "HIGH")
      TextGadget(#Text_SPRX, 5, 65, 40, 15, "SPR X")
      TextGadget(#Text_SPRY, 65, 65, 40, 15, "SPR Y")
      TextGadget(#Text_CTILE, 5, 130, 90, 15, "CURRENT TILE")
      TextGadget(#Text_MAP, 205, 5, 105, 15, "MOUSE LOCATION")
      TextGadget(#Text_XX, 205, 25, 10, 15, "X:")
      TextGadget(#Text_YY, 260, 25, 10, 15, "Y:")
      TextGadget(#Text_LX, 330, 25, 50, 15, "LAYER X:")
      TextGadget(#Text_LY, 435, 25, 50, 15, "LAYER Y:")
      TextGadget(#Text_TRC, 330, 5, 205, 15, "TOP RIGHT CORNER of LAYER")
      TextGadget(#Text_CDIT, 550, 5, 95, 15, "CURRENT TILE ID")
      TextGadget(#Text_LA, 665, 5, 85, 15, "LAST ACTIVITY")
      TextGadget(#Text_19, 5, 105, 45, 15, "X Offset")
      TextGadget(#Text_20, 65, 105, 40, 15, "Y Offset")
      
      TextGadget(#Text_MX, 220, 25, 35, 15, "", #PB_Text_Center | #PB_Text_Border)
      TextGadget(#Text_MY, 275, 25, 40, 15, "", #PB_Text_Center | #PB_Text_Border)
      TextGadget(#Text_AX, 380, 25, 50, 15, "", #PB_Text_Center | #PB_Text_Border)
      TextGadget(#Text_AY, 485, 25, 55, 15, "", #PB_Text_Center | #PB_Text_Border)
      TextGadget(#Text_TID, 550, 25, 100, 15, "", #PB_Text_Center | #PB_Text_Border)
      TextGadget(#Text_LASTACTION, 665, 20, 330, 20, "", #PB_Text_Center | #PB_Text_Border)
      
      CheckBoxGadget(#CheckBox_ISO, 205, 735, 65, 15, "ISO Map")
      RegisterGadgetEvent(#CheckBox_ISO, @CheckBox_ISO_Event())
      CheckBoxGadget(#CheckBox_HEX, 280, 735, 70, 15, "HEX MAP")
      RegisterGadgetEvent(#CheckBox_HEX, @CheckBox_HEX_Event())
      
    EndIf
  EndIf
  
EndProcedure

Open_Window_MAIN()

ChangeListIconGadgetDisplay(#ListIcon_TILE, 0) ; image tiles

SetGadgetText(#Text_AX, "0")
SetGadgetText(#Text_AY, "0") ; we always start at 0,0
SetGadgetText(#Text_TID, "0") ; and with tile ZERO

OpenWindowedScreen(WindowID(#Window_0), 200, 49, 770, 578, 0, 0, 0)

CatchSprite(#MPoint, ?Image0, #PB_Sprite_Memory)
CatchSprite(#Mouse, ?Image1, #PB_Sprite_Memory)
CatchSprite(#ZERO, ?Image2, 0)
CatchImage(#ZERO, ?Image2) ; ***** This is CHEATING!!!
CatchImage(#BLANK, ?Image3)
;CatchImage(#ZISO, ?Image4)
;CatchImage(#ZHEX, ?Image5)

SetGadgetState(#Image_CURRENTTILE, ImageID(#ZERO))
AddGadgetItem(#ListIcon_TILE, - 1, "BLANK", ImageID(#ZERO))

; make sure #ZERO is first...
SpriteID = SpriteID(#ZERO)
sprE$ = Str(SpriteID)
AddGadgetItem(#ListIcon_SPRITES, - 1, "0" + Chr(10) + "#ZERO" + Chr(10) + sprE$ + Chr(10) + "0")

Resu = ImageID(#BLANK) ; ********************************* thi sworks... whole image is BLACK
Debug "IMAGEID: " + Str(Resu)
For X = 0 To 1024
  SPR(X) = #BLANK
Next

For x = 0 To XWIDE
  For y = 0 To YHIGH
    LAYER(x, y) = 0
  Next
Next

spritenumber = 1 ; starting ID number for our next sprite as 0 has been taken

NewMap()

Repeat
  
  Event = WaitWindowEvent(8)
  If inscreen
    If MouseX() > #ScreenW - 2 Or MouseY() > #ScreenH - 2 Or MouseX() < 1 Or MouseY() < 1
      ReleaseMouse(1)
      inscreen = #False
    EndIf
  Else
    Gadget = EventGadget()
    Type = EventType()
    Window = EventWindow()
    
    Select Event
      Case #PB_Event_Gadget
        CallEventFunction(Window, Event, Gadget, Type)
    EndSelect
    
    mx = WindowMouseX(0) : my = WindowMouseY(0)
    If mx < #ScreenW + #LeftOffset And mx > #LeftOffset And my > #TopOffset And my < #TopOffset + #ScreenH
      ReleaseMouse(0)
      MouseLocate(mx - #LeftOffset, my - #TopOffset)
      inscreen = #True
    EndIf
  EndIf
  
  DoScreenDisplay(inscreen) ; I have moved this... *** eventually it slows BADLY
  If MouseButton(#PB_MouseButton_Left)
    ; set new tile number into array
    ax =(MouseX() + 127) / SPX + OffX ;these show coordinates of tile in map
    ay =(MouseY() + 63) / SPY + OffY
    goober$ = GetGadgetText(#Text_TID)
    tid = Val(goober$)
    LAYER(ax, ay) = tid
    SetGadgetText(#Text_LASTACTION, "SET TILE: " + Str(tid) + " / Location: " + Str(ax) + " / " + Str(ay))
  EndIf
  
  If MouseButton(#PB_MouseButton_Middle)
    ;new tile map checking with data directtly from LAYER() [Demivec]
    ax =(MouseX() + 127) / SPX + OffX ;these show coordinates of tile in map
    ay =(MouseY() + 63) / SPY + OffY
    tid = LAYER(ax, ay)
    SetGadgetText(#Text_LASTACTION, "TILE: " + Str(tid) + " / Location: " + Str(ax) + " / " + Str(ay))
  EndIf
  
  If MouseButton(#PB_MouseButton_Right)
    ;new tile map checking with data directtly from LAYER() [Demivec]
    tid = LAYER(ax, ay)
    ax =(MouseX() + 127) / SPX + OffX ;these show coordinates of tile in map
    ay =(MouseY() + 67) / SPY + OffY
    LAYER(ax, ay) = 0
    SetGadgetText(#Text_LASTACTION, "TILE: " + Str(tid) + " / Location: " + Str(ax) + " / " + Str(ay) + "* DELETED! *")
  EndIf
  
  ; DisplayMap(offx,offy) ; is supposed to build only the display portion fo the map
  ;new map display directly from LAYER() [Demivec]
  YYY = 0
  For y = sy To sy + YH - 1
    XXX = 0
    For x = sx To sx + XW - 1
      DisplaySprite(LAYER(x, y), XXX, YYY)
      XXX + 256 ;SPX
    Next
    YYY + 128 ;SPY
  Next
  
  DisplayTransparentSprite(#Mouse, MouseX(), MouseY())
  DisplayTransparentSprite(#MPoint, MouseX() + 127, MouseY() + 63)
  
  FlipBuffers(4)
  
Until Event = #PB_Event_CloseWindow

End
I use the following graphics:

http://www.bluemesapc.com/Downloads/ISO-SAMPLE.zip

:D
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

I still have the holes! This is extremely frustrating!
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

What I really need to do is:

I need to rotate the array by 45°. I could do that by converting each point in the array to polar coordinates, adding 45 degrees to its angle, then converting back to cartesian coordinates.

What coordinates does PB use?
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

This shows the simple way to rotate an array by 45%

Might help.

Code: Select all

OpenWindow(0,0,0,600,400,"",$ca0001)
CreateImage(0,280,280)
ImageGadget(0,10,10,280,280,ImageID(0))
CreateImage(1,280,280)
ImageGadget(1,310,10,280,280,ImageID(0))

offx=120
offy=40

size=100

For y=0 To size
  c=RGB(Random(255),Random(255),Random(255))
  StartDrawing(ImageOutput(0))
  For x=0 To size
    Plot(offx+x,offy+y,c)
  Next
  StopDrawing()
  SetGadgetState(0,ImageID(0))

  StartDrawing(ImageOutput(1))
  For x=0 To size
    ;Plot(offx+x-y,offy+x+y,c); normal 45% rotation
    Plot(offx+x-y,offy+(x+y)/2,c); scales the image, good for maps!
  Next
  StopDrawing()
  SetGadgetState(1,ImageID(1))
Next

Repeat
Until WaitWindowEvent()=16
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

But... aren't you just rotating the image?

Stuck in the warehouse so I cannot test yet!

But lets say you have an 5X5 array holding tiles for an isometric game
0,0,0,0,0
0,1,2,3,0
0,3,2,1,0
0,1,2,1,0
0,0,0,0,0

So to show it as isometric you would need to rotate it 45 degrees to show it as isometric?

If that can be done, then map editing gets easy!!!
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
citystate
Enthusiast
Enthusiast
Posts: 638
Joined: Sun Feb 12, 2006 10:06 pm

Post by citystate »

I would've thought that it would be easier to leave the map itself unrotated, and rotate the display instead.

when you rotate an array like this, because arrays use integers, cells with fractional coordinates can disappear leaving the gaps you're talking about.
there is no sig, only zuul (and the following disclaimer)

WARNING: may be talking out of his hat
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

Yep, that is basically my idea... but I have NO IDEA how to go about it! :shock:
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
GBeebe
Enthusiast
Enthusiast
Posts: 263
Joined: Sat Oct 09, 2004 6:52 pm
Location: Franklin, PA - USA
Contact:

Post by GBeebe »

I can help, but I need to know the size of your iso tiles. can you post the images in your data section?
User avatar
Demivec
Addict
Addict
Posts: 4282
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Post by Demivec »

Here's something that should give you at least some ideas.

I documented things in the code. If additional explanation is needed just ask. :wink:

Code: Select all

;Author: Jared {Demivec}
;
;Written for PureBasic v 4.31.

Enumeration
  #WindowMain = 0
  
  #instructions_txt = 0
  #tile_txt
  #pos_txt
  
  #cursorTile = 0
  #blankTile
  #floorTile_1
  #floorTile_2
  #floorTile_3
  #numTiles = #PB_Compiler_EnumerationValue
EndEnumeration

#LeftOffset = 50  ;of screen
#TopOffset = 50  ;of screen
#ScreenW = 450
#ScreenH = 450 

Global SPX = 64 ;tile width
Global SPY = 32 ;tile height
Global hspx = SPX/2 ;half width
Global hspy = SPY/2 ;half height
Global vh = 27 ;view height (in tiles)
Global vw = 6 ;view width (in tiles)

Global OffX = 0 ;tile indexes offsets of viewable window
Global OffY = 0 ;

Global Dim LAYER(12,27) ;contains the sprite#'s to display for tiles


InitSprite()
InitKeyboard()
InitMouse()

OpenWindow(#WindowMain,0,0,500,500,"test",#PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(#WindowMain),#LeftOffset,#TopOffset,#ScreenW,#ScreenW,0,0,0)

TextGadget(#instructions_txt,50,10,350,40, "Use left mouse button to draw tiles, right mouse butto to erase tiles" + Chr(10) + "Press spacebar to change tile.")
TextGadget(#tile_txt,410,10,80,20,"Tile:")
TextGadget(#pos_txt,410,30,80,20,"Pos:")

CreateSprite(#cursorTile,SPX,SPY)
StartDrawing(SpriteOutput(#cursorTile))
  FrontColor(#White)
  LineXY(0, hspy - 1, hspx - 1, 0)
  LineXY(hspx - 1, 0, SPX - 1, hspy - 1)
  LineXY(SPX - 1, hspy - 1, hspx - 1, SPY - 1)
  LineXY(hspx - 1, SPY - 1, 0, hspy - 1) 
  Plot(hspx - 1, hspy - 1)
StopDrawing()

CopySprite(#cursorTile,#blankTile)
StartDrawing(SpriteOutput(#blankTile))
  Plot(hspx - 1, hspy - 1)
  FillArea(hspx,hspy,-1,#White)
  FillArea(hspx,hspy,-1,$000001)
StopDrawing()

CopySprite(#blankTile,#floorTile_1)
StartDrawing(SpriteOutput(#floorTile_1))
  FillArea(hspx,hspy,-1,#Green)
StopDrawing()

CopySprite(#floorTile_1,#floorTile_2)
StartDrawing(SpriteOutput(#floorTile_2))
  FillArea(hspx,hspy,-1,#Blue)
StopDrawing()

CopySprite(#floorTile_1,#floorTile_3)
StartDrawing(SpriteOutput(#floorTile_3))
  FillArea(hspx,hspy,-1,#Red)
StopDrawing()

Define x,y

For x = 0 To 12
  For y = 0 To 27
    LAYER(x,y) = Random(2) + 1
  Next 
Next 

Procedure screenToArray(sx,sy,*ax.Integer,*ay.Integer)
  ;Original code by Jared {DEMIVEC}
  ;Given the screen coordinates, return the array coordinates of an iso-grid tile.
  ;This is my own solution, there's probably an easier way. ;)
  ;
  ;The iso-grid is divided into a grid that has one complete tile and 4 partial tiles.
  ;The tile that fits squarely in this grid will always be on the even numbered rows.
  ;                                                                                   
  ;         :                   :             The complete tile [A] is the one that
  ;         :.                 .:            is used as a basis for the coordinates.                                    
  ;       . :   .           .   : .                                              
  ;    .    :      .     .      :    .       The screen coordinates (sx,sy) are laid                                    
  ; . = = = : = = = = . = = = = : = = = .    over the grid.  This determines tile A.                                    
  ;    .    :B     .  |  .     C:    .                                           
  ;       . :   .1    |   2 .   : .          This grid cell is then divided into 4                                    
  ;         :.-----Tile A------.:            equal parts.  (sx,sy) is then laid over                    
  ;       . :   .3    |   4 .   : .          this smaller grid to find which part it                            
  ;    .    :D     .  |  .    E :    .       falls in.                           
  ; . = = = : = = = = . = = = = : = = = .                                        
  ;    .    :      .     .      :    .       A diagonal line is drawn from corner to
  ;       . :   .           .   : .          corner of the cell part (sx,sy) is in and
  ;         :.                 .:            it is determined which side of that line
  ;         :                   :            that the point is on.  
  ;                                                          
  ; Because line is bordered by only 2 cells it is now possible to determine exactly
  ; which tile the point lies in.  For instance if the point lies in cell [1] it can
  ; only be either tile [B] or tile [A]. The coordinates are then calculated from                         
  ; this information.                                                                      
  ;        
  
  ;uses global spx,spy,hspx,hspy ;these are the tile's dimensions and half-dimensions
  Protected wx,wy,wpx,wpy,ax,ay,bx,by,lineSide
  wx = sx / SPX
  wy = (sy / SPY) * 2
  wpx = (sx / hspx) & 1
  wpy = (sy / hspy) & 1
  
  If Not (wpx ! wpy)
    ax = wx * SPX + wpx * hspx
    ay = wy * hspy + wpy * hspy + hspy
    bx = wx * SPX + wpx * hspx + hspx
    by = wy * hspy + wpy * hspy
    
    If (bx - ax) * (sy - ay) - (by - ay) * (sx - ax) < 0
      lineSide = 1 ;value is boolean and arbitrary.  It will be flipped as needed.
    ; Else
      ; lineside = 0
    EndIf
    
    If wpx  ;BR quadrant 4
      *ax\i = wx
      *ay\i = wy + lineSide ! 1
    Else   ;TL quadrant 1
      *ax\i = wx - lineSide
      *ay\i = wy - lineSide
    EndIf 
  Else
    ax = wx * SPX + wpx * hspx
    ay = wy * hspy + wpy * hspy 
    bx = wx * SPX + wpx * hspx + hspx
    by = wy * hspy + wpy * hspy + hspy
    If (bx - ax) * (sy - ay) - (by - ay) * (sx - ax) < 0
      lineSide = 1 ;value is boolean and arbitrary.  It will be flipped as needed.
    ; Else
      ; lineside = 0
    EndIf 
    
    If wpx ;TR quadrant 2
      *ax\i = wx
      *ay\i = wy - lineSide
    Else   ;BL quadrant 3
      lineSide ! 1
      *ax\i = wx - lineSide
      *ay\i = wy + lineSide
    EndIf 
  EndIf 
EndProcedure

;given the array coordinates, return the screen coordinates
Macro arrayToScreen(ax,ay,sx,sy)
  sy = ay * hspy                   ;moves in half heights because of staggering
  sx = ax * SPX + hspx * (ay & 1)  ;moves in full widths and adds half width on alternating rows to stagger
EndMacro

Macro tileLocationFromScreen(ax,ay,sx,sy)
  ax = (sx + hspx - 1) / SPX + OffX ;these show coordinates of tile in map
  ay = (sy + hspy - 1) / SPY + OffY
EndMacro

Define curTile, event, inscreen, mx, my, x, y, ax, ay, sx, sy
curTile = #numTiles - 1
SetGadgetText(#tile_txt,"Tile: " + Str(curTile))
Repeat
  
  event = WaitWindowEvent(8)
  ExamineMouse()
  
  If inscreen
    If MouseX() > #ScreenW - 2 Or MouseY() > #ScreenH - 2 Or MouseX() < 1 Or MouseY() < 1
      ReleaseMouse(1)
      inscreen = #False
    EndIf
  Else
    mx = WindowMouseX(#WindowMain) : my = WindowMouseY(#WindowMain)
    If mx < #ScreenW + #LeftOffset And mx > #LeftOffset And my > #TopOffset And my < #TopOffset + #ScreenH
      ReleaseMouse(0)
      MouseLocate(mx - #LeftOffset, my - #TopOffset)
      inscreen = #True
    EndIf
  EndIf
  
  If MouseButton(#PB_MouseButton_Left)
    screenToArray(MouseX() + hspx - 1, MouseY() + hspy - 1, @ax, @ay)
    LAYER(ax + Offx, ay + Offy) = curTile
    SetGadgetText(#pos_txt,"Pos: (" + Str(ax + Offx) + "," + Str(ay + Offy) + ")")
  EndIf
  
  If MouseButton(#PB_MouseButton_Right)
    screenToArray(MouseX() + hspx - 1, MouseY() + hspy - 1, @ax, @ay)
    LAYER(ax + Offx, ay + Offy) = 1
    SetGadgetText(#pos_txt,"Pos: (" + Str(ax + Offx) + "," + Str(ay + Offy) + ")")
  EndIf
  
  ExamineKeyboard()
  If KeyboardReleased(#PB_Key_Space)  
    curTile = (curTile + 1) % #numTiles
    If curTile < 2
      curTile = 2
    EndIf 
    SetGadgetText(#tile_txt,"Tile: " + Str(curTile))
  EndIf
   
  ClearScreen($000000)
  For y = OffY To OffY + vh - 1
    For x = OffX To OffX + vw - 1
      arrayToScreen(x,y,sx,sy)
      DisplayTransparentSprite(LAYER(x, y), sx, sy)
    Next
  Next
  DisplayTransparentSprite(#cursorTile,MouseX(),MouseY())
  FlipBuffers()
Until event = #PB_Event_CloseWindow 
I tried to include variables for the elements you had present. I didn't implement scrolling code, though all the variables should be present to do so.
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

I thought rotating the image was what you wanted.

You keep the array as normal and draw the sprites at the rotated screen co-ords, if your sprites are already angled, as yours are in your example, then they will tile correctly.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Re: Needs help with my isometric map editor

Post by Rook Zimbabwe »

@Gee : The images are in the download link at top of page (first post) and all I am using at the moment for proof of concept!

@Derek: I can see that and your idea is interesting but I have to say t hat Demivec swoops to the resue again... Jared you need to add a S inside a diamond to your avatar!!! I am gonna dissect this and see what makes it croak! :mrgreen:
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
Demivec
Addict
Addict
Posts: 4282
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Needs help with my isometric map editor

Post by Demivec »

@Rook: Thanks for the compliment. Here is a better implementation that changes the screenToArray() procedure to use a mouse map.

Code: Select all

;Author: Jared {Demivec}
;Demonstrates mouse mapping with iso-tiles
;Written for PureBasic v 4.31.

Enumeration
  #WindowMain = 0
  
  #instructions_txt = 0
  #tile_txt
  #pos_txt

  #mouseMapImg = 0
  
  #cursorTile = 0
  #blankTile
  #floorTile_1
  #floorTile_2
  #floorTile_3
  #numTiles = #PB_Compiler_EnumerationValue
EndEnumeration

#LeftOffset = 50 ;for screen
#TopOffset = 50  ;for screen
#ScreenW = 450 
#ScreenH = 450 

Global mapWidth = 12 ; map width in tiles (0 based)
Global mapHeight = 27 ; map height in tiles (0 based)
Global SPX = 64 ;tile width
Global SPY = 32 ;tile height
Global hspx = SPX/2 ;half width
Global hspy = SPY/2 ;half height
Global vh = 27 ;view height (in tiles)
Global vw = 6 ;view width (in tiles)

Global OffX = 0 ;tile indexes offsets of viewable window
Global OffY = 0 ;

Global Dim LAYER(mapWidth,mapHeight) ;contains the sprite#'s to display for tiles


InitSprite()
InitKeyboard()
InitMouse()

OpenWindow(#WindowMain,0,0,500,500,"test",#PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(#WindowMain),#LeftOffset,#TopOffset,#ScreenW,#ScreenW,0,0,0)

TextGadget(#instructions_txt,50,10,350,40, "Use left mouse button to draw tiles, right mouse butto to erase tiles" + Chr(10) + "Press spacebar to change tile.")
TextGadget(#tile_txt,410,10,80,20,"Tile:")
TextGadget(#pos_txt,410,30,80,20,"Pos:")

CreateSprite(#cursorTile,SPX,SPY)
StartDrawing(SpriteOutput(#cursorTile))
  FrontColor(#White)
  LineXY(0, hspy - 1, hspx - 1, 0)
  LineXY(hspx - 1, 0, SPX - 1, hspy - 1)
  LineXY(SPX - 1, hspy - 1, hspx - 1, SPY - 1)
  LineXY(hspx - 1, SPY - 1, 0, hspy - 1) 
  Plot(hspx - 1, hspy - 1)
StopDrawing()

CopySprite(#cursorTile,#blankTile)
StartDrawing(SpriteOutput(#blankTile))
  Plot(hspx - 1, hspy - 1)
  FillArea(hspx,hspy,-1,#White)
  FillArea(hspx,hspy,-1,$000001)
StopDrawing()

CopySprite(#blankTile,#floorTile_1)
StartDrawing(SpriteOutput(#floorTile_1))
  FillArea(hspx,hspy,-1,#Green)
StopDrawing()

CopySprite(#floorTile_1,#floorTile_2)
StartDrawing(SpriteOutput(#floorTile_2))
  FillArea(hspx,hspy,-1,#Blue)
StopDrawing()

CopySprite(#floorTile_1,#floorTile_3)
StartDrawing(SpriteOutput(#floorTile_3))
  FillArea(hspx,hspy,-1,#Red)
StopDrawing()

CreateImage(#mouseMapImg,SPX,SPY)
StartDrawing(ImageOutput(#mouseMapImg))
  FrontColor(#White)
  LineXY(0, hspy - 1, hspx - 1, 0)
  FillArea(0,0,-1,#Red)
  LineXY(hspx - 1, 0, SPX - 1, hspy - 1)
  FillArea(SPX - 1, 0,-1, #Green)
  LineXY(SPX - 1, hspy - 1, hspx - 1, SPY - 1)
  FillArea(SPX - 1,SPY - 1,-1, #Blue)
  LineXY(hspx - 1, SPY - 1, 0, hspy - 1) 
  FillArea(0, SPY - 1,-1, #Yellow)
  FillArea(hspx,hspy,-1,#White)
  FillArea(hspx,hspy,-1,$000000)
StopDrawing()

Define x,y

For x = 0 To mapWidth
  For y = 0 To mapHeight
    LAYER(x,y) = Random(2) + 1
  Next 
Next 

Procedure screenToArray(sx,sy,*ax.Integer,*ay.Integer)
  ;Idea was from GameDev.net http://www.gamedev.net/reference/articles/article747.asp
  ;Coded by Jared {DEMIVEC}
  ;Given the screen coordinates, return the array coordinates of an iso-grid tile.
  ;
  ;The iso-grid is divided into a grid that has one complete tile and 4 partial tiles.
  ;The tile that fits squarely in this grid will always be on the even numbered rows.
  ;                                                                                   
  ;         :                   :             The complete tile [A] is the one that
  ;         :.                 .:            is used as a basis for the coordinates.                                    
  ;       . :   .           .   : .                                              
  ;    .    :-1,-1 .     .+0,-1 :    .       The screen coordinates (sx,sy) are laid                                    
  ; . = = = : = = = = . = = = = : = = = .    over the grid.  This determines tile A.                                    
  ;    .    :B     .     .     C:    .                                           
  ;       . :   .           .   : .          (sx,sy) is then translated to find the                                   
  ;         :.     Tile A      .:            cordinates relative to the grid cell.                      
  ;       . :   .   x,y     .   : .                                                                             
  ;    .    :D     .     .    E :    .       The color of that point is looked up in 
  ; . = = = : = = = = . = = = = : = = = .    the mouse map image and the tile's     
  ;    .    :+0,+1 .     .+1,+1 :    .       cordinates are adjusted using that         
  ;       . :   .           .   : .          information.                             
  ;         :.                 .:                                                    
  ;         :                   :                                   
  
  ;uses global spx,spy,hspx,hspy ;these are the tile's dimensions and half-dimensions
  Protected wx, wy, wpx, wpy, mapCell
  wx = sx / SPX        ;map grid coordinates
  wy = (sy / SPY) * 2
  wpx = sx % SPX       ;cordinates relative to map cell
  wpy = sy % SPY
  
  StartDrawing(ImageOutput(#mouseMapImg))
    mapCell = Point(wpx,wpy)
  StopDrawing()
  
  Select mapCell
    Case 0;Center
      *ax\i = wx
      *ay\i = wy
    Case #Red ;TL
      *ax\i = wx - 1
      *ay\i = wy - 1
    Case #Green ;TR
      *ax\i = wx
      *ay\i = wy - 1
    Case #Blue ;BR
      *ax\i = wx
      *ay\i = wy + 1
    Case #Yellow ;BL
      *ax\i = wx - 1
      *ay\i = wy + 1
  EndSelect
  
  ;Do bounds checking
  If *ax\i < 0 Or *ax\i > mapWidth Or *ay\i < 0 Or *ay\i > mapHeight
    ProcedureReturn #False ;out of bounds means coordinates not valid
  Else
    ProcedureReturn #True ;in bounds coordinates
  EndIf 
EndProcedure

;given the array coordinates, return the screen coordinates
Macro arrayToScreen(ax,ay,sx,sy)
  sy = ay * hspy                   ;moves in half heights because of staggering
  sx = ax * SPX + hspx * (ay & 1)  ;moves in full widths and adds half width on alternating rows to stagger
EndMacro

Macro tileLocationFromScreen(ax,ay,sx,sy)
  ax = (sx + hspx - 1) / SPX + OffX ;these show coordinates of tile in map
  ay = (sy + hspy - 1) / SPY + OffY
EndMacro

Define curTile, event, inscreen, mx, my, x, y, ax, ay, sx, sy
curTile = #numTiles - 1
SetGadgetText(#tile_txt,"Tile: " + Str(curTile))
Repeat
  
  event = WaitWindowEvent(8)
  ExamineMouse()
  
  If inscreen
    If MouseX() > #ScreenW - 2 Or MouseY() > #ScreenH - 2 Or MouseX() < 1 Or MouseY() < 1
      ReleaseMouse(1)
      inscreen = #False
    EndIf
  Else
    mx = WindowMouseX(#WindowMain) : my = WindowMouseY(#WindowMain)
    If mx < #ScreenW + #LeftOffset And mx > #LeftOffset And my > #TopOffset And my < #TopOffset + #ScreenH
      ReleaseMouse(0)
      MouseLocate(mx - #LeftOffset, my - #TopOffset)
      inscreen = #True
    EndIf
  EndIf
  
  If MouseButton(#PB_MouseButton_Left)
    If screenToArray(MouseX() + hspx - 1, MouseY() + hspy - 1, @ax, @ay)
      LAYER(ax, ay) = curTile
      SetGadgetText(#pos_txt,"Pos: (" + Str(ax) + "," + Str(ay) + ")")
    EndIf 
  EndIf
  
  If MouseButton(#PB_MouseButton_Right)
    If screenToArray(MouseX() + hspx - 1, MouseY() + hspy - 1, @ax, @ay)
      LAYER(ax, ay) = 1
      SetGadgetText(#pos_txt,"Pos: (" + Str(ax) + "," + Str(ay) + ")")
    EndIf 
  EndIf
  
  ExamineKeyboard()
  If KeyboardReleased(#PB_Key_Space)  
    curTile = (curTile + 1) % #numTiles
    If curTile < 2
      curTile = 2
    EndIf 
    SetGadgetText(#tile_txt,"Tile: " + Str(curTile))
  EndIf
   
  ClearScreen($000000)
  For y = OffY To OffY + vh - 1
    For x = OffX To OffX + vw - 1
      arrayToScreen(x,y,sx,sy)
      DisplayTransparentSprite(LAYER(x, y), sx, sy)
    Next
  Next
  DisplayTransparentSprite(#cursorTile,MouseX(),MouseY())
  FlipBuffers()
Until event = #PB_Event_CloseWindow
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Re: Needs help with my isometric map editor

Post by Rook Zimbabwe »

Jared,

Curious... I run this at home on 4.3 and looks perfect. I run at work on 4.3 and it is not... instead of diamonds I have rectangels???
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
Demivec
Addict
Addict
Posts: 4282
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Needs help with my isometric map editor

Post by Demivec »

Rook Zimbabwe wrote:Curious... I run this at home on 4.3 and looks perfect. I run at work on 4.3 and it is not... instead of diamonds I have rectangels???
The rectangular sprites have diamonds drawn on them and use DisplayTransparentSprite() to overlay them onto the screen. Maybe there is a difference with your work computer that doesn't allow the last part to work.

I wrote the code sample for v4.3 because I wanted to stay consistent with the code you presented. The commands in the newer beta would give a few more options though. We're waiting patiently for it's completion. :wink:

A side note regarding the method used in the sample code last posted: It displays the array of tiles in way that fills a rectangular screen well but it doesn't work well with a rotating array of tiles. I was going to provide an example of a method that did handle rotating an array of tiles in 90 degree increments shortly after I posted the last method but it stalled in the debugging phase when other projects pressed me for their completion. I'll try and post a working version of the other method in the near future. The other method displays the array of tiles as a larger diamond shape that allows changes of 90 degrees by simply reordering the display of the tiles (or rotating the tiles in the array itself). It's downside is it is a little more complicated (a.k.a. slower).
Anonymous

Re: Needs help with my isometric map editor

Post by Anonymous »

Code: Select all

; ISOMETRIC
ExamineDesktops()
InitSprite() : InitKeyboard() : InitMouse()
OpenScreen(DesktopWidth(0),DesktopHeight(0),32,"")

Global Dim MyMap(9,9)

Restore Map2D
For y = 0 To 9
  For x = 0 To 9
    Read MyMap(x,y)
  Next 
Next 




Procedure DisplayMap2D(TileWidth.i=64)
Static mouseflag.b,Mx.f,My.f

Mx + MouseDeltaX()
My + MouseDeltaY()



StartDrawing(ScreenOutput())

For y = 0 To 9
  For x = 0 To 9
       
    
    ;Isometric formula
    Tile_width.i  = TileWidth     
    Tile_Height.i = Tile_width / 2
    
    
    scale_x.f = (x * Tile_Height)
    scale_y.f = (y * Tile_Height) 
    
    iso_x.f = (( scale_x - scale_y )     )       + DesktopWidth(0)/2
    iso_y.f = (( scale_x + scale_y ) / 2 )       + DesktopHeight(0)/4
    

    LineXY(iso_x,iso_y-Tile_Height/2,iso_x+Tile_width/2,iso_y,$0)
    LineXY(iso_x+Tile_width/2,iso_y,iso_x,iso_y+Tile_Height/2,$0)
    LineXY(iso_x,iso_y+Tile_Height/2,iso_x-Tile_width/2,iso_y,$0)
    LineXY(iso_x-Tile_width/2,iso_y,iso_x,iso_y-Tile_Height/2,$0)

        If MyMap(x,y)=1
          For angle = 0 To 360
           px.f = iso_x + (Tile_width/4) * Cos(angle*#PI/180)
           py.f = iso_y + (Tile_Height/4) * Sin(angle*#PI/180)
           If px=>0 And py=>0 And px<DesktopWidth(0)-1 And py<DesktopHeight(0)-1
            Plot(px,py,0)
           EndIf 
          Next 
        EndIf 

  Next 
Next 

    ;Convert mouse coord to iso mouse coord
    iso_mouse_y = ((2 * My) - Mx ) / 2
    iso_mouse_x = Mx + iso_mouse_y

    ; set the mouse coord with correction (screen centered)
    ScreenMouse_X = ( Mx + DesktopWidth(0)/2  )-Tile_width/2
    ScreenMouse_Y = ( My + DesktopHeight(0)/4 )-Tile_width/2


If MouseButton( #PB_MouseButton_Left) And mouseflag = 0
mouseflag = 1
      ;Convert mousecoord to MyMap() coord
      DataX = (iso_mouse_x/Tile_Height)-1
      DataY = (iso_mouse_y/Tile_Height)
          ; Check overflow
          If DataX>=0 And DataX<=9 And  DataY>=0 And DataY<=9
            Res = MyMap(DataX,DataY)
            Res+1
            Res%2
            MyMap(DataX,DataY) = Res
          EndIf 
EndIf 


If MouseButton( #PB_MouseButton_Left)=#False And mouseflag = 1
  mouseflag=0
EndIf 

Circle(ScreenMouse_X,ScreenMouse_Y,4,$0)
DrawText(10,10,"ISOMETRIC EXAMPLE BY CPL.BATOR, CLICK ON THE TILE,ESCAPE TO QUIT.")
StopDrawing()


EndProcedure


Zoom.f = 1
Repeat
  ExamineKeyboard() : ExamineMouse()
    ClearScreen($FFFFFFFF)

  
    If MouseWheel()>0
      Zoom + 0.05
    EndIf 
   
   If MouseWheel()<0
      Zoom - 0.05
    EndIf 
   
    DisplayMap2D(Zoom*128)


    FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)





















DataSection;10x10
Map2D:
Data.i 0,0,0,0,0,0,0,0,0,0
Data.i 0,0,0,0,0,0,0,0,0,0
Data.i 0,0,0,0,0,0,0,0,0,0
Data.i 0,0,0,0,1,0,0,0,0,0
Data.i 0,0,0,0,0,0,0,0,0,0
Data.i 0,0,0,0,0,0,0,0,0,0
Data.i 0,0,0,0,0,0,0,0,0,0
Data.i 0,0,0,0,0,0,0,0,0,0
Data.i 0,0,0,0,0,0,0,0,0,0
Data.i 0,0,0,0,0,0,0,0,0,0
EndDataSection
Post Reply