Android game programming questions - Java for Android App Development

Hey,
I want to learn how to create android games, I know how to write 2D games in C++ using Allegro library.
I've recently started to learn java so that I can make such games for Android devices.
I have two books - "Android Game Programming for Dummies" and "Beginning Android Games" -
the thing is the latter is too complicated for me, and they are using frameworks which is kinda advanced - I want to start from very simple apps so that I can really understand how it all works.
The former on the other hand started well, I've learned how to make activities and switch between them, show bitmaps and simple shapes like rectangles.
However the first game in this book is a card game that is turn based - and I want to make something different entirely - a game where I need timer events - what it means is that every given amount of time some actions are executed.
How do I do it ?
Here's part of my code where I would like to include a timer and actions that will be executed.
This code shows 3 rectangles in random positions and a circle. When I touch the screen, the circle is redrawn there.
Code:
public class GameView extends View{
private Paint redPaint;
private int circleX;
private int circleY;
private float radius;
List<Obstacles> listaL = new ArrayList<Obstacles>();
List<Obstacles> listaR = new ArrayList<Obstacles>();
List<Obstacles> listaT = new ArrayList<Obstacles>();
List<Obstacles> listaB = new ArrayList<Obstacles>();
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
for (int i=0;i<3;i++)
{
Obstacles obs = new Obstacles();
listaL.add(obs);
}
Random rand = new Random();
for (int i=0;i<listaL.size();i++)
{
listaL.get(i).y=rand.nextInt(400)+20;
listaL.get(i).x=rand.nextInt(760)+20;
}
}
public GameView(Context context) {
super(context);
redPaint = new Paint();
redPaint.setAntiAlias(true);
redPaint.setColor(Color.RED);
circleX = 100;
circleY = 100;
radius = 30;
}
[user=439709]@override[/user]
protected void onDraw(Canvas canvas)
{
canvas.drawCircle(circleX, circleY, radius, redPaint);
redPaint.setStrokeWidth(1);
for (int i=0;i<listaL.size();i++){
canvas.drawRect(listaL.get(i).x,listaL.get(i).y,listaL.get(i).x+40,listaL.get(i).y+40,redPaint);
}
}
public boolean onTouchEvent(MotionEvent event)
{
int eventaction = event.getAction();
int x = (int)event.getX();
int y = (int)event.getY();
switch (eventaction)
{
case MotionEvent.ACTION_DOWN:
circleX = x;
circleY = y;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
break;
}
invalidate();
return true;
}
}

There is the Timer class in Java with a schedule method.
Check this: http://javarevisited.blogspot.de/2013/02/what-is-timer-and-timertask-in-java-example-tutorial.html

Okay thanks I'll try this.
However, is this how I am supposed to do it in android apps/games? I've read that I should measure deltatime so that on different devices it all runs equally fast. How do you make games such as linerunner where the obstacles move towards you?
I can make such a game in c++, where every time timer is executed x coordinates of obstacles are reduced by a constant so that it looks as if they were moving towards the player

Wampirate said:
Okay thanks I'll try this.
However, is this how I am supposed to do it in android apps/games? I've read that I should measure deltatime so that on different devices it all runs equally fast. How do you make games such as linerunner where the obstacles move towards you?
I can make such a game in c++, where every time timer is executed x coordinates of obstacles are reduced by a constant so that it looks as if they were moving towards the player
Click to expand...
Click to collapse
Of course, measuring the delta time and then calculating the movement is better if you want it for moving things.
I thought you want to do something every 2 or more seconds. In that case the delta time would be useless.

I want to do it every 1/60 of a second
Can you guide me how to implement the loop that measures the delta time and executes actions?
BTW: The method you gave the link to me works but its a bit laggy on my phone.

Wampirate said:
I want to do it every 1/60 of a second
Can you guide me how to implement the loop that measures the delta time and executes actions?
BTW: The method you gave the link to me works but its a bit laggy on my phone.
Click to expand...
Click to collapse
Here you go. That should work:
Code:
boolean running = true;
int oldTime = System.currentTimeInMillis();
int newTime;
while (running) {
newTime = System.currentTimeInMillis();
int deltaTime = newTime - oldTime;
//example for moving an image:
int step = speed * deltaTime;
//TODO: move the image
}
EDIT: Of course, put this into a new Thread:
Code:
Thread thread = new Thread() {
[user=439709]@override[/user]
public void run() {
//TODO: Code from above goes here
}
};
thread.start;
---------- Post added at 02:56 PM ---------- Previous post was at 02:47 PM ----------
This tutorial should be exactly what you are looking for: http://www.javacodegeeks.com/2011/06/android-game-development-tutorials.html
I used it, too.
However, using an engine like AndEngine makes every thing much easier.

