yashsingh1/xdaforums huggingface dataset:
[Java for Android App Development] Wampirate:
Worked, thanks a lot :) I had the variables inside the method
[Java for Android App Development] Wampirate:
If anybody can take a look and comment that would be great :)

[MENTION=439709]override[/MENTION]
public void run() {
Canvas c;
long beginTime;
long timeDiff;
int sleepTime;
int framesSkipped;

sleepTime=0;
while(running)
{
c = null;
if(!holder.getSurface().isValid())
{
continue;
}

c = holder.lockCanvas();
beginTime= System.currentTimeMillis();
framesSkipped=0;
if (gameState==states.PLAYING)	gameUpdate();
synchronized(holder) {
onDraw(c);
}
timeDiff = System.currentTimeMillis() - beginTime;
sleepTime = (int)(framePeriod-timeDiff);
if (sleepTime>0)
{
try {thread.sleep(sleepTime);}
catch (InterruptedException e) { e.printStackTrace(); }
}
else if (sleepTime<0)
{
while(sleepTime<0 && framesSkipped<maxFrameSkips)
{
if(gameState==states.PLAYING) gameUpdate();
sleepTime+=framePeriod;
framesSkipped++;
}
}
holder.unlockCanvasAndPost(c);
}

}

This is my run method, the thing is that its still not that smooth ingame, maybe I can improve some things a bit?
[Java for Android App Development] nikwen:
I would never use a fixed framerate but calculate the movement depending on the timeDiff.

That would increase the fps count.
[Java for Android App Development] Wampirate:
Can you extend? I kinda didn't get that
[Java for Android App Development] nikwen:
Of course, I can:

You remove that sleeping thing so that the app runs as fast as possible.

However, if you do things like

playerX += 20;

now, the character will be faster or slower on one phone than on another. Additionally, you will not get a constant framerate.

So do something like this:

playerX += timeDiff * speed;

That could be

playerX += timeDiff * 0.02;

for 20 pixels per second.

One more point: Using your current solution, what would you do if the device was a very old one (like mine) and was not able to run the game with your framerate, e.g. 30 fps?

Frame independent movement always is the best solution. ;)
[Java for Android App Development] Wampirate:
But timeDiff differs in each phone, how will that make it the same speed of the character in every phone? Btw I move the character or the obstacles during gameUpdate(), which is before timeDiff is counted.

Additionally, I'm thinking that in faster phones, not locking the fps might cause the overheat of the cpu? Or is it unlikely?

Could you please write how it should look like? I mean the whole run method

[MENTION=439709]override[/MENTION]
public void run() {
Canvas c;
long beginTime;
long timeDiff=0;

while(running)
{
c = null;
if(!holder.getSurface().isValid())
{
continue;
}
beginTime= System.currentTimeMillis();
c = holder.lockCanvas();
synchronized(holder) {
onDraw(c);
}
timeDiff = System.currentTimeMillis() - beginTime;
if (gameState==states.PLAYING)	gameUpdate(timeDiff);
holder.unlockCanvasAndPost(c);
}

}

By editing this code. In my run method I only call draw and gameUpdate
[Java for Android App Development] nikwen:
The edited code:

Add this field to your class:

int oldTime =System.currentTimeMillis();

Your run method:

[MENTION=439709]override[/MENTION]
public void run() {
Canvas c;
long timeDiff=0;

while(running)
{
if(!holder.getSurface().isValid())
{
continue;
}
beginTime= System.currentTimeMillis();
timeDiff = beginTime -oldTime;
if (gameState==states.PLAYING)gameUpdate(timeDiff);

c = holder.lockCanvas();
synchronized(holder) {
onDraw(c);
}
holder.unlockCanvasAndPost(c);
oldTime = beginTime;
}

}

Yeah, timeDiff is different on each phone. However, that is the advantage of the method. Let me explain.

Some phones might be able to run your game with 60 fps while others might get only 30 fps. Why should we limit those new phones by using a fixed framerate of 30 fps?

Instead we measure that time difference between each frame. Let's say that your object should move by 20 pixels per second. Now we measure that timeDiff and pass it to gameUpdate(). In gameUpdate we do it that way:

You know the formula: s = v * t

We have got the time t (timeDiff) and the speed v (20 px per second). So we can calculate the movement s:

movementX = 20 * timeDiff /1000f; //because timeDiff is measured in milliseconds

That results in that:

playerX += movementX

Or

