Circular Line of Sight by Zwarteziel7th Feb 2014 18:25
|
---|
Summary Circular Line of Sight: a program that lets a user navigate a map, while highlighting tiles that are in the player's Line of Sight (LOS). Description Circular Line of Sight: a program that generates a map from a file and lets the user navigate it, while highlighting tiles that are in the player's Line of Sight (LOS). The LOS is round (360dg.) but can be modified to check only a part of the circle. (For instance when one should one want to implement a method were a player can only look in the direction it is facing). The code needs a map-file (in \media\maps) which is included in the CodeBase as a .ZIP-file. Code ` This code was downloaded from The Game Creators ` It is reproduced here with full permission ` http://www.thegamecreators.com // // Round Line of Sight: a program that generates a map from a file and lets the user // navigate it, while highlighting tiles that are in the player's Line of Sight (LOS). // The LOS is round (360dg.), and based on an example from Roguebasin: bit.ly/1duW4dQ // Needs a map-file (in \media\maps) which is included in the CodeBase as a .ZIP-file. // // Zerotown, AGK v1.821 // `====================================================================================== ` Set variables and assign values `-------------------------------------------------------------------------------------- #constant KeyLeft 37 #constant KeyUp 38 #constant KeyRight 39 #constant KeyDown 40 #constant KeyEsc 27 // variables for the map global MapLength as integer : MapLength = 64 global MapWidth as integer : MapWidth = 64 type MapUDT Char$ as string Visible as integer Transparent as integer endtype dim Map[64, 64] as MapUDT // variables for the sprites global SprMap as integer global SprSize as integer : SprSize = 12 global SprPlayer as integer global SprPosX as integer global SprPosZ as integer // variables for debug information global DebugInfo as integer : DebugInfo = 1 // variables for setting the screen global ScreenAspect# as float global ScreenHeight# as float global ScreenMax# as float global ScreenMin# as float global ScreenWidth# as float // variables for minimap global PlayerPosX as integer global PlayerPosZ as integer global MapSizeX# as float : MapSizeX# = MapWidth * SprSize global MapSizeZ# as float : MapSizeZ# = MapLength * SprSize // variables for the los-function global GridX as integer global GridZ as integer global LOSRange as integer : LOSRange = 8 global SnapX# as float global SnapZ# as float // variables for the main loop global GameState as integer : GameState = 1 `====================================================================================== ` Load data and create sprite `-------------------------------------------------------------------------------------- LoadMap("maps/Dungeon02_64.map") // create map-sprite SprMap = CreateSprite(0) setSpriteSize(SprMap, SprSize, SprSize) setSpriteTransparency(SprMap, 0) SetSpriteDepth(SprMap, 11) // create player-sprite SprPlayer = CreateSprite(0) setSpriteSize(SprPlayer, SprSize, SprSize) setSpriteColor(SprPlayer, 86, 117, 226, 255) setSpriteTransparency(SprPlayer, 0) SetSpriteDepth(SprPlayer, 10) `====================================================================================== ` Set the screen `-------------------------------------------------------------------------------------- SetOrientationAllowed(0, 0, 1, 1) SetVirtualResolution(1024, 768) SetResolutionMode(0) SetPrintSize(18) SetClearColor(0, 0, 0) SetScissor(0, 0, 0, 0) SetSortTextures(1) SetSyncRate(0, 0) ScreenWidth# = GetVirtualWidth() ScreenHeight# = GetVirtualHeight() if ScreenWidth# > ScreenHeight# ScreenMin# = ScreenHeight# ScreenMax# = ScreenWidth# else ScreenMin# = ScreenWidth# ScreenMax# = ScreenHeight# endif ScreenAspect# = ScreenMax# / ScreenMin# `====================================================================================== ` Set position of player `-------------------------------------------------------------------------------------- // find a valid position for a 'player' which is used as a reference in this example repeat PlayerPosX = Random(1, MapWidth) PlayerPosZ = Random(1, MapLength) until Map[PlayerPosX, PlayerPosZ].Char$ = ":" `====================================================================================== ` Execute main program loop `-------------------------------------------------------------------------------------- repeat // calculate player position on grid GetTilePos(PlayerPosX * SprSize, PlayerPosZ * SprSize, SprSize) // clear the current LOS ClearLOS(GridX, GridZ, LOSRange) // calculate the new LOS CalcLOS(GridX, GridZ, LOSRange) // show map ShowMiniMap(1, 1, MapWidth, MapLength) // position the player-sprite SetSpritePosition(SprPlayer, PlayerPosX * SprSize, PlayerPosZ * SprSize) // check for user input CheckInput() // display some debug-information if DebugInfo = 1 ` print("FPS : " + str(Screenfps())) print("Move with arrow keys") print("Position X/Y : " + str(GridX) + ", " + str(GridZ)) endif Sync() until GameState = 0 SetRawMouseVisible(1) end `====================================================================================== ` Function to determine position on grid `-------------------------------------------------------------------------------------- function GetTilePos(PosX#, PosZ#, Size) GridX = PosX# / Size GridZ = PosZ# / Size endfunction `====================================================================================== ` Function to reset the LOS-values `-------------------------------------------------------------------------------------- function ClearLOS(PosX, PosZ, Range) // reset all visible tiles within range and edge of range for z = PosZ - (Range + 1) to PosZ + (Range + 1) for x = PosX - (Range + 1) to PosX + (Range + 1) if z => 1 and z <= MapLength if x => 1 and x <= MapWidth if Map[x, z].Visible = 1 then Map[x, z].Visible = 0 endif endif next x next z endfunction `====================================================================================== ` Function to calculate the line of sight for the player `-------------------------------------------------------------------------------------- function CalcLOS(PosX, PosZ, Range) // check tiles within range of the player in an expanding circle for Angle# = 1 to 360 step 0.3 ` decrease stepsize to increase the accuracy with which tiles are checked. (results in slower calculation) LOSPosX# = PosX + 0.5 ` convert positions of player to a float. Add 0.5 to place player in center of circle LOSPosZ# = PosZ + 0.5 AngX# = Cos(Angle#) AngZ# = Sin(Angle#) Block = 0 ` local variable to check if a position on the grid is blocked (1) or not (0) Dist = 0 ` local variable to check if distance set with LOSRange has been reached // check to see if something is blocking the LOS while Block = 0 LOSPosX# = LOSPosX# + AngX# LOSPosZ# = LOSPosZ# + AngZ# Dist = Dist + 1 // check if distance set by LOSRange has been reached if Dist > Range then Block = 1 // check if edges of the map have been reached if LOSPosX# < 1 then Block = 1 if LOSPosZ# < 1 then Block = 1 if LOSPosX# > MapWidth then Block = 1 if LOSPosZ# > MapWidth then Block = 1 // round float and convert position back to an integer if Block = 0 TrcPosX = trunc(LOSPosX#) TrcPosZ = trunc(LOSPosZ#) // check if an non-transparent tile is blocking our view if Map[TrcPosX, TrcPosZ].Transparent = 0 Block = 1 // *** // *** UNREM the following code below when using the function in a game... it causes the blocking tile to be visible. // *** The line is disabled here, because it visualizes the function better in this example. // *** ` if Map[TrcPosX, TrcPosZ].Visible = 0 then Map[TrcPosX, TrcPosZ].Visible = 1 endif // set transparent tile to be visible if it isn't already if Block = 0 if Map[TrcPosX, TrcPosZ].Visible = 0 then Map[TrcPosX, TrcPosZ].Visible = 1 endif endif endwhile next Angle# endfunction `====================================================================================== ` Function to check user input `-------------------------------------------------------------------------------------- function CheckInput() if GetRawKeyState(KeyUp) = 1 PlayerPosZ = PlayerPosZ - 1 if PlayerPosZ < 1 then PlayerPosZ = 1 endif if GetRawKeyState(KeyDown) = 1 PlayerPosZ = PlayerPosZ + 1 if PlayerPosZ > MapLength then PlayerPosZ = MapLength endif if GetRawKeyState(KeyLeft) = 1 PlayerPosX = PlayerPosX - 1 if PlayerPosX < 1 then PlayerPosX = 1 endif if GetRawKeyState(KeyRight) = 1 PlayerPosX = PlayerPosX + 1 if PlayerPosX > MapWidth then PlayerPosX = MapWidth endif if GetRawKeyState(KeyEsc) = 1 then GameState = 0 endfunction `====================================================================================== ` Function to load map-data from file `-------------------------------------------------------------------------------------- function LoadMap(FileName$) if GetFileExists(FileName$) = 1 FileId = OpenToRead(FileName$) for z = 1 to MapLength for x = 1 to MapWidth Char$ = chr(ReadByte(FileId)) Map[x, z].Char$ = Char$ Map[x, z].Visible = 0 // determine whether tile can bee 'seen though' by player or not (e.g. a wall blocks the LOS) if Char$ = "D" then Map[x, z].Transparent = 1 if Char$ = "O" then Map[x, z].Transparent = 0 if Char$ = "U" then Map[x, z].Transparent = 0 if Char$ = ":" then Map[x, z].Transparent = 1 if Char$ = "." then Map[x, z].Transparent = 0 if Char$ = "#" then Map[x, z].Transparent = 0 if Char$ = "S" then Map[x, z].Transparent = 0 next x next z CloseFile(FileId) else WriteDebugFile("Error in function [LoadMap]: file [FileName$] not found.") endif endfunction `====================================================================================== ` Function to show the minimap [StartX, StartZ, EndX, EndZ] `-------------------------------------------------------------------------------------- function ShowMiniMap(StartX, StartZ, EndX, EndZ) // display the minimap-sprites for z = StartZ to EndZ for x = StartX to EndX if z => 1 and z <= MapLength if x => 1 and x <= MapWidth Char$ = Map[x, z].Char$ // set default sprite color colR = 20 colG = 20 colB = 20 colA = 255 // set sprite color for door if Char$ = "D" or Char$ = "O" or Char$ = "U" colR = 132 colG = 128 colB = 112 colA = 255 endif // set sprite color for floor if Char$ = " " or Char$ = ":" colR = 244 colG = 226 colB = 152 colA = 255 endif // set sprite color for walls if Char$ = "#" or Char$ = "S" colR = 166 colG = 113 colB = 22 colA = 255 endif // set sprite color for tiles in LOS if Map[x, z].Visible = 1 colR = 255 colG = 255 colB = 255 colA = 100 endif // draw sprite SetSpritePosition(SprMap, (x + SprPosX ) * SprSize, (z + SprPosZ) * SprSize) SetSpriteColor(SprMap, colR, colG, colB, colA) DrawSprite(SprMap) endif endif next x next z endfunction `====================================================================================== ` Function to write debug file `-------------------------------------------------------------------------------------- function WriteDebugFile(Error$) FileId = OpenToWrite("debug.txt", 1) WriteLine(FileId, Error$) CloseFile(FileId) endfunction |