Creating puzzle games on Puzzle Script

Original author: stuartspixelgames
  • Transfer
Puzzle Script is a minimalistic game engine for creating puzzles for HTML5, it has open sources. Examples of ready-made games can be found here .

Part 1. We create the first game on Puzzle Script.


Puzzle Script is a free online program that is used to create puzzle games. She is best known for creating block-puzzles like my The Nodus . In this part we will create a game, having studied the basic functions of Puzzle Script, and in the next we will begin programming.


Go to the engine website . Click Make a Game to open the Puzzle Script editor .

Downloading Examples


To get started, let's look at a few examples. At the top of the screen, open the “Load Example” list and select the first example called “Basic”. Now click on "Run".



The game screen will appear. Click inside its window and press Enter on the keyboard.


Try to play the game. Your goal is to push the orange boxes to the black target squares. When there is a box on each target, the level will be passed. You can press Z to cancel the move, or R to restart the level.

Make the first game


Now we will create several levels. I will create one together with you, and I advise others to come up with my own. Click on “Level Editor” in the top menu.


If you do not see the level editor screen, then click “Run” and start the game. Once at the level, again click on the “Level Editor” button. This will allow you to edit the level at which you were just.

Create a new level


At the top are the game objects. When left-clicking, the selected object is drawn. Right click draws a "background" object. Left-clicking on the edge of the map increases its size, right-clicking reduces it.


To pass a level, you need to put a box on each of the goals, so at each level there should be a minimum:

  • 1 box
  • 1 goal
  • 1 player

Right-click to turn everything into grass. Then left-click on the edge of the level to make it bigger, and finally draw a level that looks like the one shown below.


Add it to the list of levels.


Having finished creating the level, we will add it to the list of levels. In the level editor, click on the white letter S next to the list of game objects to save the created level.


A message about successful compilation and a grid of funny characters should be displayed below the level editor, as shown below.


These funny characters indicate the level we just created. Each character represents a separate object. On the left side of the screen, go down and find LEGEND. The legend provides an explanation of each of the characters:

. = Background
# = Wall
P = Player
* = Crate
@ = Crate and Target
O = Target

All that is on the left side of the screen is the game code, divided into different parts, such as OBJECTS or LEGEND. Go down to LEVELS. Here we see the levels that are used in the example.


To add a new level, create a new empty line at the bottom of the level section. Then copy the characters generated for our level and paste them there. All level added.


We will test it. After creating a new level, you need to press the “Run” button at the top of the screen again to restart the game with a new level. Sometimes this does not work, and then you need to click the "Rebuild" button, and then click "Run" again.

Saving and loading a game


Try to create some more new levels. When you’re ready to save the game, go up to the beginning of the code and enter your own name, author’s name and home page, and then click on the “Save” button.



A limited number of saves are stored in the “Load” menu on your computer. However, there is a “Share” button at the top of the screen. When you click on it, a message with two web links is generated.


One of the links is the source code of your project. The second is a link to a playable version of the game that you can share with friends. I recommend periodically creating a new link to the source code and saving it in a text document so that you have a permanently stored version of the project.

Game Export


You can also export the game as an html5 file, which you can then upload to game portals, such as itch.io , Kongregate, or Newgrounds . Just click “Export” and upload the downloaded html file to the game portal.

Our sample project can be found here .

Part 2. Getting Started in Puzzle Script


In this part, we will learn how to start programming in Puzzle Script .


The code


Open a sample project . The program code is on the left side of the screen, it is divided into parts: Objects, Legend, Sounds, etc. In the Rules section, rules for the interaction of objects are set. Go into it. There should be only one line of code:

[ > Player | Crate ] -> [ > Player | > Crate ]

This line means that if the player is near the box and moves in his direction, the game moves the player and pushes the box. To explain how this works, you need to understand that the Puzzle Script code follows this structure:

[ Условие ] -> [ Событие ]

This means the following:

[ Если это условие выполняется ] -> тогда [ Делать это ]

Puzzle Script checks the conditions to the left of the arrow, for example, whether the player’s object is next to the box object. If the condition is true, then we do something, for example, push the box.

Examples of conditions


Here is an example of a condition:

[ object1 | object2 ]

This event checks if object1 is next to object2. You can check whether two objects are next to each other by placing between them прямую | линию, introduced by pressing shift + \. Terms are always enclosed in квадратные [ ] скобки.

[ crate | crate ]

The above code checks to see if two boxes are next to each other.

[ crate | crate | crate ]

This condition checks if three boxes are nearby.

[ crate target ]

This condition checks if the box is on top of the target because прямой | линииthere are no objects between the two. Objects can be on top of each other if they are located in different layers of collisions, which we will cover in the following parts of the tutorial.

