android drawRectの座標位置がおかしい 画面サイズを取得する二は?
- 評価
- クリップ 0
- VIEW 2,245
ブロック崩しを作っています。
ボールが描画できたので、バーを描画したいです。
表示させること自体はできたのですが、位置がおかしいです。
座標でいうと、(0,0)の位置に表示されてしまいます。
bar = new Bar( view_w/2 , view_h - 100 );
canvas.drawRect(bar.x, bar.y, 180, 10, paint);
bar = new Bar(500,500);
と引数を数字にするとバーも移動するのですが、画面サイズの違うスマホでも同じような位置に表示させたいので、画面サイズを取得して、変数に入れ、それをdrawRectの引数に使いたいです。
ちなみに、こちらを参考にしました。
リンク内容
リンク先ではOverrideされたsurfaceChangedの中に
view_w = width;
view_h = height;
があります。
Changedの中にあるのがいけないのかな?
と思い
surfaceCreatedの中に移動させても変わりませんでした。
Main
package com.example.blockbreak;
----中略----
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//カスタムビュークラスのインスタンスをコンテントにセット
setContentView(new CustomView(this));
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
class CustomView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
//スレッドクラス
Thread mainLoop = null;
// 描画用
Paint paint = null;
Paint paint2 = null;
Paint paint3 = null;
// 円のX,Y座標
private int circleX = 50;
private int circleY = 50;
private int circle2X = 30;
private int circle2Y = 30;
// 円の移動量
private int circleVx = 15;
private int circleVy = 15;
private int circle2Vx = 8;
private int circle2Vy = 15;
Bar bar; //バー
private float touch_x; // タッチされたx座標
int view_w, view_h; // SurfaveViewの幅と高さ
//コンストラクタ
public CustomView(Context context) {
super(context);
// SurfaceView描画に用いるコールバックを登録する。
getHolder().addCallback(this);
// 描画用の準備
paint = new Paint();
paint2 = new Paint();
paint3 = new Paint();
paint.setColor(Color.RED);
paint2.setColor(Color.CYAN);
paint3.setColor(Color.GREEN);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO 今回は何もしない。
view_w = width;
view_h = height;
}
// SurfaceView生成時に呼び出されるメソッド。
@Override
public void surfaceCreated(SurfaceHolder holder) {
// 背景
Canvas canvas = holder.lockCanvas();
canvas.drawColor(Color.BLACK);
holder.unlockCanvasAndPost(canvas);
// スレッド開始
mainLoop = new Thread(this);
mainLoop.start();
touch_x = view_w/2;
//バーを生成
bar = new Bar( view_w/2 , view_h - 100 );
}
----中略----
@Override
public void run(){
while (true) {
Canvas canvas = getHolder().lockCanvas();
if (canvas != null)
{
canvas.drawColor(Color.BLACK);
// 円1を描画する
canvas.drawCircle(circleX, circleY, 20, paint);
//円2を描画する
canvas.drawCircle(circle2X,circle2Y,20,paint2);
//長方形を描画する
canvas.drawRect(bar.x, bar.y, 180, 10, paint);
getHolder().unlockCanvasAndPost(canvas);
----中略----
}
}
}
}
}
Barクラス
package com.example.blockbreak;
public class Bar {
//表示座標
public float x;
public float y;
//バーのサイズ
public final float half_size = 100;
//コンストラクタ
public Bar( int _x, int _y ){
//初期座標をセット
x = (float)_x;
y = (float)_y;
}
// 右移動
public void right(float touch_x){
x = touch_x - half_size;
}
// 左移動
public void left(float touch_x){
x = touch_x - half_size;
}
}
追記
surfaceCreated の中で
view_w = canvas.getWidth();
view_h = canvas.getHeight();
しても値が0だった。
runの中で行っても値が0だった。
barのインスタンス化をrunの中に移し、
view_w = canvas.getWidth();
view_h = canvas.getHeight();
したら値取得できた。
@Override
public void run(){
while (true) {
Canvas canvas = getHolder().lockCanvas();
if (canvas != null)
{
view_w = canvas.getWidth();
view_h = canvas.getHeight();
// バーを生成
bar = new Bar( view_w/2 , view_h - 100 );
//長方形を描画する
canvas.drawRect( bar.x, bar.y , bar.x + 200 , bar.y + 20 , paint3);
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
check解決した方法
0
canvas.getWidth
canvas.getHeight
というのでSurfaceViewの画面サイズを取得できる。
取得した値を適当な変数に入れる。
view_w, view_hに入れれば良い。
しかし、それだけだと値がなぜか0のままだった。
view_w = canvas.getWidth();
view_h = canvas.getHeight();
// バーを生成
bar = new Bar( view_w/2 , view_h - 100 );
barのインスタンス化をrunの中に移動させると、無事drawRectの引数に値がセットされた。(理由よくわからない)
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
Canvas#drawRectの引数はleft,top,right,bottomです。
大小関係が矛盾していると0,0になったような気がします。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
surfaceCreatedの中でwidth,heightを表示してみてください。おそらく両方0のはずです。これは、
surfaceviewのライフサイクルが関係すると思われます。surfaceCreatedの中で画面サイズを取得したい場合、以下のようなコードで実現できます。だだし、これは画面全体のサイズでTitleBarや通知バーなども含まれてしまっているので、surfaceChanged内で取得できる画面サイズと異なる可能性があります。
Display display = getWindowManager().getDefaultDisplay();
Point point = new Point();
display.getSize(point);
//point.x 画面幅
//point.y 画面の高さ
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.35%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
dsuzuki
2016/04/22 17:10
view_w, view_hの値はどこで設定していますか?
提示されたコードでは、変数定義時の初期値(ゼロ)しか読めません。
masaakitsuyoshi
2016/04/22 18:55
surfaceChangedの引数にwidth, heightがあったのでこちらで定義したのですが、それでも初期値になっている?のでしょうか。
masaakitsuyoshi
2016/04/22 18:55
surfaceChangedの部分追記しました。
dsuzuki
2016/04/22 19:11
修正ありがとうございます。