playerX += 0.02 * timeDiff;

That way the game can run with 60 or 70 fps on the high-end device and with less on my old device. ;)

The movement per second will always be the same. (With more fps, the movement per frame will be lower, but due to the higher number of frames, the movement per second will always be the same).

Did you get it now?

One more thing:

Using your old code with a fixed framerate: What would happen if timeDiff was higher than your framePeriod? It would result in sleeping for a negative time. => EXCEPTION.
[Java for Android App Development] Wampirate:
I get it thanks :)

I had it covered:

else if (sleepTime<0)
{
while(sleepTime<0 && framesSkipped<maxFrameSkips)
{
if(gameState==states.PLAYING) gameUpdate();
sleepTime+=framePeriod;
framesSkipped++;
}
}

I have another question :) What bigger resolutions than 800x480 other than 1280x720 and 1920x1080 are there in android phones? But it's not that much relevant. I wanted to play music during playing but I have problems with loading the file.

The relevant parts of code:

public GameView(Context context) {
super(context);
myContext=context;
sounds = new SoundPool(5,AudioManager.STREAM_MUSIC,0);
inGameMusic = sounds.load(myContext,R.drawable.fivearmies,1);
}

then I play it using sounds.play(inGameMusic,1,1,1,-1,1);
[Java for Android App Development] nikwen:
Ah, I did not see that.

I do not know anything about the screen sizes. I just know that mine is 320 x 480 px. :laugh:

Fo the music: I always used the MediaPlayer class: http://developer.android.com/reference/android/media/MediaPlayer.html

In your code you want to load a drawable as music?! R.drawable. ...
[Java for Android App Development] Wampirate:
It only means that my music is in drawable folder in res folder...

I hate the api because it doesnt show any examples.
[Java for Android App Development] nikwen:
You cannot put music into the drawable folder. Put it in res/raw/.

(The compiler converts the graphics files to another optimized format. That is why you cannot put it in res/drawable)

Then start it that way:

MediaPlayer mp = MediaPlayer.create(<the app context>, R.raw.my_sound);
mp.start();

In an Activity the app context is "this".

They improve the API. You can find examples for some classes now. :)

---------- Post added at 04:10 PM ---------- Previous post was at 03:33 PM ----------

Another thing related to the screen sizes: You could have a look at the standard AVD screen sizes. Those should be the most common ones.
[Java for Android App Development] Wampirate:
Thanks I'll try the sounds in a moment. I was at a shopping mall today and went to an electronic store where they had some phones on exhibition for people to play with them.

I had my app apk file on my phone and sent it via bluetooth to sgs IV and galaxy note II (because the former has 1920x1080 resolution and the latter 1280x720) and my app looks good on both so I'm doing ok, don't have to worry about different resolutions.

EDIT: Tried the mediaplayer and it doesnt work :<

MediaPlayer gameMusic;
gameMusic = MediaPlayer.create(myContext,R.raw.fivearmies);
gameMusic.start();

And errors from LogCat

07-14 17:25:09.255: E/MediaPlayer(17473): Error (-38,0)
07-14 17:25:09.255: V/MediaPlayer(17473): back from callback
07-14 17:25:15.485: V/MediaPlayer-JNI(17473): start
07-14 17:25:15.485: V/MediaPlayer(17473): start
07-14 17:25:15.485: E/MediaPlayer(17473): start called in state 0
07-14 17:25:15.485: V/MediaPlayer(17473): message received msg=100, ext1=-38, ext2=0
07-14 17:25:15.485: E/MediaPlayer(17473): error (-38, 0)
07-14 17:25:15.485: V/MediaPlayer(17473): callback application
07-14 17:25:15.485: V/MediaPlayer(17473): back from callback
07-14 17:25:15.490: E/MediaPlayer(17473): Error (-38,0)
07-14 17:25:17.300: V/MediaPlayer-JNI(17473): stop
07-14 17:25:17.300: V/MediaPlayer(17473): stop
07-14 17:25:17.300: E/MediaPlayer(17473): stop called in state 0
07-14 17:25:17.300: V/MediaPlayer(17473): message received msg=100, ext1=-38, ext2=0
07-14 17:25:17.300: E/MediaPlayer(17473): error (-38, 0)
07-14 17:25:17.300: V/MediaPlayer(17473): callback application
07-14 17:25:17.300: E/MediaPlayer(17473): Error (-38,0)
07-14 17:25:17.300: V/MediaPlayer(17473): back from callback