We keep equality


The rules must be balanced. Both the condition check and the event following it should be described in the same way. I will show what that means.

[ player | crate ] -> [ player | ]

This line of code destroys the box if the player is next to it. You can not write:

[ player | crate ] -> [ player ]

because the condition on the left checks for the presence of neighboring objects in two separate grid spaces, but the event describes only one grid space that the player occupies. Puzzle Script needs to know what to do with the spaces it checks. The correct code to destroy the box should report the following:

[ Если игрок | рядом с ящиком ] -> тогда [ игрок не делает ничего | ящик удаляется ]

[ player | crate ] -> [ player | ]

That is, even empty spaces in the code matter. However, the following entry is valid:

[ player target ] -> [ player ]

Since in the condition we are talking only about one grid space, the event describes the same grid space.

How to move boxes


Let's go back to the original line of code.

[ > Player | Crate ] -> [ > Player | > Crate ]

In other words:

[ Если игрок двигается к ящику | и находится рядом с ящиком ] -> тогда [ переместить игрока | толкнуть ящик ]

Arrow> emphasizes movement.

Sometimes we need to write comments to remember what the code does. Puzzle Script ignores comments - they are for the user only. To write a comment, you need to put the text in brackets. We write a comment over our rule that describes what it does:

(Игрок толкает ящик)
[ > Player | Crate ] -> [ > Player | > Crate ]

Now, under the box push code, write the following:

(Игрок тащит ящик)
[ < Player | Crate ] -> [ < Player | < Crate ]

The inverted arrow means that if the player moves away from the box, he pulls the box. Click “Run” to test this action. You should be able to push and drag boxes. In programming, even with a typo in one letter, the computer may not understand the code, so get rid of all errors. When making changes to the code, click “Run” again to download the changes. If the game does not behave as it should, try clicking on “Rebuild” to clear the program’s memory, and then click “Run”.

Sometimes it is necessary to deactivate a line of code. Just turn it into a comment to save for the future. Let's comment out the code for pushing boxes, so that the player can only carry boxes:

(Игрок толкает ящик)
([ > Player | Crate ] -> [ > Player | > Crate ])
(Игрок тащит ящик)
[ < Player | Crate ] -> [ < Player | < Crate ]

If this worked, then comment out the code for pulling the boxes and try the following:

[ < Player | Crate ] -> [ < Player | > Crate ]

If the player moves away from the box, the player and the box will move in opposite directions. The arrows determine in which direction the object is either moving or will move. Now comment out this and try the following:

[ > Player | Crate ] -> [ Player | > Crate ]

The box moves, but the player remains in place. Experiment with ^ and v (letter v) to see how the objects will move.

Mistakes


Let's intentionally write the wrong rule and see what happens. Enter the following line:

[ < Player | Crate ] -> [ < Player ]

Try to run the program. You should see a message like this:

line 81: In a rule, each pattern to match on the left must have a corresponding pattern on the right of equal length (number of cells).

Usually Puzzle Script describes the error very well. However, sometimes Puzzle Script is mistaken by itself. In such cases, you need to go through the code yourself and figure out where the error is.

Some more experiments


Try experimenting and write the rules yourself. Here are some examples.

[ > Player | … | Crate ] -> [ > Player | … | > Crate ]

In the example above, the player will push the box if they are anywhere on the same line of the level, and the player moves to the box.

[ > Player | Crate ] -> [ Crate | Player ]

This code swaps the player and the box.

[ > Player | Crate ] -> [ Player | Target ]

In this code, if the player is near the box and moves towards it, the player will stop moving, but the box will turn into a target. The best thing about Puzzle Script is the ease of creating new things and the possibility of experimentation.

Part 3. Creating objects


All graphic fragments in games on Puzzle Script indicate objects. To create games on Puzzle Script, you must create your own objects. In this part I will tell you how to create them and add them to my code.


General information


Open a sample project . The process of creating an object consists of the following steps:

  • Create it in the list of objects
  • Adding an item to a legend
  • Adding Collisions to a Layer

Having done all these steps, you can start using the object.

Object Creation


Several objects already exist. Each game must have a background object. All objects are created from a 5 x 5 pixel grid and have at least one color. The background object is shown below.

Background
LIGHTGREEN GREEN
11111
01111
11101
11111
10111

Numbers indicate pixels in the image. Each number corresponds to its color. The first color has the number 0, the second - 1, and so on up to 9. There can be up to ten colors. In our case, each 1 colors the pixel in light green (Light Green), and 0 - in green (Green). The result looks like this:


Objects are always created as follows:

  • Title
  • Colors
  • Picture

The name is always on the top line. Colors are always on the second line, and the image takes the next 5 lines, 5 characters per line, which forms a 5 x 5 grid. Or you can do the following:

