1

I am trying to make an app using canvas and a surfaceview, and I am worrying that in the future I would have many problems with it because I am not sure if the canvas is proportional with every device. currently I can only use my emulator since my phone's usb cable doesn't work(I know.. I have to get a new one..).

anyways, i would like to know if the canvas would transfer my coordinates and make everything proportional, what I mean by that is that if i have something in point a, lets say (10, 10) on a device that the screen of it is 100 X 100 (this is just an example for easy calculation) it would be on point (1, 1) on a 10 X 10 device.

This is really bothering me...

Thanks!

Baruch
  • 1,618
  • 5
  • 23
  • 42
  • You could also send your APK to device by mail, bluetooth, ftp or whatever. You'll miss the debug stuff but just to check if your canvas is being scaled or not its sufficient. To be honest, I did exactly what you're asking for, and had to deal with scaling issues... and totally forgot about the details by now! – Cdr. Powell Jul 31 '12 at 12:13
  • @Cdr.Powell Thanks haha, by the way, how could i upload the apk to my android without signing it everytime, i would prefer over wifi or bluetooth (my phone is not rooted.. i have samsung galaxy s 4g vibrant) – Baruch Jul 31 '12 at 12:19
  • Well, I just let eclipse build the app, take the APK from bin folder, copy it to device and install. Sure, install from non-market needs to be enabled but I've never been bothered signing it manually. My dev-phones are SGS+, SGS2, SGSN and SGS3 (not a fan! wasnt my decision!). – Cdr. Powell Jul 31 '12 at 13:05

2 Answers2

3

No, this wouldn't be the case. If you have a coordinate (10,10), it would be the same on all devices. I'd suggest you scale your drawings.

To scale your drawings you simply define a bitmap (that will stay the same) you'd like to draw to (when screen sizes change, that bitmap will be stretched).

  1. Define a constant bitmap:

    Bitmap gameScreen = Bitmap.createBitmap(getGameScreenWidth(), getGameScreenHeight(), Config.RGB_565);

  2. Get the scale for both x and y

    width = game.getWindowManager().getDefaultDisplay().getWidth(); height = game.getWindowManager().getDefaultDisplay().getHeight(); scaleXFromVirtualToReal = (float) width/this.gameScreenWidth; scaleYFromVirtualToreal = (float) height/this.gameScreenHeight;

  3. Define a canvas object based on the bitmap you defined earlier on (allowing you to draw to it eg. canvas.drawRect() [...]):

    Canvas canvasGameScreen = new Canvas(gameScreen);

  4. In your rendering Thread you'll have to have a Canvas called frameBuffer, which will render the virtual framebuffer:

    frameBuffer.drawBitmap(this.gameScreen, null, new Rect(0, 0, width, height), null);

Luke Taylor
  • 9,481
  • 13
  • 41
  • 73
  • how can i scale it? can you please give more details? and also, in my app i am not using anything complicated for now, only lines and circles which are made by using the canvas.draw___(); – Baruch Jul 31 '12 at 12:14
  • would not using numbers and only canvas.getheight() and canvas.getwidth and percentages would help? i.e. canvas.getheight() *.2 – Baruch Jul 31 '12 at 12:48
  • I got confused by your post.. sorry. haha,anyways, what i am doing by now is just multiplying everything by Canvas.getwidth/480 and canvas.getHeight/800 so i would have a constant area of 480x800 and i could play around with pixels and not worry about it. Thanks anyway, if you have a better way, i would like to hear it because i think that my way is a bit "dirty", is there a way to scale everything after its drawn? for example just drawing everything and before the "unlockAndPost" method to just scale the canvas with the things on it? Thanks! – Baruch Aug 01 '12 at 02:48
  • The way you are doing will do the job, yet it would be more convenient to simply just draw without scaling every drawing. They method I posted above, you don't have to take care of the scaling every time you draw something. (What part confuses you)? – Luke Taylor Aug 01 '12 at 08:27
  • I dont get where to use scaleYFromVirtualToreal and scaleXFromVirtualToReal, i think i know what you ment by the other things, would i use the frameBuffer inside the thread? (same place that i would draw with normal canvas)? – Baruch Aug 01 '12 at 19:23
  • Sorry, the scales aren't needed to render (You only need them for touch screen). the framebuffer is inside the thread, the same place you would draw the normal canvas. – Luke Taylor Aug 02 '12 at 06:24
1

No, the unit on the screen (whether you are using canvas or OpenGL) is a pixel. You can get the size of your canvas using Canvas.getWidth() and Canvas.getHeight() if you need relative coordinates, but your Canvas drawing methods are also in Pixels, so I guess you will need to convert coordinates in OpenGL only and not while using Canvas.

Mohamed_AbdAllah
  • 5,311
  • 3
  • 28
  • 47
  • Thanks, but I am almost done with the game and I don't really want to write the whole game all over again in open gl and go through that journey, I would really like if you could help me find a way to scale my game so most, if not all devices would see it kind of the same. I know that openGl is much easier, but right now it is not an option. Again, thanks for answering my question! – Baruch Jul 31 '12 at 12:33
  • You must use relative coordinates using Canvas.getWidth() & Canvas.getHeight() to scale your coordinates. For e.g., you need a template screen resolution (let's say 480x800) that you create your drawings to and then to create a 10 unit horizontal line for e.g., its 10x(480/Canvas.getWidth()). This will make your line relative to the screen resolution. – Mohamed_AbdAllah Jul 31 '12 at 12:47
  • but how would i get the screen resolution of the current phone? – Baruch Jul 31 '12 at 12:53
  • Correction 10x(Canvas.getWidth()/480). About your question, the SurfaceView you are using (as I presume) is filling the screen (FILL_PARENT), so Canvas.getWidth() or getHeight() will get the screen size (or your view size, which is the same for your game, I guess, since this is your game's world). You also need to do the same for the height – Mohamed_AbdAllah Jul 31 '12 at 13:02
  • Sorry for a follow up question, but if Canvas.getWidth() would give me the width of the screen, when i divide it by 480, it would basically make 480 the default screen resolution and everything else would be proportional, am i correct or way off? I want to understand stuff before i use it, and not just copy/paste. Thanks! – Baruch Jul 31 '12 at 13:05
  • As I said in my answer, all of this is "if you want everything to be relative". If you want fixed coordinates, you don't have to use it, but for smaller screens, you may lose some graphics. – Mohamed_AbdAllah Jul 31 '12 at 13:11