001.
package
com.synthdreams.GalacticBlast;
002.
003.
import
net.rim.device.api.ui.UiApplication;
004.
import
net.rim.device.api.ui.container.FullScreen;
005.
import
net.rim.device.api.ui.Graphics;
006.
import
net.rim.device.api.system.Characters;
007.
import
net.rim.device.api.system.Application;
008.
import
java.lang.Thread;
009.
import
java.lang.Math;
010.
import
java.util.*;
011.
012.
013.
014.
015.
016.
017.
018.
019.
020.
021.
022.
023.
024.
025.
026.
public
class
GamePlay
extends
FullScreen
027.
{
028.
029.
public
static
GFX gfx;
030.
public
static
SND snd;
031.
public
static
Random rndGenerator;
032.
033.
Refresher _refresher;
034.
EnemyAI _enemyai;
035.
Vector _objects;
036.
037.
boolean
_active;
038.
int
_score;
039.
040.
041.
boolean
getActive() {
return
_active; }
042.
int
getScore() {
return
_score; }
043.
044.
045.
046.
047.
private
class
Refresher
extends
Thread
048.
{
049.
050.
Refresher()
051.
{
052.
start();
053.
}
054.
055.
056.
public
void
run()
057.
{
058.
059.
060.
061.
int
cleanReturn;
062.
063.
064.
while
(_active)
065.
{
066.
067.
068.
processLevel();
069.
070.
071.
072.
073.
074.
for
(
int
lcv =
0
; lcv < _objects.size() ; lcv++)
075.
{
076.
((OBJ) _objects.elementAt(lcv)).process();
077.
}
078.
079.
080.
081.
082.
OBJ.collisionDetect(_objects);
083.
084.
085.
086.
cleanReturn = OBJ.cleanObjects(_objects);
087.
088.
089.
if
(cleanReturn >=
0
)
090.
{
091.
_score += cleanReturn;
092.
093.
094.
095.
096.
invalidate();
097.
}
098.
else
099.
{
100.
101.
_active =
false
;
102.
}
103.
104.
try
105.
{
106.
107.
this
.sleep(
50
);
108.
109.
}
110.
catch
(InterruptedException e)
111.
{
112.
113.
114.
}
115.
}
116.
}
117.
118.
}
119.
120.
121.
122.
123.
124.
private
class
EnemyAI
extends
Thread
125.
{
126.
EnemyAI()
127.
{
128.
start();
129.
130.
}
131.
132.
public
void
run()
133.
{
134.
135.
while
(_active)
136.
{
137.
138.
139.
140.
141.
142.
for
(
int
lcv =
0
; lcv < _objects.size() ; lcv++)
143.
{
144.
if
(_active)
145.
((OBJ) _objects.elementAt(lcv)).think(_objects);
146.
}
147.
148.
try
149.
{
150.
151.
this
.sleep(
1000
/
5
);
152.
153.
}
154.
catch
(InterruptedException e)
155.
{
156.
157.
}
158.
}
159.
160.
}
161.
162.
}
163.
164.
public
GamePlay()
165.
{
166.
snd =
new
SND();
167.
gfx =
new
GFX();
168.
169.
rndGenerator =
new
Random();
170.
171.
_active =
true
;
172.
_score =
0
;
173.
174.
175.
gfx.initBackground(
"stars.jpg"
,
3
);
176.
177.
178.
179.
180.
181.
182.
183.
184.
snd.playMusic(
"music.mid"
);
185.
snd.stopMusic();
186.
snd.playMusic(
"music.mid"
);
187.
188.
189.
_objects =
new
Vector();
190.
191.
192.
_objects.addElement(
new
Hero(Graphics.getScreenWidth() /
2
, Graphics.getScreenHeight() -
50
));
193.
194.
195.
196.
_refresher =
new
Refresher();
197.
_enemyai =
new
EnemyAI();
198.
199.
}
200.
201.
202.
203.
public
void
processLevel()
204.
{
205.
OBJ tempObject;
206.
207.
208.
209.
if
(gfx.getBackPos() %
25
==
0
)
210.
{
211.
212.
213.
tempObject =
new
EnemyDrone(rndGenerator.nextInt() % Graphics.getScreenWidth(),
0
);
214.
215.
216.
tempObject.setY(tempObject.getY() - tempObject.getBitmap().getHeight() +
3
);
217.
218.
219.
_objects.addElement(tempObject);
220.
}
221.
}
222.
223.
224.
225.
226.
protected
void
paint(Graphics graphics)
227.
{
228.
gfx.process(graphics, _objects, _score, ((Hero)_objects.elementAt(
0
)).getLives());
229.
}
230.
231.
232.
public
boolean
keyChar(
char
key,
int
status,
int
time)
233.
{
234.
235.
boolean
retVal =
false
;
236.
237.
switch
(key)
238.
{
239.
240.
case
Characters.ESCAPE:
241.
_active =
false
;
242.
retVal =
true
;
243.
break
;
244.
245.
246.
247.
case
Characters.SPACE:
248.
((Hero)_objects.elementAt(
0
)).fire(_objects);
249.
250.
retVal =
true
;
251.
break
;
252.
253.
default
:
254.
break
;
255.
}
256.
257.
return
retVal;
258.
}
259.
260.
261.
protected
boolean
navigationMovement(
int
dx,
int
dy,
int
status,
int
time)
262.
{
263.
264.
265.
if
(dx !=
0
)
266.
((OBJ)_objects.elementAt(
0
)).setVelX(dx/Math.abs(dx)*
5
+((OBJ)_objects.elementAt(
0
)).getVelX());
267.
268.
269.
270.
if
(dy !=
0
)
271.
((OBJ)_objects.elementAt(
0
)).setVelY(dy/Math.abs(dy)*
5
+((OBJ)_objects.elementAt(
0
)).getVelY());
272.
273.
return
true
;
274.
}
275.
276.
}
Hi Toni,
It is a great tutorial.
Would you kindly tell us where can we access the jpg and the music files for this game.
Many Thanks.
Regards,
Ibn
I have the same question as Ibn. Could you make the image and sound files available?
Very nice tutorial – thanks!!
S. G
Unfortunately, I can’t post the music as it’s copyrighted by Bjorn Lynne- I had to pay a fee to use it in my project. However, I highly suggest paying the fee if you would like it in your game, he does great work and has a number of midi files perfectly suited toward games at his site: http://www.lynnemusic.com/midi.html
The hero ship I also obtained from a site, and I believe it was GPL though I cannot remember for certain now, so use at your own risk
http://www.toniwestbrook.com/images/posts/herogame.png
The starfield I grabbed from a random google image search, any work pretty well.
Toni,
Very good complete, easy to follow, fun tutorial. I am a beginner in JAVA and BB development and have been looking around for weeks for a good UI tutorial like this. The others I have seen got me no where after I was done. But this tutorial touched on many aspects and it really gave me an overall sense of how to go about building an application. Many thanks. Again, Great work!
G.M.
Awesome, glad to hear it helped! I try to explain each section of code in my tutorials, as I know from reading other tutorials on the web that sometimes people assume you have certain knowledge that you might not – and then you’re lost for the rest of the tutorial. I figure no harm in just explaining everything I can, and people can ignore the bits they already know. Thanks again.
Hi, i need an immediate help. i need to move an image over the screen at random positions, just like a bee flying.. that is my task. am able to move the bee according to the directions keys of the keyboard. but i need to move without the key directions, i just start moving when i open that screen. i used timer control to call the move() for the image to move at random x, y positions. but it is not working well. so any help can be helpful
Hi Blanc –
Take a look at the EnemyDrone class in the OBJ file – it does exactly what you’re looking for already. Enemies with AI pattern 0 move with random velocities.
Hi, this tutorial is awesome, really well done, unlike a lot of other tutorials on the internet.
Im not that great with the BB development at the moment, i’ve just started to get into it after recently getting bb Strom. The problem i have is i was using this tutorial along with another open source app (MeBoy Gameboy emulator) because when i run MeBoy, it works on the storm, the problem is it doesn’t seem to pick up any key presses. I was using this tutorial as a reference but you used the track ball. Could you tell me the different codes i need in order to use different numeric keys? Or even point me into the right direction to find a tutorial.
any help would be awesome
Thanks for a really enjoyable and easy to follow tutorial you have something good going on here!
Brian.
Hi Toni:
Great tutorial, I followed it to create my own Spider Solitaire application, since there didn’t seem to be any that I really liked online that I could play without paying a fee.
One thing I noticed, however, is that the software runs fine in the simulator, but I notice that it’s quite slow when placed on an actual blackberry device. For example, the trackball movement from one card stack to another seems to lag behind the user by almost a second or more. I was wondering if you have any advice in efficiency from the simulator to the actual BB device.
Thanks,
Scott
Hi Brian – Sorry for the long delayed response, I’ve been away from the blog for too long. You can use the code above for using the keyboard for everything and leave the trackball out completely. Using the switch statement on line 237, you can pretty much process any incoming keypress. So you would move the code from the navigationMovement function to the keychar one.
Scott – usually it should happen the other way around, running very slowly on the emulator but quickly on the actual device. Slowdowns can happen in a few places – it’s important to look at:
1. How many threads you’re trying to run simultaneously. Threads are great for multitasking, but if you try to multitask past the ability of the processor, performance is going to suffer. You’ll either need to get fancy with when your threads are running, or move things out of threads into serial loops.
2. Check all your threads/loops for exactly how much code is being executed. If you’re trying to do more in a loop than is supported by your framerate, then everything is going to appear sluggish. The goal is to have processing done before the next frame starts.
3. Calls to the java mediaplayer take a while to buffer and start playing. If you notice the slow downs when a sound is being played, you have to do your best to start playing a sound when it won’t interrupt animation. This is a tricky dance.
4. Memory intensive functions – especially in loops (see #2) – make sure you’re not reloading bitmap data every frame, or something like that. This is another juggling act, depending on the Blackberry model you have, you don’t have a ton of memory to play with, so you have to choose between preloading as much as you can to make performance acceptable, but not loading so much that you exhaust your memory (which also causes performance issues).
Hope those help a bit to get you started.
Yes, these help greatly. Thanks for the suggestions, and for posting the tutorial!
-Scott
Thanks you. Very helpful.
thank u very much for giving us such a helpful tutorial.
gfx.initBackground(“stars.jpg”, 3);
Hi Toni,
It is a very good tutorial and I thank you so much for sharing this with us, especially for people like me who are still in early learning curve in blackberry/JAVA development.
I’ve come accross this problem where my simulator (i guess) could not recognise the png or jpg file I put from a code like this:
gfx.initBackground(“stars.jpg”, 3);
I am wondering where exactly should we put the png/jpg file in a directory, or should we load it with the IDE (I use Eclipse). Should we also put complete path name in the code above?
Appreciate any help.
Many thanks,
Adi
Hi Adi – thanks for the kind words! Glad its helped out a bit. If you take a look at the initBackground method of gfx (GFX class), you’ll see it makes a call to:
Bitmap.getBitmapResource
Anytime you see a getResource kind of method (Bitmaps, InputStreams, etc), it’s going to be looking within your COD file for the resource in question. To put it into your COD file, you want to add it to your project in Eclipse. Then when you compile your source, it will add your resource into the final product (COD file).
You can put path information into any getResource, but the root of the search is the base of the package. So for instance, my Eclipse project is setup as:
GalacticBlastDemo
–src
—-com.synthdreams
——stars.jpg
Which would match a search for “stars.jpg” without any additional path info, akin to how it’s setup in the code above. Hope that helps – let me know if any of that didn’t make sense
Toni,
Success!! I put the png files in ‘src’ folder and it works! I’ve also noticed that ‘png’ and ‘PNG’ matters
Thanks a lot!
Sir
Thank u for giving such a valuable information i need images and audio files for this game could u please send them to my mail jayachandra.06ie9@gmail.com
the best i have ever seen in recent months… buddy, you rocks! It is an incredible tutorial. You don’t have idea how this post helps to beginner developers… you rocks!!!
@jacsdev
I’am not found file PNJ in project.please give me all file .PNJ.
thanks so much
Hi Mash –
If you take a look above, I link to one of the png files I used for the spaceship as an example. However, you’ll want to grab some others (e.g. from Google Images) or make your own, whatever works best for the game you’re making.