Building Browsergames: Buying Weapons (PHP)

Based on the results of our poll, you’ve all voted that players should carry two weapons(of any type they want), with a primary hand and a secondary hand that can both have weapons in them.

Our stats system is perfect for this – all we have to do is add another stat for players that keeps track of which weapon is in their primary hand, and which weapon is in their secondary hand.

INSERT INTO stats(display_name, short_name) VALUES ('Primary Hand Weapon','phand'),('Secondary Hand Weapon','shand');

With the new stats inserted, we can now start writing code to take advantage of them. But how will users obtain weapons to equip?

For the moment, players will get weapons at the Weapons Shop – which is what we will be building today. The weapons shop will list off a random selection of weapons that are available for users to purchase, and automatically put weapons into primary or secondary hands after a user purchases them.

In order for our items to work in a shop, however, we need to make another change – adding prices to them! We’ll add a column to our items table called ‘price’, and set it to have a default value of 10(for 10 gold coins):

ALTER TABLE  'items' ADD  'price' INT NOT NULL DEFAULT  '10';

With that finished, we can start working a little more on the actual Weapon Shop page. First off, we’ll build a template for the shop and call it weapon-shop.tpl:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<html>
<head>
	<title>The Weapon Shop</title>
</head>
<body>
	<p>Welcome to the Weapon Shop.</p>
	<h3>Current Equipment:</h3>
	<ul>
		<li>Primary Hand: {if $phand ne ''}{$phand}{else}None{/if}</li>
		<li>Secondary Hand: {if $shand ne ''}{$shand}{else}None{/if}</li>
	</ul>
	<p>Below are the weapons currently available for purchase.</p>
	<ul>
		{foreach from=$weapons key=id item=i}
			<li>
				<strong>{$i.name}</strong> - <em>{$i.price} gold coins</em>
				<form action='weapon-shop.php' method='post'>
					<input type='hidden' name='weapon-id' value='{$i.id}' />
					<input type='submit' value='Buy' />
				</form>
		{/foreach}
	</ul>
</body>
</html>

As you can probably see based on our template, we will be using a foreach loop to list off all of the weapons that are currently available. We’re going to use a fairly simple SQL query to list off 5 random weapons, each time that the user visits the weapon shop:

SELECT DISTINCT(id), name, price FROM items WHERE type = 'Weapon' ORDER BY RAND() LIMIT 5;

Now that we have the SQL query we’ll be using, we need to quickly write the PHP code to use that query for our shop, inside weapon-shop.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
 
require_once 'smarty.php';
 
session_start();
 
require_once 'config.php';		// our database settings
$conn = mysql_connect($dbhost,$dbuser,$dbpass)
	or die('Error connecting to mysql');
mysql_select_db($dbname);
// retrieve player's ID
$query = sprintf("SELECT id FROM users WHERE UPPER(username) = UPPER('%s')",
			mysql_real_escape_string($_SESSION['username']));
$result = mysql_query($query);
list($userID) = mysql_fetch_row($result);
 
require_once 'stats.php';	// player stats
$query = "SELECT DISTINCT(id), name, price FROM items WHERE type = 'Weapon' ORDER BY RAND() LIMIT 5;";
$result = mysql_query($query);
$weapons = array();
while($row = mysql_fetch_assoc($result)) {
	array_push($weapons,$row);
}
$phand = getStat('phand',$userID);
$phand_query = sprintf("SELECT name FROM items WHERE id = %%s",
				mysql_real_escape_string($phand));
$result = mysql_query($phand_query);
if($result) {
	list($phand_name) = mysql_fetch_row($result);
	$smarty->assign('phand',$phand_name);
}
$shand = getStat('shand',$userID);
$shand_query = sprintf("SELECT name FROM items WHERE id = %%s",
				mysql_real_escape_string($shand));
$result = mysql_query($shand_query);
if($result) {
	list($shand_name) = mysql_fetch_row($result);
	$smarty->assign('shand',$shand_name);
}
$smarty->assign('weapons',$weapons); 
$smarty->display('weapon-shop.tpl');
 
?>

We loop through all of the data returned by our query, and display information on each weapon for our shop. We display our weapons, how much they cost, and a small ‘Buy’ button for users to purchase them with. Now we just need to make it possible for users to actually buy weapons.

As you saw earlier in our template, we have placed a form into each of our weapon entries, with a ‘Buy’ button and the ID of the weapon that users would choose to buy. We will be modifying weapon-shop.php so that when users click on the ‘Buy’ button, we can purchase the weapon in question for them – or display a helpful error message if they cannot afford it. To start off, we’ll edit our template so that it can display our messages for us:

12
13
14
15
16
17
{if $error ne ''}
	<p style='color:red'>{$error}</p>
{/if}
{if $message ne ''}
	<p style='color:green'>{$message}</p>
{/if}

With that modification made, we can now add the code to handle a user clicking on the ‘purchase’ link:

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
$phand = getStat('phand',$userID);
$shand = getStat('shand',$userID);
if($_POST) {
	$weaponID = $_POST['weapon-id'];
	$query = sprintf("SELECT price FROM items WHERE id = %s",mysql_real_escape_string($weaponID));
	$result = mysql_query($query);
	list($cost) = mysql_fetch_row($result);
	$gold = getStat('gc',$userID);
	if($gold > $cost) {
		// subtract gold, equip weapon, go from there.
		if(!$phand) {
			setStat('phand',$userID,$weaponID);
			setStat('gc',$userID,($gold - $cost));
			$phand = $weaponID;
			$smarty->assign('message','You equipped the weapon in your primary hand.');
		} else {
			if(!$shand) {
				setStat('shand',$userID,$weaponID);
				setStat('gc',$userID,($gold - $cost));
				$shand = $weaponID;
				$smarty->assign('message','You equipped the weapon in your secondary hand.');
			} else {
				$smarty->assign('error','You already have two weapons! You must sell one before equipping another one.');
			}
		}
	} else {
		$smarty->assign('error','You cannot afford that weapon!');
	}
}

We’ve built some simple swapping logic here – if the player’s primary hand is empty, the purchased weapon goes there. Otherwise, it goes into their secondary hand – and if both have a weapon in them, a message is displayed.

If you haven’t noticed, we told users that they needed to sell a weapon if they wanted to purchase a new one – so that’s what we’ll be building now. We’ll start off by tweaking our template again:

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<li>
	Primary Hand:
	{if $phand ne ''}
		{$phand}
		<form action='weapon-shop.php' method='post'>
			<input type='hidden' name='sell' value='phand' />
			<input type='submit' value='Sell' />
		</form>
	{else}
		None
	{/if}
</li>
<li>
	Secondary Hand:
	{if $shand ne ''}
		{$shand}
		<form action='weapon-shop.php' method='post'>
			<input type='hidden' name='sell' value='shand' />
			<input type='submit' value='Sell' />
		</form>
	{else}
		None
	{/if}
</li>

With that change made, we’ll now modify weapon-shop.php again so that it can handle the new arguments sent to it:

21
22
23
24
25
26
27
28
29
30
31
if($_POST['sell']) {
	$weaponID = getStat($_POST['sell'],$userID);
	$query = sprintf("SELECT price FROM items WHERE id = %s",mysql_real_escape_string($weaponID));
	$result = mysql_query($query);
	list($price) = mysql_fetch_row($result);
	$gold = getStat('gc',$userID);
	setStat('gc',$userID,($gold + $price));
	setStat($_POST['sell'],$userID,'');
	$phand = getStat('phand',$userID);
	$shand = getStat('shand',$userID);
} else {

And with that finished, users can now buy and sell different weapons as they so choose. The single last change we need to make is adding a ‘Weapon Shop’ link to our main page:

18
<p><a href='weapon-shop.php'>The Weapon Shop</a></p>

And with that, we’re finished! Here’s the code behind our weapon shop, in it’s entirety:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?php
 
require_once 'smarty.php';
 
session_start();
 
require_once 'config.php';		// our database settings
$conn = mysql_connect($dbhost,$dbuser,$dbpass)
	or die('Error connecting to mysql');
mysql_select_db($dbname);
// retrieve player's ID
$query = sprintf("SELECT id FROM users WHERE UPPER(username) = UPPER('%s')",
			mysql_real_escape_string($_SESSION['username']));
$result = mysql_query($query);
list($userID) = mysql_fetch_row($result);
 
require_once 'stats.php';	// player stats
$phand = getStat('phand',$userID);
$shand = getStat('shand',$userID);
if($_POST) {
	if($_POST['sell']) {
		$weaponID = getStat($_POST['sell'],$userID);
		$query = sprintf("SELECT price FROM items WHERE id = %s",mysql_real_escape_string($weaponID));
		$result = mysql_query($query);
		list($price) = mysql_fetch_row($result);
		$gold = getStat('gc',$userID);
		setStat('gc',$userID,($gold + $price));
		setStat($_POST['sell'],$userID,'');
		$phand = getStat('phand',$userID);
		$shand = getStat('shand',$userID);
	} else {
		$weaponID = $_POST['weapon-id'];
		$query = sprintf("SELECT price FROM items WHERE id = %s",mysql_real_escape_string($weaponID));
		$result = mysql_query($query);
		list($cost) = mysql_fetch_row($result);
		$gold = getStat('gc',$userID);
		if($gold > $cost) {
			// subtract gold, equip weapon, go from there.
			if(!$phand) {
				setStat('phand',$userID,$weaponID);
				setStat('gc',$userID,($gold - $cost));
				$phand = $weaponID;
				$smarty->assign('message','You equipped the weapon in your primary hand.');
			} else {
				if(!$shand) {
					setStat('shand',$userID,$weaponID);
					setStat('gc',$userID,($gold - $cost));
					$shand = $weaponID;
					$smarty->assign('message','You equipped the weapon in your secondary hand.');
				} else {
					$smarty->assign('error','You already have two weapons! You must sell one before equipping another one.');
				}
			}
		} else {
			$smarty->assign('error','You cannot afford that weapon!');
		}
	}
}
$query = "SELECT DISTINCT(id), name, price FROM items WHERE type = 'Weapon' ORDER BY RAND() LIMIT 5;";
$result = mysql_query($query);
$weapons = array();
while($row = mysql_fetch_assoc($result)) {
	array_push($weapons,$row);
}
$phand_query = sprintf("SELECT name FROM items WHERE id = %s",
				mysql_real_escape_string($phand));
$result = mysql_query($phand_query);
if($result) {
	list($phand_name) = mysql_fetch_row($result);
	$smarty->assign('phand',$phand_name);
}
$shand_query = sprintf("SELECT name FROM items WHERE id = %s",
				mysql_real_escape_string($shand));
$result = mysql_query($shand_query);
if($result) {
	list($shand_name) = mysql_fetch_row($result);
	$smarty->assign('shand',$shand_name);
}
$smarty->assign('weapons',$weapons); 
$smarty->display('weapon-shop.tpl');
 
?>

And here’s the associated template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<html>
<head>
	<title>The Weapon Shop</title>
</head>
<body>
	<p>Welcome to the Weapon Shop.</p>
	<h3>Current Equipment:</h3>
	<ul>
		<li>
			Primary Hand:
			{if $phand ne ''}
				{$phand}
				<form action='weapon-shop.php' method='post'>
					<input type='hidden' name='sell' value='phand' />
					<input type='submit' value='Sell' />
				</form>
			{else}
				None
			{/if}
		</li>
		<li>
			Secondary Hand:
			{if $shand ne ''}
				{$shand}
				<form action='weapon-shop.php' method='post'>
					<input type='hidden' name='sell' value='shand' />
					<input type='submit' value='Sell' />
				</form>
			{else}
				None
			{/if}
		</li>
	</ul>
	<p>Below are the weapons currently available for purchase.</p>
	{if $error ne ''}
		<p style='color:red'>{$error}</p>
	{/if}
	{if $message ne ''}
		<p style='color:green'>{$message}</p>
	{/if}
	<ul>
		{foreach from=$weapons key=id item=i}
			<li>
				<strong>{$i.name}</strong> - <em>{$i.price} gold coins</em>
				<form action='weapon-shop.php' method='post'>
					<input type='hidden' name='weapon-id' value='{$i.id}' />
					<input type='submit' value='Buy' />
				</form>
		{/foreach}
	</ul>
</body>
</html>

Don’t forget, you can check out our game in it’s current state at http://buildingbrowsergames.com/game/php/index.php!

Extra Credit

  1. Add a current gold display to the Weapon Shop page, so that users can see how much gold they have remaining.
  2. Customize the ‘you cannot afford this weapon’ message to also display the weapon name, and how much more gold the player needs.
  3. Change how the weapons for sale are displayed, so that they don’t update after a user buys a weapon – or, make it so that the weapon the user just bought is not included in the new weapons list.

Wish there was more?

I'm considering writing an ebook - click here.

.

Luke is the primary editor of Building Browsergames, and has written a large portion of the articles that you read here. He generally has no idea what to say when asked to write about himself in the third person.

Monday, August 11th, 2008 buildingbrowsergames, code, php
  • Patrick

    I use the code exactly as it is here. But, i can only buy one weapon. When I try to buy a second one it displays the error message and switching my weapon hands doesn't help. Any help will be appreciated. Thanks.

blog comments powered by Disqus

About

Building Browsergames is a blog about browsergames(also known as PBBG's). It's geared towards the beginner to intermediate developer who has an interest in building their own browsergame.

Sponsors

Got Something to Say?

Send an e-mail to luke@buildingbrowsergames.com, or get in touch through Twitter at http://twitter.com/bbrowsergames