Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - Satoh

#31
Development / Re: Saving game issues
July 07, 2016, 01:53:21 AM
1.Have you configured your game to have a save folder? It should be listed in game properties editor.
2.Have you tried adding a game:save() to your treasure script, to try and force it to save?

I'm sorry I can't actually diagnose the problem for you, in lieu of giving suggestions. I've not started handling saving yet, but that's where I'd start looking.
#32
I was indeed imagining something like a drawable:set_blend_mode(mode) myself.
Sprites inherit from drawable as I understand it, so it should in theory work on manually defined surfaces as well as sprites right?

EDIT:
Link to SDL documentation on what the blend modes do. Pretty sure only the function needs to be called.
There are some other SDL_Set____BlendMode type functions, but the one in the link is the only one I found directly when I looked in the git.
#33
SDL has four blend modes, SDL_BLENDMODE_NONE, SDL_BLENDMODE_BLEND, SDL_BLENDMODE_ADD, and SDL_BLENDMODE_MOD.
SDL_BLENDMODE_NONE isn't terribly useful for Solarus so we can ignore it.

Solarus source code appears to always use BLEND already, which makes sense.
My desire is to be able to have some surfaces specify the ADD and MOD modes.
ADD is useful for creating brightly shining effects which lighten and color things under them, without washing them out or making them look hazy. Using a semitransparent sprite or surface by itself would cause the sprite underneath to lose some of its clarity.
If you wanted a particularly bright special effect, it would destroy the clarity of the scene beneath it, whereas an ADD blended surface would allow more of the detail to show through.
It would look better particularly when a dark and light colored object are beneath it, as the dark object would would be lit proportional to its original color.
A simple BLEND effect would cause the darker object to seem to be lit more, due to the BLEND surface partly replacing the scene, rather than adding to it.

Similarly MOD can be used to darken a scene, and add really rich vibrant color to it, without degrading image quality. This is fairly easy to demonstrate, using a screenshot from another SNES game.


At the top we have a BLEND mode style layering, with a blue color, at 75% opacity. It... doesn't look so great, and I wasn't able to make it much darker than that without the image turning more black than blue. Below that is a MOD style layer, which darkens the image with a rich blue color, without making the scene hazy, and it looks like a nice nighttime effect.

With the MOD blendmode, one could make an active day and night cycle by rendering a surface with different colors for different times of day, or shadows which darken sprites under them, without making them look smoky (like what happens with a black or gray semitransparent BLEND shadow)

As far as I could locate, the git src only sets the blendmode twice, so it seems like adding a blendmode property to the solarus drawable class and passing that as an argument, should work... But that's only as far as I could find. I'm sure Christopho knows the source better than I.

Anyway, that's my argument for why it would be a decent feature to have.
#34
Quote from: Starlock on July 06, 2016, 04:30:19 PM
Do you have a default block sprite implemented into the game? My editor used to crash when I used the block before I created a sprite for the block.
That seems to be the source of the issue.
For future usability, it may still be a good idea to put an error handler in there for that case, as crashing shouldn't ever be normal behavior.
#35
When I click the button to create a Block, in the map editor, the program crashes immediately.
The same happens with Crystal and Crystal Block. This is in snapshot 20160620.
#36
Diagonal walls only work when the player is actually rubbing up against the wall though.
It may not be clear what I'm trying to accomplish... but for example, if I had a sloped area that was 16 pixels wide, and 256 pixels from diagonal edge to diagonal edge, I wouldn't want the player to just walk straight across it without moving diagonally, but at that size it would be entirely possible to miss both edges, which is where the walls would be.

Its difficult to explain exactly what circumstances this would be used aside from simply pointing out that I need some raised platforms on a section of floor, and it won't look right if the player traverses them as if they were flat.
#37
I'm trying to create an entity that, when overlapped, an entity that is moving left or right, is forced to move diagonally down and left, up and right, and another entity that does the opposite diagonals, up_left down_right.

I started with this code, but I don't really get what I'm doing with all the collision tests...
and I can't seem to figure out how to control the Hero without taking the control away from the player too.
local entity = ...
--This entity forces the player into diagonal motion
--if the entity is facing LEFT the character will move DOWN and LEFT
--  or UP and RIGHT
--if the entity is facing RIGHT the character will move DOWN and RIGHT
--  or UP and LEFT