I guess you should study Thread Synchronization using java that might just do the trick
As u mentioned you have C++ experience I strongly recomend you to code using NDK its lots faster and will give a vast platform via Open GL ES
Sent from my GT-S5302 using Tapatalk 2

sak-venom1997 said:
I guess you should study Thread Synchronization using java that might just do the trick
As u mentioned you have C++ experience I strongly recomend you to code using NDK its lots faster and will give a vast platform via Open GL ES
Sent from my GT-S5302 using Tapatalk 2
Click to expand...
Click to collapse
However, programming with the NDK is much harder. And there are less tutorials.

Thanks a lot guys! Especially you nikwen, answering to all my questions You both got thanks from me.
I will try and implement the delta time timer solution.
@sak-venom1997 As I wrote my C++ experience was only in 2d, allegro library, not a big deal. I didn't learn OpenGL.
I was drawing some bitmaps and a I can't understand one thing. I have a sprite, a png file which has all the poses of the character in it, and each one of them is 41x41 pixels. They are connected so that if I want to make a movement animation I have to show some of them one after another.
The thing is when I want to draw a piece of a bitmap, and my source rectangle is 41x41 and so is the destination rectangle, it cuts some of the character.
Why is it that I have to make my source rectangle 1,5 times bigger than it is in reality? Each pose in sprite is 41x41.
Not sure if you can follow what I mean ;D I use this drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
My sprite.png is 123 pixels high - and there are 3 rows of different stands, so obviously one is 41 pixels high. So is their width. Yet when I make my source rectangle 41x41 it only draws some of the stand. I have to say for example new Rect(0,0,62,62) to get the first full stand visible.

Wampirate said:
Thanks a lot guys! Especially you nikwen, answering to all my questions You both got thanks from me.
I will try and implement the delta time timer solution.
@sak-venom1997 As I wrote my C++ experience was only in 2d, allegro library, not a big deal. I didn't learn OpenGL.
I was drawing some bitmaps and a I can't understand one thing. I have a sprite, a png file which has all the poses of the character in it, and each one of them is 41x41 pixels. They are connected so that if I want to make a movement animation I have to show some of them one after another.
The thing is when I want to draw a piece of a bitmap, and my source rectangle is 41x41 and so is the destination rectangle, it cuts some of the character.
Why is it that I have to make my source rectangle 1,5 times bigger than it is in reality? Each pose in sprite is 41x41.
Not sure if you can follow what I mean ;D I use this drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
My sprite.png is 123 pixels high - and there are 3 rows of different stands, so obviously one is 41 pixels high. So is their width. Yet when I make my source rectangle 41x41 it only draws some of the stand. I have to say for example new Rect(0,0,62,62) to get the first full stand visible.
Click to expand...
Click to collapse
Welcome.
Are you sure that the original images are 41x41? That sounds like strange dimensions.
Could you please post some code? We cannot help you without your code (just the important parts).

Code:
characterGraphic=BitmapFactory.decodeResource(getResources(),R.drawable.sprite); // this is character sprite loading from drawable folder in res
charsrc = new Rect(62,62,124,124);
chardst = new Rect(100,charY-46,193,charY+45); // these are character source and destrination rectangles, my code is kinda messy but you can see my character source rectangle is 62x62 which is about 1,5 bigger than 41x41, and I see one full stand
// theres the whole painting method
protected void onDraw(Canvas canvas)
{
//canvas.drawCircle(circleX, circleY, radius, redPaint);
if (bLost)
{
redPaint.setTextSize(72);
redPaint.setColor(Color.rgb(0,0,0));
canvas.drawText("You died. Touch screen to return.", 100, 240, redPaint);
}
else
{
canvas.drawBitmap(backgroundGraphic, bgsrc,bgdst,null);
if (!onGround()) canvas.drawBitmap(characterGraphic,charjsrc,chardst,null);
else canvas.drawBitmap(characterGraphic, charsrc, chardst, null);
redPaint.setStrokeWidth(1);
for (int i=0;i<listaL.size();i++){
canvas.drawRect(listaL.get(i).x,listaL.get(i).y,listaL.get(i).x+30,listaL.get(i).y+30,redPaint);
}
}
}
Heres the link to the properties of sprite.png so you dont think I'm crazy.
Where it says 123 it is the height and 410 is the width.

You woudnt be restricted to only using OpenGl via NDK you can happily use any c/c++ libs
Not to mention the performance boost you get
Anyway its your call do what you.feel you're comfortable with
Sent from my GT-S5302 using Tapatalk 2