EDIT2: Got it to work, I was using .ogg file , .mp3 works fine but only once. I mean I start it when my gamestate is changed to playing state, and stop the music when my gamestate is changed from playing to another state, and it works but then when I play again there is no sound. Any ideas? :)

EDIT3: It works if I create it again and again and again but that's pointless, is there any other way perhaps?

EDIT4: :D:D:D I kinda didn't understand the whole thing. There is supposed to be one MediaPlayer in which I later load sounds that I want to be played ^^ How do I do multiple sounds at a time then? How does it know which one do I want to stop and which one do I want to still be playing?
[Java for Android App Development] nikwen:
Check this: http://stackoverflow.com/questions/3855151/how-to-resume-the-mediaplayer

And this: http://stackoverflow.com/questions/9461056/android-media-player-play-pause-button
[Java for Android App Development] Wampirate:
Why can't I use ogg format? It takes a lot less space, I only put 3 songs as mp3 and the whole apk is now 26 mb, it was 500 kb before.

What you send me still doesn't tell me how to play again after stopping, I know now that I have to prepare() it first after stopping but then it doesn't play from the beginning but from the moment where it was stopped which I dont want.
[Java for Android App Development] nikwen:
There is a method seekTo:

mp.seekTo(0);
[Java for Android App Development] Wampirate:
I missed that :D Totally was searching for a method like this but I thought it would be mp.set... :) Thanks a lot :) I'll start giving thanks for each answer you give me ^^

But what about the ogg files or other format than mp3? It makes the app weigh a lot of mbs ;p
[Java for Android App Development] nikwen:
Seem as if it is not supported: It IS supported: http://developer.android.com/guide/appendix/media-formats.html

Welcome. :) And thanks for the thanks. :laugh:
[Java for Android App Development] Wampirate:
I'm gonna have to trim the music a bit. Do you know if cutting royalty free music and using it later comercially is legal or not?

And how do you do the background graphics so that they look good on all screen resolutions? I know I can scale, but there are 4:3 screens, 16:9 screens and so on, and then it doesn't look ok after scaling, because its stretched and looks unnaturally.
[Java for Android App Development] out of ideas:
You should check with whom you get the music from originally. generally "royalty-free" would mean just that, but you definitely don't want a headache and a pulled app later down the road.

i though ogg was standard android format? most boot sounds and ringtones are such.

I know thats another thing andengine can help with, but there has to be some other way to play it.

http://www.matim-dev.com/sound-and-music.html

but there has to be an easier way. all my dumb stock ringtones and alarms and notifications are .ogg, and yours probably are too.
[Java for Android App Development] nikwen:
Had a look at the website again and it IS supported: http://developer.android.com/guide/appendix/media-formats.html (under Vobis)

Sorry for the wrong information.

A solution from the web:

http://www.anddev.org/multimedia-pr...shing-with-could-not-create-track-t17028.html

They play ogg files here, too: http://blog.endpoint.com/2011/03/api-gaps-android-mediaplayer-example.html?m=1

---------- Post added at 10:37 AM ---------- Previous post was at 10:35 AM ----------

Have a look at the licenses of the sounds. For example some want you to add the artist to the credits, but others do not allow commercial use.

---------- Post added at 10:40 AM ---------- Previous post was at 10:37 AM ----------

You could make the background images a little bit bigger than needed and crop some parts when it is displayed so that it covers the full screen without stretching.
[Java for Android App Development] Wampirate:
Yeah but... It has to work both on 320x480 and 1920x1080(galaxy s4). I can't just cut everything on 320x480.

I think I'll have to scale first but in a way that the picture will never be smaller than the screen, I mean I'll make all my backgrounds squares, then it should be okay

Do you know if its possible to draw text with custom font?
[Java for Android App Development] sak-venom1997:
Hi

OP is related to game development so posting here

Anybody there have an idea to use an onDragListner

I basically need to know the distance shifted of the view and the direction of the chage that is left/right or top/bottom from the initial position
[Java for Android App Development] nikwen:
Please create your own thread for that. Let's cover one topic per thread. Everything else causes confusion.

---------- Post added at 06:15 PM ---------- Previous post was at 06:08 PM ----------

Exactly. That is what I meant. Squares should work perfectly.

Here you go for the fonts: http://www.javacodegeeks.com/2011/09/android-game-development-using-bitmap.html
[Java for Android App Development] Wampirate:
The fonts seem complicated, but I'll try to comprehend it in some time. Thanks :)

