Jump to content
  • 0

Universal LPC Sprites


InappropriateUsername

Question

7 answers to this question

Recommended Posts

  • 0

You asked if it was possible, the answer is not currently at this time.

 

If you'd like to make a suggestion here is the correct place to do so.

http://www.ascensiongamedev.com/community/bug_tracker/intersect/

 

We will not be implementing this feature anytime soon. We might do this ourselves some point in the future but it's beyond low priority as there are few resources available that could take advantage of it.

 

Source will be available and then our system can be ripped out for the one that you favor.  Topic locked.

Link to comment
Share on other sites

  • 1

I mean, your suggestion/question was actually quite good until it devolved into "OMG people are stupid and it's unfair they haven't done this!".

Yes, that would be a decent suggestion, though considering the engine as it is right now doesn't support even half those sprite frames.. You'd probably still be unhappy if it did contain such a thing.

 

It's a free engine that you don't have to pay for, either take it or leave it really. (And in 2133 when the source comes out edit it to your liking. :P)

Link to comment
Share on other sites

  • 0
18 hours ago, Dumbretard said:

I'm wondering why this was never thought through with the developers. Generate a JSON file with the expected grid layout of the spritesheet. That would allow us to be flexible on our choice of spritesheets. What's worse, the engine isn't open source "yet", not sure why they would choose not to open the private Github repository up, i see no incentive in doing that. 

 

As of right now, this engine isn't usable for my team.

 

Epic fail.

 

I can't seem to wrap my head around why you'd think the engine is an epic fail. Not fast enough? Cry me a river. Not being open source is pretty easy concept to understand, they are still changing parts of the engine like crazy and don't wan't to release the source until its in a stable state. Once its open source anything you need to add you can yourself, lord. 

Link to comment
Share on other sites

  • 0
7 hours ago, Giligis said:

 

I can't seem to wrap my head around why you'd think the engine is an epic fail. Not fast enough? Cry me a river. Not being open source is pretty easy concept to understand, they are still changing parts of the engine like crazy and don't wan't to release the source until its in a stable state. Once its open source anything you need to add you can yourself, lord. 

 

You obviously didn't read my previous comment. It's an epic fail because a JSON file could of been included that defines the expected sprite "grid" layout, enabling developers like I to spend less time editing images, and more time creating content. In fact, I proved this only takes a few minutes to accomplish since I did just that in GoDot. Here is the source code to prove it. 

animations.json:

 

{
	"max_column_length": 13,
	"max_row_length": 21,
	"casting": {
		"columns": 7,
		"rows": 4,
		"up": 0,
		"left": 13,
		"down": 26,
		"right": 39
	},
	"spear": {
		"columns": 8,
		"rows": 4,
		"up": 52,
		"left": 65,
		"down": 78,
		"right": 91
	},
	"walking": {
		"columns": 9,
		"rows": 4,
		"up": 104,
		"left": 117,
		"down": 130,
		"right": 143
	},
	"sword": {
		"columns": 6,
		"rows": 4,
		"up": 156,
		"left": 169,
		"down": 182,
		"right": 195		
	},
	"bow": {
		"columns": 13,
		"rows": 4,
		"up": 208,
		"left": 221,
		"down": 234,
		"right": 247
	},
	"dead": {
		"columns": 6,
		"rows": 1,
		"down": 260
	}
}

This grid layout defines the Universal LPC spritesheets and can easily be modified to work with any spritesheet layout. See the idea? 

 

The other piece of this code is my Sprite.gd script file which loads the animations.json file to determine how to read each individual frame and animation.

 

Sprite.gd:

 

extends Sprite

# Sprite animations sub-image offsets and make-up information

var animations = {} # loaded from animations.json
var shop = {} # Only applies to NPC's that are merchants (loaded from npcs.json)

var name = null # unique sprite name
var facing = "down" # direction sprite is facing
var is_moving = false # is our sprite moving?
var world = 1
var merchant = false
var temp_elapsed = 0 # time since last _process() call
var last_index = 0 # last used animation frame index
var animation_speed = 0.15 # miliseconds til next animation frame renders
var current_animation = "walking"
var movement_speed = 1 # movement in pixels

var using_path = false # are we using a PathFollow2D node
var path_movement_speed = 50 # speed when following a PathFollow2D node.
var current_position = Vector2(0, 0) # current sprite position when using PathFollow2D node.
var previous_position = Vector2(0, 0) # previous sprite position when using PathFollow2D node.
var positions = [] # stores last two previous positions when using PathFollow2D node.

# Child nodes
onready var facial_node = get_node("Facial") # Facial (beard, mustache, etc)
onready var hair_node = get_node("Hair")
onready var head_node = get_node("Head")
onready var neck_node = get_node("Neck")
onready var torso_node = get_node("Torso")
onready var belt_node = get_node("Belt")
onready var legs_node = get_node("Legs")
onready var feet_node = get_node("Feet")
onready var weapon_node = get_node("Weapon")
onready var formal_node = get_node("Formal")
onready var hands_node = get_node("Hands")
onready var behind_node = get_node("Behind")
onready var name_node = get_node("Name")
onready var children = self.get_children() # List of all child sprite nodes