Background
LIGHTGREEN

This code will create an object called “Background”, which will be a 5 x 5 pixel grid in light green. If you do not describe the image grid, then we get a block of solid color, which can sometimes be useful.

Give names to objects


Objects can be called as you like, but the name cannot begin with a symbol and it must be a single word without spaces. Give the objects clear names, but don't go too far. PlayerStill is a good name, PlayerThatIsStandingStill is too long and verbose.

Colors


You must declare the colors that you want to use for the object and separate them with a space. Puzzle Script has predefined colors:

  • black
  • white
  • gray
  • darkgrey
  • lightgrey
  • gray
  • darkgray
  • lightgray
  • red
  • darkred
  • lightred
  • brown
  • darkbrown
  • lightbrown
  • orange
  • yellow
  • green
  • darkgreen
  • lightgreen
  • blue
  • lightblue
  • darkblue
  • purple
  • pink
  • transparent

You can also set colors in hexadecimal, which gives us a much wider range of colors. You can use websites such as this to select hexadecimal colors . Select the color you want, and then rewrite the color code above the image. Hexadecimal color codes are written in Puzzle Script as follows:

Название
#51A2BD #ff0000 #ffffff

The color code is always preceded by the # character.

Add an object to the legend


After creating the object, you need to add it to the legend. The legend looks like this:

. = Background
# = Wall
P = Player
* = Crate
@ = Crate and Target
O = Target

Each symbol represents an object in a level. That is, when we see such a grid of characters:

#p.*.##
#.**.##
#..#..#
##....#
##...o#
#######

it actually describes our level:


Each created object must be assigned a letter, symbol or number that designates this object at the level. Like this:

P = player

Group objects in the legend


We can also create groups of objects in the legend. For example, if we have several multi-colored boxes, then we can do this:

O = OrangeCrate
B = BlueCrate
G = GreenCrate

That will allow us to use boxes in the editor level. But to create the code, you can group them together in Legend, like this:

Crates = OrangeCrate or GreenCrate or BlueCrate

And all together it will look like this:

=======
LEGEND
=======
O = OrangeCrate
B = BlueCrate
G = GreenCrate

Crates = OrangeCrate or GreenCrate or BlueCrate

Why do this? Because then instead of creating such rules:

[ > Player | OrangeCrate ] -> [ > Player | > OrangeCrate ]
[ > Player | BlueCrate] -> [ > Player | > BlueCrate ]
[ > Player | GreenCrate] -> [ > Player | > GreenCrate]

you can simply write:

[ > Player | Crates ] -> [ > Player | > Crates ]

And this code will work for the whole group of objects.

In addition, in the Collision Layers section, you can refer to the layer in which the group is located, rather than entering each individual object.

Collision layers


By default, the collision layer section is as follows:

Background
Target
Player, Wall, Crate

Each line selects objects in its own layer. The order of the layers of objects determines which objects will be on top of others. The objects in the top line will be on the bottom layer, the next line will be in the layer above it, and so on. The background should always be on the top line to be on the bottom layer. Objects in one layer cannot be on top of each other. That is, this cannot be:

[ player wall ] -> [ player wall ]

You can make objects in different layers interact with each other. For example, you can write:

[ > Player | Target ] -> [ > Player | > Target ]

Experiment


Create some new objects. Create a type of boxes that you can only push. Create another box that can only be dragged. Create a box that disappears when you touch it. Continuing the experiments, you will better remember how everything is done.

Part 4. Victory conditions


Everyone loves to win. We, as players, want to win. In this part, we will learn how to program the conditions for winning a game.

Victory conditions


Download the sample project and go to the Win Conditions code section. You should see the following:

All Target on Crate

The game is won if there is a box on each goal. If you have 3 boxes and 2 goals, then you win by setting only 2 boxes on the goals. If swapping:

All crate on target

then each box will have to be on target.

There can be one or several conditions. In the case of multiple conditions, they must all be satisfied. For example, we may have the following:

All Target on Crate
All Target2 on Crate2

If the level has target and target2, then crate and crate2, respectively. If at the level there is not one of the objects necessary to fulfill a certain victory condition, for example, there is no target2, then this condition is satisfied automatically.

Different types of victory conditions


There are several different types of victory conditions.

No Object

In this case, victory comes when there is not one such object at the level.

Some Object

You win when there is at least one object of the specified type on the level.

Some Object1 on Object2

At least one of Object1's objects must be on Object2.

No Object1 On Object2

This condition is the opposite All Target on Crate. In this case, we need all of these objects to be separate from each other, and not on top of each other. You can also combine different victory conditions with each other.

Experiment