For now I just made different texts like "play" or game name as images in gimp, like pure text written in the font I downloaded on transparent screen :> I also made it very big resolution and scale it so that it looks good on every phone.

I kinda soon will also have to save some info to the phone memory, like highscores, gold collected, purchases. Do you know any tutorials on that? :D

EDIT: I found about SharedPreferences, I'll try to use it and create highscores.
[Java for Android App Development] nikwen:
I would use a simple text file for the highscores if you want to save more than one. In my view it would be easier.
[Java for Android App Development] Wampirate:
Perhaps it would if only I knew how to do that both in java and android :D

In addition it also makes it possible for the players to manually change the scores by editing the text file which is unwanted. I'd have to encrypt it somehow.

BTW changed name of the thread so that it better reflects what it is about
[Java for Android App Development] nikwen:
Have a look at the FileWriter/FileReader classes.

You can get the file directory you can use for your app with getFilesDir().
[Java for Android App Development] Wampirate:
I'll look into it.

I have a problem again ^^ I made a pause/resume button available during gameplay, and it works. The problem is that when I close the app while it's paused and then return to it, it shows black screen. I can resume by touching where the resume button would appear and everything works. How can I draw everything once after returning ? Creating a temporary canvas and using my onDraw() method crashes the app ;/

Another question is how do I implement multitouch? I imagine it has to be pretty difficult :D I've added shooting and I can't shoot while moving which is kinda bad ;d

EDIT: I found about the multitouch and I'll try to implement it, if something goes wrong I'll post it here :D Still haven't found the solution to the black screen after onResume()
[Java for Android App Development] Wampirate:
bump

I tried using FileReader / FileWriter classes, I managed to write some text to a .txt file in a specific folder on my storage card but I cannot read it. Here's the code:

Writing text to file:

private FileOutputStream fOut;
private OutputStreamWriter osw;

private GameView view;

[MENTION=439709]override[/MENTION]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
view = new GameView(this);
setContentView(view);
view.setKeepScreenOn(true);
view.setFocusable(true);

File sdCard = Environment.getExternalStorageDirectory();
File directory = new File (sdCard.getAbsolutePath() + "/GameFiles");
directory.mkdirs();

