Нужен совет по ООП и наследованию - PullRequest
1 голос
/ 14 декабря 2011

Заметьте, что много кода размещено ниже, но в основном все то же самое, вот что я ищу для совета:)

Просто овладев ООП и наследованием, я делаю клон Android-понга, и Я пытаюсь выделить кучу повторяющихся кодов, найденных в моих классах "весло" и "бомба", в отдельный класс называется спрайт. В чем я не уверен, так это в обработке переменных-членов в моих классах бомбы и весла . Мне нужны одни и те же переменные в обоих классах для одного и того же использования, и я считаю, что они должны быть перенесены в мой класс спрайтов. Но потом я не уверен в том, чтобы использовать их в моих более специализированных классах Bomb и Paddle позже ... я мог бы сделать их защищенными, но это то, где я запутался, потому что это оставило бы меня в ситуации, когда все мои более специализированные классы делятся именно Конечно же, те же самые переменные, которые я определенно не хочу, я просто хочу, чтобы у них была копия этих переменных ... о, я не знаю, Мои классы в настоящее время довольно просты, , если бы вы могли просмотреть два из них, , посмотрите, что то же самое (в основном, методы получения и установки, метод рисования и метод обновления) и предложите, как мне следует перенести код в мой класс спрайтов, это было бы очень полезно!

Первый специализированный класс, Бомба:

package biz.hireholly.pirateponggame;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.util.Log;

public class Bomb {
    private Bitmap bitmap;  //image
    private int x;  //x coordinate
    private int y;  //y coordinate

    private Speed speed; //the speed with its directions

    public Bomb(Bitmap bmp, int x, int y){
        this.bitmap = bmp;
        this.x = x;
        this.y = y;
        this.speed = new Speed();
    }

    public Bitmap getBitmap(){
        return bitmap;
    }
    public void setBitmap(Bitmap bmp){
        this.bitmap = bmp;
    }
    public int getX(){
        return x;
    }
    public int getY(){
        return y;
    }
    public void setX(int x){
        this.x = x;
    }
    public void setY(int y){
        this.y = y;
    }
    public Speed getSpeed() {
        return speed;
    }
    public void setSpeed(Speed newSpeed) {
        this.speed = newSpeed;
    }

    /**
     * X&Y += current velocity * current direction
     */
    public void update(){
        x+= (speed.getXv() * speed.getxDirection());
        y+= (speed.getYv() * speed.getyDirection());
    }

    /**
     * takes the bitmap it was instantiated with.
     * Draws it to the canvas at the coordinates the bomb is at in that moment.
     * @param canvas
     */
    public void draw(Canvas canvas){

        canvas.drawBitmap(bitmap, x-(bitmap.getWidth() /2), y-(bitmap.getHeight() /2), null );

    }

    public void handleWallCollision(int viewW, int viewH){

        //check collision with right wall if heading right
        if (speed.getxDirection() == Speed.RIGHT //if going right
                && getX() + (bitmap.getWidth() /2) >= viewW){ //and the centre of the bitmap become greater than the view width
            //reverse x direction
            speed.toggleXDirection();
        }
        //check for collision with left wall if heading left
        if (speed.getxDirection() == Speed.LEFT
                && getX() - (bitmap.getWidth() /2) <= 0){
            //reverse x direction
            speed.toggleXDirection();
        }
        //check collision with  bottom wall if heading down
        if (speed.getyDirection() == Speed.DOWN
                && getY() + (bitmap.getHeight() /2) >= viewH){
            //reverse y direction
            speed.toggleYDirection();
        }
        //check collision with top wall if heading up
        if (speed.getyDirection() == Speed.UP
                && getY() - (bitmap.getHeight() /2) <= 0){
            speed.toggleYDirection();
        }
    }
    public void handlePaddleCollision(Paddle pad){
        //THIS WILL NEED TO WORK FOR BOTH PADDLES


        int paddleHalfH = pad.getBitmap().getHeight();
        int paddleHalfW = pad.getBitmap().getWidth();
        //int bombHalfW = bitmap.getWidth();
        int bombHalfH = bitmap.getHeight();

        //first check if the bombs x is within the paddles x
        if( x >= (pad.getX() - paddleHalfW) //x > paddle leftside
            && x <= (pad.getX() + paddleHalfW)) // x < paddle rightside
        {

            if((y+bombHalfH) >= (pad.getY() + paddleHalfH)) //base of bomb is touching top of paddle
            {
                speed.toggleYDirection();
            }

        }



    }

}

Тогда есть мой класс Paddle с множеством таких же вещей:

package biz.hireholly.pirateponggame;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.util.Log;
import android.view.MotionEvent;

public class Paddle {
    private static final String TAG = Paddle.class.getSimpleName();
    private Bitmap bitmap;  //image
    private Speed speed; //the speed with its directions

    private int x;  //x coordinate
    private int y;  //y coordinate
    private boolean touched; 

    public Paddle(Bitmap bmp, int x, int y){
        this.bitmap = bmp;
        this.x = x;
        this.y = y;
        this.speed = new Speed();
    }

    public void update(){
        //x+= (speed.getXv() * speed.getxDirection());
    }

    /**
     * takes the bitmap it was instantiated with.
     * Draws it to the canvas at the coordinates the bomb is at in that moment.
     * @param canvas
     */
    public void draw(Canvas canvas){
        //just to make things easier to read
        int halfX = bitmap.getWidth() /2;
        int halfY = bitmap.getHeight() /2;

            canvas.drawBitmap(bitmap, x-halfX, y-halfY, null );

    }

