Archive

Posts Tagged ‘game maker’

Game Programming: Click and drag, chapter 3


Welcome back! Did I tell you I love comments? Very few people write... Be original :)

Chapter 3 takes you almost all the way through managing the click & drag inventory and actions management.

 

If you just got here, you should start on the main game programming page. You can get the source code to the game’s development to this point by right-clicking – saving target as here.

The keys to succeeding in doing this are object depth and object duplication. To the player, it will seem like there is a gun object and a cookies object (sample objects). In the game however, there are four different gun and cookie objects: travelling, inventory, equiped and control.

Inventory objects: They are the ones that appear in the inventory. They will stay there when clicked on, and only be destroyed when they are effectively equiped (dragged into the character equiped slot).

Travelling objects: Once an inventory object is selected, and as long as the left mouse button remains pressed, a travelling object is created and follows the cursor.

Equiped objects: If a travelling object exists, and the left mouse button is released over an equiped slot, then the travelling object is destroyed and an equiped object is created at the corresponding slot’s coordinate, in such a way that it will follow if the character panel is moved around.

Control objects: These are the ones that appear in the action panel below. Much like equiped objects, they are dragged there either from the inventory or from the character panel. The difference being that wherever it comes from, the original object will not be destroyed.

4 different objects with same sprites - illusion of same object transfering.

 

Note: more restrictions will need to be applied later, like not allowing to equip an object that cannot be equiped.

Each of  these objects have different depth values. The travelling object has the shallowest, so that it will appear over anything it travels over.

Look for left mouse click events on those objects’ properties, as well as left mouse release events on the control bar and character panel squares. Those events trigger the process of creating and destroying the appropriate object types so that the illusion of transfering an object from one place to the other can take effect.

Left press event triggers travel

 

Since the first objects to exist are the inventory objects, as they appear in the inventory automatically when they are found in the game interactions, they are the first you will be able to click on once you find them.

Clicking and dragging is done with the left pressed mouse event. As long as the left mouse button is pressed over one of the two objects, that event is happening, and the associated actions are triggered.

Since this isn’t a draw event, it cannot trigger any code that contains any drawing instructions. That is OK, since we only need to do one thing: create the travelling object that corresponds to the one that has been clicked on (gun for gun, cookies for cookies).

Important: it must only do so if the travelling object doesn’t exist yet, so there has to be a control variable:

if instance_exists(gun_travelling)=0 
    instance_create(global.mouse_x – global.correct_x_travel[20],
      global.mouse_y – global.correct_y_travel[20], gun_travelling);

If it didn’t only create it when the gun_travelling object doesn’t exist, it would create a new object at every step until the left button is released, which would get quite messy and bog the game down!

Then the left_released event, over the character or control bar squares (this shows in each of the squares where this is possible), causes the travelling object to be destroyed if it exists, and an equiped object to be created at the square’s location.

 

Left release kills travel and creates equiped object.

 

    if global.object_travelling[20]=1
        {
        instance_create(x,y,gun_eq);
        global.slot[100]=20;
        global.item_equiped[20]=1;
        global.object_travelling[20]=0;
        global.slot_location_for_item[20]=100;
        global.slot[global.slot_location_for_item[20]]=20;
        }
       
for(i=0; i<=500; i+=1) global.object_travelling[i]=0;

 

A few variables are set for later use: the item is now in slot 100, and slot 100 holds item 20 (the value that corresponds to the water gun). Also, object 20 is no longer travelling.

Later chapters will cover restrictions such as only allowing a hat (or any object specifically meant to be worn on the head) to be equiped on the head slot, only being able to equip equipable objects, triggering events when clicking on an object that has been added to the control panel, using an object in the inventory when right-clicking…

Also, chapters will be shorter from now on so that I can release them more often, and make them easier to learn (locating the code in the new source code).

Have fun!

Post to Twitter Post to Plurk Post to Yahoo Buzz Post to Delicious Post to Digg Post to Facebook Post to MySpace Post to Ping.fm Post to Reddit Post to StumbleUpon