Wampirate said:
Code:
characterGraphic=BitmapFactory.decodeResource(getResources(),R.drawable.sprite); // this is character sprite loading from drawable folder in res
charsrc = new Rect(62,62,124,124);
chardst = new Rect(100,charY-46,193,charY+45); // these are character source and destrination rectangles, my code is kinda messy but you can see my character source rectangle is 62x62 which is about 1,5 bigger than 41x41, and I see one full stand
// theres the whole painting method
protected void onDraw(Canvas canvas)
{
//canvas.drawCircle(circleX, circleY, radius, redPaint);
if (bLost)
{
redPaint.setTextSize(72);
redPaint.setColor(Color.rgb(0,0,0));
canvas.drawText("You died. Touch screen to return.", 100, 240, redPaint);
}
else
{
canvas.drawBitmap(backgroundGraphic, bgsrc,bgdst,null);
if (!onGround()) canvas.drawBitmap(characterGraphic,charjsrc,chardst,null);
else canvas.drawBitmap(characterGraphic, charsrc, chardst, null);
redPaint.setStrokeWidth(1);
for (int i=0;i<listaL.size();i++){
canvas.drawRect(listaL.get(i).x,listaL.get(i).y,listaL.get(i).x+30,listaL.get(i).y+30,redPaint);
}
}
}
Heres the link to the properties of sprite.png so you dont think I'm crazy.
Where it says 123 it is the height and 410 is the width.
Click to expand...
Click to collapse
Thanks. Will check it later.

sak-venom1997 said:
You woudnt be restricted to only using OpenGl via NDK you can happily use any c/c++ libs
Click to expand...
Click to collapse
I didn't know about it. That's interesting, could you tell me a bit more about it? Where do I start ?
@nikwen Thanks

Wampirate said:
I didn't know about it. That's interesting, could you tell me a bit more about it? Where do I start ?
@nikwen Thanks
Click to expand...
Click to collapse
Sure
Ill fetch some links for you
EDIT :
http://stackoverflow.com/a/4920992/2408192
This should get you started
Sent from my GT-S5302 using Tapatalk 2

Another question emerged ;D
Code:
// its a function in my GameView class extending View
public void gameUpdate()
{
postInvalidate();
}
public class GameLoopThread extends Thread{
private boolean running;
public void setRunning()
{
running=!running;
}
[user=439709]@override[/user]
public void run() {
while (running)
{
GameView.gameUpdate();
}
}
}
And beneath the method from GameView class is my game loop thread class, how do I make the drawing initiate, because GameView.gameUpdate(); doesnt work, says I cant make a static reference to a non-static method, and when I change gameUpdate method to static then there is a problem with postInvalidate(); which cant be in a static method?

Wampirate said:
Another question emerged ;D
Code:
// its a function in my GameView class extending View
public void gameUpdate()
{
postInvalidate();
}
public class GameLoopThread extends Thread{
private boolean running;
public void setRunning()
{
running=!running;
}
[user=439709]@override[/user]
public void run() {
while (running)
{
GameView.gameUpdate();
}
}
}
And beneath the method from GameView class is my game loop thread class, how do I make the drawing initiate, because GameView.gameUpdate(); doesnt work, says I cant make a static reference to a non-static method, and when I change gameUpdate method to static then there is a problem with postInvalidate(); which cant be in a static method?
Click to expand...
Click to collapse
Replace GameView.gameUpdate();
With gameUpdate()
Sent from my GT-S5302 using Tapatalk 2
---------- Post added at 01:48 PM ---------- Previous post was at 01:45 PM ----------
Sry if GameThread is an inner class use GameView.this.gameUpdate()
Sent from my GT-S5302 using Tapatalk 2

sak-venom1997 said:
Replace GameView.gameUpdate();
With gameUpdate()
Sent from my GT-S5302 using Tapatalk 2
---------- Post added at 01:48 PM ---------- Previous post was at 01:45 PM ----------
Sry if GameThread is an inner class use GameView.this.gameUpdate()
Sent from my GT-S5302 using Tapatalk 2
Click to expand...
Click to collapse
What if it's not an inner class? Does it have to be? I never know when I can make another class file and use methods/variables from another class file
Because its not inner in my case, and alone gameUpdate(); doesnt work either.

Wampirate said:
What if it's not an inner class? Does it have to be? I never know when I can make another class file and use methods/variables from another class file
Because its not inner in my case, and alone gameUpdate(); doesnt work either.
Click to expand...
Click to collapse
If you intend to call it from GameView class use ..
Sent from my GT-S5302 using Tapatalk 2
---------- Post added at 01:58 PM ---------- Previous post was at 01:54 PM ----------
Add this field to GameThread
private GameView mGameView;
Add this constructor
public GameThread(GameView view)
{
mGameView = view;
}
Now you can call
mGameView.your public method(args)
Sent from my GT-S5302 using Tapatalk 2