func paperdoll(type, action, spritesheet=null):
	# type: defined in 'types' dictionary below
	# action: 'show', 'hide', 'delete', 'set'
	# spritesheet: path to spritesheet
	# adds or removes a paperdoll on top of our sprite
	var types = {
	    "head": head_node,
	    "hair": hair_node,
	    "facial": facial_node,
	    "neck": neck_node,
	    "torso": torso_node,
	    "belt": belt_node,
	    "legs": legs_node,
	    "feet": feet_node,
	    "weapon": weapon_node,
	    "formal": formal_node,
	    "hands": hands_node,
	    "behind": behind_node,
	}
	if types.has(type):
		var type_node = types[type]
		if action == "show":
			type_node.show()
		elif action == "hide":
			type_node.hide()
		elif action == "set":
			if spritesheet:
				var imagetexture = ImageTexture.new()
				imagetexture.load(spritesheet)
				type_node.set_texture(imagetexture)
		elif action == "delete":
			type_node.queue_free()
	
func _fixed_process(delta):
	# for pathfollow2d node.
	if using_path:
		get_parent().set_offset(get_parent().get_offset() + (path_movement_speed*delta))
		
func update_children_animations(children, frame):
	for child in children:
		if child.get_type() == "Sprite":
			child.set_frame(frame)

func _process(delta):
	# update sprite animation frames and movement
	if using_path:
		# if the sprite is using a PathFollow2D node.
		# Update the animation based on direction walking.
		current_position = get_parent().get_pos()
		if positions.size():
			previous_position = positions[positions.size()-1]
			if (int(current_position.y) > int(previous_position.y)):
				# moving down
				facing = "down"
			elif (int(current_position.y) < int(previous_position.y)):
				# moving up
				facing = "up"
			elif (int(current_position.x) > int(previous_position.x)):
				# moving right
				facing = "right"
			elif (int(current_position.x) < int(previous_position.x)):
				# moving left
				facing = "left"
		if (positions.size() > 2):
			# clear the list after the length exceeds 3 to free up memory.
			positions.clear()
		positions.append(get_parent().get_pos())
	if current_animation:
		var starting_frame = animations[current_animation][facing]
		var ending_frame = starting_frame + animations[current_animation]['columns']
		var max_frame = animations[current_animation]['columns']
		var frames = range(starting_frame, ending_frame) # calculate frames in animation
		# update movement
		if is_moving and not using_path:
			var new_pos = Vector2(get_pos().x, get_pos().y)
			if facing == "down":
				new_pos.y += movement_speed
			elif facing == "up":
				new_pos.y -= movement_speed
			elif facing == "left":
				new_pos.x -= movement_speed
			elif facing == "right":
				new_pos.x += movement_speed
			set_pos(new_pos)
		temp_elapsed = temp_elapsed + delta
		# update animation
		if(temp_elapsed > animation_speed):
			if is_moving:
				# update animation while moving
				if(last_index == max_frame):
					set_frame(frames[0])
					last_index = 0
					update_children_animations(children, frames[last_index])
				else:
					if (last_index == 0):
						# prevents frames[0] from being rendered twice after last_index is reset to 0.
						last_index = 1
					# print(current_animation, facing, frames) # debugging
					set_frame(frames[last_index])
					update_children_animations(children, frames[last_index])
					last_index += 1
				temp_elapsed = 0
			else:
				# set idle sprite animation
				last_index = 0
				set_frame(frames[last_index])
				update_children_animations(children, frames[last_index])
				
func load_json_config(filename, dict):
	# Load filename.json and copy contents to empty dict.
	var file = File.new()
	file.open(filename, file.READ)
	var text = file.get_as_text()
	dict.parse_json(text)
	file.close()
	
func set_name(new_name):
	# Sets both the class-member name value and Label (Name) node text.
	name = new_name
	name_node.set_text(new_name)

func _ready():
	load_json_config("res://animations.json", animations)
	# set the default sprite frame (facing down while idle).
	set_process(true)
	set_fixed_process(true)
	var starting_frame = animations[current_animation][facing]
	var ending_frame = starting_frame + animations[current_animation]['columns']
	var frames = range(starting_frame, ending_frame) # calculate frames in animation
	set_frame(frames[last_index])
	update_children_animations(children, frames[last_index])
	if name:
		name_node.set_text(name)

func output_spritesheet_animation_offsets(images_per_row, amount_of_rows):
	# For debugging and testing
	for row_number in range(amount_of_rows):
		var offset = images_per_row * row_number
		print(offset)

So if you have a copy of GoDot, load up my script and include my JSON file to see it in action.

 

Again, this is to prove that this can be accomplished with little effort, and it came to my mind immediately. So I'm wondering why the devs here didn't think of this.

 

Heck I might have to create my own engine on-top of GoDot (with proper JSON files included) if the devs don't add this anytime soon.

Link to comment
Share on other sites

  • -4

I'm wondering why this was never thought through with the developers. Generate a JSON file with the expected grid layout of the spritesheet. That would allow us to be flexible on our choice of spritesheets. What's worse, the engine isn't open source "yet", not sure why they would choose not to open the private Github repository up, i see no incentive in doing that. 

 

As of right now, this engine isn't usable for my team.

 

Epic fail.

Link to comment
Share on other sites

×
×
  • Create New...