We will experiment with different conditions of victory. Try to create a game in which the win occurs if all the boxes are not on target. Or make a game in which you need to destroy all the boxes of a certain type, but there are other pushed boxes in your way.

My completed example project can be viewed here .

Part 5. late command


PuzzleScript has a very useful command called "late." The order of origin of events in the game is important, and sometimes you need a code that is executed later to get the desired results. In this part I will talk about using the late command .

Why do we need it


Open an example project , then paste the following code into the game and run it:

[ player | target ] -> [ player | ]

It can be expected that as soon as the player stands next to the goal, the goal will be destroyed, but this does not happen. Instead, the target disappears in the course after the player stands next to it. So try another code:

late [ player | target ] -> [ player | ]

As soon as you stand next to the goal, it will disappear. It happened because everything designated as late happens after all the rest of the code is executed. Sometimes this is necessary.

Order of events


Here's how the code in Puzzle Script executes with every move.

  1. Puzzle Script discovers that the player wants to move
  2. Whenever possible, rules are read and executed from top to bottom.
  3. Player moves if possible
  4. Late rules apply

The computer starts from the top line of code and reads down, line by line. checking every condition. So when you try to move around, Puzzle Script reads all the rules and checks to see if the conditions are true, and if so, it does something. For example, the first line could be like this:

[ player | spikeTrap ] -> [ | spikeTrap ]

If the player is not standing next to the stake trap, the code continues execution. This means that the order of writing lines of code is important. You can use the late command in some cases, which you will learn over time in practice.

Ways to use Late in practice


In my experience, it is best to use the late command when you are checking to see if objects are on top of each other or next to each other, but there are other cases. If you check if one object is on another, then the event will not be registered until the next turn, unless you use the late command:

[ player spikeTrap ] -> [ spikeTrap ]

In the above case, the player will not be killed by a trap with stakes until the next turn after moving into the trap. To make the player die instantly, just add the late command,

late [ player spikeTrap ] -> [ spikeTrap ]

To restart the entire level when the character dies, you can do the following:

late [ player spikeTrap ] -> restart

And the level will restart when the player falls into the trap with stakes.

You can see the finished project example here .

Part 6. Work with sound effects.


We made a great game on Puzzle Script , but now we need to add sounds to it. How to do it? Now I will tell you!

Sound generation


Open a sample project . Add sounds to it. Under the game screen, you can see black squares with white symbols. They are used to generate sound. Each character generates a unique type of sound, and a cross deletes the created sounds. Try clicking on the squares and listen to the sounds.


Yellow numbers are unique codes that need to be copied and pasted into places in the code where sounds are needed.

How to use sounds


Once you find the right sound, you must insert it into the Sounds section of the game code.


Sounds can be used in several ways. The easiest is to create a new sound effect (sfx). They must be numbered. We create a new sfx, assigning it a number from 0 to 10 when inserting a numeric sound ID. In the Sounds list, create a new sfx called sfx0 and assign it the generated sound:

sfx0 36301705

To use sound, you need to insert it into the rules after the event. Let's attach the newly created sfx0 to the box destruction event (the event is already present in the project example):

(The player destroys a crate)
[ > Player | CrateVanish ] -> [ Player | ] sfx0

Sounds can also be declared for playback with certain events, for example:

Crate MOVE 36772507

In this case, the sound will play when you move the Crate. Generate a new sound effect for dragging and dropping CratePull objects and make it play when you move CratePull:

CratePull MOVE 12735307

Sounds of events should be declared only in the Sounds section: they do not need to be mentioned in the rules.

List of sound reproduction methods


Below is a list of the various event sounds that you can use, taken from the Puzzle Script documentation .

Object Action 541566 - plays when an object is exposed to an action during a move.

Object Create 641667 - plays when creating a specific object.

EndGame 5416789 - plays when the game ends.

EndLevel 6417822 - plays after the completion of the level.

Object CantMove 781673 - plays when an object tried unsuccessfully to move in any direction.

Player CantMove Down Left 464674 - plays when an object unsuccessfully tried to move down or left.

CloseMessage 344456- is played when the player closes the message box.

Object Destroy 187975 - plays when an object is destroyed.

Object Move 264567 - plays when an object successfully moves in any direction.

Object Move Down Left 765432 - plays when the object has successfully moved down or left.

Object Move Horizontal 345367 - plays when the object has successfully moved horizontally. You can also use Vertical.

Restart 7865435 - plays when the player presses the restart button R.

SFX0 765743 - can be anything from SFX0 to SFX10. These are special sound events that can be performed from the rules.

ShowMessage 478483- plays when a message is displayed.

StartGame 234626 - plays at the beginning of a new game.

Startlevel 765436 - plays at the beginning of each level.

