Christopho, your idea worked! I believe I got the basics working, if anyone would like to use it.
game_manager.lua (gravity and jumping):
local game_manager = {}
local map_metatable = sol.main.get_metatable("map")
local gravity = 2
local jump_height = 8
local jumping = false
local i = 0
function game_manager:start_game()
local exists = sol.game.exists("save1.dat")
local game = sol.game.load("save1.dat")
if not exists then
-- Initialize a new savegame.
game:set_max_life(1)
game:set_life(game:get_max_life())
end
game:start()
function game:on_command_pressed(command)
if command == "up" and not jumping then
-- override default behaviour and make the hero jump up!
jumping = true
i = 0
end
end
end
function map_metatable:on_update()
-- gravity: move entities down one pixel on every update if there's no collision
-- (like with the ground or a platform)
local x,y,l = self:get_game():get_hero():get_position()
if not jumping then
if not self:get_game():get_hero():test_obstacles(0,gravity) then
self:get_game():get_hero():set_position(x,y+gravity,l)
end
else
self:get_game():get_hero():set_animation("jumping")
for i=1, jump_height do
if not self:get_game():get_hero():test_obstacles(0,-1) then
self:get_game():get_hero():set_position(x,(y-1),l)
end
end
sol.timer.start(50*jump_height, function()
jumping = false
if self:get_game():is_command_pressed("right") or self:get_game():is_command_pressed("left") then
self:get_game():get_hero():set_animation("walking")
else
self:get_game():get_hero():set_animation("stopped")
end
end)
end
for entity in self:get_entities("g_") do
local gx,gy,gl = entity:get_position()
if not entity:test_obstacles(0,gravity) then
entity:set_position(gx,gy+gravity,gl)
end
end
end
return game_manager
monster.lua (example of a goomba-like enemy that you jump on to kill):
local enemy = ...
local state = "stopped" -- "stopped", "moving", "going_back" or "paused".
local initial_xy = {}
local activation_distance = 24
function enemy:on_created()
self:set_life(1)
self:set_damage(2)
self:create_sprite("enemies/monster")
self:set_size(32, 32)
self:set_origin(16, 29)
initial_xy.x, initial_xy.y = self:get_position()
end
function enemy:on_update()
local hero = self:get_map():get_entity("hero")
if state == "stopped" and self:get_distance(hero) <= 192 then
-- Check whether the hero is close.
local x, y = self:get_position()
local hero_x, hero_y = hero:get_position()
local dx, dy = hero_x - x, hero_y - y
if math.abs(dy) < activation_distance then
if dx > 0 then
self:go(0)
else
self:go(2)
end
end
if state == "stopped" and math.abs(dx) < activation_distance then
if dy > 0 then
self:go(3)
else
self:go(1)
end
end
end
end
function enemy:go(direction4)
local dxy = {
{ x = 8, y = 0},
{ x = 0, y = -8},
{ x = -8, y = 0},
{ x = 0, y = 8}
}
-- Check that we can make the move.
local index = direction4 + 1
if not self:test_obstacles(dxy[index].x * 2, dxy[index].y * 2) then
state = "moving"
self:get_sprite():set_animation("walking")
local x, y = self:get_position()
local angle = direction4 * math.pi / 2
local m = sol.movement.create("straight")
m:set_speed(40)
m:set_angle(angle)
m:set_max_distance(104)
m:set_smooth(false)
m:start(self)
end
end
function enemy:on_obstacle_reached()
self:go_back()
end
function enemy:on_movement_finished()
self:go_back()
end
function enemy:on_collision_enemy(other_enemy, other_sprite, my_sprite)
if other_enemy:get_breed() == self:get_breed() and state == "moving" then
self:go_back()
end
end
function enemy:on_attacking_hero(hero, enemy_sprite)
-- If hero is above the enemy (jumping on its head), kill it; otherwise, hurt the hero
if self:get_angle(hero) >= 0.8 and self:get_angle(hero) <= 2.2 then
self:remove_life(2)
else
hero:start_hurt(self, 1)
end
end
function enemy:go_back()
if state == "moving" then
state = "going_back"
self:get_sprite():set_animation("walking")
local m = sol.movement.create("target")
m:set_speed(32)
m:set_target(initial_xy.x, initial_xy.y)
m:set_smooth(false)
m:start(self)
elseif state == "going_back" then
state = "paused"
self:get_sprite():set_animation("immobilized")
sol.timer.start(self, 500, function() self:unpause() end)
end
end
function enemy:unpause()
self:get_sprite():set_animation("immobilized")
state = "stopped"
end