local hero = entity:get_map():get_hero()

function entity:on_created()
  self:add_collision_test(function entity:overlaps(hero,"overlapping")
    return true
  end, entity:on_traversed())
end

function entity:on_traversed()
  if self:get_direction() == 0 and hero:get_direction() == 0 then
    -- here is where I'm stuck. The API reference isn't giving me enough info to figure it out.
  end
end


My game will have some large 'sloped' floors, such as staircases, that will simply not look good if the player is allowed to move in straight left and right directions when traversing them.

As my comment in the code states, I'm not sure how to control the hero's direction, without removing player control completely.
I want the player to act freely as they normally would, but simply move in the specified diagonal directions when moving.

I'm also not certain I'm using add_collision_test correctly for a custom entity. I don't know how to get a reference to 'what entity is colliding with self' in order to perform actions on it or do tests from it, as the API reference does not say that any collision tests return any entity references.

In short, I need help and am severely confused. (though I understand lua a lot better than I did the last time I was here, so yay~)

EDIT:
Ok, I found a method that does technically work, but I fear there may be some weird repercussions for certain things I didn't account for due to complexity... if someone has suggestions I'd like to hear them.
new code:
local entity = ...
--This entity forces the player into diagonal motion
--if the entity is facing LEFT the character will move DOWN and LEFT
--  or UP and RIGHT
--if the entity is facing RIGHT the character will move DOWN and RIGHT
--  or UP and LEFT

local hero = entity:get_map():get_hero()
local game = entity:get_map():get_game()
local simulating = nil

function entity:on_update()

  if self:overlaps(hero,"overlapping") and hero:get_state() == "free" then
    if (self:get_direction() == 0 and game:is_command_pressed("right")) or
      (self:get_direction() == 2 and game:is_command_pressed("left")) then
      game:simulate_command_pressed("down")
      simulating = "down"
    elseif (self:get_direction() == 0 and game:is_command_pressed("left")) or
      (self:get_direction() == 2 and game:is_command_pressed("right")) then
      game:simulate_command_pressed("up")
      simulating = "up"
    end
    if self:get_direction() == 0 then
      if not game:is_command_pressed("left") and simulating == "up" then
        game:simulate_command_released(simulating)
        simulating = nil
      end
      if not game:is_command_pressed("right") and simulating == "down"  then
        game:simulate_command_released(simulating)
        simulating = nil 
      end
    end
    if self:get_direction() == 2 then
      if not game:is_command_pressed("left") and simulating == "down" then
        game:simulate_command_released(simulating)
        simulating = nil
      end
      if not game:is_command_pressed("right") and simulating == "up"  then
        game:simulate_command_released(simulating)
        simulating = nil
      end
    end
    if (simulating == "up" and game:is_command_pressed("down")) or
      (simulating == "down" and game:is_command_pressed("up")) then
      game:simulate_command_released("up")
      game:simulate_command_released("down")
      simulating = nil
    end
  elseif simulating ~= nil then
    game:simulate_command_released(simulating)
    simulating = nil
  end
end
#38
If they're flickering energy balls it could be that they're flickering at a speed that your screen can't handle, which causes them to be drawn only on the solid frame or the transparent frame, not one on one off like it should be.
If your monitor supports higher refresh rates (60hz, 70hz, 80hz, etc) try one of those, and see if it persists... (Or look for the script that defines them and change the rate they flash)

If they flash at a seemingly random rate, its probably the refresh rate of the screen.
It could still be a bug though. (and probably should be a bug anyway if its not drawing correctly at all refresh rates anyway)

tl;dr
Could be a hardware issue that the script doesn't account for.
#39
Cool. Nice to see we're all on the same page then.

I have actually installed cmake and mingw once before, and given that experience (it took 4 days to make it work correctly because missing libraries from X distribution, no download sources for Y library, etc) it was rightly and truly a nightmare. That's the main reason I'm hesitant to try doing any of this on my own. I could probably muddle through the C++, but setting up the build environment... that's terrifying.
#40
While I like the engine as it is, and I'm glad it works as well as it does, there are often little tweaks I'd like to make to some of the Hero's behavior.