TitleScreen 876543 - plays after loading the screen saver.

Undo 436234 - plays when a player presses the cancel key (Z).

You can specify directions for move and cantmove so that when moving in different directions, different sounds are reproduced.

A finished example of the project is here .

Part 7. Play music


We learned how to create games on Puzzle Script, but wouldn’t it be great to add music to them? It is possible, and now I will tell you how to do it.

Note: it seems that at the moment this function in Puzzle Script is broken, so go on to the next part.

What do we have to do


Open the project blank . Music works in Puzzle Script as follows: you can insert a link to a single video from Youtube into the game. PuzzleScript will automatically play all the sounds of this video. Open Youtube and select any video, or use the following:

youtube.com/watch?v=CKAc3nYEatw

To play music from a video, we need to get a unique video ID. The green part in the line above is a unique ID.


Under the author’s homepage at the beginning of the project, add the youtube tag, and after it a unique video ID, for example,

youtube CKAc3nYEatw

To make sure that it works correctly, click on “Share” and click on the game link (not the source code link). During testing inside the editor, Puzzle Script music cannot be played. If you want the game to have music, you need to upload it as a video on Youtube and insert a unique ID into your project. Each project can have only one Youtube video.

Project example


An example Puzzle Script project can be found here .

Part 8. How to use the Action command


We already know how to move, push and drag blocks, but what if we need to do something by pressing a certain key, such as a space ?

The input possibilities in PuzzleScript are quite limited, mainly arrow keys, Z to cancel, R to restart, and we cannot change them. But the engine gives us an additional key for action - pressing the space bar or the X key .

Working with the Action team follows the format described above. We used the basic PuzzleScript code format:

[ Условие ] -> [ Событие ]

If the condition is true, then we execute the event. The action command is used in the same way, but it has its own rules. It looks like this:

[ Action дополнительные условия ] -> [ Событие ]

Here is an example of using the Action command:

[ ActionPlayer ] -> [ Crate ]

First, Action is always the first word of a condition.

Secondly, if we want to influence a certain object in the game, then we need to mention this object both in the condition and in the event (if we mention another object, the program will delete the original one and replace it with a new object, and if you do not specify the object, then he will just retire).

Finally, the word Action should be used only in the condition , but sometimes it is worth using it in both the condition and the event. I will talk about this below.

Check the code shown above in the game project. You can start with this example . You will see that when you press the space bar or X, the player becomes a box.

The condition reports [If we press the Action key and there is a Player object on the level ] -> then [ replace the player object with a box]

Now, let's try the following code in the project example:

[ Action Player | Crate ] -> [ Player | > Crate ]



Make sure that you are surrounded on all sides by boxes, as in the image above. You will notice that an action only affects one box at a time. I don’t know exactly what the reason is, but if you want to influence several objects using the Action command , you need to specify it both in the condition and in the event.

Replace the code with the updated version:

[ Action Player | Crate ] -> [ Action Player | > Crate ]


Now we can push all the boxes at once. If you need to apply an action to several objects, then put Action in both the condition and the event.

Part 9. Checking multiple conditions


Let's learn to check several conditions, for example, the presence of a bomb AND destructible block.


Open a sample project . Now add the following code to it:

late [Player Switch][DoorClosed] -> [Player Switch][DoorOpen]

The code follows this format:

[ Условие 1 ] [ Условие 2 ] -> [ Действие 1 ] [ Действие 2 ]

If condition 1 is true and condition 2 is true, then step 1 and step 2 are executed. In our case, in condition 1, it is checked whether the Player is on Switch. If yes, then condition 2 is checked, that is, the presence at the level of a closed door? If the condition is true, then the DoorClosed object turns into a DoorOpen object, opening the door.


Suppose we need the door to close when the hero leaves the switch, because we want the player to push the box to the switch to open the door. You can write something like this:

late [Player | Switch][DoorOpen] -> [Player | Switch][DoorClosed]

If the player is standing next to the switch and somewhere on the level there is an open door, then we close the door. Finally, we need the door to remain open if we push the box onto the switch:

late [Crate Switch][DoorClosed] -> [Crate Switch][DoorOpen]

Now the door will remain open while the drawer is on the switch.

You can see the finished project example here .

Part 10. Creating breakpoints


Perhaps you have a good idea for playing Puzzle Script, but it needs control points (checkpoints) so that the player recovers on them in case of death. How to do it? Pretty simple, and now I will explain how.


Create breakpoints


Open a sample project . Now we need to program a breakpoint. Just one line of code is enough for this:

late [ Player FlagRed ] -> CHECKPOINT

FlagRed is a checkpoint. When the player is on top of the flag, this code creates a checkpoint (CHECKPOINT). If you do not use late, then the checkpoint function will not work.

