Tutorial: improved
This commit is contained in:
parent
15e86c7940
commit
e184552458
20
board.lua
20
board.lua
@ -1,7 +1,8 @@
|
||||
board=klass()
|
||||
|
||||
function board:init(watcher,ruleset)
|
||||
self.watcher=watcher
|
||||
function board:init(w)
|
||||
local ruleset=w.ruleset
|
||||
self.watcher=w
|
||||
self.ruleset=ruleset
|
||||
self.cursor=cursor:new(self)
|
||||
self.animator=animator:new()
|
||||
@ -44,9 +45,7 @@ function board:init(watcher,ruleset)
|
||||
return new.rank==lst.rank-1
|
||||
end))
|
||||
|
||||
local seed=seeds:choose(self.ruleset.pool)
|
||||
printh("chosen seed: "..tostr(seed,2))
|
||||
self:deal(watcher.seed or seeds:choose(self.ruleset.pool))
|
||||
self:deal(w.seed or seeds:choose(self.ruleset.pool))
|
||||
end
|
||||
|
||||
function board:deal(seed)
|
||||
@ -70,13 +69,13 @@ function board:deal(seed)
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
function board:on_idle()
|
||||
self:find_automove()
|
||||
self.watcher:update(self)
|
||||
end
|
||||
|
||||
function board:pre_move(card)
|
||||
@ -85,7 +84,6 @@ end
|
||||
|
||||
function board:on_move()
|
||||
self:find_automove()
|
||||
self.watcher:update(self)
|
||||
end
|
||||
|
||||
function board:is_won()
|
||||
@ -166,7 +164,6 @@ function board:draw()
|
||||
local cpl=self.ruleset.layouts:checkpoint()
|
||||
local x,y=cpl:place_card(0)
|
||||
self.ruleset.deck:draw_card(x,y,self.checkpoint.card,{shadowed=true})
|
||||
print("❎",x+1,y+9,7)
|
||||
end
|
||||
|
||||
self.animator:draw()
|
||||
@ -175,13 +172,12 @@ function board:draw()
|
||||
local hover_slot=self.cursor:hover_slot()
|
||||
forall_slots(function(x,y,s_ix,s,l,n)
|
||||
if hover_slot==s_ix then
|
||||
local x,y=l:place_card(n+1)
|
||||
self.cursor:draw_at(l,x,y)
|
||||
self.cursor:draw_at(l,n+1)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
self.watcher:draw(self)
|
||||
end
|
||||
end
|
||||
|
||||
slot=klass()
|
||||
|
41
cursor.lua
41
cursor.lua
@ -34,15 +34,19 @@ end
|
||||
|
||||
function cursor:toggle_grab()
|
||||
local acc,src,tar=self:acceptance_state()
|
||||
local slot=self:hover_slot()
|
||||
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
|
||||
if (not self.board.watcher:intercept("drop",slot)) return
|
||||
self.board:pre_move(src:peek())
|
||||
local card=src:pop()
|
||||
tar:add(card)
|
||||
self.grabbed=nil
|
||||
self.board:on_move(card)
|
||||
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
|
||||
else
|
||||
assert(false,"invalid acceptance state")
|
||||
@ -73,42 +77,23 @@ function cursor:grabbed_card()
|
||||
return nil
|
||||
end
|
||||
|
||||
function cursor:draw_at(l,x,y)
|
||||
function cursor:draw_at(l,i)
|
||||
local card=self:grabbed_card()
|
||||
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
|
||||
x+=sin(time()/2)*2+0.5
|
||||
y+=sin(time()/4)+0.5+1
|
||||
dx=flr(sin(time()/2)*2+0.5)
|
||||
dy=flr(sin(time()/4)+0.5+1)
|
||||
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
|
||||
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
|
||||
if (acc==acceptance_state.would_accept) fg=9
|
||||
draw_surround_box(fg)
|
||||
draw_layout_hint(l,i,fg,false,dx,dy)
|
||||
else
|
||||
draw_overlapping_box(9)
|
||||
draw_layout_hint(l,i,9,true,dx,dy)
|
||||
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()
|
||||
extcmd("rec")
|
||||
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
|
||||
|
||||
function main:update()
|
||||
|
4
main.p8
4
main.p8
@ -9,6 +9,7 @@ __lua__
|
||||
#include dealer.lua
|
||||
#include cursor.lua
|
||||
#include layout.lua
|
||||
#include layout_hint.lua
|
||||
#include ruleset.lua
|
||||
#include progression.lua
|
||||
#include seed_constants.lua
|
||||
@ -16,11 +17,10 @@ __lua__
|
||||
#include state_manager.lua
|
||||
#include state_gameround.lua
|
||||
#include state_ironman.lua
|
||||
#include tutorial_watcher.lua
|
||||
#include tutorial.lua
|
||||
#include text.lua
|
||||
#include watcher.lua
|
||||
#include main.lua
|
||||
|
||||
--[[
|
||||
srand(2)
|
||||
for i=1,10 do
|
||||
|
@ -1,7 +1,7 @@
|
||||
state_ironman=klass()
|
||||
function state_ironman:init()
|
||||
function state_ironman:init(sequence)
|
||||
self.sequence=sequence
|
||||
self.level=1
|
||||
self.tutorial_enabled=true
|
||||
end
|
||||
|
||||
function state_ironman:enter() self:on_enter() end
|
||||
@ -14,11 +14,9 @@ function state_ironman:on_enter()
|
||||
self.done=true
|
||||
local level=self.level
|
||||
self.level+=1
|
||||
if level <= #progression then
|
||||
local watcher_fn=tutorial[level]
|
||||
local watcher=tutorial_watcher:new()
|
||||
if (self.tutorial_enabled and watcher_fn) watcher=watcher_fn()
|
||||
main.state_manager:push(state_gameround:new(watcher, progression[level]))
|
||||
if level <= #self.sequence then
|
||||
local w=self.sequence[level]()
|
||||
main.state_manager:push(state_gameround:new(w))
|
||||
end
|
||||
end
|
||||
|
||||
|
42
tutorial.lua
42
tutorial.lua
@ -1,12 +1,36 @@
|
||||
tutorial={
|
||||
[1]=function()
|
||||
return tutorial_watcher:new(10,{
|
||||
tutorial_stage:new(
|
||||
"slot",1,2,
|
||||
tutorial_move_slot(1,1),
|
||||
"stack on 5! (🅾️)",
|
||||
function(b) return b:can_take_input() end
|
||||
)
|
||||
function()
|
||||
return watcher:new(progression[1], 10,{
|
||||
tutorial_grab:new(1,4),
|
||||
tutorial_grab:new(5,1),
|
||||
tutorial_grab:new(4,3),
|
||||
tutorial_grab:new(2,4),
|
||||
})
|
||||
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