On Screen Controller

Any community contributions to libgdx go here! Some may get included in the core API when permission is granted.

On Screen Controller

Postby dengyin2000 » Wed Mar 23, 2011 9:22 am

I hope libgdx can add OnScreenController in the next version, Andengine has this component. I want to implement such feature in my game. Does anyone have already done such feature or give me some suggestions. Thanks.

The attached image is what I want.
Attachments
xxx.jpg
On Screen Controller
xxx.jpg (21.32 KiB) Viewed 7974 times
dengyin2000
 
Posts: 10
Joined: Wed Mar 23, 2011 8:53 am

Re: On Screen Controller

Postby mzechner » Thu Mar 24, 2011 1:50 pm

Hi,

why not use Andengine then? I'm afraid we are not going to implement anything of that kind since libgdx is a framework, not an engine. See [1].

[1] http://code.google.com/p/libgdx/wiki/GoalsFeatures
mzechner
Site Admin
 
Posts: 4879
Joined: Sat Jul 10, 2010 3:50 pm

Re: On Screen Controller

Postby warrd » Thu Mar 24, 2011 2:51 pm

I made such a class that might be helpful. You'll probably want to change it so it has nice looking sprites though. You'll need to implement an InputProcessor to call the methods updateFromTouch() and setToZero(). You get the output by polling getAngle() and getAmount()...

Code: Select all
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.math.Vector2;

public class Thumbpad {

   private static final int THUMB_AREA_VERTS = 50;
   private static final int THUMB_PT_VERTS = 15;
   
   private final int radius; // Radius in pixels
   private final Vector2 centre; // Centre position in pixels
   private int screenHeight; // Screen height in pixels
   
   private float angle = 0;
   private float amount = 0;
   private Vector2 distance = new Vector2(0,0);

   private Mesh thumbArea;
   private Mesh thumbPoint;
      
   public Thumbpad(int radius, Vector2 centre, int screenHeight) {
      this.radius = radius;
      this.centre = centre;
      this.screenHeight = screenHeight;
      initialiseShapes();
   }
   
   // Call after touch down or touch dragged
   public void updateFromTouch(float x, float y) {
      distance.x = x - centre.x;
      distance.y = (screenHeight - y) - centre.y;
      amount = distance.len()/radius;   
      if (amount > 1) { amount = 1; }
      amount *= amount;
      angle = (float)(Math.atan2(distance.y, distance.x));
   }
   
   // Call after touch up
   public void setToZero() {
      amount = 0;
   }
   
   // Angle in radians
   public float getAngle() { return angle; }
   
   // Amount 0-1
   public float getAmount() { return amount; }   
         
   public void initialiseShapes() {

      // Initialise thumb area
      thumbArea = new Mesh(
            true,
            THUMB_AREA_VERTS,
            THUMB_AREA_VERTS,
            new VertexAttribute(Usage.Position, 3, "position")
      );
      float[] vertices = new float[THUMB_AREA_VERTS*3];
      for (int i=0; i<THUMB_AREA_VERTS; i++) {
         float angle = (float)(1/(float)THUMB_AREA_VERTS * i * Math.PI * 2);
         vertices[i*3] = (float)Math.sin(angle) * radius + centre.x;
         vertices[i*3 +1] = (float)Math.cos(angle) * radius + centre.y;
         vertices[i*3 +2] = 0;
      }
      thumbArea.setVertices(vertices);
      
      // Initialise thumb point
      thumbPoint = new Mesh(
            false,
            THUMB_PT_VERTS,
            THUMB_PT_VERTS,
            new VertexAttribute(Usage.Position, 3, "position")
      );
      vertices = new float[THUMB_PT_VERTS*3];
      for (int i=0; i<THUMB_PT_VERTS; i++) {
         float angle = (float)(1/(float)THUMB_PT_VERTS * i * Math.PI * 2);
         vertices[i*3] = (float)Math.sin(angle) * (radius/5) + centre.x;
         vertices[i*3 +1] = (float)Math.cos(angle) * (radius/5) + centre.y;
         vertices[i*3 +2] = 0;
      }
      thumbPoint.setVertices(vertices);
            
   }
   
