Battle Forces Online -(http://www.battleforcesonline.com)
I've put some time and effort into Battle Forces Online.
I gave the entire game a face lift. I bought a template from monsterTemplates.com, modified it a good bit and used that as a new front end. I really like it, but I'm still in need of a good name for this game.
Killed a few bugs, attacking was a bit glitchy. The admin panels had all kinds of problems. So I put some time in and fixed those.
Because I fixed the admin panels, I was able to easily modify the game, so I added a few more maps/levels. (There are now 13, the last being Devils Delight)
I added a few more characters.
Created an iGoogle gadget for the game. (read the Tutorial)
Created a map function that tracks who is where.
Started a one month turnament.
Put some google ads on the game.
All in all, I like the upgrade, waiting to see what users think, but traffic is picking up allready so I take that as a good sign.
Tuesday, January 13
Enhancements to my Battle Forces Online
Labels:
Battle Forces Online,
code,
game programming,
press release
It's been a busy few weeks....
Well its been a busy end and beginning of the year. I always seem to get a bit more productive around these times. And the last few weeks I've been unable to sleep on my working schedule. (I've always been a night owl, had to train myself to sleep right in order to be effective at my day job)
So the next few post will be about some of the things that I've done in the past few weeks.
So the next few post will be about some of the things that I've done in the past few weeks.
Wednesday, January 7
Make an iGoogle Gadget for Your Game in 5 Steps
So the other day to help promote my game, I decided to create an iGoogle gadget.
For those who might know, Google allows users to setup their own homepage with nice little gadgets that do all sorts of things. You can check that out here: http://www.google.com/ig
To build a gadget you must understand that it consists of two parts.
xml file - This is the base file and contains all the formatting and javascript of your gadget.
data file - This contains the data that is displayed by your gadget
The gadget I am building is for my new game www.rpgcardz.com , the gadget will display the top ranking folks.
Step 1:
Get the developer gadget, from here, (click the add now link). It will allow you to refresh and test your gadget without posting to google's gadget directory. This is important...without this you will have a very hard time...go get it.
Step 2:
Create the xml document. Notice this looks very similar to an HTML document. Do the following to the file:
Step 3:
Notice there is some javascript here which calls a remote location and takes the content there and shoves it into a div. You will need to point the code to the right location and create the data file (see Step 4).
We use a special google function called _IG_FetchContent(), which you pass a url to and it calls the function that you specify and passes back the contents:
The main body of the page consists of some simple HTML. (If you can't make sense of this, you probably should not be doing this stuff.)
That one anyone can use them.
So highscores.php looks like the following:
Step 5:
Test, Test, Test...
Go to your iGoogle page, in the developer gadget you just added type the location of your XML file.
Watch the magic.
Notes and More:
Google caches your gadgets, they refresh the cached copy at least once a day. Check your cached copy before releasing to the world.
Try going putting the url of your data file in your browser...if it crashes or errors you have problems.
Try putting the url of your xml file in your browser...if it crashes or errors you have problems.
You can create the same type of gadget without using ajax. (PHP can generate xml docs...or you can do print statements to write the xml file)
Odd things happen with cached data, that could be the source of all your headaches.
Firebug is your friend (firebug's a javascript debugger plugin for firefox)
For those who might know, Google allows users to setup their own homepage with nice little gadgets that do all sorts of things. You can check that out here: http://www.google.com/ig
To build a gadget you must understand that it consists of two parts.
xml file - This is the base file and contains all the formatting and javascript of your gadget.
data file - This contains the data that is displayed by your gadget
The gadget I am building is for my new game www.rpgcardz.com , the gadget will display the top ranking folks.
Step 1:
Get the developer gadget, from here, (click the add now link). It will allow you to refresh and test your gadget without posting to google's gadget directory. This is important...without this you will have a very hard time...go get it.
Step 2:
Create the xml document. Notice this looks very similar to an HTML document. Do the following to the file:
- Edit the Author, Title, URL and Screenshot information in lines 1 to 10
- Edit the css style elements between lines 16 and 22
Step 3:
Notice there is some javascript here which calls a remote location and takes the content there and shoves it into a div. You will need to point the code to the right location and create the data file (see Step 4).
We use a special google function called _IG_FetchContent(), which you pass a url to and it calls the function that you specify and passes back the contents:
var requestType = "highscores";
var timer = null;
function getHighScores()
{
requestType = "highscores";
url = 'http://www.yoursite.com/rpgcardz.com/feeds/highscores.php'
//send request using google API
_IG_FetchContent(url, responseHandler, { refreshInterval: (10) });
}
function responseHandler(response)
{
if (response == null || typeof(response) != "string")
{
$("mainDiv").innerHTML = "It appears that no one is online...";
return;
}
fullText =response;
if(requestType == "highscores")
{
//take contents and shove it into the mainDiv
var d = document.getElementById("mainDiv");
d.innerHTML = fullText;
//Refresh in 10 min
timer = setTimeout("getHighScores()", 600000);
}
}
//call the function when the gadget loads
//another google api function
_IG_RegisterOnloadHandler(getHighScores);
The main body of the page consists of some simple HTML. (If you can't make sense of this, you probably should not be doing this stuff.)
The data that actually get displayed is generated by a different page. I usually put this in a folder called feeds. For example: www.rpgCardz.com/feeds/highscores.php
<center>
<a href="http://www.battleforcesonline.com" target=blank
><img src="http://www.rpgCardz.com/iGoogle/logo.jpg" border=0></a>
<h1>Rankings</h1>
<div id="mainDiv" style=" background-color: #EEE; margin:0 auto;">
Loading...
</div>
</center>
Step 4:
That one anyone can use them.
So highscores.php looks like the following:
//connect to the database
include_once "../connect.php";
//
// Make sure the page is not cached
//
header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
$sql = "select userID, username, score ";
$sql.= " from c_user ";
$sql.= " where isGuest = 'N' ";
$sql.= " order by score desc limit 10";
$q = executeQuery($sql);
?>
<table width=100%>
<tr>
<td class=label>Position</td>
<td class=label align=right>Score</td>
<td class=label>Player</td>
</tr>
</table>
Step 5:
Test, Test, Test...
Go to your iGoogle page, in the developer gadget you just added type the location of your XML file.
Watch the magic.
Notes and More:
Google caches your gadgets, they refresh the cached copy at least once a day. Check your cached copy before releasing to the world.
Try going putting the url of your data file in your browser...if it crashes or errors you have problems.
Try putting the url of your xml file in your browser...if it crashes or errors you have problems.
You can create the same type of gadget without using ajax. (PHP can generate xml docs...or you can do print statements to write the xml file)
Odd things happen with cached data, that could be the source of all your headaches.
Firebug is your friend (firebug's a javascript debugger plugin for firefox)
Monday, November 24
Server and Client Communications (Sort Of)
In a typical gaming environment there is a "game server" which is responsible for tracking all the communications between players (clients) within the game. Communications can be considered anything from the chat function, to the location of bullets within the game. Pretty much any piece of data that one player needs to send to another goes through the game server.
(That was in its simplest form, it is more complicated than that...go google it)
With a PBBG it gets a little tricky because there is no game server in play, its all cron jobs and reactions to players. (This is due to web development being "stateless"....again go google it, its why web programming is "different")
I use the following code to send interactions between two or more players. Pretty much you have a table that translates the game commands to each player...however the client code (javascript) has to be a bit smarter to handle the "statelessness" of the content)
See it in Action (note, you will have to enable popups)
If you want to implement it, you will need to create the following two tables.
User Table: Hopefully you allready have one of these, if so just add lastCommID to it.
Command Table: "Meat of the code"
Please keep in mind...USER IDs are HARD CODED in the source...you will need to config/play with that yourself.
For those that just like to "look". Here is some javascript....
(That was in its simplest form, it is more complicated than that...go google it)
With a PBBG it gets a little tricky because there is no game server in play, its all cron jobs and reactions to players. (This is due to web development being "stateless"....again go google it, its why web programming is "different")
I use the following code to send interactions between two or more players. Pretty much you have a table that translates the game commands to each player...however the client code (javascript) has to be a bit smarter to handle the "statelessness" of the content)
See it in Action (note, you will have to enable popups)
If you want to implement it, you will need to create the following two tables.
User Table: Hopefully you allready have one of these, if so just add lastCommID to it.
CREATE TABLE `lab_user` (
`userID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`userName` VARCHAR( 20 ) NOT NULL ,
`lastCommID` INT NOT NULL
) ENGINE = MYISAM ;
Command Table: "Meat of the code"
You can download the source here.
CREATE TABLE `lab_command` (
`commID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`userID` INT NOT NULL ,
`command` VARCHAR( 20 ) NOT NULL ,
`commandOptions` VARCHAR( 255 ) NOT NULL
) ENGINE = MYISAM ;
Please keep in mind...USER IDs are HARD CODED in the source...you will need to config/play with that yourself.
For those that just like to "look". Here is some javascript....
var xmlHttpDivID = "";
var ajaxInUse = false;
var readyToSend = true;
function getXmlHttpObject(handler)
{
var objXMLHttp=null;
if (window.XMLHttpRequest)
{
objXMLHttp=new XMLHttpRequest()
}
else if (window.ActiveXObject)
{
objXMLHttp=new ActiveXObject("Microsoft.XMLHTTP")
}
if(objXMLHttp == null)
{
alert("Your browser is not AJAX/Web 2.0 enabled");
}
return objXMLHttp;
}
//////////////////////////////////////////////////////////////////////////
//
//
// Sending the commands to the server
//
//
//
//////////////////////////////////////////////////////////////////////////
function mouseClicked(e)
{
if(readyToSend)
{
pos = getMousePos(e);
sendCommand("move", "player_|" + pos[0] + "," + pos[1]);
}
else
{
log("Waiting for a listener!");
}
}
function sendCommand(command, options)
{
if(!ajaxInUse)
{
ajaxInUse = true;
xmlHttp=getXmlHttpObject();
xmlHttp.onreadystatechange=commandSent;
url="commandHandler.php?action=sendComm";
url+="&userID="; //very bad, change this for testing...
url+="&command=" + command;
url+="&options=" + options;
url+="&cache_killer=" + Math.random();
xmlHttp.open("GET",url,true)
xmlHttp.send(null);
log("Command Sent");
}
else
{
log("Ajax is in use...try later");
}
}
function commandSent()
{
if (xmlHttp.readyState==4)
{
log("Command Sent and Done");
ajaxInUse = false;
}
}
//////////////////////////////////////////////////////////////////////////
//
//
// Reading Commands from the server
//
//
//
//////////////////////////////////////////////////////////////////////////
var commTimerID = "";
function startListening()
{
requestNextHttp=getXmlHttpObject();
url="commandHandler.php?action=start";
url+="&userID="; //very bad, change this for testing...
url+="&cache_killer=" + Math.random();
requestNextHttp.open("GET",url,true)
requestNextHttp.send(null);
//log("Ask for next command");
requestNextCommand();
}
function requestNextCommand()
{
requestNextHttp=getXmlHttpObject();
requestNextHttp.onreadystatechange=processCommand;
url="commandHandler.php?action=getComm";
url+="&userID="; //very bad, change this for testing...
url+="&cache_killer=" + Math.random();
requestNextHttp.open("GET",url,true)
requestNextHttp.send(null);
//log("Ask for next command");
clearTimeout(commTimerID);
}
function processCommand()
{
if (requestNextHttp.readyState==4)
{
str = requestNextHttp.responseText;
if(str != "")
{
log2(requestNextHttp.responseText);
performCommand(str);
}
commTimerID = setTimeout("requestNextCommand()", 3000);
}
}
function performCommand(str)
{
data = str.split("|");
if(data.length > 2)
{
commID = data[0];
sentByUserID = data[1];
command = data[2];
if(command == "move")
{
objID = data[3];
pos = data[4].split(",");
destX = pos[0];
destY = pos[1];
log("Moving " + objID + " to " + destX + "," + destY);
setDest(objID, destX, destY);
}
}
}
//
//add the event to the document
//
document.onclick = mouseClicked;
document.onload = startListening();
Javascript - Move that Image
Another Code Report,
How to move an image to another place on the screen. The user picks the location by clicking the mouse somewhere within the window.
This builds on the last code base, which featured the mouse Position finder code.
Watch It In Action (View source to get the code)
A couple of notes to keep in mind:
How to move an image to another place on the screen. The user picks the location by clicking the mouse somewhere within the window.
This builds on the last code base, which featured the mouse Position finder code.
Watch It In Action (View source to get the code)
A couple of notes to keep in mind:
- You can only click once, then you have to wait for it to get to it's destination
- log() - Puts a message in the div, a cheap debugging technique
- move() - The meat! What we call a re-cursive function, is called again and again until the object reaches its destination
- findPos() - returns the position of an object, this is actual a cheater function as it does not get the true position of an object. (see mobLib for the full function)
var speed = 1;
var moving = false;
function mouseClicked(e)
{
if(!moving)
{
pos = getMousePos(e); //from included js file
moving = true;
move("player", pos[0],pos[1]);
log("Clicked: " + pos[0] + "," + pos[1]);
}
else
{
log("Object is in the process of moving.");
log("Click refresh to start over.");
}
}
function log(msg)
{
document.getElementById("log").innerHTML = msg + "
" + document.getElementById("log").innerHTML;
}
function move(objID, destX, destY)
{
var obj = document.getElementById(objID);
var pos = findPos(objID);
currentX = pos[0];
currentY = pos[1];
newX = currentX;
newY = currentY;
if(destX > currentX)
{
//log("X:" + destX + " vs CurrentX: " + currentX);
newX+=speed;
}
if(destX <> currentY)
{
newY+=speed;
}
if(destY < top =" newY;" left =" newX;" t =" setTimeout(" moving =" false;" posx =" 0;" posy =" 0;" e =" window.event;" posx =" e.pageX;" posy =" e.pageY;" posx =" e.clientX" posy =" e.clientY" out =" new" obj =" document.getElementById(objectID);" curleft =" curtop" curleft =" obj.offsetLeft" curtop =" obj.offsetTop" onclick =" mouseClicked;">
Some things to try and play with:
- Can you speed up the movement to the destination?
- Can you add more images and allow the user to control more than 1?
- Can you make the image move so that it's center ends up on the destination point? (right now the top left corner ends up there)
Javascript - Finding that mouse position
I seem to constantly need this bit of code. Hope it helps someone else.
The following javascript code, finds the mouse position and returns it in an array.
Demo - You can see it in action here.
Credits - I got the basics of this script from here.
The following javascript code, finds the mouse position and returns it in an array.
function getMousePos(e) {
var posx = 0;
var posy = 0;
if (!e) var e = window.event;
if (e.pageX || e.pageY)
{
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY)
{
posx = e.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop
+ document.documentElement.scrollTop;
}
var out = new Array(2);
out[0] = posx;
out[1] = posy;
return out;
}
Demo - You can see it in action here.
Credits - I got the basics of this script from here.
Monday, November 3
Tool - Popup builder
An very old bit of code, written before popups were considered a curse.
This tool will allow a user to build their own popup screen and handler.
Again bit old, but I thought I'd put it out there.
View the Tool
This tool will allow a user to build their own popup screen and handler.
Again bit old, but I thought I'd put it out there.
View the Tool
Tool - Creating Drop Down Menus
Another experiment for the lab. I got a bit tired of creating those drop down menus by hand, so I built this page to help me create them.
Looking back, I could have built a code snippet or macro to do the same thing, but this was more fun to build.
All HTML and javascript.
Feel free to use and modify for your own use.
Right click and "View Source" to get code.
Drop Down Builder
Looking back, I could have built a code snippet or macro to do the same thing, but this was more fun to build.
All HTML and javascript.
Feel free to use and modify for your own use.
Right click and "View Source" to get code.
Drop Down Builder
Code - Javascript Animation
Many moons ago, I wrote this small library package. It handles a number of interactive functions that one might use on a Web 2.0 site.
It's not fully tested but I use parts and pieces of it quite often.
I figure that if anyone else finds it useful they might like to look at it. Especially those new to programming.
The most interesting is an animation function which allows you to set the velocity of a div tag and then watch it zoom around the screen.
Most functions are multi-browser compatible, I think one if IE only though.
Feel free to use for any of your projects. A link would be nice but not mandatory.
Source Available
It's not fully tested but I use parts and pieces of it quite often.
I figure that if anyone else finds it useful they might like to look at it. Especially those new to programming.
The most interesting is an animation function which allows you to set the velocity of a div tag and then watch it zoom around the screen.
Most functions are multi-browser compatible, I think one if IE only though.
Feel free to use for any of your projects. A link would be nice but not mandatory.
Source Available
Thursday, October 30
Path Finding in Javascript
I went back to the Lab (cause I needed to get my mind off the job). I decided to write a path finding algorithm in javascript.
I used my typical map setup. I found some pseudo-code for the A* path finder. I did the best I could (there was a heuristic in that pseudo code that I could not quite duplicate)
Anyway, it seems to work nicely. It does not find the shortest path, but it does find a path.
Feel free to use it for your own usage.
One Note: It uses a recurring function, I limited it to 40 loops. If you have a large map, you may need to up this a bit.
Take a Look
Source Code
I used my typical map setup. I found some pseudo-code for the A* path finder. I did the best I could (there was a heuristic in that pseudo code that I could not quite duplicate)
Anyway, it seems to work nicely. It does not find the shortest path, but it does find a path.
Feel free to use it for your own usage.
One Note: It uses a recurring function, I limited it to 40 loops. If you have a large map, you may need to up this a bit.
Take a Look
Source Code
Followers
Copyright 2009 mobeamer. Powered by Blogger
Blogger Templates created by Deluxe Templates
Wordpress by Nattywp