需要OOP和继承建议

时间:2011-12-14 18:02:56

标签: java android oop inheritance

请注意,下面发布的代码很多,但大部分都是相同的,这就是我正在寻找的建议:)

刚刚掌握OOP和继承,我正在制作一个android pong克隆,并且我试图将我的“paddle”和“bomb”类中发现的一堆重复代码分离成一个单独的类叫做精灵。我不确定的是处理当前炸弹和桨类中的成员变量。我希望两个类中的相同变量用于相同的用途,并且认为它们应该移动到我的精灵类。但后来我不确定在我更专业的Bomb和Paddle课程中使用它们......我可以让它们受到保护但这是我感到困惑的地方,因为这会让我处于一种我所有更专业的课程都完全分享的情况相同的变量肯定,我绝对不想要,我只是希望他们有这些变量的副本..哦,我不知道,我的课程目前很简单,如果你可以看一看其中两个,看到相同的内容(主要是getter& setters,draw方法和更新方法)并建议我应该如何将代码移动到我的sprite类中,我们将不胜感激!

第一个专业课,炸弹:

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 个答案:

答案 0 :(得分:2)

  

我正在尝试将一堆重复的代码分离出来   “paddle”和“bomb”类成为一个名为sprite的独立类。什么   我不确定是否处理我当前的成员变量   炸弹和桨类。我想在两个类中使用相同的变量   相同的用途和估计它们应该被移动到我的精灵类。但   然后我不确定在我更专业的Bomb中使用它们   Paddle课程稍后......我可以让他们受到保护,但这是   在那里我感到困惑,因为这会让我陷入困境   我所有更专业的类都完全共享相同的变量   当然,我绝对不想要,我只是希望他们有一份副本   那些变量..哦,我不知道

他们共享相同的变量。

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

class Bomb extends Sprite { 

}

class Paddle extends Sprite { 

}

在上面的示例中,您创建的每个Bomb实例或Paddle实例都有自己的ab。如果您 希望他们共享某个字段,则需要将其声明为static

答案 1 :(得分:1)

创建Sprite课程是迈向OOP精神的一个很好的一步。你甚至可以走得更远,继承SpecialPaddleSprite

SpecialBombSpriteSprite

根据具体情况,您可以直接从Sprite继承或从特殊变体继承。这样你就可以以OOP方式重用代码了。

所以类层次结构可能看起来像

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

这样,如果你有更多种类的特殊桨和炸弹,它们的共同行为可以在SpecialPaddleSpriteSpecialBombSprite