   public void render() {
      GL10 gl = Gdx.app.getGraphics().getGL10();
      gl.glColor4f(0.9f, 0.3f, 0.3f, 1.0f);
      thumbArea.render(GL10.GL_LINE_LOOP, 0, THUMB_AREA_VERTS);
      gl.glPushMatrix();
      gl.glTranslatef(
            amount * radius * (float)Math.cos(angle),
            amount * radius * (float)Math.sin(angle),
            0
      );
      thumbPoint.render(GL10.GL_TRIANGLE_FAN, 0, THUMB_PT_VERTS);
      gl.glPopMatrix();
   }
   
}


You'l also probably need a separate camera from that for the game.

Initialisation:
Code: Select all
thumbpad = new Thumbpad(radius,centre,screenHeight);
overlayCam = new OrthographicCamera(screenWidth, screenHeight);


Rendering:
Code: Select all
overlayCam.update();
overlayCam.apply(gl);
thumbpad.render();
warrd
 
Posts: 3
Joined: Thu Mar 24, 2011 1:33 pm

Re: On Screen Controller

Postby saidinstouch » Thu Mar 24, 2011 4:18 pm

I was just going to reply that while it isn't a feature I expected (and as Mario stated) them to implement, it would be a very easy (relatively speaking even for someone who is rusty at programming) for someone to make a class that does just that. You could make it very robust to the texture added to it probably without much effort and give it some good animations for feedback on use. It looks like warrd already did this and some simple customization could probably be done on it and then you have a nice reusable solution ala andengine built for libdgx.

This is one of the things I like about gdx a lot actually is that while it is a bit slower to do some things like this kind of button, it isn't _that_ hard to implement these things either. With such a great community a lot of these problems are already solved for us. So what we get is a really great framework to easily develop games with a great deal of control and a lot of features and ideas shared by the community. Add that to the AMAZING testing as a native java program on the desktop for performance over the emulator (and the ability to sell as a pc game if desired) and this is probably one of the easiest game libraries for someone with some programming knowledge (of java ideally, but a C/C++ background works), but little game development experience to get into!
saidinstouch
 
Posts: 79
Joined: Wed Feb 16, 2011 7:44 pm

Re: On Screen Controller

Postby dengyin2000 » Fri Mar 25, 2011 5:00 am

mzechner wrote:Hi,

why not use Andengine then? I'm afraid we are not going to implement anything of that kind since libgdx is a framework, not an engine. See [1].

[1] http://code.google.com/p/libgdx/wiki/GoalsFeatures


Hi mzechner, Thanks for reply, I love libgdx because it has much more document, and can develop android game in desktop.
dengyin2000
 
Posts: 10
Joined: Wed Mar 23, 2011 8:53 am

Re: On Screen Controller

Postby dengyin2000 » Fri Mar 25, 2011 5:03 am

Thanks for sharing code with us. I will help me a lot.

warrd wrote:I made such a class that might be helpful. You'll probably want to change it so it has nice looking sprites though. You'll need to implement an InputProcessor to call the methods updateFromTouch() and setToZero(). You get the output by polling getAngle() and getAmount()...

Code: Select all
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.math.Vector2;

public class Thumbpad {

   private static final int THUMB_AREA_VERTS = 50;
   private static final int THUMB_PT_VERTS = 15;
   
   private final int radius; // Radius in pixels
   private final Vector2 centre; // Centre position in pixels
   private int screenHeight; // Screen height in pixels
   
   private float angle = 0;
   private float amount = 0;
   private Vector2 distance = new Vector2(0,0);

   private Mesh thumbArea;
   private Mesh thumbPoint;
      
   public Thumbpad(int radius, Vector2 centre, int screenHeight) {
      this.radius = radius;
      this.centre = centre;
      this.screenHeight = screenHeight;
      initialiseShapes();
   }
   
