Build an isometric 3D game in 2D — #4 Fall and jump

This is part 4 of the 2d/3d(game/engine) conversion used in my puzzle game: Ladder Box, which is available on Steam:

Jump state

When a movable has a block at its same height in its moving direction, that movable will switch to the jump state.

func is_direction_jumpable(direction:Vector3) -> bool:
if direction in [Vector3.UP,Vector3.DOWN]:
return false

var _self_up_coordinate = game_pos + Vector3.UP
if !Grid.coordinate_within_rangev(_self_up_coordinate):
return false
var _self_up_item = Grid.get_game_axisv(_self_up_coordinate)
if _self_up_item != null:
return false

var _direction_up_axie = game_pos + direction + Vector3.UP
if !Grid.coordinate_within_rangev(_direction_up_axie):
return false

var _direction_up_item = Grid.get_game_axisv(_direction_up_axie)
if _direction_up_item != null:
return false

return true
  • check if the game position after jump and move is clear or not.
func set_next_target():
......
else:
if movable.is_direction_jumpable(direction):
_state_machine.switch_state("jump",{"direction":direction})
else:
_state_machine.switch_state("idle")
pass
func _command(_msg:Dictionary={}) -> void:
if _msg.keys().has("direction"):
var command = _msg["direction"]
match command:
Vector3.FORWARD,Vector3.BACK,Vector3.LEFT,Vector3.RIGHT:
pass
_:
return
var _move_target_coordinate = movable.game_pos + command
if Grid.coordinate_within_rangev(_move_target_coordinate) &&\
Grid.get_game_axisv(_move_target_coordinate) == null:
_state_machine.switch_state("move",{"direction":command})
elif movable.is_direction_jumpable(command):
_state_machine.switch_state("jump",{"direction":command})
else:
print("%s not able to move" % _move_target_coordinate)
extends StateBasevar move_direction:Vector3func _enter(_msg:={}) -> void:
if !_msg.keys().has("direction"):
return

move_direction = _msg["direction"]
print("enter jump")
new_movable(0,0,0)
new_unmovable(0,0,2)
new_unmovable(1,0,0)

Actual jump movement

Like in the move state, we will have a set_next_target function and some variables.

var engine_direction:Vector2 = GridUtils.game_direction_to_engine(Vector3.UP)var target_game_pos:Vector3
var target_z:int
var target_engine_pos:Vector2
func set_next_target():
target_game_pos = movable.game_pos + Vector3.UP
var _target_game_pos_obj = Grid.get_game_axisv(target_game_pos)
if Grid.coordinate_within_rangev(target_game_pos) && _target_game_pos_obj == null:
var _target_v3 = GridUtils.game_to_enginev(target_game_pos)
target_engine_pos = Vector2(_target_v3.x,_target_v3.y)
target_z = _target_v3.z-1
movable.set_game_posv(target_game_pos)
else:
_state_machine.switch_state("idle")
func _update(_delta:float) -> void:
var _after_move = movable.position + engine_direction * _delta * movable.MOVESPEED
var _reach_target = Math.is_betweenv(movable.position,_after_move,target_engine_pos)

if !_reach_target:
movable.position = _after_move
else:
movable.position = target_engine_pos
_state_machine.switch_state("move",{"direction":move_direction})

Fall state

Just like move and jump state, there will be a set_next_target and all those variables:

func set_next_target():
target_game_pos = movable.game_pos + Vector3.DOWN
var _target_game_pos_obj = Grid.get_game_axisv(target_game_pos)

if Grid.coordinate_within_rangev(target_game_pos) && _target_game_pos_obj == null:
var _target_v3 = GridUtils.game_to_enginev(target_game_pos)
target_engine_pos = Vector2(_target_v3.x,_target_v3.y)
target_z = _target_v3.z
movable.set_game_posv(target_game_pos)
else:
if movable.is_direction_movable(move_direction):
_state_machine.switch_state("move",{"direction":move_direction})
elif movable.is_direction_jumpable(move_direction):
_state_machine.switch_state("jump",{"direction":move_direction})
else:
_state_machine.switch_state("idle")
func _update(_delta:float) -> void:
var _after_move = movable.position + engine_direction * _delta * movable.MOVESPEED
var _reach_target = Math.is_betweenv(movable.position,_after_move,target_engine_pos)

if !_reach_target:
movable.position = _after_move
else:
movable.position = target_engine_pos
set_next_target()

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store