File file = new File(directory, "mysdfile.txt");
try {
fOut = new FileOutputStream(file);
osw = new OutputStreamWriter(fOut);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
[MENTION=439709]override[/MENTION]
protected void onDestroy()
{
String s = view.getDataFileText();
try {
osw.write(s);
osw.flush();
osw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Reading text

private FileInputStream fis;
private InputStreamReader isr;

File sdCard = Environment.getExternalStorageDirectory();
try {
fis = new FileInputStream(sdCard.getAbsolutePath()+"/GameFiles/mysdfile.txt");
isr = new InputStreamReader(fis);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
CharBuffer target = CharBuffer.allocate(100);
try {
isr.read(target);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("string",target.toString());

What do I do wrong? I kinda don't get the CharBuffer
[Java for Android App Development] nikwen:
Hm, you do not need the CharBuffer.

Just use two classes: java.io.FileReader and java.io.FileWriter

You do not need all those Streams. It can be done easier.

If you want to read and write files on the SD card, your app needs the right permission.

However, you can use the directory you get using getFilesDir() without it.

That will be the path: /data/data/<your package>/files/

The other advantage is that every other app needs SU rights to access it. So only rooted users can modify the file. (They can also modify the SharedPreferences.)

If the screen is black after returning to the app, you need to call the drawing code once in onResume(), but just if onPause() was called before.
[Java for Android App Development] Wampirate:
EDIT : Nevermind the text saving and reading, I got it. :)

About the black screen though

[MENTION=439709]override[/MENTION]
protected void onResume() {
// TODO Auto-generated method stub
if (view.gameState != view.getPlayingState())	view.resume();
if (view.ifPaused()){
Canvas c = null;
view.onDraw(c);
}

super.onResume();
}

this crashes the app;/ ifPaused() returns whether the game is paused or not

No idea what could be the problem here ;<

Do you know if there are devices >= Android 2.2 that do not have multitouch support?
[Java for Android App Development] nikwen:
You need a real Cancas, not null.

Could you please post your run method?

Some cheap devices might not support multi touch.

There is a flag for Google Play which can be added to the manifest, causing that your app is not shown on those devices.
[Java for Android App Development] Wampirate:
I know I have the flag :D The multitouch implementation is a pain though ^^ I have a tutorial but I didn't ever touch bitwise AND operations which are used there. And all those indexes and ids are highly confusing.

Run method:

[MENTION=439709]override[/MENTION]
public void run() {
Canvas c;
long beginTime;
long timeDiff=0;

while(bRunning)
{
c = null;
if(!holder.getSurface().isValid())
{
continue;
}
beginTime= System.currentTimeMillis();
c = holder.lockCanvas();
synchronized(holder) {
onDraw(c);
}
holder.unlockCanvasAndPost(c);
timeDiff = System.currentTimeMillis() - beginTime;
if (gameState==states.PLAYING)	{
if(score>500){
if(bLaserCheckAlert)
{
if(System.currentTimeMillis()-attackTime>=13000)
{
bLaserAlert=true;
laserY = rand.nextInt(screenH-bmpLaser.getHeight())+bmpLaser.getHeight()/2;
bLaserCheckAlert=false;
}
}
if (System.currentTimeMillis()-attackTime>=15000)
{
//if (bSound)
bLaserAttack=true;
bLaserAlert=false;
attackTime+=18000;
}
}
gameUpdate(timeDiff);
}
}
}
[Java for Android App Development] nikwen:
Thanks. :)

Yeah, multi touch is a pain.

An attempt:

Add this to your Activity:

boolean activityPaused = false;

In onPause:

activityPaused = true;

In the onResume add this:

if (activityPaused) {
Canvas c = holder.lockCanvas();
synchronized(holder) {
onDraw(c);
}
holder.unlockCanvasAndPost(c);
activityPaused = false;
}
[Java for Android App Development] Wampirate:
It doesn't work. Actually I think the problem lies in the roots of my application.

I mean it's all one activity,and there is one surface view class that implements Runnable, in which I later create threads that use the run method from this surface view class, so I dont create my own thread class(I actually started over in the middle of this thread on xda, with SurfaceView, I dont remember now why I did it like this(with implementing runnable).

And in this view class, I have my two own method of pause and resume that destroy/create new thread. The pause method I call in onPause() when it wasn't called before(by pause button), and the resume is called in OnResume always when the gamestate is other than playing state.

So there is no thread working when I resume activity but the game is paused, might that be the problem?

I tried making a method that creates thread, starts it, draws once and then destroys it but it crashes app as well.

I realize I confuse a bit
[Java for Android App Development] nikwen:
Does the app crash with my code or does it simply not do what you want?

Hm, I don't know whether that is the problem.

For the solution you described: Could you please post the logcat?
[Java for Android App Development] Wampirate:
how I implemented your solution:

[MENTION=439709]override[/MENTION]
protected void onPause() {
// TODO Auto-generated method stub
if (view.gameState == view.getPlayingState() && !view.ifPaused()) {
//view.pause();
view.togglePause();
activityPaused = true;
}
else if (view.gameState != view.getPlayingState()) view.pause();
super.onPause();
}
[MENTION=439709]override[/MENTION]
protected void onResume() {
// TODO Auto-generated method stub
if (view.gameState != view.getPlayingState())	view.resume();
if (activityPaused){
Canvas c = view.getHolder().lockCanvas();
synchronized(view.getHolder()){
view.onDraw(c);
}
view.getHolder().unlockCanvasAndPost(c);
activityPaused=false;
}
super.onResume();
}

I'll post the one with mine soon, I'd have to write it again because I deleted it :D
[Java for Android App Development] nikwen:
I'd always call the super implementation first: (Code includes some more changes)

[MENTION=439709]override[/MENTION]
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
if (view.gameState == view.getPlayingState() && !view.ifPaused()) {
//view.pause();
view.togglePause();
}
else if (view.gameState != view.getPlayingState()) view.pause();
activityPaused = true;
}
[MENTION=439709]override[/MENTION]
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (view.gameState != view.getPlayingState())view.resume();
if (activityPaused){
Canvas c = view.getHolder().lockCanvas();
Log.d("c", c.toString());
synchronized(view.getHolder()){
view.onDraw(c);
}
view.getHolder().unlockCanvasAndPost(c);
activityPaused=false;
}

}

Could you please post the log with this code?

If it does not work:

Which line makes onDraw crash? (You can find the line number in the logcat.) Could you please post the relevant code with that line highlighted?