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

Topics - The Pink Bunny

#1
Development / Path Movement behaving weirdly
April 17, 2019, 12:41:39 AM
I have a soldier enemy which does a path movement and a target movement. For some reason, any time the path movement is stopped (when the target movement happens, or when I stop it manually), it seems to still be happening in the background. Once whatever movement or animation controlling the entity is finished, the entity rapidly follows all of the path movements that would have happened during that time.

I have been trying to debug this for hours, and I am absolutely stumped why this is happening, or how to stop it. Can anyone help?
#2
Development / Pre-made LttP Maps?
January 29, 2019, 12:37:50 AM
Does anyone know where I can find maps from A Link to the Past already made in Solarus? I'm working on a little LttP fan game, just for myself to teach myself coding and such, and that involves recreating all the maps myself. It's kind of tedious work, and I'm sure someone's done it before, at least for the overworlds. I couldn't find anywhere on the forums, so I figured I'd ask!
#3
I'm trying to make a soldier enemy like ALttP, and I'm having some trouble getting it to walk right. The way I have it, the enemy does a "looking" animation (2 frames, 500ms frame delay, no loop), then begins a path movement and goes into a walking animation. But for some reason, after the "looking" animation ends, the sprite teleports a couple of tiles away and continues with the path movement. After looking at the console while it's happening, it appears that the path movement is happening during the 2 frame "looking" animation, but not displaying on either the game window or the console until the "looking" animation completes, then continuing with the path movement as if it had begun moving at the start of the "looking" animation. I don't know if this explanation is clear, but hopefully it's at least replicable.

I've tried writing it in every way I could think of, but they all either do what's described above, or do nothing after the "looking" animation as if I never told it to start the movement. Below is my current attempt (using a timer instead of defining a callback in sprite:set_animation() ), which does what is described in the first paragraph:

Code ( lua) Select

-- move, sprite, paths, and the functions are declared above this in the full code

function pathset()

local dir = sprite:get_direction()

move:set_path(paths[dir])
sprite:set_animation("walking")
move:start(soldier)

end


function look_around()

sprite:set_animation("looking")
sol.timer.start(1000, pathset)

end


function soldier:on_restarted()

look_around()

end



And here is another format of look_around() I've tried which does nothing at all on completing the animation:

Code ( lua) Select

function look_around()

sprite:set_animation("looking", pathset)

end


I'm not sure what I could be doing wrong. Like I said, I've tried a bunch of different formats for this process, but I've deleted most of them out of frustration (probably a bad idea). The full enemies/soldier.lua is attached along with the sprite i'm using for it if anyone wants to try to replicate the error.
#4
Can movements only be applied to one entity at a time? I'm trying to have two entities make the same movement a bit delayed from each other, but when the second movement starts, the first just stops. I know I can fix that by just making another movement, but that seems like strange behavior to me. Is that intentional?