Game Programming: Click and Drag, chapter 2

 

This is the second chapter of the RPG game programming tutorials (click and drag inventory and action). Get the GM source code: right-click, save target as. If you just got here you should start there!

We’re going to go one step further into elaborating dynamic inventory management. So far, we were able to open a bag using an inventory icon and drag that bag around the room. Now that bag will include items you’ve found playing the game.

Of course this requires that it be possible to find items in the game, so that part is covered as well.

Part I: What is new – taking game programming into new perspectives.

Just like the first time, let’s start by running the game. Put the source code source file in the same folder you put the first one, then double click on it to run it with GM. Run the game by clicking Run the game.

rungame

It starts just the same as it did before, but now when you click on space when you are near the table there is a reaction.

 player options

 

At this point, we are using GM’s built-in dialog boxes. We can make our own from scratch, or customize those somewhat. That will come in later tutorials. For now, we are programming game interaction using those.

This game interaction will lead to finding items that will automatically be added in the player’s inventory. In this case we find cookies and a watergun (hey, this is rated PG!)

Run through the options and when you’ve found the cookies and the gun, check your inventory.

You do this by clicking the bag icon on the right. This is what you see:

 Inventory

Click on the black top bar and hold the left mouse button down.  Move the mouse around and you see the panel, as well as the newly included objects, move accordingly. 

Click on the head or bag button again and the corresponding  panel disappears.

We are one step further into interactive inventory management. Let’s look in the game programming code and see how we got it to work.

 

Game Programming tutorial – Making RPG games chapter 2, part 2.

 

Before we look further into actual programming, it is very important that we dedicate just one small part to organizing your work.

As the game grows, things can quickly get messy. The scripts add up, as well as the other components when we get further into the game.

First we’ll see how you can organize. Then we’ll see how that organization needs to be based on the game loop.

Make games efficiently by organizing the components – game programming success depends on workflow!

To organize components efficiently, you’ll need to put them into folders, or groups. Some of these groups will also have sub-groups.

 

 Create folder

 

Let’s see how the scripts are organized.

 Script folders

Scripts are quite simply grouped by function. When something happens, the first to run is character_control(). It will check if there is something to do where the player is located because he pressed Space. If it determines there is nothing to do, it will run the nothing_to_do() script.

Other player actions will lead to other scripts. The inventory management scripts are located in the inventory folder. Scripts that react to game interaction in room0 in the game reactions by room group.

Taking the time to name groups and sprites with long, descriptive names is worth it. SnS has 164 scripts. As your game gets larger you can very easily waste a lot more time looking for the right script to work on than the time you dedicated to writing explicit names.

