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 - Max

#151
Development / Re: Bomb overlap assistance
July 21, 2018, 05:46:04 PM
Yeah, I wouldn't put this test in map:on_started() necessarily. Is this something that only happens in this map? If so, maybe having a timer check over and over works, but it might make more sense to run the check code whenever you place a bomb.

Either way, what I would do is run some code that checks to see if both entities bomb and test both exist before trying to disable one. Try the method map:has_entities(), and if you get nil back, don't do the code.

If map:has_entitiy("bomb_1") and bomb_1:overlaps(test) then
...
#152
General discussion / Re: Templates for Resources
July 21, 2018, 04:07:48 AM
Yeah, with this whatever tile you want can be anywhere. If you want a really poor organization system, you can go ahead and do that to yourself, lol : )
#153
General discussion / Re: Templates for Resources
July 20, 2018, 04:01:56 PM
As long as you're working with multiples of 8 (8, 16, 32, 128, 640, etc) when you build a tileset in the program, the engine will be fine. There are a couple restrictions, like diagonal wall tiles have to be square. That said, the engine right now expects the player sprite to be about 16x24, give or take a couple pixels, and items (pickups and stuff) all have to be 16x16.

Since you build each tileset yourself in the program, it doesn't matter where the tiles are in the set, or how large they are, since you'll be telling the engine that as you build.

