You Are Here:

Community: Blogs

Widget Workshop's Forum Nokia Blog

Developing our first widget: Bombus

mobileradicals | 20 September, 2007 12:33

Firstly, sorry for the delay in writing up the next installment of our S2F blog - we found it difficult to develop and blog simultaneously. So, with that in mind, let's start with a confession:

The game's already finished! It's called Bombus, and as promised, it's a side-scrolling arcade game.

Bombus screenshots

Here's a video showing the gameplay:

Whilst developing the game we took notes, but to do each blog entry justice (by including a write-up after the end of each step) would have resulted in delaying the completion date significantly.

However, we now have some free time to write down our experiences, and more importantly, share some code. So whilst this might go against the S2F ethos slightly, we hope you can forgive us and hopefully seeing how the game turned out will help.

1. Getting started

Our first step was to download the SDK from the WidSets wiki. The wiki is an invaluable source of information containing general development guides as well as scripting and configuration documentation. The WidSets developer forum also proved useful as members of the WidSets team seem to visit often and are quick to offer help and advice.

The SDK consists of a set of command-line tools for compiling, invoking the emulator, uploading widgets etc (WidSets SDK wiki article). We used UltraEdit as our IDE, which is essentially a powerful text-editor. The SDK contains a syntax highlighting file for UltraEdit which helps with code readability. With the SDK installed, we encountered our first minor problem: widgets are distributed centrally from the WidSets server, so in order to login and subsequently upload/publish widgets, a connection to the server is necessary. Here at Lancaster University, we sit behind a proxy server, so we had to define our connection settings before we could connect.

So instead of:

> devkit login username password

We had to use:

> devkit --proxy wwwcache.lancs.ac.uk:8080 --auth user1 pass1 login user2 pass2

Where user1 and pass1 are our proxy authentication details and user2 and pass2 are our WidSets username and password (the proxy need only needs to be defined once). To register a developer account at WidSets, we visited http://dev.widsets.com/install - currently this link isn’t easy to find on the main site. N.B. The WidSets developer client is different to the regular client.

After following the guides on the wiki, checking out a few of the examples and with the scripting, configuration and stylesheet documentation open in the browser, we were ready to start.

We used the Hello World (found in examples/hello_world) example as the starting template for our own widget. Copying all the files from this directory to our working directory (bombus/) allowed us to bootstrap the development. The wiki provides a good overview of the files to are need to make up a widget here.

Here's what the first version of Bombus looked like...

Screenshots first step


Not much of a game yet, but we can get an idea of where our game content will be (on the blue canvas). The important files used to create this version are listed below.

Configuration file (widget.xml):
<?xml version="1.0" encoding="utf-8"?>
<widget spec_version="2.0">
<info>
<name>Bombus</name>
<version>0.1</version>
<author>Widget Workshop</author>
<shortdescription>
A one button side scrolling arcade game
</shortdescription>
<longdescription>
Guide Bombus through the cave.
</longdescription>
<tags>
bombus game arcade side scrolling one button
</tags>
</info>
<parameters>
<parameter
type="string"
name="widgetname"
description="Name of widget"
help="This is the name of the widget"
editable="false"
visible="true">
Bombus
</parameter>
</parameters>
<resources>
<code src="bombus.he"/>
<stylesheet src="style.css"/>
<img src="mobile_radicals.png" scale="false" />
</resources>
<layout minimizedheight="3em">
<view id="viewMini">
<label class="outerFrame">Bombus</label>
</view>
<view id="viewMain">
<script id="gameView" />
</view>
</layout>
</widget>
Helium script (bombus.he):
class {

// Command IDs
const int CMD_BACK = 1;
const int CMD_NEW_GAME = 10;
const int CMD_INSTRUCTIONS = 11;
const int CMD_ABOUT = 12;

// Member vars.
Shell gameShell;
Flow gameFlow;
Canvas gameCanvas;

// Menu items (mapped to softkeys)
MenuItem BACK = new MenuItem(CMD_BACK, "Back");
MenuItem OPTIONS = new MenuItem(OPEN_MENU, "Options");

// Create options menu (using chaining)
Menu MENU = new Menu()
.add(CMD_NEW_GAME, "New game")
.add(CMD_INSTRUCTIONS, "Instructions")
.add(CMD_ABOUT, "About");

// Push shell onto screen
void showShell(Shell shell) {
int w, int h = getScreenSize();
slideIn(-w, 0, w, h, shell);
}

// Pop shell off screen
void hideShell(Shell shell) {
int w, int h = getScreenSize();
slideOut(w, 0, w, h, shell);
}

// Called for each view element
Component createElement(
String viewId, String elementId, Style s, Object o) {

if(elementId.equals("gameView")) {

gameFlow = new Flow(getStyle("outerFrame"));
gameCanvas = new Canvas(getStyle("default"));
gameCanvas.setPreferredSize(-50, -50);
gameFlow.add(gameCanvas);

return gameFlow;

}
return null;
}

// Create minimized view
void startWidget() {
setMinimizedView(createView("viewMini", null));
}

void stopWidget() {} // Stop

// Create maximized view when the widget is opened
Shell openWidget() {
gameShell = new Shell(createView("viewMain", null));
showShell(gameShell); // Show main shell
return null; // We've already push shell into view
}

// Release resources
void closeWidget() {
gameCanvas = null;
gameFlow = null;
gameShell = null;
}

// Paint the gameCanvas
void paint(Component c, Graphics g, Style s, int w, int h) {
g.setColor(0x0000FF);
g.fillRect(0, 0, w, h);
g.setColor(0xFFFFFF);
g.drawString(
"Our canvas!", w / 2, h / 2, HCENTER | TOP);
}

// Get the menu
Menu getMenu(Shell shell, Component source) {
return MENU;
}

// Softkey event handler
MenuItem getSoftKey(Shell shell, Component focused, int key) {
if(key == SOFTKEY_OK)
return OPTIONS;
else if(key == SOFTKEY_BACK)
return BACK;
return null;
}


// Key event handler
boolean keyAction(Component source, int op, int code) {
return false; // Key event not consumed
}

// Action event handler
void actionPerformed(Shell shell, Component source, int action) {

switch(action) {
case CMD_NEW_GAME:
break;
case CMD_INSTRUCTIONS:
break;
case CMD_ABOUT: // Display 'about' info.
setBubble(
getImage("mobile_radicals.png"),
"Bombusnmobileradicals.com");
break;
case CMD_BACK:
// Pop shell
hideShell(shell);
break;
}
}
}
Stylesheet (style.css):
outerFrame {
align: hcenter vcenter;
background: solid #000000;
color: #FFFFFF;
width: 100%;
}
Please note, blogs after this will not post complete source listings, but instead provide important fragments that demonstrate key game concepts.