    /**
     * checks if player is touching paddle
     * @param eventx
     * @param eventy
     */
    public void handleActionDown (int eventx, int eventy){
        int extray = 20; //extra height desired so that paddle can be easily touched

        if(eventx >= (x - bitmap.getWidth()/2) && //touch within paddles width
                eventx <= (x + bitmap.getWidth()/2)){

                if ( eventy >= (y - bitmap.getHeight() + extray ) && //within height
                        eventy <= (y + bitmap.getHeight()) + extray ) {

                        setTouched(true);
                } 
                else { setTouched(false); }
        }
        else { setTouched(false); }

    }

    public void onTouchEvents(MotionEvent e, int viewW){
        //DETECT PRESS
        if (e.getAction() == MotionEvent.ACTION_DOWN){
            // delegating event handling to the paddle
            handleActionDown((int)e.getX(), (int)e.getY());
        }
        //MOVE GESTURES
        if (e.getAction() == MotionEvent.ACTION_MOVE){
            if (isTouched()){
                //paddle is being dragged

                //SETTING NEW POSITION
                setX( (int)e.getX() );

                if (getX() - (bitmap.getWidth() /2) <= 0)
                {//Left wall collision
                    setX ( 0 + (bitmap.getWidth() /2));
                }
                if (getX() + (bitmap.getWidth()/2) >= viewW)
                {//right wall collision
                    setX( viewW - (bitmap.getWidth()/2) );                  
                }

            }
        }
        //PRESS RELEASED
        if (e.getAction() == MotionEvent.ACTION_UP){
            if (isTouched()){
                //no longer being dragged
                setTouched(false);
            }
        }
    }

    public Speed getSpeed() {
        return speed;
    }
    public void setSpeed(Speed newSpeed) {
        this.speed = newSpeed;
    }

    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
    public Bitmap getBitmap(){
        return bitmap;
    }
    public void setBitmap(Bitmap bmp){
        this.bitmap = bmp;
    }
    public boolean isTouched() {
        return touched;
    }
    public void setTouched(boolean touched) {
        this.touched = touched;
    }
}

Так что я считаю Sprite.java должен выглядеть примерно так ...

package biz.hireholly.pirateponggame;

import android.graphics.Bitmap;
import android.graphics.Canvas;

public class Sprite {
    private Bitmap bitmap;  //image
    private int x;  //x coordinate
    private int y;  //y coordinate

    private Speed speed; //the speed with its directions

    public Bitmap getBitmap(){
        return bitmap;
    }
    public void setBitmap(Bitmap bmp){
        this.bitmap = bmp;
    }
    public int getX(){
        return x;
    }
    public int getY(){
        return y;
    }
    public void setX(int x){
        this.x = x;
    }
    public void setY(int y){
        this.y = y;
    }
    public Speed getSpeed() {
        return speed;
    }
    public void setSpeed(Speed newSpeed) {
        this.speed = newSpeed;
    }


    public void update(){
        x+= (speed.getXv() * speed.getxDirection());
        y+= (speed.getYv() * speed.getyDirection());
    }


    public void draw(Canvas canvas){

        canvas.drawBitmap(bitmap, x-(bitmap.getWidth() /2), y-(bitmap.getHeight() /2), null );

    }

}

Ответы [ 2 ]

2 голосов
/ 14 декабря 2011

Я пытаюсь выделить кучу повторяющихся кодов, найденных в моих классах "paddle" и "bomb", в отдельный класс, называемый sprite.В чем я не уверен, так это в обработке переменных-членов в моих классах бомбы и весла.Мне нужны одни и те же переменные в обоих классах для одного и того же использования, и я считаю, что они должны быть перенесены в мой класс спрайтов.Но потом я не уверен в том, чтобы использовать их в моих более специализированных классах Bomb и Paddle позже ... я мог бы сделать их защищенными, но это то, где я запутался, потому что это оставило бы меня в ситуации, когда все мои более специализированные классы делятся именноКонечно, те же переменные, которые я определенно не хочу, я просто хочу, чтобы у них была копия этих переменных .. о, я не знаю

Они не , разделяющие одно и то жепеременные.

abstract class Sprite  { 
    protected Field a;
    protected Field b;
}

class Bomb extends Sprite { 

}

class Paddle extends Sprite { 

}

В приведенном выше примере каждый создаваемый вами экземпляр Bomb или Paddle будет иметь свои собственные a и b.Если вы хотите, чтобы они разделяли поле, его необходимо объявить static.

1 голос
/ 14 декабря 2011

Создание класса Sprite - хороший шаг навстречу духу ООП.Вы даже можете пойти дальше и иметь SpecialPaddleSprite и SpecialBombSprite, которые наследуют от Sprite

Как только у вас есть это, в зависимости от ситуации, вы можете наследовать от Sprite напрямую или от специальных вариантов.Таким образом, вы будете повторно использовать свой код в режиме ООП.

Таким образом, иерархия классов может выглядеть следующим образом:

         ------> SpecialPaddleSprite ------> SpecialPaddle
       /
Sprite --------> SpecialBombSprite ------> SpecialBomb
       \
         -------> Paddle
         \
           -------> Bomb

Таким образом, если бы у вас было больше видов специальных ракет и ракет,их общее поведение может быть в SpecialPaddleSprite и SpecialBombSprite

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...