Sliding Puzzle (CMS)

From The Official Visionaire Studio: Adventure Game Engine Wiki
Revision as of 22:38, 13 November 2014 by AFRLme (talk)
Name Type By
Sliding Puzzle (3x3) Definition AFRLme

This script is used to generate & control a randomized sliding puzzle consisting of a 3x3 grid. Visionaire Studio 4.1+ is required to run this script.

Instructions

1. Add the main script to the Visionaire Studio Script Editor & set the script as a definition script.
2a. First thing you should do is update the t[1] to t[9] tables with the correct x, y positions for where each tile should be placed (top left pixel).

 t[1] = { .. x = 96, y = 77

2b. Next you should define where each tile is allowed to slide to in the move section of each of the tables. See the diagram below for an explanation of how I determined which tiles can move where.

t[1] = { .. move = {2,4} -- grid position 1
t[2] = { .. move = {1,3,5} } -- grid position 2
t[3] = { .. move = {2,6} } -- grid position 3
t[4] = { .. move = {1,5,7} } -- grid position 4
t[5] = { .. move = {2,4,6,8} } -- grid position 5
t[6] = { .. move = {3,5,9} } -- grid position 6
t[7] = { .. move = {4,8} } -- grid position 7
t[8] = { .. move = {5,7,9} } -- grid position 8
t[9] = { .. move = {6,8} } -- grid position 9
Sliding puzzle grid.png

3. Next you need to edit the animation names inside of the n table. All names should be the same but with a prefix number on the end. Any changes you make here will have to be changed inside of the puzzleState function.

n = { "anim_p1", "anim_p2", "anim_p3", "anim_p4", "anim_p5", "anim_p6", "anim_p7", "anim_p8" }

4. To check if a tile slot is empty or whether tile can be moved you should create an execute a script action inside of a left click (immediate) action containing...

canMove(i) -- replace i with the tile slot number.

Main Script

--[[
Sliding Puzzle (3x3) [v1] (13/11/2014)
Written by AFRLme [Lee Clarke]
-- + --
alternatingfrequencies@hotmail.com | skype @ AFRLme
-- + --
This script is donation optional. In game credit is non-negotiable.
You are free to: ¹ use it in your game(s). ² modify the script.
Do not remove - or edit - this comment block.
--]]

-- * tables * --
local n, t = {}, {} -- empty tables (see below)

-- * function for randomly generating tile positions * --
function initPuzzle(c)
 -- + initialize the grid properties + --
 t[1] = { x = 96, y = 77, name = nil, move = {2,4} }
 t[2] = { x = 246, y = 77, name = nil, move = {1,3,5} }
 t[3] = { x = 396, y = 77, name = nil, move = {2,6} }
 t[4] = { x = 96, y = 187, name = nil, move = {1,5,7} }
 t[5] = { x = 246, y = 187, name = nil, move = {2,4,6,8} }
 t[6] = { x = 396, y = 187, name = nil, move = {3,5,9} }
 t[7] = { x = 96, y = 297, name = nil, move = {4,8} }
 t[8] = { x = 246, y = 297, name = nil, move = {5,7,9} }
 t[9] = { x = 396, y = 297, name = nil, move = {6,8} }
 -- + initialize the tile names (1-8) + --
 n = { "anim_p1", "anim_p2", "anim_p3", "anim_p4", "anim_p5", "anim_p6", "anim_p7", "anim_p8" }
 -- + loops which are used for randomly generating the tile order & names etc + --
 for i = 1, (#n * #n) do
  c = n[8]; table.remove(n, 8); table.insert( n, math.random(8), c ) -- shuffle the tile names
  if i == (#n * #n) then
   for b = 1, 8 do t[b].name = n[b] end -- update "t" table names with shuffled "n" table names
   for a = 1, 8 do startObjectTween(ActiveAnimations[ t[a].name ], VAnimationCurrentPosition, ActiveAnimations[ t[a].name ].AnimationCurrentPosition, {x = t[a].x, y = t[a].y}, 200, easeLinearOut) end
  end
 end
end

-- * function used to determine if player wins * --
function puzzleState(v)
 for i = 1, 8 do
  if t[i].name == "anim_p"..i then v = v + 1 end
  if i == 8 and v == 8 then Objects["obj_solved"]:to(1000, {ObjectVisibility = 100}, easeQuintOut); Conditions["puzzle_solved"].ConditionValue = true end
 end
end

-- * function for updating tile positions * --
function canMove(v)
  for i = 1, table.maxn(t[v]["move"]) do
   if t[ t[v]["move"][i] ].name == nil and Conditions["puzzle_solved"].ConditionValue == false then moveTile(v, t[v]["move"][i], 200, easeLinearOut); break end
  end
end

-- * function that is used to move the animation from one position to another with delay & easing * --
function moveTile(a, b, delay, easing)
 startObjectTween(ActiveAnimations[ t[a].name ], VAnimationCurrentPosition, ActiveAnimations[ t[a].name ].AnimationCurrentPosition, {x = t[b].x, y = t[b].y}, delay, easing)
 t[b].name = t[a].name; t[a].name = nil; puzzleState(0) -- update tile position names & check puzzle state
end

Resources

Name Description
sliding_puzzle.zip A working example of the script in action. Visionaire Studio 4.1+ required to run the included .ved file.