Beginner's corner

Top  Previous  Next

High scores

Some games don't need complicated load / save code; this snippet consists of a simple game that saves the high score to a file. You can use my example to learn how to save high scores, game settings, etc; you could even replace the save / load instructions that are implemented in the A5 engine.

The goal of the game is to get the high score by clicking on as many panels as possible. The panels appear at random positions so you need to be fast.

Here is my main function:

function main()
{
  fps_max = 50;
  level_load (black_wmb);
  wait (2); // wait for the level to be loaded
  init_mouse();
  start_game();
}

I'm loading a dummy level and after 2 frames I initialize the mouse and start the game. Function init_mouse is common:

function init_mouse()
{
  mouse_map = arrow_pcx;
  mouse_mode = 2;
  while (1)
  {
     mouse_pos.x = pointer.x;
     mouse_pos.y = pointer.y;
     wait (1);
  }
}

We choose the pointer, we set the mouse_mode to a value that shows the cursor and then we allow the mouse to move freely using a while loop.

function start_game()
{
  highscore_handle = file_open_read("hiscore.dat");
  max_clicks = file_var_read (highscore_handle);
  while (timer > 0)
  {
     timer -= 1;
     target_pan.pos_x = random(736); // 800 - 64
     target_pan.pos_y = random(536); // 600 - 64
     target_pan.visible = on;
     waitt (16);
     target_pan.visible = off;
     waitt (32);
  }
  if (current_clicks > max_clicks) // new high score
  {
     highscore_handle = file_open_write("hiscore.dat");
     file_var_write (highscore_handle, current_clicks);
     file_close(highscore_handle);
  }
  while (mouse_right == 0) {wait (1);}
  current_clicks = 0;
  timer = 20;
  main();
}

Function start_game does (almost) all the job. First of all, it opens the hiscore.dat file and then it sets max_clicks to the value that was read from hiscore.dat. This file is a simple text file, just like your regular wdl file. I have created it in a text editor, I have named it hiscore.dat and I have typed a 0 (zero) inside it. This means that when you run the game for the first time, the high score is 0.

I have set timer to 20 so the while loop below will run 20 times:

  while (timer > 0)
  {
     timer -= 1;
     target_pan.pos_x = random(736); // 800 - 64
     target_pan.pos_y = random(536); // 600 - 64
     target_pan.visible = on;
     waitt (16);
     target_pan.visible = off;
     waitt (32);
  }

The code inside the loop generates a random position for the panel and makes it visible for 1 second. If the player clicks on the panel, the function associated to the panel (on_click) is executed:

function add_clicks()
{
  current_clicks += 1;
}

This function simply adds another click to the current_clicks var. At the end of the game the target panel has been displayed 20 times and we go on:

  if (current_clicks > max_clicks) // new high score -> save it
  {
     highscore_handle = file_open_write("hiscore.dat");
     file_var_write (highscore_handle, current_clicks);
     file_close(highscore_handle);
  }
  while (mouse_right == 0) {wait (1);}
  current_clicks = 0;
  timer = 20;
  main();
}

At this point the game is over; if we have got a high score it will be written to the hiscore.dat file, overwriting the existing data in it. The game will wait until we click the right mouse button and then it will reset the score (not the high score!) and restart.

You can encrypt the data that is being saved to the file if you want to; the easiest thing to do is to convert the numbers to strings, use a simple algorithm to encrypt them and save the strings on the hard disk. When you start the game, read the strings, decrypt them, convert them to numbers and you're ready to go.


"House of terror" elevator

How can you create a huge elevator that operates at huge speeds? You can have a huge level and use (read loose) additional memory and frame rate or you could use the code below.

If you have loaded the office.wmp example that came with this piece of code you have noticed that the two floors are real close. I'm using a trick here: I'm moving the textures on the elevator walls upwards so the player things that he is moving downwards. I could move the textures for hours and the player would think that he has traveled tens of miles.

action platform
{
  my.skill11 = 100;
  my.skill10 = 100;
  while (vec_dist (player.x, my.x) > 50) {wait (1);}
  while (player.z > 50)
  {
     snd_tune (snd_handle, 100, my.skill10, 0);
     if (snd_handle == 0)
     {
        snd_loop (elevator_snd, 100, 0);
        snd_handle = result;
     }
     my.z -= start_speed * time * 1.1;
     my.skill10 += 5 * time; // increase the frequency
     player.z = my.z + 40;
     wait (1);
  }
  while (my.skill11 > 0)
  {
     my.skill11 -= 1 * time;
     elevator_pnt.v += max_speed * time;
     wait (1);
  }
  while (my.z > -210)
  {
     snd_tune (snd_handle, 100, my.skill10, 0);
     my.z -= start_speed * time * 1.1;
     my.skill10 -= 5 * time; // decrease the frequency
     player.z = my.z + 40;
     wait (1);
  }
  snd_stop (snd_handle);
}

The platform will start to move if the distance between it and the player goes below 50 quants; this assures me that the player will come close to its center. The platform will start moving downwards until player's z coordinate goes below 50 (a point near the middle of the elevator in my example). I'm changing the sound frequency for the elevator (with snd_tune and skill10) to make everything look even more "real". The platform is moved using brute force (my.z instead of ent_move) so the player must be moved together with the platform; this is why the player is placed 40 quants above the platform (an approximate value; you might need to change it if you use another player model). So what have we got so far? Regular platform / elevator code. When player.z goes below 50 this loop starts to run:

  while (my.skill11 > 0)
  {
     my.skill11 -= 1 * time;
     elevator_pnt.v += max_speed * time;
     wait (1);
  }

I have defined a pointer to the elevator walls and I'm moving the textures on the walls upwards by changing their v. This part gives the "length" of the effect: if you set skill11 to bigger values at the beginning of the action, the elevator will go deeper; use smaller skill11 values for smaller elevators. When the time has passed the final while loop runs:

  while (my.z > -210)
  {
     snd_tune (snd_handle, 100, my.skill10, 0);
     my.z -= start_speed * time * 1.1;
     my.skill10 -= 5 * time; // decrease the frequency
     player.z = my.z + 40;
     wait (1);
  }

The elevator will slow down until it reaches a certain point where it will stop (-210 in my example, get this value in Wed). The "high speed" elevator sound is reverted back to "normal speed" sound.

You should cover the elevator otherwise your client will see the trick; I've used a simple platform to allow you to see how it works.