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 - wizard_wizzle (aka ZeldaHistorian)

#226
Development / Re: Moving platform
February 01, 2015, 04:03:52 PM
I'll give that a try. How would that work to set the hero's position only if he's on the platform though? Move the whole collision test to entity:on_position_chanted()?

Any thoughts on why the platform won't traverse water? My self:set_can_traverse_ground("deep_water", true) call doesn't seem to be functioning. Am I doing something wrong or is it a bug in the engine?
#227
Development / Re: Moving platform
February 01, 2015, 06:09:38 AM
Thanks! I'll report that problem on github.

I knew the dynamic tile solution was simpler, but I may go with the custom entity approach to give me more flexibility to create multiple types of platforms that can be reused. The problem with the dynamic tile is that I want the platform to traverse ONLY water and holes - when it reached regular ground that the hero can traverse, it would reverse direction (or whatever other action). Using a custom entity, I can now get it to be traversable by the hero, but it won't traverse water.

local entity = ...
local map = entity:get_map()
local hero = map:get_entity("hero")

local ex, ey, el, hx, hy, hl
local recent_obstacle = 0
local timer

-- Platform: entity which moves in either horizontally or
-- vertically (depending on direction) and carries the hero on it.

function entity:on_created()
  self:create_sprite("entities/platform")
  self:set_size(32, 32)
  self:set_origin(20, 20)
  self:set_can_traverse_ground("hole", true)
  self:set_can_traverse_ground("deep_water", true)
  self:set_can_traverse_ground("traversable", false)
  self:set_can_traverse_ground("shallow_water", false)
  self:set_can_traverse_ground("wall", false)
  self:set_modified_ground("traversable")

  self:add_collision_test("overlapping", function(platform, other)
    -- This callback will be repeatedly called while other is overlapping the platform
    if other:get_type() ~= "hero" then
      return
    end
    local hero = other

    -- Only do this in some specific states (in particular, don't do it while jumping, flying with the hookshot, etc.)
    if hero:get_state() ~= "free" and hero:get_state() ~= "sword loading" then
      return
    end
   
    -- Keep the hero on the platform as it moves
    if timer == nil then
      timer = sol.timer.start(self, 50, function()
hx, hy, hl = hero:get_position()
        ex, ey, el = entity:get_position()
        local ox = hx - ex
        local oy = hy - ey
        hero:set_position(hx-(ox/5), hy-(oy/5))
        timer = nil  -- This variable "timer" ensures that only one timer is running.
      end)
    end

  end)

  local direction4 = self:get_sprite():get_direction()
  local m = sol.movement.create("path")
  m:set_path{direction4 * 2}
  m:set_speed(32)
  m:set_loop(true)
  m:start(self)

end

function entity:on_obstacle_reached()
  local direction4 = self:get_sprite():get_direction()
  self:get_sprite():set_direction((direction4 + 2) % 4)

  local x, y = self:get_position()
  recent_obstacle = 8

  local direction4 = self:get_sprite():get_direction()
  local m = sol.movement.create("path")
  m:set_path{direction4 * 2}
  m:set_speed(32)
  m:set_loop(true)
  m:start(self)

end

function entity:on_position_changed()
  if recent_obstacle > 0 then
    recent_obstacle = recent_obstacle - 1
  end
end

function entity:on_movement_changed(movement)
  local direction4 = movement:get_direction4()
  self:get_sprite():set_direction(direction4)
end

P.S. This probably isn't the best way to keep the hero on the platform either, but it works for now.
#228
How would someone recommend implementing moving platforms (over water or holes only) in Solarus? I've tried a dynamic tile with movement applied, but I can only get it to traverse what the hero could and not water. I've tried a custom entity, but I can't get it to be traversable by the hero - if the platform sits on water, the hero just jumps into the water rather than walking on the platform. I'm probably just doing something wrong, but was hoping for some direction either way.
#229
Development / Re: Quicksand custom entity
January 20, 2015, 12:46:21 AM
Works great, Christopho! Thanks!

One question - if I wanted to slow the hero's walking speed when he overlaps the quicksand (making it harder to get out), how would I go about returning his speed when he's no longer in the quicksand? Also, any advice on how to make the hero sink/fall when he gets to the center?

Updated (working) code:
local entity = ...
local map = entity:get_map()
local hero = map:get_entity("hero")

local ex, ey, el
local timer

-- Quicksand: entity which slows the hero until
-- he finally falls in

function entity:on_created()
  self:create_sprite("entities/quicksand")
  self:set_size(32, 32)
  self:set_origin(16, 16)
  ex, ey, el = self:get_center_position()
  self:get_sprite():set_animation("quicksand")

  self:add_collision_test("overlapping", function(quicksand, other)
    -- This callback will be repeatedly called while other is overlapping the quicksand

    if other:get_type() ~= "hero" then
      return
    end
    local hero = other

    -- Only do this in some specific states (in particular, don't do it while jumping, flying with the hookshot, etc.)
    if hero:get_state() ~= "free" and hero:get_state() ~= "sword loading" then
      return
    end

    --hero:set_walking_speed(44)

    -- Move the hero toward the quicksand's center every 20 ms while he is overlapping it.
    if timer == nil then
      timer = sol.timer.start(self, 20, function()
hx, hy, hl = hero:get_position()
if ex > hx then hx = hx + 1 else hx = hx - 1 end
if ey > hy then hy = hy + 1 else hy = hy - 1 end
        hero:set_position(hx, hy)
        timer = nil  -- This variable "timer" ensures that only one timer is running.
      end)
    end

  end)
end



Speaking of my game, I just (quietly) released a new version today! :)
#230
Your projects / Re: Zelda: Book of Mudora
January 20, 2015, 12:41:56 AM
UPDATE! Version 0.3 (the first true public beta) has been released! This is very similar to the last version, but with some polish and a little more action added in. For all the details and the download link, please check out the game's site: https://sites.google.com/site/zeldabom/demos
#231
Development / Quicksand custom entity
January 19, 2015, 04:38:08 PM
I'm looking to make a custom entity which behaves like quicksand (think Link to the Past's desert temple) - when the hero approaches it, he's slowly dragged into the center, then when he reached the center, he sinks (behavior like a hole, probably). I can't seem to figure it out. Any thoughts?