   // Call after touch down or touch dragged
   public void updateFromTouch(float x, float y) {
      distance.x = x - centre.x;
      distance.y = (screenHeight - y) - centre.y;
      amount = distance.len()/radius;   
      if (amount > 1) { amount = 1; }
      amount *= amount;
      angle = (float)(Math.atan2(distance.y, distance.x));
   }
   
   // Call after touch up
   public void setToZero() {
      amount = 0;
   }
   
   // Angle in radians
   public float getAngle() { return angle; }
   
   // Amount 0-1
   public float getAmount() { return amount; }   
         
   public void initialiseShapes() {

      // Initialise thumb area
      thumbArea = new Mesh(
            true,
            THUMB_AREA_VERTS,
            THUMB_AREA_VERTS,
            new VertexAttribute(Usage.Position, 3, "position")
      );
      float[] vertices = new float[THUMB_AREA_VERTS*3];
      for (int i=0; i<THUMB_AREA_VERTS; i++) {
         float angle = (float)(1/(float)THUMB_AREA_VERTS * i * Math.PI * 2);
         vertices[i*3] = (float)Math.sin(angle) * radius + centre.x;
         vertices[i*3 +1] = (float)Math.cos(angle) * radius + centre.y;
         vertices[i*3 +2] = 0;
      }
      thumbArea.setVertices(vertices);
      
      // Initialise thumb point
      thumbPoint = new Mesh(
            false,
            THUMB_PT_VERTS,
            THUMB_PT_VERTS,
            new VertexAttribute(Usage.Position, 3, "position")
      );
      vertices = new float[THUMB_PT_VERTS*3];
      for (int i=0; i<THUMB_PT_VERTS; i++) {
         float angle = (float)(1/(float)THUMB_PT_VERTS * i * Math.PI * 2);
         vertices[i*3] = (float)Math.sin(angle) * (radius/5) + centre.x;
         vertices[i*3 +1] = (float)Math.cos(angle) * (radius/5) + centre.y;
         vertices[i*3 +2] = 0;
      }
      thumbPoint.setVertices(vertices);
            
   }
   
   public void render() {
      GL10 gl = Gdx.app.getGraphics().getGL10();
      gl.glColor4f(0.9f, 0.3f, 0.3f, 1.0f);
      thumbArea.render(GL10.GL_LINE_LOOP, 0, THUMB_AREA_VERTS);
      gl.glPushMatrix();
      gl.glTranslatef(
            amount * radius * (float)Math.cos(angle),
            amount * radius * (float)Math.sin(angle),
            0
      );
      thumbPoint.render(GL10.GL_TRIANGLE_FAN, 0, THUMB_PT_VERTS);
      gl.glPopMatrix();
   }
   
}


You'l also probably need a separate camera from that for the game.

Initialisation:
Code: Select all
thumbpad = new Thumbpad(radius,centre,screenHeight);
overlayCam = new OrthographicCamera(screenWidth, screenHeight);


Rendering:
Code: Select all
overlayCam.update();
overlayCam.apply(gl);
thumbpad.render();
dengyin2000
 
Posts: 10
Joined: Wed Mar 23, 2011 8:53 am

Re: On Screen Controller

Postby Bastionpayne » Fri Jun 03, 2011 8:27 pm

I have already posted in game art, but if you want some quick sprites to use for your onscreen controller, I did some quick ones. You can use them for whatever, just if you do a cool game put me in the credits! I'd love that, Special thanks to Bastionpayne, Controller Sprites: Bastionpayne :D
Attachments
controllerSprites.zip
pack file with associated images.
(97.01 KiB) Downloaded 531 times
OnScreenControllerScreen.png
ScreenShot
OnScreenControllerScreen.png (44.6 KiB) Viewed 7571 times
"You can't build a reputation on what you are going to do."- Henry Ford
Bastionpayne
 
Posts: 105
Joined: Wed May 11, 2011 3:49 pm
Location: USA


Return to Libgdx Contributions

Who is online

Users browsing this forum: No registered users and 1 guest