Tutorial: improved
This commit is contained in:
parent
15e86c7940
commit
e184552458
20
board.lua
20
board.lua
@ -1,7 +1,8 @@
|
|||||||
board=klass()
|
board=klass()
|
||||||
|
|
||||||
function board:init(watcher,ruleset)
|
function board:init(w)
|
||||||
self.watcher=watcher
|
local ruleset=w.ruleset
|
||||||
|
self.watcher=w
|
||||||
self.ruleset=ruleset
|
self.ruleset=ruleset
|
||||||
self.cursor=cursor:new(self)
|
self.cursor=cursor:new(self)
|
||||||
self.animator=animator:new()
|
self.animator=animator:new()
|
||||||
@ -44,9 +45,7 @@ function board:init(watcher,ruleset)
|
|||||||
return new.rank==lst.rank-1
|
return new.rank==lst.rank-1
|
||||||
end))
|
end))
|
||||||
|
|
||||||
local seed=seeds:choose(self.ruleset.pool)
|
self:deal(w.seed or seeds:choose(self.ruleset.pool))
|
||||||
printh("chosen seed: "..tostr(seed,2))
|
|
||||||
self:deal(watcher.seed or seeds:choose(self.ruleset.pool))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function board:deal(seed)
|
function board:deal(seed)
|
||||||
@ -70,13 +69,13 @@ function board:deal(seed)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function board:undo()
|
function board:undo()
|
||||||
if (self.checkpoint) self.checkpoint:apply(self) print("applied")
|
if (not self.watcher:intercept("undo")) return
|
||||||
|
if (self.checkpoint) self.checkpoint:apply(self)
|
||||||
self.checkpoint=nil
|
self.checkpoint=nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function board:on_idle()
|
function board:on_idle()
|
||||||
self:find_automove()
|
self:find_automove()
|
||||||
self.watcher:update(self)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function board:pre_move(card)
|
function board:pre_move(card)
|
||||||
@ -85,7 +84,6 @@ end
|
|||||||
|
|
||||||
function board:on_move()
|
function board:on_move()
|
||||||
self:find_automove()
|
self:find_automove()
|
||||||
self.watcher:update(self)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function board:is_won()
|
function board:is_won()
|
||||||
@ -166,7 +164,6 @@ function board:draw()
|
|||||||
local cpl=self.ruleset.layouts:checkpoint()
|
local cpl=self.ruleset.layouts:checkpoint()
|
||||||
local x,y=cpl:place_card(0)
|
local x,y=cpl:place_card(0)
|
||||||
self.ruleset.deck:draw_card(x,y,self.checkpoint.card,{shadowed=true})
|
self.ruleset.deck:draw_card(x,y,self.checkpoint.card,{shadowed=true})
|
||||||
print("❎",x+1,y+9,7)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self.animator:draw()
|
self.animator:draw()
|
||||||
@ -175,13 +172,12 @@ function board:draw()
|
|||||||
local hover_slot=self.cursor:hover_slot()
|
local hover_slot=self.cursor:hover_slot()
|
||||||
forall_slots(function(x,y,s_ix,s,l,n)
|
forall_slots(function(x,y,s_ix,s,l,n)
|
||||||
if hover_slot==s_ix then
|
if hover_slot==s_ix then
|
||||||
local x,y=l:place_card(n+1)
|
self.cursor:draw_at(l,n+1)
|
||||||
self.cursor:draw_at(l,x,y)
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
|
||||||
|
|
||||||
self.watcher:draw(self)
|
self.watcher:draw(self)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
slot=klass()
|
slot=klass()
|
||||||
|
41
cursor.lua
41
cursor.lua
@ -34,15 +34,19 @@ end
|
|||||||
|
|
||||||
function cursor:toggle_grab()
|
function cursor:toggle_grab()
|
||||||
local acc,src,tar=self:acceptance_state()
|
local acc,src,tar=self:acceptance_state()
|
||||||
|
local slot=self:hover_slot()
|
||||||
if acc==acceptance_state.not_grabbed then
|
if acc==acceptance_state.not_grabbed then
|
||||||
if (self.board.slots[self:hover_slot()]:peek()) self.grabbed=self:hover_slot()
|
if (not self.board.watcher:intercept("grab",slot)) printh("intercepted") return
|
||||||
|
if (self.board.slots[slot]:peek()) self.grabbed=slot
|
||||||
elseif acc==acceptance_state.would_accept then
|
elseif acc==acceptance_state.would_accept then
|
||||||
|
if (not self.board.watcher:intercept("drop",slot)) return
|
||||||
self.board:pre_move(src:peek())
|
self.board:pre_move(src:peek())
|
||||||
local card=src:pop()
|
local card=src:pop()
|
||||||
tar:add(card)
|
tar:add(card)
|
||||||
self.grabbed=nil
|
self.grabbed=nil
|
||||||
self.board:on_move(card)
|
self.board:on_move(card)
|
||||||
elseif acc==acceptance_state.no_move or acc==acceptance_state.would_not_accept then
|
elseif acc==acceptance_state.no_move or acc==acceptance_state.would_not_accept then
|
||||||
|
if (not self.board.watcher:intercept("cancel")) return
|
||||||
self.grabbed=nil
|
self.grabbed=nil
|
||||||
else
|
else
|
||||||
assert(false,"invalid acceptance state")
|
assert(false,"invalid acceptance state")
|
||||||
@ -73,42 +77,23 @@ function cursor:grabbed_card()
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function cursor:draw_at(l,x,y)
|
function cursor:draw_at(l,i)
|
||||||
local card=self:grabbed_card()
|
local card=self:grabbed_card()
|
||||||
local acc=self:acceptance_state()
|
local acc=self:acceptance_state()
|
||||||
|
|
||||||
|
local dx,dy=0,0
|
||||||
if card and acc!=acceptance_state.would_accept and acc!=acceptance_state.no_move then
|
if card and acc!=acceptance_state.would_accept and acc!=acceptance_state.no_move then
|
||||||
x+=sin(time()/2)*2+0.5
|
dx=flr(sin(time()/2)*2+0.5)
|
||||||
y+=sin(time()/4)+0.5+1
|
dy=flr(sin(time()/4)+0.5+1)
|
||||||
end
|
end
|
||||||
x=flr(x)
|
|
||||||
y=flr(y)
|
|
||||||
|
|
||||||
local function draw_surround_box(fg)
|
|
||||||
if (not fg) return
|
|
||||||
if l.rotated then
|
|
||||||
rect(x-4,y+6,x+13,y+16,fg)
|
|
||||||
else
|
|
||||||
rect(x-1,y-1,x+9,y+16,fg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function draw_overlapping_box(fg)
|
|
||||||
if (l.obscured) draw_surround_box(fg) return
|
|
||||||
if l.rotated then
|
|
||||||
rectfill(x-3,y+7,x+12,y+15,fg)
|
|
||||||
else
|
|
||||||
rectfill(x,y,x+8,y+15,fg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
if card then
|
if card then
|
||||||
local card_fg=self.ruleset.deck:draw_card(x,y,card,{rotate=l.rotated})
|
local x,y=l:place_card(i)
|
||||||
|
local card_fg=self.ruleset.deck:draw_card(x+dx,y+dy,card,{rotate=l.rotated})
|
||||||
local fg=card_fg
|
local fg=card_fg
|
||||||
if (acc==acceptance_state.would_accept) fg=9
|
if (acc==acceptance_state.would_accept) fg=9
|
||||||
draw_surround_box(fg)
|
draw_layout_hint(l,i,fg,false,dx,dy)
|
||||||
else
|
else
|
||||||
draw_overlapping_box(9)
|
draw_layout_hint(l,i,9,true,dx,dy)
|
||||||
end
|
end
|
||||||
end
|
end
|
21
layout_hint.lua
Normal file
21
layout_hint.lua
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
function draw_layout_hint(l,i,fg,filled,dx,dy)
|
||||||
|
-- layout, index
|
||||||
|
local x,y=l:place_card(i)
|
||||||
|
x+=dx
|
||||||
|
y+=dy
|
||||||
|
|
||||||
|
if (l.obscured) filled=false
|
||||||
|
if filled then
|
||||||
|
if l.rotated then
|
||||||
|
rectfill(x-3,y+7,x+12,y+15,fg)
|
||||||
|
else
|
||||||
|
rectfill(x,y,x+8,y+15,fg)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if l.rotated then
|
||||||
|
rect(x-4,y+6,x+13,y+16,fg)
|
||||||
|
else
|
||||||
|
rect(x-1,y-1,x+9,y+16,fg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
2
main.lua
2
main.lua
@ -4,7 +4,7 @@ add(modules,main)
|
|||||||
function main:init()
|
function main:init()
|
||||||
extcmd("rec")
|
extcmd("rec")
|
||||||
self.state_manager=state_manager:new() -- instantiate one global
|
self.state_manager=state_manager:new() -- instantiate one global
|
||||||
self.state_manager:push(state_ironman:new())
|
self.state_manager:push(state_ironman:new(tutorial))
|
||||||
end
|
end
|
||||||
|
|
||||||
function main:update()
|
function main:update()
|
||||||
|
4
main.p8
4
main.p8
@ -9,6 +9,7 @@ __lua__
|
|||||||
#include dealer.lua
|
#include dealer.lua
|
||||||
#include cursor.lua
|
#include cursor.lua
|
||||||
#include layout.lua
|
#include layout.lua
|
||||||
|
#include layout_hint.lua
|
||||||
#include ruleset.lua
|
#include ruleset.lua
|
||||||
#include progression.lua
|
#include progression.lua
|
||||||
#include seed_constants.lua
|
#include seed_constants.lua
|
||||||
@ -16,11 +17,10 @@ __lua__
|
|||||||
#include state_manager.lua
|
#include state_manager.lua
|
||||||
#include state_gameround.lua
|
#include state_gameround.lua
|
||||||
#include state_ironman.lua
|
#include state_ironman.lua
|
||||||
#include tutorial_watcher.lua
|
|
||||||
#include tutorial.lua
|
#include tutorial.lua
|
||||||
#include text.lua
|
#include text.lua
|
||||||
|
#include watcher.lua
|
||||||
#include main.lua
|
#include main.lua
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
srand(2)
|
srand(2)
|
||||||
for i=1,10 do
|
for i=1,10 do
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
state_ironman=klass()
|
state_ironman=klass()
|
||||||
function state_ironman:init()
|
function state_ironman:init(sequence)
|
||||||
|
self.sequence=sequence
|
||||||
self.level=1
|
self.level=1
|
||||||
self.tutorial_enabled=true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function state_ironman:enter() self:on_enter() end
|
function state_ironman:enter() self:on_enter() end
|
||||||
@ -14,11 +14,9 @@ function state_ironman:on_enter()
|
|||||||
self.done=true
|
self.done=true
|
||||||
local level=self.level
|
local level=self.level
|
||||||
self.level+=1
|
self.level+=1
|
||||||
if level <= #progression then
|
if level <= #self.sequence then
|
||||||
local watcher_fn=tutorial[level]
|
local w=self.sequence[level]()
|
||||||
local watcher=tutorial_watcher:new()
|
main.state_manager:push(state_gameround:new(w))
|
||||||
if (self.tutorial_enabled and watcher_fn) watcher=watcher_fn()
|
|
||||||
main.state_manager:push(state_gameround:new(watcher, progression[level]))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
42
tutorial.lua
42
tutorial.lua
@ -1,12 +1,36 @@
|
|||||||
tutorial={
|
tutorial={
|
||||||
[1]=function()
|
function()
|
||||||
return tutorial_watcher:new(10,{
|
return watcher:new(progression[1], 10,{
|
||||||
tutorial_stage:new(
|
tutorial_grab:new(1,4),
|
||||||
"slot",1,2,
|
tutorial_grab:new(5,1),
|
||||||
tutorial_move_slot(1,1),
|
tutorial_grab:new(4,3),
|
||||||
"stack on 5! (🅾️)",
|
tutorial_grab:new(2,4),
|
||||||
function(b) return b:can_take_input() end
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
end
|
end,
|
||||||
|
function()
|
||||||
|
return watcher:new(progression[2], 10,{
|
||||||
|
tutorial_grab:new(1,6),
|
||||||
|
tutorial_grab:new(1,2),
|
||||||
|
tutorial_grab:new(1,5),
|
||||||
|
tutorial_grab:new(1,5),
|
||||||
|
tutorial_grab:new(2,1),
|
||||||
|
tutorial_grab:new(2,1),
|
||||||
|
tutorial_grab:new(6,1),
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
function()
|
||||||
|
return watcher:new(progression[3],3,{
|
||||||
|
tutorial_grab:new(7,6),
|
||||||
|
tutorial_undo:new(),
|
||||||
|
tutorial_grab:new(6,7),
|
||||||
|
tutorial_grab:new(6,8),
|
||||||
|
tutorial_grab:new(2,6),
|
||||||
|
tutorial_grab:new(2,4),
|
||||||
|
tutorial_grab:new(3,1),
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
function() return watcher:new(progression[4]) end,
|
||||||
|
function() return watcher:new(progression[5]) end,
|
||||||
|
function() return watcher:new(progression[6]) end,
|
||||||
|
function() return watcher:new(progression[7]) end
|
||||||
}
|
}
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
tutorial_watcher=klass()
|
|
||||||
function tutorial_watcher:init(seed,stages)
|
|
||||||
self.seed=seed
|
|
||||||
self._stages=stages
|
|
||||||
end
|
|
||||||
function tutorial_watcher:update(board)
|
|
||||||
local stage=self._stages[1]
|
|
||||||
if (stage) stage:update(board)
|
|
||||||
end
|
|
||||||
function tutorial_watcher:active_stage(board)
|
|
||||||
local stage=self._stages[1]
|
|
||||||
if (stage and stage:active()) return stage
|
|
||||||
end
|
|
||||||
function tutorial_watcher:draw(board)
|
|
||||||
local stage=self:active_stage()
|
|
||||||
if (not stage) return
|
|
||||||
local layouts=board.ruleset.layouts
|
|
||||||
-- stop("calling: "..stage._layout_name)
|
|
||||||
local layout=layouts[stage._layout_name](layouts,stage._layout_arg)
|
|
||||||
local x,y=layout:place_card(stage._layout_arg_2)
|
|
||||||
|
|
||||||
local tx=stage._text
|
|
||||||
local w,h=measure_text(tx)
|
|
||||||
x+=4
|
|
||||||
x-=w\2
|
|
||||||
y+=25
|
|
||||||
local lx=x+w\2
|
|
||||||
line(lx,y-9,lx,y,15)
|
|
||||||
rectfill(x-2,y-2,x+w,y+h,1)
|
|
||||||
rect(x-2,y-2,x+w,y+h,15)
|
|
||||||
print(tx,x,y,15)
|
|
||||||
end
|
|
||||||
|
|
||||||
tutorial_stage=klass()
|
|
||||||
function tutorial_stage:init(layout_name,layout_arg,layout_arg_2,move,text,requirement_cb)
|
|
||||||
self._layout_name=layout_name
|
|
||||||
self._layout_arg=layout_arg
|
|
||||||
self._layout_arg_2=layout_arg_2
|
|
||||||
self._move=move
|
|
||||||
self._text=text
|
|
||||||
self._requirement_cb=requirement_cb
|
|
||||||
self._enabled=not self._requirement_cb
|
|
||||||
end
|
|
||||||
|
|
||||||
function tutorial_stage:update(board)
|
|
||||||
if (not self._enabled and self._requirement_cb(board)) self._enabled=true
|
|
||||||
end
|
|
||||||
|
|
||||||
function tutorial_stage:active()
|
|
||||||
return self._enabled
|
|
||||||
end
|
|
||||||
|
|
||||||
-- todo: restart?
|
|
||||||
function tutorial_move_undo()
|
|
||||||
return "undo"
|
|
||||||
end
|
|
||||||
function tutorial_move_slot(slot_src,slot_dst)
|
|
||||||
return tostr(slot_src).."->"..tostr(slot_dst)
|
|
||||||
end
|
|
85
watcher.lua
Normal file
85
watcher.lua
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
watcher=klass()
|
||||||
|
function watcher:init(ruleset,seed,stages)
|
||||||
|
self.ruleset=ruleset
|
||||||
|
self.seed=seed
|
||||||
|
self._stages=stages or {}
|
||||||
|
end
|
||||||
|
function watcher:active_stage(board)
|
||||||
|
local stage=self._stages[1]
|
||||||
|
if (stage and stage:active()) return stage
|
||||||
|
end
|
||||||
|
function watcher:intercept(x,arg)
|
||||||
|
local stage=self:active_stage()
|
||||||
|
if (not stage) return true
|
||||||
|
local allowed,drop=stage:intercept(x,arg)
|
||||||
|
if (drop) deli(self._stages,1)
|
||||||
|
return allowed
|
||||||
|
end
|
||||||
|
function watcher:draw(board)
|
||||||
|
local stage=self:active_stage()
|
||||||
|
if (not stage) return
|
||||||
|
|
||||||
|
local layouts=board.ruleset.layouts
|
||||||
|
local layout,i,x,y,text
|
||||||
|
layout,i,text=stage:draw(board,layouts)
|
||||||
|
|
||||||
|
x,y=layout:place_card(i)
|
||||||
|
local w,h=measure_text(text)
|
||||||
|
x+=1
|
||||||
|
y+=20
|
||||||
|
local lx=x+3
|
||||||
|
line(lx,y-4,lx,y,15)
|
||||||
|
rectfill(x-2,y-2,x+w,y+h,1)
|
||||||
|
rect(x-2,y-2,x+w,y+h,15)
|
||||||
|
print(text,x,y,15)
|
||||||
|
end
|
||||||
|
|
||||||
|
tutorial_grab=klass()
|
||||||
|
function tutorial_grab:init(src,dst)
|
||||||
|
self.src=src
|
||||||
|
self.dst=dst
|
||||||
|
end
|
||||||
|
|
||||||
|
function tutorial_grab:active()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function tutorial_grab:intercept(x, slot)
|
||||||
|
if (x=="grab" and slot==self.src) return true,false
|
||||||
|
if (x=="drop" and slot==self.dst) return true,true
|
||||||
|
end
|
||||||
|
function tutorial_grab:draw(board,layouts)
|
||||||
|
local layout,i,text
|
||||||
|
if board.cursor:acceptance_state() == acceptance_state.not_grabbed then
|
||||||
|
-- show a hint for grabbing
|
||||||
|
layout=layouts:slot(self.src)
|
||||||
|
i=#board.slots[self.src].contents
|
||||||
|
draw_layout_hint(layout,i,15,false,0,0)
|
||||||
|
text="🅾️"
|
||||||
|
else
|
||||||
|
layout=layouts:slot(self.dst)
|
||||||
|
i=#board.slots[self.dst].contents+1
|
||||||
|
draw_layout_hint(layout,i,15,false,0,0)
|
||||||
|
text="🅾️"
|
||||||
|
end
|
||||||
|
return layout,i,text
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
tutorial_undo=klass()
|
||||||
|
function tutorial_undo:init() end
|
||||||
|
function tutorial_undo:active()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
function tutorial_undo:intercept(x)
|
||||||
|
if (x=="undo") return true,true
|
||||||
|
end
|
||||||
|
function tutorial_undo:draw(board,layouts)
|
||||||
|
local layout,i,text
|
||||||
|
layout=layouts:checkpoint()
|
||||||
|
draw_layout_hint(layout,0,15,false,0,0)
|
||||||
|
text="❎"
|
||||||
|
return layout,i,text
|
||||||
|
end
|
||||||
|
|
||||||
|
-- todo: restart?
|
Loading…
Reference in New Issue
Block a user