Test the game. Go over the control point, and then a little further and press R. You will need to start from the control point.

Multiple Control Points


If there are several control points, the game uses the last activated by the player.

To avoid reactivating an already used control point, you need to change it to another object. To do this, create a white copy in the OBJECTS section of the code under the red flag.

FlagWhite
White Orange
.1…
.00..
.000.
.1…
.1…

Now rewrite this line in the legend:

Flag = FlagRed or FlagWhite

We can create a group of objects. In this case, Flag will be either FlagRed or FlagWhite. While at least one of the grouped objects is assigned a symbol (we assigned FlagRed a symbol F), we will not need to assign symbols to other objects of the group, and you can only access them in the code, but not in the level editor. Then you can assign collision layers to the group, which we did. An access to a group of objects, for example, Flag, refers to the entire group. Therefore:

[ > Player | Flag ] -> [ > Player | ]

This code will affect both the red and the white flag.

Change flag object


Here's how to change FlagRed to FlagWhite:

late [ Player FlagRed ] -> [ Player FlagWhite ]

If at the end of the turn the player is on the red flag, then we turn it into white. However, you need to make the flag graphics change after you create the breakpoint, because the code is read from top to bottom. Test the program.

Change the second flag


There are two flags in the project. Let's make sure that when the second flag is activated, the old white flag turns into black so that it cannot be used again. We write the following:

late [ Player FlagRed ][ FlagWhite] -> [ Player FlagRed ][FlagBlack]

The code says: if the player is on the red flag and somewhere in the game there are white flags, then you need to make the white flags black. Since the code is read from top to bottom, we need to do this in the following order:

late [ Player FlagRed ] -> CHECKPOINT
late [ Player FlagRed ][ FlagWhite] -> [ Player FlagRed ][FlagBlack]
late [ Player FlagRed ] -> [ Player FlagWhite ]

If you do not understand why the code should be in this order, then try changing the order of the lines and test the program. To solve your own problems, you need to learn to take a step back and ponder what the code does. But I will give you a hint - when you play, where are the red flags during the last line of code in the following incorrect example?

[ > Player | Crate ] -> [ > Player | > Crate ]
[ > Crate | Flag ] -> [ Crate | Flag ]
late [ Player FlagRed ] -> CHECKPOINT
late [ Player FlagRed ] -> [ Player FlagWhite ]
late [ Player FlagRed ][ FlagWhite] -> [ Player FlagRed ][FlagBlack]

View the finished example project here . In addition, I just showed you the easiest way to animate. In the next part I will talk about creating more complex animations, such as explosions.

Part 11. Animations


There are two ways to create animations in PuzzleScript. One of them uses real time, but in this part I will not talk about it. Another is used for quick one-time animations, such as an explosion or a character descending a vertical ladder.

Open a sample project . We will create a bomb and a series of shots of the explosion, and then animate them.

Object animation


For 2D animations, you need several drawings of an object moving from one state to another, for example, a sprite of a running Mario. It contains 4 frames of animation.


To simulate the transition of one frame of animation to another, we will create several objects in PuzzleScript that will be frames of animation, and then use the code to switch between them.

Bomb


Create such a bomb object.

Bomb
black yellow grey
..1..
..1..
.000.
00020
.000.

Remember to add it to the layers and to the legend.

To animate the explosion, we need to create each frame of the animation as a separate object, and then switch between them in the code. Let's create explosion objects.

Explosion1
black yellow grey red
..1..
..1..
.000.
00320
.000.

Explosion2
black yellow grey red
..1..
..1..
.333.
03330
.333.

Explosion3
black yellow grey red
..1..
.333.
33333
33333
.333.

Explosion4
black yellow grey red
.333.
33333
33333
33333
.333.

Explosion5
black yellow grey red
.333.
33333
33.33
33333
.333.

Explosion6
black yellow grey red
.333.
3...3
3...3
3...3
.333.

Explosion7
black yellow grey red
.....
.....
.....
.....
.....

It will correctly number the objects in order to know which frame of the animation we need. After adding them to the layers and to the legend, we can add several lines of code.

[Explosion7] -> []
[Explosion6] -> [Explosion7]
[Explosion5] -> [Explosion6]
[Explosion4] -> [Explosion5]
[Explosion3] -> [Explosion4]
[Explosion2] -> [Explosion3]
[Explosion1] -> [Explosion2]
[Bomb] -> [Explosion1]

Try adding this code, and then place a bomb at the level and start the game. You will notice that with each movement, the bomb animation changes by one frame. Switching between objects, we create an animation.

