Создание игровой силы тяжести в Android (продолжение)?

EDIT: я взглянул на LogCat, и он сказал, что он не может раздуть com.example.playground. Затем я понял, что мне это нужно для com.game.myapp.Playground. Он работал после того, как я изменил его.

Недавно я спросил, почему гравитация не работает в моем приложении для Android ( ссылка ), и у меня все еще есть проблемы с этим. Я изменил представление на класс «Игровая площадка», но теперь он просто заставляет закрывать. Что я делаю не так?

package com.game.myapp; import android.app.Activity; import android.graphics.Canvas; import android.graphics.Paint; import android.os.Bundle; public class InGame extends Activity{ Playground v; private int radius; private int xPosition; private int yPosition; private Paint paint; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Rewrite this, it sucks. Seriously. super.onCreate(savedInstanceState); v = new Playground(this); setContentView(v); } public InGame(int x, int y, int radius, int color) { this.xPosition = x; this.yPosition = y; this.radius = radius; paint = new Paint(color); } void moveBall(int x, int y){ xPosition = x; yPosition =y; } void onDraw(Canvas canvas){ canvas.drawCircle(xPosition, yPosition, radius, paint); } } 

Класс игровых площадок:

 package com.game.myapp; import android.content.Context; import android.graphics.Canvas; import android.view.View; public class Playground extends View{ public static InGame ball; public Playground(Context context) { super(context); // TODO Auto-generated constructor stub } @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); if (ball != null ){ ball.onDraw(canvas); } } } 

Heres the LogCat:

 11-04 16:36:33.945: D/dalvikvm(13177): newInstance failed: no <init>() 11-04 16:36:33.949: D/AndroidRuntime(13177): Shutting down VM 11-04 16:36:33.949: W/dalvikvm(13177): threadid=1: thread exiting with uncaught exception (group=0x4001e578) 11-04 16:36:33.953: E/AndroidRuntime(13177): FATAL EXCEPTION: main 11-04 16:36:33.953: E/AndroidRuntime(13177): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.game.myapp/com.game.myapp.InGame}: java.lang.InstantiationException: com.game.myapp.InGame 11-04 16:36:33.953: E/AndroidRuntime(13177): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1573) 11-04 16:36:33.953: E/AndroidRuntime(13177): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667) 11-04 16:36:33.953: E/AndroidRuntime(13177): at android.app.ActivityThread.access$1500(ActivityThread.java:117) 11-04 16:36:33.953: E/AndroidRuntime(13177): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935) 11-04 16:36:33.953: E/AndroidRuntime(13177): at android.os.Handler.dispatchMessage(Handler.java:99) 11-04 16:36:33.953: E/AndroidRuntime(13177): at android.os.Looper.loop(Looper.java:130) 11-04 16:36:33.953: E/AndroidRuntime(13177): at android.app.ActivityThread.main(ActivityThread.java:3687) 11-04 16:36:33.953: E/AndroidRuntime(13177): at java.lang.reflect.Method.invokeNative(Native Method) 11-04 16:36:33.953: E/AndroidRuntime(13177): at java.lang.reflect.Method.invoke(Method.java:507) 11-04 16:36:33.953: E/AndroidRuntime(13177): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842) 11-04 16:36:33.953: E/AndroidRuntime(13177): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600) 11-04 16:36:33.953: E/AndroidRuntime(13177): at dalvik.system.NativeStart.main(Native Method) 11-04 16:36:33.953: E/AndroidRuntime(13177): Caused by: java.lang.InstantiationException: com.game.myapp.InGame 11-04 16:36:33.953: E/AndroidRuntime(13177): at java.lang.Class.newInstanceImpl(Native Method) 11-04 16:36:33.953: E/AndroidRuntime(13177): at java.lang.Class.newInstance(Class.java:1409) 11-04 16:36:33.953: E/AndroidRuntime(13177): at android.app.Instrumentation.newActivity(Instrumentation.java:1021) 11-04 16:36:33.953: E/AndroidRuntime(13177): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1565) 11-04 16:36:33.953: E/AndroidRuntime(13177): ... 11 more 

Вот полный код. Я просто написал это и протестировал его. Оно работает. Я добавил таймер к активности, чтобы перемещать мяч вправо и вниз на 10 пикселей каждую секунду. Изучите его, изучите его и приспособите к вашим потребностям.

Класс шара.

 package com.example; import android.graphics.Canvas; import android.graphics.Paint; public class Ball{ private int radius; private int xPosition; private int yPosition; private int color; private Paint paint; public Ball(int x, int y, int radius, int color) { this.xPosition = x; this.yPosition = y; this.radius = radius; paint = new Paint(); paint.setColor(color); } int getX(){return this.xPosition;} int getY(){return this.yPosition;} void moveBall(int x, int y){ xPosition = x; yPosition =y; } void onDraw(Canvas canvas){ canvas.drawCircle(xPosition, yPosition, radius, paint); } } 

Класс игровых площадок

 package com.example; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.widget.ImageView; public class Playground extends ImageView { private Ball ball; public Playground(Context context) { this(context,null); } public Playground(Context context, AttributeSet attrs) { this(context, attrs,0); } public Playground(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setBall(Ball ball){ this.ball = ball; } @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); if (ball != null ){ ball.onDraw(canvas); } } } 

Класс активности

 package com.example; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import java.util.Timer; import java.util.TimerTask; public class MyActivity extends Activity { /** * Called when the activity is first created. */ Playground playground; Ball ball; Timer myTimer; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); playground = (Playground) findViewById(R.id.playground); ball = new Ball(100, 100, 20, Color.RED); playground.setBall(ball); myTimer = new Timer(); myTimer.schedule(new TimerTask() { @Override public void run() { Update(); } }, 0, 1000); } private void Update() { this.runOnUiThread(moveBall); } private Runnable moveBall = new Runnable() { public void run() { ball.moveBall(ball.getX() + 10, ball.getY() + 10); playground.invalidate(); } }; } 

[EDIT] XML

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.example.Playground android:id="@+id/playground" android:layout_width="fill_parent" android:layout_height="fill_parent"/> </LinearLayout> 

Ключевые моменты для ООП.

Бал не знает о игровой площадке или о деятельности. У него есть метод, который может быть вызван тем, что он просит его рисовать на холсте, но для всего, что он знает, это может быть невидимый холст или холст кнопки или холст растрового изображения – он не знает или надо знать. Работа над тем, что вызывает метод, беспокоится об этом.

Игровая площадка не знает о деятельности или Бал. Он знает, что у него может быть экземпляр класса Ball, и если он есть, он должен называть его методом onDraw, но он не знает, что такое мяч или что он рисует. Шар беспокоится об этом.

Активность не знает о шаре или игровой площадке, кроме одного из них, и вызывает метод перемещения шара, а затем говорит, что игровая площадка будет перерисовываться.

Дело в том, что вы можете изменить методы рисования, методы перемещения и все остальное без перекодирования (обычно, в общем). Например, вы можете изменить onDraw в классе Ball, чтобы нарисовать прямоугольник. Конечно, название класса теперь плохой выбор, но вы получаете идею …

У вас нет конструктора по умолчанию в вашем InGame Activity , который необходим для того, чтобы Android мог его создать.

Наличие явного конструктора не приведет к определению неявного конструктора no-arg. Возможно, вам понадобится предоставить собственный конструктор no-arg, который инициализирует его члены значениями по умолчанию.

Я бы удалил явный конструктор и поместил инициализацию в метод onCreate(Bundle) .