You did see this tutorial, right?:
https://youtu.be/bC0IScIohjA
#154
If you learn best by doing, download maybe the Zelda resource pack or the open source one (not sure how complete that is) and try making something like the intro pre-dungeons that Zelda has (Link to the Past's sewers, for example). Get the code to someone else's game (if they're on this forum, they'll probably help you understand it for references so you can learn stuff like making doors that open when you kill enemies, how switches and timers work, etc.

That's how I'd start, at least. And any specific questions you have, just ask on here, somebody usually can help you pretty quickly. Welcome to the forum : D
#155
That worked! Thanks, Christopho. I'll post the code for anyone interested in an enemy that runs away from you, and/or teleports via explosions. The only problem is that they hardcore get stuck in corners, even sloped corners. I'll have to figure out a workaround for this. Maybe once I have him tossing bombs at the hero, the dodging you'd have to do to avoid damage would cause the hero to move in such a way that he wouldn't get stuck, but I don't know.

Code (lua) Select

local enemy = ...
local game = enemy:get_game()
local map = enemy:get_map()
local hero = map:get_hero()
local sprite
local teleporting = false
local can_teleport = true
local teleport_frequency = 10000

function enemy:on_created()
  sprite = enemy:create_sprite("enemies/" .. enemy:get_breed())
  enemy:set_life(100)
  enemy:set_damage(1)
  enemy:set_attack_consequence("explosion", "protected")
  enemy:set_hurt_style("boss")
end

function enemy:on_restarted()
  enemy:check_hero()
end

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

function enemy:check_hero()
  --teleport
  if enemy:get_distance(hero) < 75 and can_teleport == true then enemy:teleport() end --the boss teleports if you get too close

  if not teleporting then --teleporting has a movement and we don't want the movements to conflict
    local hero_angle = enemy:get_angle(hero) --gets angle toward hero
    local mov_angle = hero_angle + math.pi --the angle opposite of the hero
    enemy:stop_movement()
    local m = sol.movement.create("straight")
    m:set_angle(mov_angle)
    m:set_speed(80)
    m:set_max_distance(0)
    m:set_smooth(true)
    m:start(enemy)
  end
  sol.timer.start(enemy, 100, function() enemy:check_hero() end)
end

function enemy:teleport()
  enemy:set_attack_consequence("sword", "protected") --while he's preparing to teleport, he's invincible
  enemy:set_attack_consequence("arrow", "protected")
  teleporting = true
  can_teleport = false --we don't want him to teleport again right away
  sol.timer.start(map, teleport_frequency, function() can_teleport = true end) --when he can teleport again (in 10 seconds)
  enemy:stop_movement()
  sprite:set_animation("teleport_charge", function()
    local x, y, layer = enemy:get_position()
    map:create_explosion({ x = x, y = y, layer = layer})
    sol.audio.play_sound("explosion")
    sprite:set_animation("teleporting")
    local t = sol.movement.create("straight")
    local telang = enemy:get_angle(480, 240)
    t:set_angle(telang)
    t:set_speed(200)
    t:set_smooth()
    t:set_max_distance(180)
    t:start(enemy)
    sol.timer.start(enemy, 1500, function()
      x, y, layer = enemy:get_position()
      map:create_explosion({ x = x, y = y, layer = layer})
      sol.audio.play_sound("explosion")
      enemy:set_attack_consequence("sword", 1)
      enemy:set_attack_consequence("arrow", 1)
      sprite:set_animation("walking")
      enemy:check_hero()
      teleporting = false
    end) --end of after teleporting timer

  end) --end of after charging animation
end

#156
Zefk, I do the exact same thing. But you have to admit, it's not great to export the entire image, set up the animations, then have to re-export the image for every change. It'd be a lot easier to view animations in the app your animating in.
#157
I know there's a way to set up Photoshop for pixel art, you might try looking up if there are settings for that. I've seen enty of pixel art done in Photoshop.

But if you can't get that set up, you might try GIMP.  It's not the best tool for pixel art, especially animating, and it doesn't have the tools designed specifically for pixel art. But if you're familiar with Photoshop it should come naturally, many options are in the same places and the basic workflow is the same.

#158
Oh, duh! Thanks, I totally forgot about context. I'll try that as soon as I get home.
#159
So, I'm designing a boss who basically runs away from the hero, but I have a really weird problem. Every time he takes damage, he gets a bit slower until he stops moving altogether.

Here's the part of the script that controls his movement:

Code (lua) Select

function enemy:check_hero()
  --teleport
--  if enemy:get_distance(hero) < 75 and can_teleport == true then enemy:teleport() end --the boss teleports if you get too close

  if not teleporting then --teleporting has a movement and we don't want the movements to conflict
    local hero_angle = enemy:get_angle(hero) --gets angle toward hero
    local mov_angle = hero_angle + math.pi --the angle opposite of the hero
    enemy:stop_movement()
    local m = sol.movement.create("straight")
    m:set_angle(mov_angle)
    m:set_speed(80)
    m:set_max_distance(0)
    m:set_smooth(true)
    m:start(enemy)
  end
  sol.timer.start(100, function() enemy:check_hero() end)
end


I figure that has got to be that part of the script that's causing the slowdown, but I can post the whole thing at the bottom of this post. Anyway, anybody have any idea what might be causing this? In the mean time, I'm going to try using some movement other than straight and see if that helps things.

UPDATE: it does not help things. Here's what I changed the movement to:

Code (lua) Select

function enemy:check_hero()
  --teleport
--  if enemy:get_distance(hero) < 75 and can_teleport == true then enemy:teleport() end --the boss teleports if you get too close

  if not teleporting then --teleporting has a movement and we don't want the movements to conflict
    local dir_hero = enemy:get_direction8_to(hero)
    dir_hero = (dir_hero + 4) if dir_hero > 7 then dir_hero = dir_hero - 8 end
    enemy:stop_movement()
    local m = sol.movement.create("path")
    m:set_path({dir_hero})
    m:set_loop()
    m:set_speed(75)
    m:start(enemy)

  end
  sol.timer.start(100, function() enemy:check_hero() end)
end


This does not prevent him from slowing down, and it also makes him get stuck on like, any corner. The diagonal walls don't seem to work like I'd expect them to, pushing the enemy around. But his slowing down every time he takes damage is the main thing. This hasn't happened with any other enemy.



The whole script:
Code (lua) Select

local enemy = ...
local game = enemy:get_game()
local map = enemy:get_map()
local hero = map:get_hero()
local sprite
local teleporting = false
local can_teleport = true
local teleport_frequency = 10000

function enemy:on_created()
  sprite = enemy:create_sprite("enemies/" .. enemy:get_breed())
  enemy:set_life(100)
  enemy:set_damage(1)
  enemy:set_attack_consequence("explosion", "protected")
  enemy:set_hurt_style("boss")
end

function enemy:on_restarted()
  enemy:check_hero()
end

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

function enemy:check_hero()
  --teleport
--  if enemy:get_distance(hero) < 75 and can_teleport == true then enemy:teleport() end --the boss teleports if you get too close

  if not teleporting then --teleporting has a movement and we don't want the movements to conflict
    local hero_angle = enemy:get_angle(hero) --gets angle toward hero
    local mov_angle = hero_angle + math.pi --the angle opposite of the hero
    enemy:stop_movement()
    local m = sol.movement.create("straight")
    m:set_angle(mov_angle)
    m:set_speed(80)
    m:set_max_distance(1)
    m:set_smooth(true)
    m:start(enemy)
  end
  sol.timer.start(100, function() enemy:check_hero() end)
end

function enemy:teleport()
  enemy:set_attack_consequence("sword", "protected") --while he's preparing to teleport, he's invincible
  enemy:set_attack_consequence("arrow", "protected")
  teleporting = true
  can_teleport = false --we don't want him to teleport again right away
  sol.timer.start(teleport_frequency, function() can_teleport = true end) --when he can teleport again (in 10 seconds)
  enemy:stop_movement()
  sprite:set_animation("charging", function()
    local x, y, layer = enemy:get_position()
    map:create_explosion({ x = x, y = y, layer = layer})
    sol.audio.play_sound("explosion")
    sprite:set_animation("teleporting")
    local t = sol.movement.create("straight")
    local telang = enemy:get_angle(480, 240)
    t:set_angle(telang)
    t:set_speed(200)
    t:set_smooth()
    t:set_max_distance(180)
    t:start(enemy)
    sol.timer.start(1500, function()
      x, y, layer = enemy:get_position()
      map:create_explosion({ x = x, y = y, layer = layer})
      sol.audio.play_sound("explosion")
      enemy:set_attack_consequence("sword", 1)
      enemy:set_attack_consequence("arrow", 1)
      sprite:set_animation("walking")
      enemy:check_hero()
      teleporting = false
    end) --end of after teleporting timer

  end) --end of after charging animation
end
#160
So, don't credits normally scroll from the bottom to the top?
#161
Development / Re: [Solved]Timer problem
July 16, 2018, 06:19:19 AM
No problem! The syntax

For x in map:get_entities("prefix") do
X:function()
End

Is super useful for applying the same code to an arbitrary number of entities. Once I found out a out it, my life was made much easier, lol.
#162
Development / Re: Timer problem
July 16, 2018, 04:09:43 AM
You could try this syntax:

Local switches_on= 0

For switch in map:get_entities("solid") do
switch:on_activated()
Switches_on = switches on + 1
If switches_on >= 4 then
Switches_on = 0
Sol.timer.start(5000, function() deactivate_switches() end)
End
End
End

Local Function deactivate_switches()
For switch in map:get_entities("solid") do
Switch:set_activated(false)
End
End


I typed this on mobile so the capitalization is off and there's typos probably, but I think that'd work.
#163
I guess it would depend on how you set up your game, but Oracle really had very few of these per map, since each was just one screen. Even with larger maps, I don't imagine you'd be having more than a couple dozen per map tops. Especially if you did ice as a tileset thing like how I suggested water that dries up in summer. I mean, realistically, how many dynamic tiles do you need before any systems would start to struggle? 100?

Also, after further consideration, most dynamic tiles I was thinking could probably be normal tiles. Vines, for example, in the summer tileset you'd have vine tiles that were set as a ladder tile, and in the other tilesets you'd have a corrospondingly named tile that's just blank and empty. So the tile is still there (no errors when the tileset is switched), but it's just empty. Puddles could be done like this too, most aesthetic changes, you could have corrosponding empty tiles for snow banks, etc. Then there's even fewer dynamic tiles you'd need.

The reason I was thinking you wouldn't want multiple map.dat files is because wouldn't each season then he considered a new map, and therefore would respawn enemies, regrow cut bushes, reset pushed blocks, etc when the season changed?
#164
And now we're just hijacking this thread to discuss how you'd hypothetically do this, but Oracle of Seasons is probably my favorite Zelda game, haha.

The rod item I think could easily change the tileset, wouldn't you just do
Local game = item:get_game()
game:set_tileset(game:get_value(current_season )+ 1)
If current_season == 3 then current season = 0
Where you have a game value for the season and your tilesets are named accordingly. Then you'd set a new value for current_season. It'd be easiest if your seasons were just numbered.

Most of the seasonal changes could be dynamic tiles that the map:on_season_changed() function could set enabled/disabled. Ice, leaves, vines, snow, that could all be done with dynamic tiles. Water getting shallow in summer could be the same, but honestly I'd have a special type of "summer shallow" water in the tilesets set to deep water in 3 of them and shallow water for the summer set, so it'd work automatically. Same with bushy trees you can only squeeze past in winter.

There's a few elements like those bouncy flowers that bloom in spring that'd need to be custom entities. But things like those rock mushrooms that are pickable in fall could be destructables, you'd just stack the pickable and the stuck on top of each other and set the pickable disabled 3 seasons and set it enabled in fall, reverse for the non-pickable version.

Then I'm sure there's plenty of ideas that Capcom didn't even think of. Difficult to traverse mud in spring, or slopes you couldn't climb because of mud, a river that floods in the spring and the nearby forest is in a floodplain, so it'd all be shallow water. Maybe fires might start during the summer, or maybe you'd need to bring autumn rains to put one out. A rainy season, especially if you had a particular area of the world that got spring or autumn rains so it wouldn't be global, but in that area there'd be mudslides, puddles, flooded rivers, fires would be put out, rapids would develop, plants would grow big.

Certain enemies could only appear in certain seasons, or be in different parts of their life cycles. Maybe there's a grub enemy that's easy to fight in spring, but by autumn it's matured into a dangerous beetle. Winter might kill off some enemies or cause them to hibernate. Maybe there's a bear like a Snorlax that won't wake up and get out of your path until spring. Maybe theres a forest full of wolves, but they're just a few here and there, but in winter they're only in their den and there's a bunch right together.

Then there's a ton of small environmental touches that Oracle of Seasons couldn't do because of the gameboy's processing power. Fireflies in the summer, falling leaves in the autumn, snow effects in the winter. A random weather system would pair well, and the probabilities of weather would change with each season, so it's unlikely to rain during the summer, but if it does it's a big thunderstorm.

I've thought a lot about this kind of system because Oracle of Seasons is probably my favorite Zelda game, but I've never acted much on it because I've been hesitant to just steal an idea so wholesale like that. But I also think Capcom could have gone much further- for example, why didn't they ever use the season mechanic in dungeons? The puzzle density and different player expectations for dungeons would have paired fantastically, I think.

There's some overall design decisions to make too- I think having the player explore much more of the overworld before they can change the seasons at all would be better, to develop seasonal mechanics and how they work before the player messes with them, so that way the player can form their own solutions based on previous experiences. So instead of, I can't cross this river, but I can cause either winter or summer so I'll see which helps, instead of that it'd be, I can't cross this river but I remember encountering a frozen river earlier, or I remember a dry stream bed from earlier, maybe I can make that happen. Give the player a reason to be more intentional with which season they choose- equipping each season independently would reinforce this, so they'd choose "I want to bring summer" instead of, "let's try a different season." This could be a setup like A Link to the Past, where you have to travel the majority of the world to go through a couple dungeons to even get the main mechanic.

Capcom was smart about only letting the player change the season at certain spots though, because that automatically prevents a lot of tricky situations where you'd suddenly be stuck in a snow bank, I would personally keep that.

Maybe I'll work on it someday. In the mean time, anyone who tries this system in their own game has my full support.
#165
Your projects / Re: Ocean's Heart
July 14, 2018, 07:46:39 PM
Still working away on this, even if I haven't posted here about it in a couple months. I didn't get a ton done in the second half of june / first half of july because I was moving and between packing, unpacking, setting everything up, etc. I've been otherwise occupied, but I'm back into development now.

I thought I'd post a couple updates here. The mini-boss of one of the later dungeons is done and I'm pretty happy with him, he's based on the 12th century engineer Al-Jazari, who is a cool dude. Here's a video on youtube of me (unskillfully) fighting him:
Fight!

I also have been posting more frequent updates to twitter, in case anyone wants to follow me there:
Max's Twitter

I think as far as the major stuff goes, I'm over the main hump and the end is in sight! Sometime in 2019 I bet this will be releasing.