I'm creating a grid for my game, but I want the size of the grid to vary, depending on the phone's dimensions. When I run the code (note: I removed a lot from ondraw, only concerned about lines atm), it seems like the size of the grid is the same on both my HTC Desire and Wildfire - Which makes the grid look perfect on the wildfire, but there is a massive space below the grid on the desire- prob cos the desire screen is bigger? What I'm asking is...
How do i make the grid scale to the phones dimensions - I want the grid to take up the majority of the phone's screen, but have a margin.Thanks
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
padding = 8;
for (int i = 0; i < 9; i++) {
canvas.drawLine(padding + testWidth* i, padding, padding
+ testWidth * i, testWidth* 8+padding, dark);
canvas.drawLine(padding, padding+testWidth* i, testWidth* 8
+ padding, padding+testWidth* i, dark);
}
}
}
public void onSizeChanged(int w, int h, int oldw, int oldh) {
testWidth= w / 9f;
testHeight = h / 9f;
border = w;
getRect(selX, selY, selRect);
super.onSizeChanged(w, h, oldw, oldh);
}
EDIT: I can now make a grid that scales to the phone's dimensions, however it is a rectangular grid. It looks kind of silly, I need a square one. Maybe I should make padding bigger if the screen is bigger?
This answer is supplementing Nicolas Brown's answer, but you might identify your problem a little better by introducing some more local variables. For example, your original loop could be replaced by:
padding = 8;
for (int i = 0; i < 9; i++) {
int xposition = padding + testWidth * i;
int yposition = padding + testHeight * i;
// Horizontal line
canvas.drawLine(padding, yposition, padding + testWidth * 8, yposition, dark);
// Vertical line
canvas.drawLine(xposition, padding, xposition, padding + testHeight * 8, dark);
}
Also, as Nicolas suggested, you are not accounting for the 8 pixel padding. So, in your onSizeChanged you want:
testWidth = (w - 16f) / 9f;
testHeight = (h - 16f) / 9f;
The problem is a typing error. Seems like you've copied and pasted testWidth and forgot to change it to. Try this:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
padding = 8;
for (int i = 0; i < 9; i++) {
canvas.drawLine(padding + testWidth* i, padding, padding
+ testWidth * i, testWidth* 8+padding, dark);
canvas.drawLine(padding, padding+testHeight* i, testHeight* 8
+ padding, padding+testHeight* i, dark);
}
}
Related
I'm using the thumb of the horizontal scroll view to indicate which page the user is on. What I would like to happen is the thumb width be the screenwidth/number of pages which is what happens on larger devices. The problem comes when I switch to a phone: the thumb width is no longer the size it's bigger which I cannot use.
Is there a way to change the width of the thumb in a horizontal scroll view (or the hight in a vertical scroll view)?
So I figured it out. You cannot change the actual scrollviews scrollbars because you need the class ScrollBarDrawable which isn't in the ADK. So what I did was overrode the scrollview and drew a custom scrollbar. Also make sure to disable the scrollviews default scrollbars (View.setVericalScrollbarEnabled(boolean) or android:scrollbars="none")
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w,h,oldw,oldh);
width = getWidth() - getPaddingLeft() - getPaddingRight();
//you need this to get the total width of the scrollview (with all of the children)
measure(w,h);
totalWidth = getMeasuredWidth();
}
#Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
float xPer = getScrollX() / totalWidth;
canvas.drawRect(
(xPer * width) + getScrollX(),
getHeight() - scrollBarHeight,
//scroll position //width of the bar //offset in the actual canvas
((xPer * width) + (width/(totalWidth/width)) + getScrollX(),
getHeight(), paint);
}
Hope this helps someone else!
My render method:
public void render(float delta) {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
int w = GateRunner.WIDTH;
int h = GateRunner.HEIGHT;
cam.update();
cam.setToOrtho(false, w, h);
Gdx.input.setInputProcessor(this);
game.batch.begin();
game.batch.draw(title_background, 0, 0, GateRunner.WIDTH, GateRunner.HEIGHT);
game.batch.draw(title, (w / 2) - (w / 2), h / 2 + h * 12 / 90, w, (int) (w * 0.5));
playButtonSprite.setPosition((w / 2) - (w / 2), h / 2 + h / 20);
playButtonSprite.setSize(w, (int) (w * (144.0 / 1080)));
playButtonSprite.draw(game.batch);
game.batch.draw(instructions_button, (w/2) - (w/2), h/2 + h/20 - h*3/40, w, (int) (w * (144.0 / 1080)));
game.batch.draw(about_button, (w / 2) - (w / 2), h / 2 + h/20 - 2*h*3/40, w, (int)(w*(144.0/1080)));
game.batch.end();
}
My touchDown method.
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
float pointerX = InputTransform.getCursorToModelX(windowWidth, screenX);
float pointerY = InputTransform.getCursorToModelY(windowHeight, screenY);
if(playButtonSprite.getBoundingRectangle().contains(pointerX, pointerY)) //Play button
{
game.setScreen(new PlayScreen(game));
dispose();
}
return true;
}
I wanted to make it so when I clicked the Play "button", which is just a Sprite, it would move to PlayScreen. I did this by checking if the rectangle where the Play sprite was clicked. However, even though this part works, whenever I click in that rectangle area in PlayScreen, it runs the code again - it starts the PlayScreen over. How can I fix this?
Edit: also, there might be a better name for this question, so feel free to suggest.
This is happenning because when you change screen, you still have the same input processor in place which is checking whether that rectangle of the screen is tapped. Whether the button is visible or not is irrelevant.
You can do one of these to fix it...
Make each screen have its own input processor specific to its needs - this is the preferred option
Have a single input processor that checks what the current screen is before handling actions
Alternatively, look into frameworks like scene2d.ui to handle this sort of stuff for you.
I am upgradring an Android app from a target version of 2.3 (10) to 4.4 (19) but the Canvas Path draw does not work in the same way - and I can't find any docs saying what has changed.
I it regarding the grey semi transparent overlay - it should be like the first image(Target Android 2.3)
Target: Android 2.3 (10)
Target: Android 4.4 (19)
Here is the code:
public class ProgramItemBackgroundDrawable extends Drawable{
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int height;
private int width;
private int topViewHeight;
private boolean showBorder;
public ProgramItemBackgroundDrawable(){
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setStrokeWidth(1);
...
}
public void draw(Canvas canvas) {
int cornerCutSize = convertDpToPixels(20, context);
int smallCornerTopMargin = convertDpToPixels(4, context);
if (cornerCutSize > height)
cornerCutSize = height - smallCornerTopMargin;
drawBaseBackgroundColors(canvas, cornerCutSize);
int margin = convertDpToPixels(3, context);
paint.setColor(Color.BLACK);
paint.setAlpha((int) (255 * 0.12));
Path path = new Path();
if(showBorder){
//Marks bottom part of item with space around for the border
path.moveTo(margin, margin + topViewHeight);
path.lineTo(margin, height - margin);
path.lineTo(width - cornerCutSize, height - margin);
path.lineTo(width - margin, height - cornerCutSize);
path.lineTo(width - margin, margin + topViewHeight);
path.close();
//Marks bottom corner
path.moveTo(width - cornerCutSize, height);
path.lineTo(width, height - cornerCutSize);
path.lineTo(width, height);
path.close();
} else {
//Marks bottom part of item
path.moveTo(0, margin + topViewHeight);
path.lineTo(0, height);
path.lineTo(width, height);
path.lineTo(width, margin + topViewHeight);
path.close();
//Marks bottom corner if it overlaps with the top view area
if(height < (topViewHeight + margin + cornerCutSize)) {
int smallCornerCutSize = Math.abs((height - cornerCutSize) - topViewHeight - margin);
path.moveTo(width - smallCornerCutSize, margin + topViewHeight);
path.lineTo(width+1, margin + topViewHeight - smallCornerCutSize);
path.lineTo(width+1, margin + topViewHeight);
path.close();
}
}
path.setFillType(Path.FillType.INVERSE_WINDING);
canvas.drawPath(path, paint);
}
private void drawBaseBackgroundColors(Canvas canvas, int cornerCutSize) {
...
}
public static int convertDpToPixels(float dp, Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float px = dp * (metrics.densityDpi/160f);
return (int) px;
}
}
Any idea what has changed in the way android handles the drawing?
Update 1:
I think it might have something to do with the Hardware Acceleration changes in Api level 14
This fixes it:
containingView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
I disable Hardware Acceleration.
But isn't there some drawbacks with this solution?
And how could I get it working with Hardware Accelerations?
Hi I'm trying to make a square 8x8 grid on a canvas. I've managed to make a grid, but it turns out to be rectangular, but for the game I'm making it needs to be square. How do I change my code to make it a square grid scaled to the phone.
float testWidth = (getWidth() - 16f) / 9f;
float testHeight = (getHeight() - 16f) / 9f;
for (int i = 0; i < 9; i++) {
canvas.drawLine(padding + testWidth* i, padding, padding
+ testWidth * i, testHeight* 8+padding, dark);
canvas.drawLine(padding, padding+testHeight* i, testWidth* 8
+ padding, padding+testHeight* i, dark);
}
EDIT: I can now make a square grid, but I don't know how to center the grid into the middle of the phone
You'll want to take the shortest of the two (Width or Height) and use that to build the grid upon. (So your grid can fit on the screen)
Something like...:
float gridSide = 0;
if (getWidth() > getHeight()) {
gridSide = getHeight();
}
else {
gridSide = getWidth();
}
Simpler logic provided by appsroxcom:
float gridSide = Math.min(testWidth(), testHeight());
Use gridSide as the total length and total width of the grid
RelativeLayout container = (RelativeLayout) findViewById(R.id.sc);
I've then added my canvas class to this container, but my grid is in the top left corner, i.e there is big space below the grid and I would like to know how to center the grid. This is my code to draw the grid.
float testWidth = (getWidth() - 16f) / 9f;
float testHeight = (getHeight() - 16f) / 9f;
for (int i = 0; i < 9; i++) {
canvas.drawLine(testWidth* i, 0 , testWidth * i, testWidth* 8, dark);
canvas.drawLine(0, testWidth* i, testWidth* 8, testWidth* i, dark);
}
Do I use gravity/margin in the xml file?
Check if it works for you.
float testWidth = (getWidth() - 16f) / 9f;
float testHeight = (getHeight() - 16f) / 9f;
float size = Math.min(testWidth, testHeight);
float offsetW = (getWidth() - size*8) / 2;
float offsetH = (getHeight() - size*8) /2;
for (int i = 0; i < 9; i++) {
canvas.drawLine(offsetW + size*i,
offsetH,
offsetW + size*i,
offsetH + size*8,
dark);
canvas.drawLine(offsetW,
offsetH + size* i,
offsetW + size* 8,
offsetH + size* i,
dark);
}
The code is not tested. The idea is to provide horizontal and vertical offset to the grid.
Use gravity = "center" in the XML file of the PARENT view. In that case, all children of the view will be centered.