Thanks a lot ! Not sure how this works but it does

Related

Preference changes only happen when restarting the app

Hey there! I was coding an app I added a preferences menu, and it works, but changes happen only when I restart the application,anyone knows how to make changes happen whithout exitting the app??? Thanks in advance
My code ( from main activity):
preferencias = preferenceManager.getDefaultSharedPreferences(TimeToSpeechActivity.this);
OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
//nothing here, do I have to put anything?
}
};
preferencias.registerOnSharedPreferenceChangeListener(listener);
getPrefs();
changefont(fuente, letra);
if (boole == true) {fontcolors();}
private void getPrefs(){
fuente = Typeface.createFromAsset(getAssets() , preferencias.getString("elegirfuente", "fonts/Default.ttf"));
letra = Integer.parseInt(preferencias.getString("fontstyle", "0"));
bol = preferencias.getBoolean("randomcolors", true);
}
Click to expand...
Click to collapse
I have nothing put in preference activity, do i have to put anything?
Also, do I have to edit this?: (SharedPreferences prefs, String key) I ask this because i havent created prefs and key varibles
Thanks in advance!!!
It should update for you if you put getPrefs() inside the sharedpreferences listener
Sent from my Xoom using xda premium
thanks, but if I do that I get a nullpointer exception, I think its caused because the params I use to set "changefont(fuente, letra);" and "if (boole == true) {fontcolors();}" have null value....another idea ,please? I am breaking my head with this...
My updated code:
preferencias = preferenceManager.getDefaultSharedPreferences(Time ToSpeechActivity.this);
OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener () {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
getPrefs();
}
};
preferencias.registerOnSharedPreferenceChangeListener(listener);
changefont(fuente, letra);
if (boole == true) {fontcolors();}
private void getPrefs(){
fuente = Typeface.createFromAsset(getAssets() , preferencias.getString("elegirfuente", "fonts/Default.ttf"));
letra = Integer.parseInt(preferencias.getString("fontstyle ", "0"));
bol = preferencias.getBoolean("randomcolors", true);
}
Click to expand...
Click to collapse
i tried to put changefont and fontcolors functions inside the sharedpreference listener... but if i do, that options are not set... so I think there is a problem with the listener...why???
I will add the code of my preference class:
public class PantallaOpciones extends PreferenceActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.opciones);
}
}
Click to expand...
Click to collapse
One way ive always done preference updates was to use a dedicated method for updating (like you have with openPrefs()) then calling it after operations:
runOperation(){
updatePrefsMethod();
getPrefsMethod();
}
If i was near my pc i could give you a more solid example, but alas, im stuck at work lol
Also, use the stacktraces to check which line gives it null (itll say something like "at com.yourapp.identifier(offending Class - line number)
maybe if you a null check on the boolean for color that sets it false, you may not get the nullPointerException
Sent from my Xoom using xda premium
z3nful said:
One way ive always done preference updates was to use a dedicated method for updating (like you have with openPrefs()) then calling it after operations:
runOperation(){
updatePrefsMethod();
getPrefsMethod();
}
If i was near my pc i could give you a more solid example, but alas, im stuck at work lol
Also, maybe if you a null check on the boolean for color that sets it false, you may not get the nullPointerException
Sent from my Xoom using xda premium
Click to expand...
Click to collapse
OK, could you give me an example as soon as you can,please?

[Q] Parsing XML from web into ListView

Hey guys,
I've been making an app for my ROM (SkyDragon) and I want to include a news section, which will retrieve info from the web using a XML file.
But, I've tried many things and they won't work. So could anyone post a quick working parsing code here that will put the items in a listview, so I can experiment a bit with it? It'd be widely appreciated
I might reccommend using a library like Jackson 2.0+. I have not had the experience to use it with XML, but rather JSON, but it does appear to be just as easy to do so (at least since 2.0).
You would set up a POJO (Plain Old Java Object) class to represent the structure of the xml data, for instance:
Code:
public class Simple
{
private int x, y;
public int getX(){ return x; }
public int getY(){ return y; }
public void setX(int x){ this.x = x; }
public void setY(int y){ this.y = y; }
}
would represent xml like:
Code:
<Simple>
<x>1</x>
<y>2</y>
</Simple>
and to build the object you would use the library as such:
Code:
ObjectMapper xmlMapper = new XmlMapper();
Simple value = xmlMapper.readValue("<Simple><x>1</x><y>2</y></Simple>", Simple.class);
Thanks, will try it. But it can't be that simple, right? I mean, every tutorial is pretty big, and uses multiple activities.
Sent from my awesome fridge
Well like I said, I haven't actually used it for XML but rather JSON, but it really was that simple for me. What I listed is of course a very simple example, but scaling it up really just requires mapping your xml source to a POJO. The hardest part about your use will be that you don't control the XML.
Here is an example right out of a project of mine that worked great. "request.result" was basically a String object that contained the JSON response from a restful web service that I did not control but knew the structure of (by examination). Truly it is just these 2 lines of code to parse the response and after that you have an object that is easy to use.
Code:
ObjectMapper mapper = new ObjectMapper();
inventory = mapper.readValue(request.result, PlayerInventory.class);
Unfortunately this service no longer exists so I cannot get you an example response, but below is the POJO that I used to map it.
Code:
package com.mcdermotsoft;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class PlayerInventory
{
private int ok;
private Map<String,Slot> contents;
public PlayerInventory(){}
public int getOk() {
return ok;
}
public Map<String,Slot> getContents() {
return contents;
}
public void setOk(int ok) {
this.ok = ok;
}
public void setContents(Map<String,Slot> contents) {
this.contents = contents;
}
}
"@JsonIgnoreProperties(ignoreUnknown = true)" is important because I really didn't care to map everything from the response so this annotation tells the Jackson parser to ignore anything it can't map instead of throwing an exception (don't remember what the exception is but you might run into it yourself).

[Q] Issues with adding objects to a photo taken by the user

I've been trying to learn to program for Android lately by simply coming up with ideas and implementing them. It started out easy enough with pulling information from an online RSS feed and showing this in a nice environment. But the current idea has me stumped.
I'd like the following to happen:
Take a picture using intent
Entire picture is shown in a new activity
Zoom in on a certain spot
Add predefined items to the picture
Press next which connects the items from left to right
Add some more items
Press next to connect the new items
Zoom out
Save the image
First taking a picture, this wasn't too hard using the camera intent:
Code:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
I can then extract the absolute path from fileUri with the following line:
Code:
String path = new File(fileUri.getPath()).getAbsolutePath();
This path can be put in a bundle which can be put in an intent which is then used to start the activity that should show the image.
Code:
public class TestActivity extends Activity implements SurfaceHolder.Callback {
private static final String TAG = TestActivity.class.getSimpleName();
private String path = "";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SurfaceView view = new SurfaceView(this);
setContentView(view);
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
path = bundle.getString("path");
view.getHolder().addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Canvas canvas = holder.lockCanvas();
if (canvas == null) {
Log.d(TAG,"Can't draw because canvas is null");
}
else {
Bitmap bitmap = BitmapFactory.decodeFile(path);
Paint paint = new Paint();
if(bitmap == null) {
Log.d(TAG,"Can't draw because bitmap is null");
}
else {
canvas.drawBitmap(bitmap,0,0,paint);
}
holder.unlockCanvasAndPost(canvas);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int frmt, int w, int h) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
The first issue here is that it of course doesn't show the entire photo. Not that surprising considering it's larger than the view. Ideally I'd like to zoom out to show the entire photograph. Once I've zoomed one way I'd assume that zooming in on the part that you want should also be possible.
Next is adding the objects. My idea was simply catching any touch events and adding a new object once the finger is released. This way I'd end up with a list of items with each having a draw function which can be called through the surfaceview when it is redrawn.
Connecting these items could simply be done by creating a line object and going through the list of all items and using their locations for the begin and endpoints of the lines
One of the big issues here is that the x and y locations would be relative to the screen, not to the photo. Which would mean that when you zoom back out the entire background would change but the actual items would remain at the same spot and in the same size.
I've been searching and searching for any tutorial or other question about the same issue, but either I've had no luck or I've been using the wrong keywords. And for all I know everything I have up till now could be wrong.
If anyone could give some pointers, or maybe knows a guide or tutorial somewhere or some better keywords I could use for searching I'd really appreciate it.
Xylon- said:
One of the big issues here is that the x and y locations would be relative to the screen, not to the photo. Which would mean that when you zoom back out the entire background would change but the actual items would remain at the same spot and in the same size.
Click to expand...
Click to collapse
would you just not need to either control or track the sample/scale if the image so that you know the 1st pixel displayed (top left) and the scale factor, then the eventX/Y can be processed to be relative to what you want ?

[Q] Animation, ratation image

Hello everyone, I am new to android app making.
I would like to make an app that works like a spining bottle, Onclick start spinning and the the arrow stops in a radom place after random time.
So my picture spins but on click it stops at the start position.
Please help thank you !
I would like to show you my code but i can't sorry
ed37 said:
Hello everyone, I am new to android app making.
I would like to make an app that works like a spining bottle, Onclick start spinning and the the arrow stops in a radom place after random time.
So my picture spins but on click it stops at the start position.
Please help thank you !
I would like to show you my code but i can't sorry
Click to expand...
Click to collapse
Not sure anyone can help you if you dont really ask a question.... what you have currently reads like
I want to do "abcdefghijklmnopqrstuvwxyz" can someone tell me how ?
You should really be asking how do I do "a" but having some idea and learned the basics yourself ...then maybe someone could be constructive in helping
Ok, well how to I get an image view to stop rotating after a random time like 2 to 15 secs?
ed37 said:
Ok, well how to I get an image view to stop rotating after a random time like 2 to 15 secs?
Click to expand...
Click to collapse
using a timer/thread , never actually done something like that but I suspect you can get the frame that is currently being played and work out the rotation, stop the animation and set that rotation.
Or maybe even rotate the thing yourself and do all of it in onDraw of a view or by manually drawing it on a canvas/surface
Use a canvas object, like that you get a drawn object you can completely personalize. Also the rotation angle
---------------------------------
Phone : Nexus 4
OS:
Pure KitKat 4.4.2 stock, no root, no mods (but only for the first time ;D)
---------------------------------
Gesendet von Tapatalk
Here is what I have so far
Code:
public class SpinFragment extends Fragment {
public SpinFragment(){}
private Button btnRotate, btnstop;
private ImageView imgview;
AnimationListener listener;
Random rand = new Random();
int milis = (rand.nextInt(10) + 2)*1000;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_spin, container, false);
TextView txt = (TextView) rootView.findViewById(R.id.textView1);
Typeface font = Typeface.createFromAsset(getActivity().getAssets(), "fonts/harabara.ttf");
txt.setTypeface(font);
final ImageView iv = (ImageView) rootView.findViewById(R.id.image_arrow);
btnRotate = (Button) rootView.findViewById(R.id.start);
btnstop = (Button) rootView.findViewById(R.id.stop);
final Animation rotation = AnimationUtils.loadAnimation(getActivity(), R.anim.button_rotate);
rotation.setRepeatCount(Animation.INFINITE);
rotation.setAnimationListener(listener);
btnRotate.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
iv.startAnimation(rotation);
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
iv.clearAnimation();
}
}, milis);
}
});
return rootView;
}
}