Some of these, like changing animations, can be done sort of easily.... but changing the range of a sword strike seems to require a full source mod.

What I'd like to see is the ability to modify some things in the default behavior, from Lua.

There are also times when having a full 16x16 is a bit too large for collision, especially if you're making a game with a smaller character. (I think Link was actually 12 or 14 originally, to allow for a slight amount of wall overlap. If nothing else its a common thing in GBA and SNES games anyway.)

Allowing Lua to modify the Hero behaviors would add a lot of flexibility. Especially since all the other entities in the engine are Lua based.

What I had in mind is "Use default behavior, but allow Lua to override functions by name."
What would be less flexible, but probably a lot easier, would be redirecting the hard coded parameters like sword length (14) to a settings variable, which can be changed.

(Some of the things I had in mind to want more flexibility with are sword behavior and length, bow behavior such as nocking an arrow but not firing until the command is released, shield behavior like manually blocking, allowing for a throwing animation, which there doesn't seem to be, and so forth)


Secondly, a debug console to print messages to would be helpful for error testing.
#41
Development / Re: Custom Entity: Companion
January 23, 2015, 10:23:44 PM
Ah! Ok, I'm used to C type languages where everything is immutable after it's created!

I didn't realize I could modify the structure of an object at runtime. That makes things a lot easier.
I got it working now, thanks to all your help.

Knowing what I do now, I might even be able to create a crude party system... only question is, what do I do with this knowledge... so many possibilities.
#42
Development / Re: Custom Entity: Companion
January 23, 2015, 04:04:10 AM
Several hours of trial and error and I have finally discovered why it wasn't working.
I was trying to get references too early in the script, and thus the coordinates I was supplying, didn't exist, so neither did the entity.

After rearranging some things, it does exactly what I thought it should when I first wrote it.

You mentioned 'keeping its state' before.
Its not strictly necessary for this, but I've been considering some more complex followers, that may need to remember 'where they are' in relation to the hero when changing maps, so they can return there when created fresh. (and maybe other things like equipment or something)

Anyway, in short, how do I store that type of information to be reloaded on the next map?
My instinct is "create a save game variable" like with items, but that seems a bit messy for something that could get written frequently. (If the player changes maps really fast)
#43
Development / Re: Custom Entity: Companion
January 22, 2015, 02:59:29 AM
I can't seem to get my entity to be created.
I've tried placing it on a map directly,
I've tried adding game:on_map_changed(map) to it...
I tried creating it in a map script event I can trigger manually...

I added a sound effect in the on_created() so I'd at least know it was there even if it was invisible.

Nothing I do makes the entity work.

This is the whole script. Sorry I can't shorten it for convenience.
local entity = ...
local hero = map:get_entity("hero")
local acceleration = 1
local maxspeed = 4
local xspeed = 0
local yspeed = 0
local sprite2 = nil
local x = 0
local y = 0

function game:on_map_changed(map)
  map:create_custom_entity{
      name = "navy",
      layer = 2,
      x = 0,
      y = 0,
      direction = 3,
      --model = "entities/fae"
      model = "fae"
    }
end

function entity:on_created()
  self:create_sprite("entities/faeglow")
  self:set_size(8, 8)
  self:set_origin(4, 4)
  x, y = hero:get_position()
  self:set_position(x, y, 2)
  self:get_sprite():set_animation("glow")
  sprite2 = sol.sprite.create("entities/faewing")
  sprite2:set_animation("flap")
  sol.timer.start(33, moving)
  sol.audio.play_sound("secret")

end

local function moving()
  local hero_x, hero_y = hero:get_position()
  --x, y = self:get_position()
  --Each direction gets a unique check because the entity accelerates each way separately.
  --This creates a nice simple sinusoidal motion and allows the object to follow a fluid organic
  --path to and orbit around its destination, instead of stopping.
  if hero_x > x and xspeed < maxspeed then
    xspeed += acceleration
  end
  if hero_y > y and yspeed < maxspeed then
    yspeed += acceleration
  end
  if hero_x <= x and xspeed > -maxspeed then
    xspeed -= acceleration
  end
  if hero_y <= y and yspeed > -maxspeed then
    yspeed -= acceleration
  end
  x+=xspeed
  y+=yspeed
  --now we actually change the position.
  self:set_position(x, y)
  --self:set_position(x+xspeed, y+yspeed)
  return true --restarts timer
end

function entity:on_pre_draw()
  self:get_map():draw_sprite(sprite2, x+xspeed, y+yspeed)
end


I can't figure out what I've done wrong.
#44
Development / Re: Custom Entity: Companion
January 21, 2015, 08:17:01 PM
What object should I attach my game:on_map_changed() to?

Where should I put my timer, if not on_update()?
I'm assuming scripts only get updated when something tells them to update, so I'm not sure how to make a timer in Lua that wouldn't be frame-rate dependent.

EDIT:
Ah, ok, I forgot sol.timer.start(...)
I should put that in on_created() right? Then it should call the function for movement, and restart its timer...
#45
Development / Custom Entity: Companion
January 21, 2015, 06:32:23 AM
Ok, so I think a custom entity is what I need for this.

I want to make an object that follows and orbits the hero across multiple maps.
In this case something like a fairy or a spirit orb or the like.

There are a few problems I have, mostly because I'm not sure how the engine does them (if it does them).

The first thing is blending modes: Add and Multiply.
The SNES could overlay sprites as transparent objects that would add to the brightness of pixels beneath them (this is how they made sunbeams and torch lights work for example), but this is Solarus, not SNES. I'm not sure if it supports this currently. (the method for implementing it isn't hard if you can modify pixel arrays. In case you need to add it, the general logic is like this:

foreach spritepixel //we only need to mess with the sprite
{
  final_R = Math.Min(screen_R + sprite_R, 255); //If the result is bigger than a byte, we clamp it.
  final_G = Math.Min(screen_G + sprite_G, 255);
  final_B = Math.Min(screen_B + sprite_B, 255);
  //Additive sprites usually don't need alpha since black + any color = no change.
  //so we'll ignore the alpha channel.
  //Obviously this is not in C++ syntax, but I'm sure you're able to fix that easily.
}

I don't think I can do it directly from Lua, judging by how solarus handles drawing, and there's no mention of blending modes. If it's not in the engine, consider this a feature request.

Moving on.
I know exactly how I want the orbit to work, but I'm not certain if it works in Solarus.
local entity = ...
local hero = map:get_entity("hero")
local acceleration = 0.2
local maxspeed = 4.0
local xspeed = 0.0
local yspeed = 0.0
local sprite2 = nil
local x = 0.0
local y = 0.0

function entity:on_created()
  self:create_sprite("entities/faeglow")
  self:set_size(8, 8)
  self:set_origin(4, 4)
  x, y = self:get_position()
  self:set_position(x, y, 2)
  self:get_sprite():set_animation("faeglow")
  sprite2 = sol.sprite.create("entities/faewings")
  sprite2:set_animation("faewings")
end

function entity:on_update()
  local hero_x, hero_y = hero:get_position()
  x, y = self:get_position()
  --Each direction gets a unique check because the entity accelerates each way separately.
  --This creates a nice simple sinusoidal motion and allows the object to follow a fluid organic
  --path to and orbit around its destination, instead of stopping.
  if hero_x > x and xspeed < maxspeed then
    xspeed += acceleration
  end
  if hero_y > y and yspeed < maxspeed then
    yspeed += acceleration
  end
  if hero_x <= x and xspeed > -maxspeed then
    xspeed -= acceleration
  end
  if hero_y <= y and yspeed > -maxspeed then
    yspeed -= acceleration
  end
  --now we actually change the position.
  self:set_position(x+xspeed, y+yspeed)
end

function entity:on_pre_draw()
  self:get_map():draw_sprite(sprite2, x, y)
end


I believe this should work, but I'm not entirely certain if the engine can handle decimal positions, and I'm not sure if this is all I need.

Lastly, I don't know how to make this be a global entity. I've considered making it some kind of item that's simply always in use... but I'm not sure if that would work either.

So, can I get some advice?