'----------------------------------------------------------------
'   TITLE: Isometric Demo
'   AUTHOR: n00b
'   DATE: Nov 13, 2025
'
'   DESCRIPTION: Nirvana Isometric Game Example
'
'----------------------------------------------------------------

Include "nirvana.bas"

title$ = "Nirvana2D Template"
w = 640
h = 480
fullscreen = FALSE
vsync = TRUE

'Open a graphics window
OpenWindow( title$, w, h, fullscreen, vsync )

'Load Nirvana Stage
Nirvana_LoadStage("isometric_stage", 0, 0, w, h)


'Get Playfield layer index
nv_playfield_index = Nirvana_GetLayerIndex("playfield")

'Get nirvana index for hero sprite
nv_hero_index = Nirvana_GetLayerSpriteIndex(nv_playfield_index, "hero")

'Get Sprite ID for hero
hero = Nirvana_GetSpriteID(nv_hero_index)

'Note: Hero collision body is detached so we have to get the detached sprite to move the hero
'Note: We will need the hero sprite to set animations but the detached body will be what we actually move
hero_detached_sprite = Nirvana_GetDetachedSpriteID(nv_hero_index)
SetSpriteSolid(hero_detached_sprite, TRUE)


'Vector for storing camera position
Dim camera_position As Nirvana_Vector2D

'We will center the camera on our sprite
'Note: Unless we are dealing with animation for setting how the sprite is rendered, we must use the detached body
camera_position.X = (SpriteX(hero_detached_sprite) + (SpriteWidth(hero)/2)) - (w/2)
camera_position.Y = (SpriteY(hero_detached_sprite) + (SpriteHeight(hero)/2)) - (h/2)



Nirvana_SetStageOffset(camera_position)

hero_direction = 180
hero_is_moving = FALSE
animation_change = FALSE

hero_speed_x = 0
hero_speed_y = 0

hero_move_speed = 70

hero_animation = Nirvana_GetSpriteAnimationIndex(nv_hero_index, "IDLE_" + Str(hero_direction))
SetSpriteAnimation(hero, hero_animation, -1)

'Exit While Loop when ESCAPE is pressed
While Not Key(K_ESCAPE)
	'Get the Current Camera Position
	camera_position = Nirvana_GetStageOffset()
	animation_change = FALSE
	
	old_direction = hero_direction
	prev_hero_move = hero_is_moving
	
	hero_speed_x = 0
	hero_speed_y = 0
	
	hero_is_moving = FALSE
	'Move camera position Left or Right when arrow keys are pressed
	If Key(K_LEFT) Then
		hero_direction = 270
		hero_is_moving = TRUE
		hero_speed_x = -1 * hero_move_speed
	ElseIf Key(K_RIGHT) Then
		hero_direction = 90
		hero_is_moving = TRUE
		hero_speed_x = hero_move_speed
	End If
	
	'Move camera position Up or Down when arrow keys are pressed
	If Key(K_UP) Then
		Select Case hero_direction
		Case 90
			hero_direction = 45
		Case 270
			hero_direction = 315
		Default
			hero_direction = 0
		End Select
		
		hero_speed_y = -1 * hero_move_speed
		
		hero_is_moving = TRUE
		
	ElseIf Key(K_DOWN) Then
		Select Case hero_direction
		Case 90
			hero_direction = 135
		Case 270
			hero_direction = 225
		Default
			hero_direction = 180
		End Select
		
		hero_speed_y = hero_move_speed
		
		hero_is_moving = TRUE
	End If
	
	If (hero_direction <> old_direction) Or (hero_is_moving <> prev_hero_move) Then
		animation_change = TRUE
	End If
	
	If animation_change Then
		Select Case hero_is_moving
		Case FALSE
			hero_animation = Nirvana_GetSpriteAnimationIndex(nv_hero_index, "IDLE_" + Str(hero_direction))
			SetSpriteAnimation(hero, hero_animation, -1)
		Case TRUE
			hero_animation = Nirvana_GetSpriteAnimationIndex(nv_hero_index, "WALK_" + Str(hero_direction))
			SetSpriteAnimation(hero, hero_animation, -1)
		End Select
	End If
	
	'SetSpriteRotation(hero_detached_sprite, hero_direction)
	SetSpriteLinearVelocity(hero_detached_sprite, hero_speed_x, hero_speed_y)
	
	camera_position.X = (SpriteX(hero_detached_sprite) + (SpriteWidth(hero)/2)) - (w/2)
	camera_position.Y = (SpriteY(hero_detached_sprite) + (SpriteHeight(hero)/2)) - (h/2)
	
	'Set camera to new position
	Nirvana_SetStageOffset(camera_position)

	'This update function must be used for Nirvana Projects
	Nirvana_Update()
Wend