[Tutorial] Learn to create a Matrix Effect

Hello,
I create that thread to present you a tutorial learning you how to create a Matrix Effect, also known as Digital Rain Effect, on Android. The tutorial is also available as a Youtube video :
Create a Matrix Effect on Android
Also know as Digital Rain Effect, the Matrix Effect is a classic effect featured in the Matrix series films. A green code is falling and represents the activity of the virtual reality environment of the Matrix on screen. On Android, Matrix Effect has been implemented in various applications often as a Live Wallpaper. In that tutorial, you are going to learn how to create a simple Matrix Effect.
1. Create a Matrix Effect custom View
First, you need to create a custom view named MatrixEffect :
Code:
package com.ssaurel.digitalraineffect;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import java.util.Random;
/**
* Created by ssaurel on 22/09/2016.
*/
public class MatrixEffect extends View {
private static final Random RANDOM = new Random();
private int width, height;
private Canvas canvas;
private Bitmap canvasBmp;
private int fontSize = 40;
private int columnSize;
private char[] cars = "+-*/!^'([])#@&?,=$€°|%".toCharArray();
private int[] txtPosByColumn;
private Paint paintTxt, paintBg, paintBgBmp, paintInitBg;
public MatrixEffect(Context context, AttributeSet attrs) {
super(context, attrs);
paintTxt = new Paint();
paintTxt.setStyle(Paint.Style.FILL);
paintTxt.setColor(Color.GREEN);
paintTxt.setTextSize(fontSize);
paintBg = new Paint();
paintBg.setColor(Color.BLACK);
paintBg.setAlpha(5);
paintBg.setStyle(Paint.Style.FILL);
paintBgBmp = new Paint();
paintBgBmp.setColor(Color.BLACK);
paintInitBg = new Paint();
paintInitBg.setColor(Color.BLACK);
paintInitBg.setAlpha(255);
paintInitBg.setStyle(Paint.Style.FILL);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = w;
height = h;
canvasBmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
canvas = new Canvas(canvasBmp);
canvas.drawRect(0, 0, width, height, paintInitBg);
columnSize = width / fontSize;
txtPosByColumn = new int[columnSize + 1];
for (int x = 0; x < columnSize; x++) {
txtPosByColumn[x] = RANDOM.nextInt(height / 2) + 1;
}
}
private void drawText() {
for (int i = 0; i < txtPosByColumn.length; i++) {
canvas.drawText("" + cars[RANDOM.nextInt(cars.length)], i * fontSize, txtPosByColumn[i] * fontSize, paintTxt);
if (txtPosByColumn[i] * fontSize > height && Math.random() > 0.975) {
txtPosByColumn[i] = 0;
}
txtPosByColumn[i]++;
}
}
private void drawCanvas() {
canvas.drawRect(0, 0, width, height, paintBg);
drawText();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(canvasBmp, 0, 0, paintBgBmp);
drawCanvas();
invalidate();
}
}
First, we define the variables for the Matrix Effect with the size of the code, the size of a column, the position of the bottom text for each column and then the caracters that will be used for the code. Note that you can put the caracters you want here or why not a custom font.
In the constructor, we initialize the paint objects. To get view width and height, we override the onSizeChanged method of the View. We initialize the position of the first caracter for each column. We use a random position between the top of the screen and the middle of the screen.
Then, we define a draw text method used to draw a random caracter for each column at the position indicated by txtPosByColumn variable.
The drawCanvas method is used to draw the background of our view and then the code.
Finally, we override the onDraw method of our custom view to call the drawCanvas method and invalidate the view to force a redraw. With that call, the Matrix Effect could progress from top to bottom in infinite mode. Note that it is not the most optimized way to manage a Matrix Effect, but for a tutorial it's sufficient.
2. Define the MatrixEffect View on the Layout
Now, we can define the MatrixEffect View on the layout of the Main Activity.
Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.ssaurel.digitalraineffect.MainActivity">
<com.ssaurel.digitalraineffect.MatrixEffect
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
3. Set the layout on the Main Activity
Last step is to set the layout as content view for the Main Activity.
Code:
package com.ssaurel.digitalraineffect;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
4. Demo
To enjoy the Matrix Effect, you have just to launch the application on an Android device and you sould see the following effect :
Don't hesitate to give it a try and give me your feedbacks.
Thanks.
Sylvain
Nice work mate, will give it a try.
Sent from my SM-G935F using XDA-Developers mobile app
silverrum said:
Nice work mate, will give it a try.
Sent from my SM-G935F using XDA-Developers mobile app
Click to expand...
Click to collapse
Thanks
I really like this animated wallpaper app.
Thanks for the detailed tutorial, it's always nice to see actually what the code does. :highfive:
In theory, would it be possible to take smali from the app you create and use it to create this effect on the notification screen (for example)?
Seeing the code I’m sure this app drain a lot of battery but it's very nice.
Ticklefish said:
Thanks for the detailed tutorial, it's always nice to see actually what the code does. :highfive:
In theory, would it be possible to take smali from the app you create and use it to create this effect on the notification screen (for example)?
Click to expand...
Click to collapse
Thanks.
Did you mean put the effect on the lock screen ? I thought it was not possible now to put live wallpaper on lock screen. If it's possible it could be great.
slnit said:
Seeing the code I’m sure this app drain a lot of battery but it's very nice.
Click to expand...
Click to collapse
For sure . But life is a choice, like in Matrix films, cool effect on your screen or save your battery lol
sylsau said:
Thanks.
Did you mean put the effect on the lock screen ? I thought it was not possible now to put live wallpaper on lock screen. If it's possible it could be great.
Click to expand...
Click to collapse
Should be possible to pull the AOSP lockscreen source (or the source from OEM variants that are actually available...) and replace the wallpaper code, right?
Interesting , definitely going to try it on Samsung TW later , great idea mate ..
thereassaad said:
Interesting , definitely going to try it on Samsung TW later , great idea mate ..
Click to expand...
Click to collapse
Thanks
Thanks for this tutorial With this I've started learning to work with canvas Nice job!
thereassaad said:
Interesting , definitely going to try it on Samsung TW later , great idea mate ..
Click to expand...
Click to collapse
Me too. hope it works
Excellent work.
rejm0901 said:
Me too. hope it works
Click to expand...
Click to collapse
It works mate ?
Hello! nice tutorial, everything works fine. But I would like to add buttons to change the colors of chars but i'm not able to call the method from the main activity.
I've tried this but giving errors
Code:
MatrixEffect matrixEffect = new MatrixEffect(); // this gives an error : MatrixEffect(Context, AttributSet) in MatrixEffect cannot be applied to ()
final Paint paintTxt = effetMatrix.peindreTxt;
paintTxt.setColor(Color.BLUE);
Is there a way that I can call paintTxt.setColor() to change color?
PS: Im just a noob on programming
esQmo said:
Hello! nice tutorial, everything works fine. But I would like to add buttons to change the colors of chars but i'm not able to call the method from the main activity.
I've tried this but giving errors
Code:
MatrixEffect matrixEffect = new MatrixEffect(); // this gives an error : MatrixEffect(Context, AttributSet) in MatrixEffect cannot be applied to ()
final Paint paintTxt = effetMatrix.peindreTxt;
paintTxt.setColor(Color.BLUE);
Is there a way that I can call paintTxt.setColor() to change color?
PS: Im just a noob on programming
Click to expand...
Click to collapse
If you want to add buttons to change the color of the Matrix Effect, you should work on the layout and add two buttons at the bottom of the screen under the MatrixView. The, you have to change the colors of the Matrix Effect when a user click on one of these buttons.
esQmo said:
Hello! nice tutorial, everything works fine. But I would like to add buttons to change the colors of chars but i'm not able to call the method from the main activity.
I've tried this but giving errors
Code:
MatrixEffect matrixEffect = new MatrixEffect(); // this gives an error : MatrixEffect(Context, AttributSet) in MatrixEffect cannot be applied to ()
final Paint paintTxt = effetMatrix.peindreTxt;
paintTxt.setColor(Color.BLUE);
Is there a way that I can call paintTxt.setColor() to change color?
PS: Im just a noob on programming
Click to expand...
Click to collapse
SOLVED!
---------- Post added at 11:13 PM ---------- Previous post was at 11:05 PM ----------
sylsau said:
If you want to add buttons to change the color of the Matrix Effect, you should work on the layout and add two buttons at the bottom of the screen under the MatrixView. The, you have to change the colors of the Matrix Effect when a user click on one of these buttons.
Click to expand...
Click to collapse
Already solved. I added 4 buttons for 4 colors and i used switch statement
1st, created a custom text color inside MAtrixEffect
Code:
public void setCustomTextColor(int color){
peindreTxt.setColor(color);
invalidate();
then, in mainactivity :
Code:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
MatrixEffect matrixEffect;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
matrixEffect = (MatrixEffect) findViewById(R.id.arrPlan);
final Button boutton_blanc = (Button) findViewById(R.id.b_bl);
final Button boutton_bleu = (Button) findViewById(R.id.b_b);
final Button boutton_rouge = (Button) findViewById(R.id.b_r);
final Button boutton_rose = (Button) findViewById(R.id.b_ro);
if (boutton_bleu != null) {
boutton_bleu.setOnClickListener(this);
}
if (boutton_blanc != null) {
boutton_blanc.setOnClickListener(this);
}
if (boutton_rouge != null) {
boutton_rouge.setOnClickListener(this);
}
if (boutton_rose != null) {
boutton_rose.setOnClickListener(this);
}
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.b_bl:
matrixEffect.setCustomTextColor(Color.WHITE);
break;
case R.id.b_b:
matrixEffect.setCustomTextColor(Color.BLUE);
break;
case R.id.b_ro:
matrixEffectsetCustomTextColor(Color.MAGENTA);
break;
case R.id.b_r:
matrixEffect.setCustomTextColor(Color.RED);
break;
case R.id.b_def:
matrixEffect.setCustomTextColor(Color.GREEN);
break;
}
}
}
Now it works fine and i can change color while a button is pressed
esQmo said:
SOLVED!
---------- Post added at 11:13 PM ---------- Previous post was at 11:05 PM ----------
Already solved. I added 4 buttons for 4 colors and i used switch statement
1st, created a custom text color inside MAtrixEffect
Code:
public void setCustomTextColor(int color){
peindreTxt.setColor(color);
invalidate();
then, in mainactivity :
Code:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
MatrixEffect matrixEffect;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
matrixEffect = (MatrixEffect) findViewById(R.id.arrPlan);
final Button boutton_blanc = (Button) findViewById(R.id.b_bl);
final Button boutton_bleu = (Button) findViewById(R.id.b_b);
final Button boutton_rouge = (Button) findViewById(R.id.b_r);
final Button boutton_rose = (Button) findViewById(R.id.b_ro);
if (boutton_bleu != null) {
boutton_bleu.setOnClickListener(this);
}
if (boutton_blanc != null) {
boutton_blanc.setOnClickListener(this);
}
if (boutton_rouge != null) {
boutton_rouge.setOnClickListener(this);
}
if (boutton_rose != null) {
boutton_rose.setOnClickListener(this);
}
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.b_bl:
matrixEffect.setCustomTextColor(Color.WHITE);
break;
case R.id.b_b:
matrixEffect.setCustomTextColor(Color.BLUE);
break;
case R.id.b_ro:
matrixEffectsetCustomTextColor(Color.MAGENTA);
break;
case R.id.b_r:
matrixEffect.setCustomTextColor(Color.RED);
break;
case R.id.b_def:
matrixEffect.setCustomTextColor(Color.GREEN);
break;
}
}
}
Now it works fine and i can change color while a button is pressed
Click to expand...
Click to collapse
Great
This is just the kind of guide that I have been waiting for! I am gonna implement this as a hidden feature in my Rom Control apk. Good lookin on the guide brother

Categories

Resources