edit: Since this question is more trivial than practical (and I don't want to start two threads in a row), I'll also ask this here: Is there a difference between 'entity:on_obstacle_reached(movement)' and 'movement:on_obstacle_reached()' ?
#5
Development / Error message with hud (solved)
June 21, 2016, 11:15:17 PM
I have a simple hud that I made to display health as hearts and magic as a number. It was working just fine until I made some change to a file that was NOT the hud script, and now it displays this error message whenever I start the game:

QuoteError: Failed to load script 'menus/hud': [string "menus/hud.lua"]:1: '=' expected

Which sounds like the script is missing an equals sign in line 1, except it is definitely there and I don't know what the problem is. Below is menus/hud.lua . I thought it was a simple syntax error, so I didn't want to bring it to the forum, but I have tried everything I can think of and I've got nothing. My game runs just fine if I comment out all references to hud.lua in my game manager (also down below).

Thanks for the help, and if it IS a stupid syntax error, sorry for wasting your time.

Code ( lua) Select
local hudmenu = {}

function hudmenu:create(game)  -- the game is passed as an input to the function so it can be used

local hud = {}
local hudsurface = sol.surface.create(256,224)
local hearts = 1
local heart = {}
local health = 0
local fullhearts = 0
local halfheart = 0
local magic = 0
local maxmag = 0
local magbar
local magbarbg
local magsize = 0
local jaricon
local jars = 0
local jartext
local decicon
local decs = 0
local dectext

sol.menu.start(game, hudmenu)

sol.timer.start(100, function()  -- runs health calculationsn 10x/sec instead of every frame
hearts = game:get_max_life()/4

for h = 1,hearts do
heart[h] = sol.sprite.create("hud/lifebar")
heart[h]:set_frame_delay(nil)
end

health = game:get_life()
fullhearts = math.floor(health/4)

for h = 1,fullhearts do
heart[h]:set_frame(0)
end

halfheart = 0   -- it's actually just binary "is there a half heart or not", but I need it to be able to do math

if health-fullhearts*4 == 1 or health-fullhearts*4 == 2 then
heart[fullhearts+1]:set_frame(1)
halfheart = 1
end

for h = fullhearts+halfheart+1,hearts do
heart[h]:set_frame(2)
end

magic = game:get_magic()
maxmag = game:get_max_magic()
magbarbg = sol.sprite.create("hud/magic_meter_bg")
magsize = math.floor(magic/max*34)

if magsize == 0 and magic > 0 then
magsize = 1
end

if magic == 0 then
magbar = sol.surface.create(10,34)
magbar:fill_color({0,0,0,0})
else
magbar = sol.surface.create(10,magsize)
magbar:fill_color({32,192,40})
end

jars = game:get_item("magic_jar_storage"):get_amount()
jartext = sol.text_surface.create({font = "8_bit", text = jars,})
decs = game:get_item("magic_dec_storage"):get_amount()
dectext = sol.text_surface.create({font = "8_bit", text = decs,})

return true
end)

jaricon = sol.sprite.create("entities/items")
jaricon:set_animation("drops/magic_jar")
decicon = sol.sprite.create("entities/items")
decicon:set_animation("drops/magic_jar")
decicon:set_direction(1)

function hudmenu:on_draw(hudsurface)

for h = 1,hearts do
heart[h]:draw(hudsurface, 21+(h-1)*8, 5)
end

magbarbg:draw(hudsurface, 5, 5)
magbar:draw(hudsurface, 8, 9+34-magsize)

jaricon:draw(hudsurface, 60, 10)
jartext:draw(hudsurface, 56, 18)

decicon:draw(hudsurface, 72, 10)
dectext:draw(hudsurface, 68, 18)

end

function hud:quit()
if sol.menu.is_started(hud) then
  sol.menu.stop(hud)
end
end

return hud

end

return hudmenu


Code ( lua) Select
-- Script that creates a game ready to be played.

-- Usage:
-- local game_manager = require("scripts/game_manager")
-- local game = game_manager:create("savegame_file_name")
-- game:start()

local dialog_box_manager = require("scripts/dialog_box")
local hudmenu = require("menus/hud")
local inventory = require("menus/inventory")


local game_manager = {}

-- Sets initial values for a new savegame of this quest.
local function initialize_new_savegame(game)
  game:set_starting_location("Hyrule Castle/dungeon")
  game:set_max_money(100)  -- default is 0
  game:set_max_life(12)
  game:set_life(game:get_max_life())
  game:set_max_magic(100)
  game:set_magic(100)
 
  item_cooldown = false
 
end

function item_cooldown_timer()
sol.timer.start(500, function()
item_cooldown = false
end)
end

-- Creates a game ready to be played.
function game_manager:create(file)

  -- Create the game (but do not start it).
  local exists = sol.game.exists(file)
  local game = sol.game.load(file)
  if not exists then
    -- This is a new savegame file.
    initialize_new_savegame(game)
  end

  local dialog_box
  local hud

  -- Function called when the player runs this game.
  function game:on_started()
hud = hudmenu:create(game)
    dialog_box = dialog_box_manager:create(game)

--game:set_command_joypad_binding("item_1", "button 1")
--game:set_command_joypad_binding("attack", nil)
--game:set_command_joypad_binding("pause", "button 7")
  end

  -- Function called when the game stops.
  function game:on_finished()

    dialog_box:quit()
    dialog_box = nil
hud:quit()
  end

  function game:on_paused()
inventory:open(game)
  end
 
  function game:on_unpaused()
sol.menu.stop(inventory)
  end

  local rupee_icon = sol.surface.create("entities/miscellaneous.png")
  local rupee_text = sol.text_surface.create()
  rupee_text:set_font("8_bit")                   -- these three things are all set outside of the function so that they aren't redefined every frame (bad)

local magic_num = sol.text_surface.create()
magic_num:set_font("8_bit")
local life_num = sol.text_surface.create()
life_num:set_font("8_bit")

  function game:on_draw(dst_surface) --function is called every time game is redrawn (same as framerate)

--rupee_icon:draw_region(0, 16, 8, 8, dst_surface, 5, 5) -- reference Solarus documentation
--rupee_text:set_text(game:get_money())
--rupee_text:draw(dst_surface, 14, 8)
--[[
magic_num:set_text(game:get_magic())
magic_num:draw(dst_surface, 16, 16)

life_num:set_text(game:get_life())
life_num:draw(dst_surface, 16, 8)
--]]
  end
 
 
  function game:on_joypad_button_pressed(butt)
--[[
iBuffalo Classic USB Gamepad button guide:
SNES button - index (default command mapping)
A - 0 ("action")
B - 1 ("attack")
X - 2 ("item_1")
Y - 3 ("item_2")
L - 4 ("pause")
R - 5
select - 6
start - 7

For mysterious and currently unknown reasons, the controller only works the first time
you start the quest from the editor. After that, it doesn't even register anything
happening. Also, the editor keeps crashing, but I don't know if that's related.
Actually, maybe it is, because it crashes every third time I close the game window.
--]]

if butt == 5 then
game:get_item("magic_jar_storage"):on_using()
end
if butt == 4 then
game:get_item("magic_dec_storage"):on_using()
end
if butt == 6 then
print("save menu to be implemented later")
end
  end

  function game:on_key_pressed(key)

if key == "f" then
game:get_item("magic_jar_storage"):on_using()
end

if key == "g" then
game:get_item("magic_dec_storage"):on_using()
end

  end
 
  return game
 
end

return game_manager
#6
Development / Custom Commands?
April 12, 2016, 06:30:42 PM
Is it possible to add a command to the list of game commands? (like "action","item_1","pause", etc.) I know I can just use game:on_key_pressed() or main:on_key_pressed(), but I want to be able to create a new command that works with things like game:set_command_keyboard_binding(). It would be great if I could look at the actual game object code to figure it out, but I can't find it in the data files or documentation.
#7
I'm programming an item that is a short range fire spell that creates a few custom entities right in front of the hero. I currently have each of them created in a separate function local to the item so that I can create each of them sequentially. Right now I just have each of them take the hero, map, and game as input for things like where to be and not to be created if it's on a wall tile. I'm wondering if it would be faster for the computer to take the hero's position in on_using() and use that as the input, or does that really matter for something like this?

Edit: I realize that there's a lot of things in here that I could probably optimize better, but would it really affect performance?

Code ( lua) Select
function flamethrower:on_using()

if not item_cooldown then

local map = self:get_map()
local hero = map:get_entity("hero")
local game = self:get_game()
local flame_base
local flame_mid = {}
local flame_end = {}
item_cooldown = true

flame_base = flamethrower_base(map, hero, game)
flame_mid = flamethrower_mid(map, hero, game, flame_base)
flame_end = flamethrower_end(map, hero, game, flame_mid)

end

flamethrower:set_finished()

end


And the flamethrower_base function:
Code ( lua) Select
local function flamethrower_base(map, hero, game)

local x,y,layer = hero:get_position()    -- these two lines happen in each of the three functions. Should I do it differently?
local dir = hero:get_direction()

if dir == 0 then
x = x + 12
elseif dir == 1 then
y = y - 12
elseif dir == 2 then
x = x - 12
elseif dir == 3 then
y = y + 12
else
print("Error in flamethrower.lua; flamethrower_base(): direction is not integer 0 to 3")
end


flame_base = map:create_custom_entity{ 
name = "flame base",
x = x,
y = y,
width = 8,
height = 8,
layer = layer,
direction = dir,
sprite = "entities/flame_base",
}

flame_base:set_origin(4,4)

local xb, yb, layerb = flame_base:get_position()

if map:get_position(xb, yb, layerb) == "wall" then
flame_base:remove()
base_exists = false
end

flame_base:add_collision_test("overlapping", function(entity, other)

if other:get_type() == "enemy" then
other:hurt(1)
end
end)

return flame_base

end


(also, is there a hotkey to break an infinite loop while the game is running? I keep doing that to myself)
#8
Development / ALttP fireball graphics problem
March 16, 2016, 06:10:45 AM
So, I'm trying to make an item that lets you shoot fireballs (like the ones Zoras shoot), and I'm having some trouble making the animated tail part. What I'm doing is when you use the item, a custom entity that is the actual projectile ("firehead") moves straight in the direction you're facing, and every 150ms as it goes, a second stationary custom entity ("firetail") is being created which is a single 3 frame sprite of the shrinking circle so it looks just like in A Link to the Past. The idea is that each firetail entity is destroyed after its 3 frames finish playing, but I am having trouble getting that to happen. Here's the relevant bit of code:

Code ( lua) Select

sol.timer.start(map, 150, function()
t = t+1
xt,yt,layert = projectiles[p]:get_position()  -- creating it wherever the projectile currently is
firetail[t] = map:create_custom_entity{
name = "firetail",
x = xt,
y = yt,
width = 8,
height = 8,
layer = layert,
direction = 0,
sprite = "entities/firetail"  -- three frame sprite of the circle shrinking
}

-- this is what I tried last, but sprite and firet keep getting redefined to new firetails
--    before the animation finishes because t gets incremented too quickly, especially
                        --    if you use the item again
local sprite = firetail[t]:get_sprite()
local firet = firetail[t]
function game:on_draw()
if sprite:get_frame()==2 then
firet:remove()
end
end

--[[  --This one destroyed some of the entities before the animation finished playing
sol.timer.start(map,150,function()
for entities in map:get_entities("firetail") do
entities:remove()
end
end)
--]]

--[[ --This one also couldn't keep t in phase
sol.timer.start(map, 150, function()
print(t)  -- for debugging
local firet = firetail[t]
firet:remove()
end)
--]]

while projectiles[p]:exists() do
return true
end
end)


I've tried doing it by indexing each firetail entity from a table and by using map:get_entities(), but I either end up with flashing firetail sprites not getting removed and hanging around on the map, or removing firetail sprites before they finish animating. If you know a solution or that I am going about this entirely wrong, please let me know. I attached the full item script and the sprites I'm using if you want to see it yourself.