This is what I have so far, which isn't even close to working:
local entity = ...
local map = entity:get_map()
local hero = map:get_entity("hero")

-- Quicksand: entity which slows the hero until
-- he finally falls in

function entity:on_created()
  self:create_sprite("entities/quicksand")
  self:set_size(32, 32)
  self:set_origin(16, 16)
  ex, ey, el = self:get_position()
  self:get_sprite():set_animation("quicksand")
end

function entity:on_update()
  self:add_collision_test("overlapping", function()
    if hero:get_walking_speed() >= 8 then hero:set_walking_speed(hero:get_walking_speed()-1) end
    m = sol.movement.create("target")
    m:set_target(ex, ey)
    m:start(hero)
  end)
end
#232
Bugs & Feature requests / Re: Solarus features ?
October 01, 2014, 01:29:40 AM
My attempt at a particle engine in pure Lua under Solarus: http://forum.solarus-games.org/index.php/topic,52.0.html

Needs a lot of work still, but could be a start if you need it.
#233
Development / Re: Help with light and darkness
September 20, 2014, 04:43:16 PM
I don't believe it is currently, as I also need this for my game. The current approach to darkness/light is to apply a dark sprite over the whole screen, with a transparent area in the middle which appears as "light" (and can follow the hero, such as with the lamp). The problem is that you can't apply multiple lights because there is no actual light, only a lack of darkness in a small area. If you had pre-arranged areas of light, I suppose you could do multiple "cut-out" areas in the dark sprite, but this can't be done dynamically.

Eventual implementation of shaders in the engine could allow for more advanced lighting effects.
#234
Bugs & Feature requests / Re: cmake error on Ubuntu
August 23, 2014, 04:25:35 PM
It seems to be a problem with the location of my libraries and my environment variables. I got OpenAL and PhysFS to work, but I'm still having problems with Lua. Setting an environment variable for that one doesn't seem to be working, unless I'm setting the wrong one. I'm setting "LUA_DIR" and "LUA_LIBS" and still no luck.
#235
Bugs & Feature requests / cmake error on Ubuntu
August 23, 2014, 03:34:18 PM
When I go to compile solarus 1.3, I get a cmake error stating that OPENAL can't be found, but according to my system it's installed. Is something wrong with cmake or my system? I've compiled before, so unless something has changed, I'm confused  :-\

Error output:
CMake Error at /usr/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:108 (message):
  Could NOT find OpenAL (missing: OPENAL_LIBRARY)
Call Stack (most recent call first):
  /usr/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:315 (_FPHSA_FAILURE_MESSAGE)
  /usr/share/cmake-2.8/Modules/FindOpenAL.cmake:97 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  CMakeLists.txt:18 (find_package)


OPENAL installation:
sudo apt-get install libopenal*
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Note, selecting 'libopenais2' for regex 'libopenal*'
Note, selecting 'libopenais-dev' for regex 'libopenal*'
Note, selecting 'libopenal0a' for regex 'libopenal*'
Note, selecting 'libopenal-dev' for regex 'libopenal*'
Note, selecting 'libopenal1' for regex 'libopenal*'
Note, selecting 'libopenafs-dev' for regex 'libopenal*'
Note, selecting 'libopenal-data' for regex 'libopenal*'
Note, selecting 'libopenais-legacy-dev' for regex 'libopenal*'
libopenafs-dev is already the newest version.
libopenal-data is already the newest version.
libopenal-dev is already the newest version.
libopenal1 is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 30 not upgraded.
#237
Your projects / Re: Zelda: Book of Mudora
August 09, 2014, 01:19:54 AM
I would estimate 30-40% complete, depending on how much of my plan I end up executing. It's fully playable to the third dungeon, and partially to the fourth (plus about half of an ongoing dungeon). Obviously things will be added, so throw ideas my way if you have them!
#238
Your projects / Zelda: Book of Mudora
August 08, 2014, 01:53:58 AM
My full Zelda game, Book of Mudora, is done! The release includes Solarus 1.5(.1), the pre-release that Christopho posted to fix the software surface memory leak) for Windows, and other platforms are available at http://www.solarus-games.org/

