Let's code a battle system
I needed one for my game, so looked around the web for existing free scripts - you know, the amazing amount of free code people share? - but surprisingly, found very little. Only one on Github, but I couldn't get it working. So I gave up and tried creating one from scratch. It may not be perfect, but maybe someone will find it useful.Disclaimer: this tutorial is written for absolute beginners, but I'm also just a hobbyist myself. So apologies for the cringy bits, experts, and if you see any parts that could be explained or coded better, please let me know!
For users of Mysidia framework: please see this guide for integration into your game. Many more fun things can be done with PHP, involving pet stats, items and custom abilities.Setting the scene
Firstly, optional, but worth it: set up a clear battlefield layout. You can copy this HTML/CSS template if you want.We use variables for generating and holding data - stat numbers, attack modifiers, random enemy names or quotes, anything. Any of these variables can be kept 'behind the scenes', or made public, with player seeing them update in real time. Doing that with each side's HP is essential, for example. There will be moves later that change stats, so let's do it with them too. For a variable to visibly update we must create a unique div to put it in. 'hpdiv', 'strengthdiv' and so on.
We place all JavaScript code within SCRIPT tags. First let's declare (create) some variables. There are two kinds of 'scope' you can use variables in: global or local.Global variables are declared outside any function, you can use (or change) them inside any functions, and they'll update outside the function too. We definitely need these during a battle, to keep track of stats, from start to finish!
Local variables are ones you create inside a certain function, and they only exist inside that function. Basically they're temporary, they vanish after the function ends. We can use these for little random numbers to add flavour to the main attack formulae, for example. They'll be re-generated every time and are not so important that we need to hold onto them afterwards.
Sometimes you'll see the word var before a variable name. It doesn't matter if you add 'var' when creating global variables, but it makes a difference to variables created inside functions. If no 'var' they'll become global! I like to keep local stuff local, it feels tidy, so you'll notice a lot of 'var' around.
Try to be careful with variable names. Don't accidentally re-declare a global one locally (such as writing var ghp), that might overwrite it and cause Bad Stuff (never tried it so can't elaborate). You can create many local variables with the same names inside different functions though. They can't 'see' the local vars inside each other.
ghp = 180;
ehp = rand between 120,240;
gstrength = sth;
gspeed = sth;
gfocus = sth;
estrength = rand;
espeed = sth;
efocus = sth;
Using those stats
Anyway, how do things visibly update on the page? We can use jQuery to change HTML elements in all sorts of ways. Hide/show them, animate, change their CSS, replace or add to their content... let's look at 4 snippets:I'm not using any other CSS-changing stuff in this system, so let's move on. Code!
// global vars
// up here!
// action function here { ... }
// another function here {...
}
// and another {...}
}</script>
Now, an attack!
var rand2 = Math.floor(Math.random() * 15) + 1;
var griffbite = gstrength + gspeed + rand1;
var enemybite = estrength + espeed + rand2;
Note the var when creating these temporary variables.
ehp = ehp - griffbite;
$('#griffhealth').html('Health: <b>' +ghp+ '</b>');
$('<br>{$gname} sharply bites for ' +griffbite+ ' damage! Enemy hits back for ' +enemybite+ ' damage!<br>').appendTo('#reports');
Important note: be careful with long messages! Multi-line stuff will probably break. Keep it short for now. I'll expand on this issue later.
latest.scrollTop = latest.scrollHeight;
$('#enemyhealth').html('Health: <b>0</b>');
$('#actionbox').html('You defeated ' +ename+ '! Congratulations!');
$('#victory').show();
if (ghp <= 0 && ehp <= 0){
$('#griffhp').html('Health: <b>0</b>');
$('#enemyhealth').html('Health: <b>0</b>');
$('#actionbox').html('The battle was a draw!');
$('#drawn').show();
if (ghp <= 0 && ehp > 0){
$('#griffhp').html('Health: <b>0</b>');
$('#actionbox').html('Unfortunately you lost the battle.');
$('#lost').show();
}
Finally, end this whole attack function with another bracket.
Just one attack isn't much of an option! So let's add another, called Kick, using a different formula. Here's the whole function:
var rand1 = Math.floor(Math.random() * 70) + 1;
var rand2 = Math.floor(Math.random() * 70) + 1;
var griffkick = gstrength + gfocus + rand1;
var ekick = estrength + efocus + rand2;
ehp = ehp - griffkick;
ghp = ghp - ekick;
$('<p>{$gname} kicks, dealing ' +griffkick+ ' damage! Enemy strikes back for ' +ekick+ ' damage!</p>').appendTo('#reports');
var latest = document.getElementById('reports');
latest.scrollTop = latest.scrollHeight;
$('#enemyhealth').html('Health: <b>0</b>');
$('#actionbox').html('You defeated ' +ename+ '! Congratulations!');
$('#victory').show();
if (ghp <= 0 && ehp <= 0){
$('#griffhp').html('Health: <b>0</b>');
$('#enemyhealth').html('Health: <b>0</b>');
$('#actionbox').html('The battle was a draw!');
$('#drawn').show();
if (ghp <= 0 && ehp > 0){
$('#griffhp').html('Health: <b>0</b>');
$('#actionbox').html('Unfortunately you lost the battle.');
$('#lost').show();
}
var rand1 = Math.floor(Math.random() * 10) + 1;
var rand2 = Math.floor(Math.random() * 25) + 1;
var gbuff = 30 + rand1;
var ebuff = {$ebuff} + rand2;
ghp = (ghp - gbuff) - ebuff;
gfocus = gfocus * 2;
gspeed = gspeed * 2;
$('<p>{$gname} loses ' +gbuff+ ' HP to double STR, SPD! Meanwhile, enemy hits for ' +ebuff+ ' damage!</p>').appendTo('#reports');
var latest = document.getElementById('reports');
latest.scrollTop = latest.scrollHeight;
$('#enemyhealth').html('Health: <b>0</b>');
$('#actionbox').html('You defeated ' +ename+ '! Congratulations!');
$('#victory').show();
if (ghp <= 0 && ehp <= 0){
$('#griffhp').html('Health: <b>0</b>');
$('#enemyhealth').html('Health: <b>0</b>');
$('#actionbox').html('The battle was a draw!');
$('#drawn').show();
if (ghp <= 0 && ehp > 0){
$('#griffhp').html('Health: <b>0</b>');
$('#actionbox').html('Unfortunately you lost the battle.');
$('#lost').show();
}