简单的2D游戏,试图理解多个类

时间:2014-05-11 09:23:33

标签: java

我正在创建一个简单的2D游戏,而且我很难理解如何与其他类进行交互。

例如,在此之前,我已将所有播放器图片和坐标存储在程序的主循环中,但现在我希望将其带到一个新的类中。并且像Player.whateverhere

一样引用播放器

更改它...例如OO编程。

GitHub Link我的完整代码。

    public int x, y;

public boolean up, down, left, right, jump;

public Image offScreen;
public Graphics d;
public BufferedImage walkAnimations[] = new BufferedImage[5];
public BufferedImage background;
public BufferedImage player;

public void run() {
    // Set Window Size
    x = 100;
    y = 100;

    try {
        // Import the images to use in the game
        background = ImageIO.read(new File("img/background.jpg"));
        walkAnimations[0] = ImageIO.read(new File("img/walkleft.png"));
        walkAnimations[1] = ImageIO.read(new File("img/walkright.png"));
        walkAnimations[2] = ImageIO.read(new File("img/walkup.png"));
        walkAnimations[3] = ImageIO.read(new File("img/walkdown.png"));
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    player = walkAnimations[3];

    while (true) {

        // Create the Gravity (If player !jumping; and if player is below or above the ground, then set player to ground.
        if (!jump) {
            if (y < Character.GROUND_LEVEL || y > Character.GROUND_LEVEL) {
                y = Character.GROUND_LEVEL;

            }
        }

        // If Keys are Pressed, Move the object
        if (left) {
            x -= 2;
        } else if (right) {
            x += 2;
        } else if (up) {
            y -= 2;
        } else if (down) {
            y += 2;
        }

        // Repaint the window to update the changes
        repaint();

        try {
            // Make the thread sleep
            Thread.sleep(20);
        } catch (InterruptedException e) {
            // Catch any errors with the Thread
            e.printStackTrace();
        }
    }
}

(对于那些不想去访问我的GitHub代码的麻烦的人);我基本上想要拍摄x / y,图像和东西,然后把它们放在一个名为&#34; Player&#34;但是很难让它发挥作用(例如通过做这个.player.y或player.y)

简单地说,如果你看看Alpha 0.003更新,你可以在2个类中看到它。 我试图将所有播放器内容移动到名为Player的新类/包中

所以我希望能够将其称为player.x = 0;,而不是x = 0; 和设置动画一样。

我想做this.player = walkAnimations[0]

但我不明白如何正确地做到这一点。正在做Player player = new Player();错误吗?

3 个答案:

答案 0 :(得分:0)

"this.player = walkAnimations[0]"

this.player是一个播放器类型变量。

walkAnimations[0]是BufferedImage类型数组的单元格。

因此,该行不会编译。

答案 1 :(得分:0)

基本上,你所做的就是邪恶。不是&#34;我谋杀了一个婴儿并且喝了它的血液邪恶&#34;,只是那种和蔼可亲的友善邪恶,就像#34;我在商业休息期间去小便&#34;。

所以回答这个问题,对象应该如何互动?

他们应该通过发送彼此的消息进行交互。 在Java™中,您通过调用方法进行交互。

例如,根据我最近的强制性转让以及另一项技术援助,我们有SimplePlayer class作为说明性示例:

    @Override
    public void setDirection(Direction dir) {
        this.faces = dir;
    }

因此,如果我想告诉玩家对象朝南,我可以发一条消息告诉它面向南方:

    player.setDirection(Direction.SOUTH);

现在,您可以问,为什么不这样称呼它?

    p.faces = Direction.SOUTH;

这不起作用吗?

是的,在此仅此实例中。 但是,在做这类事情时可能还会遇到其他问题。也许玩家对象在转身时必须做点什么。也许它必须告诉音响系统发出一些噪音。也许它必须在某个地方添加一个数字,记录你已经采取了多少步骤。也许它必须向NSA发送电子邮件。谁知道。当你发送信息时,你不必关心。 Player对象负责所有这些。你不是。

这是问题的答案&#34;我应该如何与我的对象互动?&#34;

答案&#34;为什么我不做什么工作?&#34;这些类型不匹配。您正试图让播放器成为BufferedImage对象,而不是您想要的对象。

答案 2 :(得分:0)

你的问题不是很清楚,但我会尝试给你一些关于如何处理OO游戏编程的一般指导,因为我认为这基本上就是你的要求。

面向对象编程中的关键是实体由类表示,类包含实体的状态(与之相关的数据)及其操作。

例如,汽车可以用Car类来表示。这个课程将包含汽车的特征 - 它的重量,颜色,价格等等 - 并且还包含它可以做什么 - 开始,开车,停止等等。 / p>

这意味着游戏中的每个实体(无论是玩家,怪物,等等)都应该拥有它自己的类。该类应包含所有实体的信息 - 例如它在屏幕上的位置(x,y),它的图像 - 以及它可以做的任何事情(例如在屏幕上移动,跳跃,发射导弹)。

这是一个非常简单的Entity类,例如java-pseudocode。所有游戏实体类都应该继承自这个类:

class Entity{

    private int x, y; // position on screen
    private int dx, dy; // this is how much the entity moves each game-loop cycle.
    private Image image;
    private Rectangle boundingBox;
    private int healthPoints;

    public Entity(int x, int y){

        // ths position of the thing is set through the constructor
        this.x = x;
        this.y = y;

        dx = 0;
        dy = 0;

        healthPoints = 100;

        Image = new Image(/*some file*/); // this is pseudo code.
        boundingBox = new Rectangle(image); // pseudo code. A rectangle the size of the image.

    }

    public int getX(){ return x; }

    public int getY() { return y; }

    public Image getImage() { return image; }

    // user input can affect this from the outside, to move the entity. or possibly an ai mechanism.
    public void setDX(int dx){ this.dx = dx; }
    public void setDY(int dy){ this.dy = dy; }

    public void move(){
        x += dx;
        y += dy;
    }

    public Rectangle getBoundingBox(){ return boundingBox; }

}

从此类派生的任何对象都将为其自身 保存所有数据和操作。

现在,您的游戏循环控件从外部管理实体并访问其数据 - 移动它们,检查碰撞,显示其图像等。

例如,一个非常简化的游戏类,持有游戏循环。在伪代码(这是一种方法,但从类似的东西开始是好的):

Class GameClass{

    ArrayList entities;

    public GameClass(){

        entities = new ArrayList();
        startGameLoop();

    }

    private void startGameLoop(){

        while(true){ // this is bad, don't do this.

            displayEntities(); // step 1 of gameloop.
            moveEntities(); // step 2
            checkForCollisions(); // step 3

        }

    }

    private void displayEntities(){

        for(int i=0; i<entities.size(); i++){
            Entity entity = entities.get(i);
            displayImage(entity.getImage(),entity.getX(),entity.getY());
        }

    }

    private void updateEntities(){

        for(int i=0; i<entities.size(); i++){
            Entity entity = entities.get(i);
            entity.move();
        }

    }

    private void checkForCollisions(){

        for(int i=0; i<entities.size(); i++){
            Entity entity = entities.get(i);

            for(int j=0; j<entities.size(); j++){
                entities.remove(i);
            }

        }

    }

}

缺少用户输入的课程逻辑。您可以做的是例如当用户按下右箭头时,设置character.setDX(2),左箭头将是character.setDX(-2)。请注意,dx是在调用x时每个周期添加到move()的值。这是一种方法。

它还缺少其他许多东西。

无法涵盖这一篇文章中的所有基础知识。但请记住一件事:

所有实体都封装在类中,这些类拥有自己的数据和操作。有一个集中管理它的中心类,控制游戏循环。类也可以有方法与其他类交互。

希望这有帮助。

编辑:Also, here's a series of tutorials that helped me a lot when I was starting out.