0

In fact, we want to code a Bridge Constructor Game and the user must be able to draw these lines to make the bridge..

Already answered : I've been trying to create a class would allow me to draw lines on an existing layout, but the app crashed when we try to launch the activity "Game" (by pressing the button in the Main Menu). The LogCat told us that : "FATAL EXCEPTION : main" and that we have a NullPointerException.

[EDIT] : We search now how to get back all the lines we've created as individual objects (we suppose there are the bitmaps that the canvas created), but we really don't know how to get these Bitmaps...

Here is the code of the activity "CustomView" (Use to draw the lines) :

    package com.g70.buildmybridge;

import java.util.LinkedList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.view.MotionEvent;
import android.view.View;

public class CustomView extends View {

    private Paint   mPaint;
    private Bitmap  mBitmap;
    private Canvas  mCanvas;
    private Path    mPath;
    private Paint   mBitmapPaint;

    private LinkedList<Path> paths = new LinkedList<Path>();


        public CustomView (Context context) {
               super(context);
               setFocusable(true);
               setFocusableInTouchMode(true);

               mPath = new Path();
               mCanvas = new Canvas();
               mBitmapPaint = new Paint();
               mPaint = new Paint();
               mPaint.setColor(Color.BLACK);
               mPaint.setStyle(Paint.Style.STROKE);
               mPaint.setStrokeJoin(Paint.Join.BEVEL);
               mPaint.setStrokeCap(Paint.Cap.ROUND);
               mPaint.setStrokeWidth(6);
               paths.add(mPath);
           }

         @Override
           protected void onDraw(Canvas canvas) {
             for (Path p : paths){
                    canvas.drawPath(p, mPaint);
                }

        }

        private float mX, mY;
        private static final float TOUCH_TOLERANCE = 4;

     // à la touche posée
        private void touch_start(float x, float y) {

                x=Math.round(x/100)*100;
                y=Math.round(y/100)*100;
                mPath.reset();
                // deplacement du path et positionnement en x,y
                mPath.moveTo(x, y);
                mX = x;
                mY = y;

        }

        // a la touche levée
        private void touch_up(float x, float y) {
            float dX=(x-mX);
            float dY=(y-mY);
            if(dY>=0&dY<=50){
                y=mY;
            }
            if(dY>=50){
                y=mY+100;
            }
            if(dX>=0&dX<=50){
                x=mX;
            }
            if(dX>=50){
                x=mX+100;
            }
            if(dX<=0&dX>=-50){
                x=mX;
            }
            if(dY<=0&dY>=-50){
                y=mY;
            }
            if(dX<=-50){
                x=mX-100;
            }
            if(dY<=-50){
                y=mY-100;
            }
            mPath.lineTo(x, y);
            // dessin du path sur l'objet paint
            mCanvas.drawPath(mPath, mPaint);
            // reset du path pour ne pas avoir le chemin précédent
            mPath = new Path();
            paths.add(mPath);
            mPath.reset();
         }


        // lancement des methodes de touch de l'écran tactile du smartphone
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            // prend l'axe des X
            float x = event.getX();
            // prend l'axe des Y
            float y = event.getY();

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    touch_start(x, y);
                    invalidate();
                    break;
                case MotionEvent.ACTION_UP:
                    touch_up(x,y);
                    invalidate();
                    break;
            }
            return true;
        }

        /**public void ChangeColor(String s){
            if(s=="Metal"){
                mPaint.setColor(Color.GRAY);
            }
            if(s=="Wood"){
                mPaint.setColor(Color.YELLOW);
            }
        }**/
}

And here is the code of the Game :

package com.g70.buildmybridge;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.GridLayout;
import android.widget.LinearLayout;
import android.view.View;
import android.view.View.OnClickListener;

public class Game extends Activity {

    protected GridLayout DrawLayout;
    CustomView customview;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.game1);
        DrawLayout = (GridLayout) findViewById(R.id.game1);
        customview = new CustomView(this);
        DrawLayout.addView(customview);
        customview.requestFocus();


        final Button exit = (Button) findViewById(R.id.button4);
        exit.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
        Intent intent = new Intent(Game.this, MainActivity.class);
        startActivity(intent);
        }
      });

        /**final Button undo = (Button) findViewById(R.id.button5);
        undo.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            CustomView.paths.pollLast();
        }
      });**/


    }  

}

Thank you in advance !

1 Answers1

1

Here's an error in Game/onCreate:

MainLayout = (LinearLayout) findViewById(R.layout.draw);

Here you must get an ID, not a layout...
So, in your /res/layout/game must be a LinearLayout with id="@+id/draw"

Solution: Change the above instruction to:

MainLayout = (LinearLayout) findViewById(R.id.draw);

Note: it's findViewById, not findViewByLayout.

[EDIT]

You never initialize the path object in the CustomView Class. Do this in the constructor, after the super line:

mPath = new Path();

[EDIT 2]

Also these objects need to be initialized:

private Paint mPaint;
private Bitmap  mBitmap;
private Canvas  mCanvas;
private Paint   mBitmapPaint;

You then start using a new paint object, paint, but then try to use mBitmapPaint and mPaint, instead.

[EDIT 3]

I found a post you might find very interesting: Android How to draw a smooth line following your finger

[EDIT 4]

Finally it works, but we want now to get the Bitmap we created as objects (each line one by one !) to make them move ... We don't find anything on how to get them ! I will edit our code to see what we have done !

That should really be another question... 1 Q => 1 A.
It makes no sense (and also adds confusion) to edit the question and change it to a different one.
It could also invalidate previous answers...

Community
  • 1
  • 1
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115