Download: https://sites.google.com/site/zeldabom/download

Trailer: https://www.youtube.com/watch?v=wk13ltcilDM

Thanks everyone for your help, and enjoy!
#239
Development / Re: Particle system
June 11, 2014, 02:14:58 PM
Okay, the display issue has been corrected and the "sparkle" (renamed to just spark) particle emitter now works! I've also added alpha fade to these particles, so they start to disappear as they age. If anyone could come up with or point me to other examples of particle emitter mathematics, I will add them, but I'm not very good at this kind of thing. I'd like to get a few more emitter types built in and then post this in the "Your Projects" board for others to use.
#240
Development / Re: Particle system
June 07, 2014, 08:15:21 PM
Thanks for the feedback, Christopho!

New particles.lua:
local particle_system = {}

function particle_system:new(game)
  local object = {}
  setmetatable(object, self)
  self.__index = self
  return object
end

function particle_system:initialize(game)
  self.game = game
  if not self.type then
    print("Aborting. Call 'particle_system:set_type' before initializing.")
    return false
  end
  if not self.time then self.time = 1 end
  if not self.count then self.count = 5 end
  if not self.color then self.color = {255, 255, 255} end
  self.particles = {}

  if self.type == "sparkle" then
    self.alive = true
    for i=1, self.count do
      self.particles[i] = {}
      self.particles[i].x = self.x
      self.particles[i].xspeed = math.random(-100,100)
      self.particles[i].y = self.y
      self.particles[i].yspeed = math.random(-200,50) + (self.ysp or 0)
    end
    return self
  elseif self.type == "dust" then
    self.alive = true
    if not self.time then self.time = 0 end
    return self
  end
end

function particle_system:set_type(type)
  self.type = type
end

function particle_system:set_position(x, y, layer)
  self.x = x
  self.y = y
  self.layer = layer or 1
end

function particle_system:set_particle_count(count)
  self.count = count
end

function particle_system:set_particle_color(color)
  self.color = color
end

function particle_system:set_decay_time(time)
  self.time = time
end

function particle_system:set_y_speed(ysp)
  self.ysp = ysp
end

function particle_system:is_active()
  return self.alive
end

function particle_system:on_update(dt)
  self.time = self.time - dt

  if self.type == "sparkle" then
    if self.time < 0 then
      self.alive = false
      return
    end
    for i,v in ipairs(self.particles) do
      v.x = v.x + v.xspeed*dt
      v.yspeed = v.yspeed + 500*dt
      v.y = v.y + v.yspeed*dt
    end
  elseif self.type == "dust" then
    if self.time > 0.25 then
      self.alive = false
      return
    end
  end
end

function particle_system:on_draw(dst_surface)
  if self.type == "sparkle" then
    for i,v in ipairs(self.particles) do
      dst_surface:fill_color(self.color, 0.5+v.x, 0.5+v.y, 1, 1)
    end
  elseif self.type == "dust" then
    dst_surface:fill_color(self.color, self.x-self.time*16, self.y-self.time*16, 1, 1)
    dst_surface:fill_color(self.color, self.x+self.time*16, self.y-self.time*16, 1, 1)
    dst_surface:fill_color(self.color, self.x-self.time*16, self.y+self.time*16, 1, 1)
    dst_surface:fill_color(self.color, self.x+self.time*16, self.y+self.time*16, 1, 1)
  else
    --dst_surface:clear()
  end
end

return particle_system


New map script:
local map = ...
local game = map:get_game()
local particle_system = require("particles")
local emitter = particle_system:new(game)

function sensor:on_activated()
  emitter:set_type("sparkle")
  emitter:set_position(100, 100)
  emitter:set_particle_count(50)
  emitter:set_decay_time(10)
  emitter:initialize()
  sol.timer.start(map, 1000, function()
    if emitter ~= nil then emitter:on_update(1) end
    return true
  end)
end

function map:on_draw(dst_surface)
  if emitter ~= nil then emitter:on_draw(dst_surface) end
end


The script now operates without error and as expected, but the display is not correct. I usually only get one particle on screen and it disappears without moving. It probably has to do with the drawing method that I used (dst_surface:fill_color) since I don't know if it allows for multiple fill_color calls on one surface. If all else fails, I can re-write it to use sprites, I just thought this method would be faster.