The order of switching between animations is critical. The last frame should be on top, and the first - at the bottom. Do not forget that the code is read from top to bottom. If the frames of the animation are in a different order, then we will never see the changes. We will see only the last frame, and in our case the bomb will simply disappear. It will change to the first frame, then to the second and so on, in one frame, even before you see the graphic. By placing the last frame at the beginning, in each turn we will see the next change.

Using Again


To animate everything together, we need a team again . Again means that after reading all the code, PuzzleScript will pause, and then it will read the code again by running all the commands again . It can be used for gravity, sliding on ice, and in our case, for animations. All that is needed is to rewrite the code as follows:

[Explosion7] -> []
[Explosion6] -> [Explosion7] again
[Explosion5] -> [Explosion6] again
[Explosion4] -> [Explosion5] again
[Explosion3] -> [Explosion4] again
[Explosion2] -> [Explosion3] again
[Explosion1] -> [Explosion2] again
[Bomb] -> [Explosion1] again

Test the game. You will see that the entire bomb animation is played immediately. If in your opinion it is too slow or fast, then the speed can be changed. At the very beginning of the program text, under the homepage write the following code:

again_interval 0.1

This is part of what PuzzleScript calls prelude . This is the place where, before the rest of the code, you can set additional rules that determine the behavior of the game. Now the animation should play faster. Try changing the number after again_interval and check that it has changed.

You can see the finished project example here .

Part 12. Gravity


Usually PuzzleScript is used to create games with a top down, but in fact you can simulate some elements of side scrollers, albeit with limited PuzzleScript rules, that is, they will still be step-by-step. In this part I will tell you how to implement gravity.

Project example


Open a sample project . I created a simple level, it has a player, a box on the ledge and a door below. We want to make sure that when a player pushes a box from a ledge, he falls to the ground. We also want the player to fall to the ground when he leaves the edge.

Fall Stage 1


Here is the first part of the code that we will use:

down [ Player | no Object ] -> [ | Player ]
down [ Crate | no Object no Player ] -> [ | Crate ]

Try to push the box from the edge. You will notice that after moving the box hangs in the air, but after another move it falls to the ground. Here a few things happen.

First, let's talk about the down keyword . By adding down , we limit the rule to the fact that it applies only in the down direction. That is why the box moves down. If you replace down with right , you will see that the box is stuck in the right wall, as in the game with anti-gravity. Try to do so.

Next, we will do something unusual. Instead of checking whether the player is next to a specific object (for example, a box), we check whether he is next to a generalized object. If you look at the legend in the example code, you will see that we have defined object as a group of objects, that is, with each use of the word object, we mean a group of objects. That is, we check if there are any of these objects under the player. If not, we order the player to occupy this empty space and leave the previous space, because of the word down, following in a downward direction.

But you can also notice that after colliding with a ledge, the box does not fall until the next move, and that it instantly reaches the ground. To eliminate this delayed crash, you can use the late keyword:

late down [ Player | no Object ] -> [ | Player ]
late down [ Crate | no Object no Player ] -> [ | Crate ]

But how to make it fall gradually, frame by frame?

Fall Stage 2


Now we use the random keyword . We rewrite the code as follows:

random down [ Player | no Object ] -> [ | Player ]
random down [ Crate | no Object no Player ] -> [ | Crate ]

Run the code. It works very similar to the previous code, but with one important difference. The box freezes in the air, but each time the player moves, it falls down one cell. This is due to the word random . Strictly speaking, random is designed to create games with random elements, but it came in handy here. It forces the corresponding line of code to be executed once per turn. PuzzleScript executes each rule in one move as many times as possible, and only then the player sees graphic changes. That is why it seems that the box falls to the ground instantly. But when using the word random, we allow it to fall only one cell at a time.

Fall Stage 3


Now we will add the keyword again :

random down [ Player | no Object ] -> [ | Player ] again
random down [ Crate | no Object no Player ] -> [ | Crate ] again

Launch the game. Everything is almost perfect. The box freezes for some time in the air, but if you move again, it gradually falls to the ground. We are already familiar with the keyword again , in essence, it means that at the end of the turn, PuzzleScript reads the code again and tries to execute all the commands again as a separate move, after which it pauses, then repeats them again as many times as it can. The important thing here is that he pauses between turns again , which allows us to see the box fall.

Final stage


And the final touch. In order for the box to fall to the ground immediately after being pushed from the edge, we need to add another line of code above the one we just wrote:

[moving Player] -> [moving Player] again
random down [ Player | no Object ] -> [ | Player ] again
random down [ Crate | no Object no Player ] -> [ | Crate ] again

The moving keyword used in square brackets [] in front of player means we are checking to see if the player is moving. This means that if a player moves, then we order him to continue moving and run the team again . Then immediately everything that uses the keyword again will work ; in our case, this is the animation of the fall of the box.