The same goes for all other components (sprites, sounds, backgrounds, paths, fonts, time lines, objects and even rooms if you have a large game world that can be cut up by geographic location. We will see that some rooms can be created for a whole other purpose than showing a part of your game world, and such rooms belong in a separate folder as well.

You might be able to get by without paying attention to this part for a small game, but game programming gets interesting, fun and profitable when you start making games large!

Game Programming tutorial – Making RPG games chapter 2, part 3.

 

Efficient game programming requires that you keep track of your game loop when you make games.

Keeping your game loop in mind is a good way to not get lost or have to spend hours figuring out where to add new code to get a new feature to work.

Our sample game’s game loop is already getting a bit complex. That can be intimidating, but it shouldn’t. If you keep good track of it, you’ll realize it is just a series of logical steps that slowly build up as your game develops.

Things that happen to the character (events such as draw, left key, up key…) cause actions (executing code, running scripts). The scripts and codes can start new events of their own by creating new objects (instance_create()) for example. Scripts can also call new scripts (if certain conditions are met by using an if statement, or without conditions at all).

The game loop restarts at each step. How long a step lasts depends on the room speed you choose in room settings. Default is 30 steps per second, which means a step lasts 1/30th of a second. In this game I changed it to 60 so that the cursor would stay on the topbar. I’ll change it back in a later tutorial though… There are other ways.

At each step the room is restarted. All possible events are either checked for (key events) or executed every time (step events, draw events).

Game programming events generated by existing objects.
Each object can potentially generate events, just by existing. The step event happens at every step, as well the draw event. Nothing special has to happen.

The main character object events.

main_ch is the name of the main character object. If you open its object properties, you’ll see four keyboard events, an O key event, a draw event and a space release event.

key event If one of the arrow keys is pressed, this is an event that main_ch will respond to by carrying out the list of actions on the right. Arrow key actions for main_ch are execute a piece of code, which adjusts the direction the character is heading (global.heading), its coordinate (x or y depending on the key that is pressed) and checking if nothing is in the way:

(if instance_position(x-10,y,all)=noone x-=4
else if global.space_mess=0 global.space_mess=1;

This translates as: if no object (noone) of any type (all) is at instance position (my x coordiante-10, my y coordinate) or 10 pixels to my left, then my new x coordinate is x-4 (x-=4) so I will move 4 pixels to the left. Otherwise (else), if global.space_mess=0, then change that global variable (global means it will be recognized in other scripts maunched by other objects) becomes =1.

global.space_message is a variable that will be used to determine if a message is shown on the screen later in the loop. This prepares for that message to be shown, if another object is on its way to the left.

key event The O key event starts a dialog box you can use to rename Hobo.

Draw event main_ch is drawn. If space_message=1, it shows a message informing the player that the space key will show what options he has at any given point in the game if he is facing something.

The sprite associated to the object is drawn, in conformity with the global.heading value.

Takes the x and y “local” values and copies them into global values that can be used anywhere (global.posx and y).

Runs the script character_options() if a variable value is equal to 1.

Key released event Space is released. This changes a variable that will be used in the next main_ch object’s draw event. The variable changes if there is anything in one of the four directions, 10 pixels away. If not, it “sleeps” for 1/1000th of a second for each direction and then runs nothing_to_do(), another script that says there is nothing to do.

Now let’s move on to another object.

Game Programming tutorial – Making RPG games chapter 2, part 4.

Making games in GML: object oriented game programming.

Many objects besides the main character will make up a game. In this sample, there are the inactive objects that will be detected by the main character. There is the table, which, recognized as such, will cause specific reactions (see previous part). The doors will soon act appropriately using the same method. You previously read that the main character reacts to key prompts (arrow keys for movement and heading, O for renaming, space to see available options)

You can imagine countless options such as other characters to talk to, monsters to shoot, closets to explore, doors or windows to open…

There are the interface objects that react to mouse clicks or hovering (NoButton). Those are the character and inventory objects on the right (they react by creating or destroying the corresponding panels, as well as the objects they contain, by running the open and close inventory scripts), the two topbars and the squares.

And then there are item objects that are created when the right variables are set at the right values (the topbars are as well), and stored in their own inventory slots when they are picked up. That’s all they do for now, but they will soon react to mouse events as well.

Objects are the core of your game. They make the game loop continue. When all object events have caused the assigned actions, the next step begins and the loop is restarted, ready to react to new events by running new actions.

Making scripts run in your game.

We saw that the space key causes a check for close objects, and a variable change if it finds something. This is done by using the if statement and instance_position(). Once that variable is changed, you get reactions by making sure that variable is checked at each step. You do that by assigning that verification in an action (a script or execute a piece of code). This action results from an event that happens at every step. Draw is one of them, and it is the one you must use if what happens next involves drawing text or images. If it is just variable value updates, the Step event will work fine. If you aren’t sure yet, then just use the draw event to be sure.

In the main character draw event, if global.checking_character_options=1 character_options(); launches the script character_options because Space was pressed, causing the if condition here to be true.

Other variables determine if, ultimately, the gun and cookies end up in your inventory, and where. global.just_taken=10; in get_cookies() is a variable used to determine which object was just taken (item 10 is the cookies). This is used in the inventory scripts. First, add_to_inv() will determine what slot it will go in (the first available). Then when the inventory is open, open_inventory() draws the cookies inventory objects at the same coordinates as the square it was assigned to. Since the cookie’s inventory object has a lower depth than the inventory square, it appears on top, giving the illusion that it is inside it.

Arrays are used to do this quickly. This allows you to update values using single or double “for” loops. Take a look at the open_inventory() script in the inventory folder. You’ll see this is extremely useful (you can’t make a decent game without it!)

Post to Twitter Post to Plurk Post to Yahoo Buzz Post to Delicious Post to Digg Post to Facebook Post to MySpace Post to Ping.fm Post to Reddit Post to StumbleUpon

Game Programming: Click and drag chapter 1.

Create an original RPG game: Chapter one.

 

You should start here to have a better idea where this is going!

After unzipping the source code package (right-click – save as to download),source filedouble-click on it and this will start Game Maker.  Run the game to get a feel of what it does.  To do this, simply click on the green icon that is labelled Run the game.

rungame 

 

This will start the game in demonstration mode.  You do this from time to time to check if your game is running correctly.

When your games aren’t working properly, and you want to see what’s going wrong, you can also run the game in debug mode. 

rungamedebug 

It does the same as running the game, except you have a small window that gives you info on what is going on as the game runs.  This helps figure out what went wrong. 

So for now, you’re just running the game normally, and this is what you see.  Obviously, we’re just starting so it’s rather basic.  We’ll worry about graphics later.

advgamepicchapter1 

Click on the head or bag and rudimentary panels appear, each containing an inactive “square”.  Run your mouse over the square and it changes color, but that’s all for now.

One of these panels is the inventory (bag) and the other is your character panel.

advgamepic2chapter1 

Click on the black top bar and hold the left mouse button down.  Move the mouse around and you see the panel moves accordingly. 

Click on the head or bag button again and the corresponding  panel disappears.

There you have it, the early stages of interactive inventory management.

You might have noticed that below the world view area there are five squares, similar to the ones in the inventory and character panels.  These make up the control bar.

Soon you’ll be able to find items in the room that will automatically appear in your inventory (given there is still space there), click and drag these items to the character panel to equip them, do the same towards the control bar to be able to use them by clicking on it there.

But for now, let’s look at how we’ve gotten these results so far.

 

Game programming with dynamic objects.

 

Don’t worry if you don’t know what objects are just yet. It will become very clear as you read on.

Before doing anything you will need to create a room. Right-click on Rooms and create one. Don’t do anything with it yet.

create-room

To create objects you first create the associated sprite(s). Sprites are just a buzz word for the small images that move around the screen (your character, the bag image, the table…) To include sprites you must first create them. At this stage I only created very basic sprites for the sake of having something. Once you have an image ready, right-click on the sprites folder and “upload” the sprite into the game.

uploading-sprite 

 Then you create the objects (right click on Objects folder, just like sprites or rooms) Double-click on the new object in the panel, name it,

create-object 

and then you associate the sprite.

associate-sprite 

For dynamic objects, (objects that don’t always look the same) I often prefer to not associate sprites, but use the draw event to call a piece of code.

The code will dispay the sprite according to variables that change as the player interacts with the game. This gives many more options than by using the limited point and click features.

draw-call-code 

  1. Create the draw event (pick it from the options that appear by clicking on Add Event).

  2. Select the Control Tab.

  3. Click and drag “Execute Code” from the Control Tab to the list of actions.

Several objects are used at this point.

  1. The character object (main_ch) which can move around and trigger a pop up when it hits something.

  2. The north, east, south, and west doors. Only north and east are in that room, but the others are available for later rooms.

  3. The horizontal and vertical wall pieces.

  4. A table object.

  5. Square objects for future inventory slots.

  6. Topbar, and inventory objects.

  7. A bag and character inventory objects.

Objects can be placed in the world view, or Rooms to appear in the game. Sometimes you won’t place them there at first but they will be created later by the game, according to situations that occur. They can react to different situations (be created, be destroyed, change appearance, move…). Those situations result from the programming and can be much more diverse by programming code than they can be with the point and click options.

 

Game programming – starting with the world view.

 

I started by creating a very basic world view, just for the sake of illustration.  There is a character, with a very prominent nose  that changes directions according to which arrow keys you use.

There are also a few walls, doors, and a table.  Each was added directly to “room0” by opening the room, selecting the objects and clicking at the appropriate spot.

 add-object-to-room

To make the character able to move around, you need to open the character’s Object Properties window.  It’s already created so just double click on the main_ch object in the object list.

Add the left keyboard event by clicking Add event, then selecting the bottom left option, then selecting <left> in the list that appears.

 add-left-keyboard-event 

At this point there are two options to consider.  The first is to use the point and click tabs in the move tab on the right.  The second is to insert a piece of code as seen previously.

Like I said before, I don’t like point and click.  It is too limited and you don’t truly learn to program games by relying on those.  It isn’t that hard to learn so… 

The left event triggers Execute a piece of code from the control tab.

global.heading=4;

if instance_position(x-10,y,all)=noone x-=4

    else if global.space_mess=0 global.space_mess=1;

This is the code when the left arrow key is pressed. 

- Global is necessary when the variable heading is meant to be used in scripts other than the one it is included in. 

- Heading = 4 means the character will be facing west (1 for N, 2 for E…).

- if instance_position(x-10,y,all)=noone checks for any type of object that intersects with the character’s x coordinate-10 (10 pixels to the left) and the character’s y coordinate. 

o       If there is anything just to the left of your character, that means the “if condition” is not met (it doesn’t find “no one” because it finds something).  In that case it runs the statement found in “else”.  “all” means it checks for anything at all – this can be replaced by specific object names.

o       If there is nothing there, then the “if condition” is met.  It moves the character 4 pixels to the left by subtracting 4 from its x coordinate.

else if global.space_mess=0 global.space_mess=1; is what happens when there is an object ten pixels to the left of your character while pressing the left arrow key.

o       If the variable global.space_mess=0, then it changes the variable to 1.  Space_mess stands for “space message”.  If you run into a wall or the table, a message appears that reads “When facing an object hit SPACE to see your options”.  This is just to demonstrate that you can trigger this.  Hitting SPACE doesn’t do anything at this point.

o       In the draw event, part of the associated code is:  if global.space_mess=1 {…} which means that if the variable’s value is one then it will run what is in between the brackets.

§        show_message(“When facing an object hit SPACE to see your options”);  This shows the message (the OK button is included automatically).

§       global.space_mess=2; This ensures that the message is only showed once.  If I wanted that message to appear each time the player runs into an object I would set it back to 0 so the entire process could run again, or even simpler simply not have created this variable at all.

 

The control bar.

 

Below the world view there is a control bar made up of five “squares”. 

control-bar

These don’t show much unless you run the mouse over them.  At this point they only react to Mouse Enter and Mouse Leave events.  Again, you add events by double-clicking on the object it will apply to on the left.  Then you add the Mouse Enter and Mouse Leave events the same way you added events previously.

At this point the game doesn’t require more than point and click so I used the Change sprite button in the main1 tab.  This could change later though if I need this to trigger code (it will).

 mouse-enter-leave

  1. Open the Object properties for a square object.
  2. Create Mouse Enter and Mouse Leave events.
  3. Select one of the two.
  4. Open the main1 tab.
  5. Click and drag change-sprite into the list of Actions.
  6. Double click on it then.
  7. Select the sprite you want it to change into.
  8. okand repeat for the other event.

In both cases, they change sprites accordingly.  For this I used the predefined action “change sprite”.

In later versions these will react to items being “dragged into them”.

 

Game programming – click and drag inventory and action components!

 

This is what stands out at this point.  Having control panels that can be dragged around the screen.

 advgamepic2chapter1

These are made up of two main elements:  the topbar (black) and the brown surface that “follows” the topbar wherever it goes.  Then there are the squares, or item slots.  There is something very particular about these that we will discuss a bit later.

 

Creating and destroying the panels.

 

The first step is creating the panel.  This happens when the left mouse button released event occurs for the adequate object (either the blue button for the character panel or the bag button for the inventory panel).  Left mouse released doesn’t happen when the player clicks, it happens when he releases the button.  Almost the same but not quite.

 left-released

The code starts by checking if the topbar exists already.  If it doesn’t, the if condition is met so it reads variable values, which will be used to define where the topbar is located. tbx is topbar x coordinate, tby is topbar y coordinate.

Then it will assign the location for the brown inventory box (just below it) and the item slot squares.

Then it will create the two, and since they are always a fixed distance from each other, when the topbar is clicked and dragged, the brown box follows.

But we still have to make the topbar react to clicking and dragging. 

This is done in a very similar way, by using the No button mouse event on the topbar object, which is triggered when the mouse runs over the topbar without clicking.  When this is active, it calculates the x and y distance between the mouse cursor and the top-left pixel of the topbar.

These variables are recalculated at every step (1/60th of a second according to Room Properties.)

When the mouse is clicked on the Topbar (Left Button mouse event), the variables stop changing and can be used to determine where the topbar is located at every step.

And the inventory box called equiped follows, as well as the squares.

 

A bit more detail about the code:

 

When the mouse is over the topbar and no button is pressed, this generates the “no button” event.   What happens then is a constant recalculation of the distance between the mouse and the topbar’s “origin”.

Note that the origin can be set in the sprite’s settings.  It can be the center of the topbar, or the top left corner (x=0 and y=0) or any coordinate you choose.  This doesn’t matter much, as long as it is the same for all the objects involved.

This is how the distance between the mouse and the origin are calculated at each step:

    global.tb_correct_x=mouse_x-x;

    global.tb_correct_y=mouse_y-y;

tb_correct_x stands for topbar correct x (for the x coordinate).  That’s a variable name I chose.  Always be explicit with variables so that you can recognize their function when debugging, or reviewing your code for whatever reason.

mouse_x is the built-in variable for the mouse’s x coordinate.

x is the topbar’s built-in x coordinate.  Note that it doesn’t need to be global since it is only used for the current object (topbar).

global.tb_correct_x and global.tb_correct_y are respectively the horizontal and vertical distance between the topbar’s top left corner (origin) and where the mouse is during that step.  Those are global variables because I will use them later to determine where the topbar needs to be at each step.

When the left button is pressed over the topbar, this generates the Left Button mouse event for the topbar.  The following code is then applied:

x=mouse_x-global.tb_correct_x;

y=mouse_y-global.tb_correct_y;

 x and y stay at a constant distance from the mouse because since the no button event is no longer occurring, the recalculations aren’t happening.  This means that global.tb_correct_x and global.tb_correct_y aren’t changing.

When you move the mouse, the topbar just “follows” as long as you keep the left button down.

 global.equiped_x=x+global.equiped_correct_x;

global.equiped_y=y+global.equiped_correct_y;

 This keeps the brown square at equal distance between the topbar’s origin (x and y), which means it “follows” as well.

 global.square100_x=x+global.square100_correct_x;

global.square100_y=y+global.square100_correct_y;

This keeps the item slot square at equal distance between the topbar’s origin (x and y), which means it “follows” as well.  This is included in each square’s step event (recalculates position at each step).

The same can be done for any other object.  More item slot squares of course, but also any number of tabs, buttons (…).

 

Frequent problem.

 

If you look at the room settings you’ll see I changed the room speed (default = 30, I set it to 60).  If it is too slow, the mouse keeps popping out of the topbar space because your mouse runs at system speed (much faster).

Changing the speed, however, also speeds up all the objects in the game.  Your character walks faster for instance.  Setting it too high would make the click and drag work better but you’d need to slow down the game with a sleep() command at each step.

Room speed being 60 means 60 steps occur per second instead of 30. There are better ways to fix this but I’ll leave it at that for now.

Back to Game Programming 

 

Other posts of interest:

 

The power of sound for better productivity, creativity, training and state of mind.

Post to Twitter Post to Plurk Post to Yahoo Buzz Post to Delicious Post to Digg Post to Facebook Post to MySpace Post to Ping.fm Post to Reddit Post to StumbleUpon