RSSComments

change the name

kellogs | 27/03/2008, 01:21

Hello developpers,

please have a look at www.bombus-im.org.

Bottomline: an application named bombus have been arround for very much longer than your game. This is what have caught my eye while I was browsing nokia's newsletter - the word "bombus". This j2me jabber client is also far more popular and complex than the bombus game.
I dont know anything about the intellectual rights on the name "bombus", but I really hope you will change your app's name.

Regards,
kellogs

Re: Developing our first widget: Bombus

WebSeed | 15/04/2008, 14:04

kellogs, the widget is called "Bombus Game" and Bombus is latin for "bumblebee" - I don't really see too much of a problem here (although I must admit, I hadn't spotted this when I did the initial name search).

And as for:

"This j2me jabber client is also far more popular and complex than the bombus game."

I really don't see what this has to do with anything!? We aren't claiming to have developed anything particularly complex - that's kind of the point of widgets.

You must login to post comments. Login
 

Rate This

 
 
Bookmark this page: DeliciousDiggFacebookGoogleYahooStumbleUponRedditDiigoTechnocratiTwitter  Share this page Share this page Print this Page Print this page Invite a friend Invite a friend
京ICP备05048969号    Email Newsletters Press Terms & Conditions Privacy Policy Sitemap Contact Us © 2009 Nokia 
RDF Facets: qdcZdescriptionQSxmobileradicalsE20E7cE2020E20SeptemberE2cE202007E2012E3a33E20FirstlyE2cE20sorryE20forE20theE20delayE20inE20writingE20upE20theE20neE78tE20installmentE20ofE20ourE20S2FE20blogE20E2dE20weE20foundE20itE20difficultE20toE20developE20andE20blogE20simultaneouslyE2eE20SoE2cE20withE20thatE20inE20mindE2cE20letE27sE20startE20withE20aE20confessionE3aE20TheE20gameE27sE20alreadyE20finishedE21E20ItE27sE20calledE20BombusE2cE20andE20asE20promisedE2cE20itE27sE20aE20sideE2dscrollingE20arcadeE20gameE2eE20HereE27sE20aE20videoE20showingE20theE20gameplayE3aE20WhilstE20developingE20theE20gameE20weE20tookE20notesE2cE20butE20toE20doE20eachE20blogE20entryE20justiceE20E28byE20includingE20aE20writeE2dupE20afterE20theE20endE20ofE20eachE20steE2eE2eE2eX qdcZidentifierQSxhttpE3aE2fE2fblogsE2eforumE2enokiaE2ecomE2fblogE2fwidgetE2dworkshopsE2dforumE2dnokiaE2dblogE2f2007E2f09E2f20E2fdevelopingE2dourE2dfirstE2dwidgetE2dbombusX qdcZpublisherQUxhttpE3aE2fE2fswE2enokiaE2ecomE2fidE2fc764fd1cE2d8b06E2d499aE2d9a6aE2d17c3903d5a65E2fforumE5fnokiaE5fcrawlerE5fagentX qdcZtitleQSxWidgetE20WorkshopE27sE20ForumE20NokiaE20BlogE20E7cE20E44evelopingE20ourE20firstE20widgetE3aE20BombusX qdcZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qdcZtypeQUqfntypeZBlogContentQ qdcZtypeQUqfntypeZBlogE45ntryQ qdcZtypeQUqfntypeZCommunityContentQ qdcZtypeQUqfntypeZE52esourceQ qdcZtypeQUqfntypeZWebpageQ qdcZtypeQUqmarsZManagedE52esourceQ qdcZtypeQUqwebZInformationE52esourceQ qdcZtypeQUqwebZPageQ qdcZtypeQUqwebZE52esourceQ qdcZtypeQUqrdfsZE52esourceQ qrssZdescriptionQSxmobileradicalsE20E7cE2020E20SeptemberE2cE202007E2012E3a33E20FirstlyE2cE20sorryE20forE20theE20delayE20inE20writingE20upE20theE20neE78tE20installmentE20ofE20ourE20S2FE20blogE20E2dE20weE20foundE20itE20difficultE20toE20developE20andE20blogE20simultaneouslyE2eE20SoE2cE20withE20thatE20inE20mindE2cE20letE27sE20startE20withE20aE20confessionE3aE20TheE20gameE27sE20alreadyE20finishedE21E20ItE27sE20calledE20BombusE2cE20andE20asE20promisedE2cE20itE27sE20aE20sideE2dscrollingE20arcadeE20gameE2eE20HereE27sE20aE20videoE20showingE20theE20gameplayE3aE20WhilstE20developingE20theE20gameE20weE20tookE20notesE2cE20butE20toE20doE20eachE20blogE20entryE20justiceE20E28byE20includingE20aE20writeE2dupE20afterE20theE20endE20ofE20eachE20steE2eE2eE2eX qfnZdistributionQUxhttpE3aE2fE2fblogsE2eforumE2enokiaE2ecomE2fX qfnZtopicQUqfnTopicZbrowsingQRqdcZtypeQUqrdfsZE52esourceQRqmarsZrelevanceQNx100X qfnZtopicQUqfnTopicZentertainmentQRqmarsZrelevanceQNx100X qfnZtopicQUqfnTopicZgamesQRqdcZtypeQUqrdfsZE52esourceQRqmarsZrelevanceQNx100X qfnZtopicQUqfnTopicZjavaQRqdcZtypeQUqrdfsZE52esourceQRqmarsZrelevanceQNx100X qfnZtopicQUqfnTopicZwebE5ftechnologyQRqmarsZrelevanceQNx100X qfnZtypeQUqfntypeZBlogContentQ qfnZtypeQUqfntypeZBlogE45ntryQ qfnZtypeQUqfntypeZCommunityContentQ qfnZtypeQUqfntypeZE52esourceQ qfnZtypeQUqfntypeZWebpageQ qfnZupdatedQDx2008E2d04E2d15X qfnZuserE5ftagQSxbrowsingX qfnZuserE5ftagQSxentertainmentX qfnZuserE5ftagQSxgamesX qfnZuserE5ftagQSxjavaX qfnZuserE5ftagQSxwebE2dtechnologyX qmarsZdescriptionQSxmobileradicalsE20E7cE2020E20SeptemberE2cE202007E2012E3a33E20FirstlyE2cE20sorryE20forE20theE20delayE20inE20writingE20upE20theE20neE78tE20installmentE20ofE20ourE20S2FE20blogE20E2dE20weE20foundE20itE20difficultE20toE20developE20andE20blogE20simultaneouslyE2eE20SoE2cE20withE20thatE20inE20mindE2cE20letE27sE20startE20withE20aE20confessionE3aE20TheE20gameE27sE20alreadyE20finishedE21E20ItE27sE20calledE20BombusE2cE20andE20asE20promisedE2cE20itE27sE20aE20sideE2dscrollingE20arcadeE20gameE2eE20HereE27sE20aE20videoE20showingE20theE20gameplayE3aE20WhilstE20developingE20theE20gameE20weE20tookE20notesE2cE20butE20toE20doE20eachE20blogE20entryE20justiceE20E28byE20includingE20aE20writeE2dupE20afterE20theE20endE20ofE20eachE20steE2eE2eE2eX qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX qrdfZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qrdfZtypeQUqfntypeZBlogContentQ qrdfZtypeQUqfntypeZBlogE45ntryQ qrdfZtypeQUqfntypeZCommunityContentQ qrdfZtypeQUqfntypeZE52esourceQ qrdfZtypeQUqfntypeZWebpageQ qrdfZtypeQUqmarsZManagedE52esourceQ qrdfZtypeQUqwebZInformationE52esourceQ qrdfZtypeQUqwebZPageQ qrdfZtypeQUqwebZE52esourceQ qrdfZtypeQUqrdfsZE52esourceQ