You can see the finished project example here .

Part 13. Checking the direction of travel


Direction indication


Sometimes it happens that you need to check something in only one direction. For example, you need to make blocks that can only be pushed horizontally, or create a duck that can only walk left.

Be that as it may, we can indicate that events occur only in certain directions.

Open PuzzleScript, create a game based on the Basic example and replace it with Rules with the following code:

[ LeftPlayer ] -> [ Crate ]

Launch the game and see what happens.

If you try to go left, the player will turn into a box. This is a good example of how directioning works.

We are already used to the format in which I explained the PuzzleScript code:

[ Условие ] -> [ Событие ]

If the event is true, then the event occurs.

But now, when we need to check directions, he will follow the new rules:

[ Movement DirectionObject Affected ] -> [ New State of Object ]

That is our previous code:

[ LeftPlayer ] -> [ Crate ]

checks if the player is moving to the left ( Left ). If so, then we replace the player with the box object.

Types of Destinations


You can choose from the following types of destinations:

  • Up
  • Down
  • Left
  • Right
  • Horizontal (checks if there is horizontal movement)
  • Vertical (checks if there is vertical movement)


Part 14. Creating custom moves


For some reason, the game may need a custom move. Ducks can only walk left, boxes can only be pushed horizontally, and so on. It is very easy to do. Let's take another look at the basic PuzzleScript code format:

[ Условие ] -> [ Событие ]

If the condition is true, then an event occurs. To create a custom move, you need to do the following:

[ Condition ] -> [ Movement Direction Object To Move]

Here's what the example would look like:

[ Player | Crate ] -> [ Player | Left Crate ]

Download PuzzleScript , open the Basic example , paste this code and see what happens. Go to the box around which there are no walls.

You will see that when a player is near the box, the box is pushed to the left. However, since there is no Late keyword , this happens in the course after you have taken the first step towards it.

When specifying in the Event, in addition to the object, the direction of movement , for example Left , PuzzleScript will try to move the object in the specified direction. That is why the box, and not the player, moves to the left - Left is next to the Crate .

Remember this code from the previous part?

[ НаправлениедвиженияОбъект] -> [ Новое состояние объекта]

If you indicate the direction of movement in the condition next to the object, then it checks whether this object is moving in this direction. This is an important difference. You can rewrite it like this:

[ Проверяем это ] -> [ Делаем это ]

Allowable custom moves


Custom movements can be created with any of these words:

  • Up
  • Down
  • Left
  • Right

You cannot use Horizontal or Vertical , because PuzzleScript will not understand in which direction you want to move the object, or to do this, it will take a lot of workarounds. It is necessary to indicate a specific direction.

Part 15. Checking cells next to objects


Sometimes it is necessary to check what is next to the object. This is pretty easy to do. Let's take another look at the PuzzleScript code format:

[ Условие ] -> [ Событие ]

i.e

[ Проверяем это ] -> если это истинно [ То делаем это ]

To check on the side of the object, we need to add one element. The format is as follows:

Проверяемая сторона [ проверяемый object1 | object2 рядом ] -> [ object1 | object2]

Before the condition, we check in which side of the object we want to perform the check.

Inside the condition, we assume that at least two cells are needed. A cell is, in fact, any objects that are in the same space and not next to each other.

[ Это одна ячейка ]

[ Это первая ячейка | это вторая ячейка | это третья ячейка ]

The first cell is the object whose sides we are checking. The second cell is the object whose presence we are checking. Try the following examples:

Left [ Player | Crate ] -> [ Player | ]

The code shown above deletes boxes if they are in the square to the left of the player.

Left [ Crate | Crate ] -> [ Player | Crate ]

This code checks if the box is to the left of another box. If so, then the box whose side is checked will become the player’s new object.

Left [ Crate | Crate ] -> [ Crate | Player ]

In the above code there is the same check, but the box on the left becomes the player’s object.

Left [ Crate | Crate | Crate ] -> [ Crate | Player | Crate ]

This code also uses a similar pattern. The box immediately to the left of the checked becomes a player if 3 boxes are next to each other horizontally.

Left [ Crate | Crate | Crate ] -> [ Crate | Crate | Player ]

If 3 boxes are next to each other horizontally, then the leftmost one becomes a player.

If you test each of these examples, you will begin to understand the pattern. The first cell is the object that we check to see what is next. The following cells, from the closest to the farthest, are the objects we check for.

Keywords


  • Up - checks on an object
  • Down - checks under the object
  • Left - checks to the left of the object
  • Right - checks to the right of the object
  • Horizontal - checks to the left and right of the object
  • Vertical - checks above and below the object

image

image

image

image

Also popular now: