jjzjj

java - 初学者 Java 问题 - "Breakout"游戏。我的下一步是什么?

coder 2024-03-08 原文

这是我关于 SO 的第一篇文章!

我已经独自学习了几周斯坦福大学的“编程方法论”类(class),该类(class)介绍了如何使用 Java 进行编程。到目前为止,我一直在毫无困难地完成所有程序,以最小的困难研究我需要的东西。

现在,我只有一组积木和一个可以从墙上弹回的球。目前,球除了在 Canvas 中反弹并穿过砖 block 外什么都不做。
涉及很多步骤,我很确定我可以处理其他步骤。我很难相处的是...

1) 让球从砖 block 上弹开。
2) 当球弹开时,让砖 block 消失。

我一直在使用的一些资源-
Using the ACM Graphics Package
Stanford PDF with the assignment guidelines

我想我的问题是。为了能够解决上面列出的问题,我需要了解什么。在其中一个讲座中,教授谈到了使用“getElementAt()”,但我真的不明白该方法是如何工作的,或者我如何使用它让我的球从砖 block 上弹开,然后让它们消失。

到目前为止我写的代码 -

/*
 * File: Breakout.java
 * -------------------
 * Name: Sandi
 * Section Leader: I'm learning this online
 *
 * This file will eventually implement the game of Breakout.
 */

import acm.graphics.*;
import acm.program.*;
import acm.util.*;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Breakout extends GraphicsProgram {

    /** Width and height of application window in pixels */
    public static final int APPLICATION_WIDTH = 400;
    public static final int APPLICATION_HEIGHT = 600;

    /** Dimensions of game board (usually the same) */
    private static final int WIDTH = APPLICATION_WIDTH;
    private static final int HEIGHT = APPLICATION_HEIGHT;

    /** Dimensions of the paddle */
    private static final int PADDLE_WIDTH = 60;
    private static final int PADDLE_HEIGHT = 10;

    /** Offset of the paddle up from the bottom */
    private static final int PADDLE_Y_OFFSET = 30;

    /** Number of bricks per row */
    private static final int NBRICKS_PER_ROW = 10;

    /** Number of rows of bricks */
    private static final int NBRICK_ROWS = 10;

    /** Separation between bricks */
    private static final int BRICK_SEP = 4;

    /** Width of a brick */
    private static final int BRICK_WIDTH = (WIDTH - (NBRICKS_PER_ROW - 1)
            * BRICK_SEP)
            / NBRICKS_PER_ROW;

    /** Height of a brick */
    private static final int BRICK_HEIGHT = 8;

    /** Radius of the ball in pixels */
    private static final int BALL_RADIUS = 10;

    /** Offset of the top brick row from the top */
    private static final int BRICK_Y_OFFSET = 70;

    /** Number of turns */
    private static final int NTURNS = 3;

    /* Method: run() */
    /** Runs the Breakout program. */

    public void run() {
        addBricks();
        addBall();

        //velocity of the ball's x and y
        ballVX = 1;
        ballVY = 2;

        while (true) {
            moveBall();
            pause(10);
        }
    }

    private void addBricks() {
        int startY = BRICK_Y_OFFSET;
        GRect brick;

        for (int i = 0; i < NBRICK_ROWS; i++) {

            int startX = BRICK_SEP;

            for (int j = 0; j < NBRICKS_PER_ROW; j++) {
                brick = new GRect(startX, startY, BRICK_WIDTH, BRICK_HEIGHT);
                add(brick);

                colorBricks(brick, Color.RED, 0, 1);
                colorBricks(brick, Color.ORANGE, 2, 3);
                colorBricks(brick, Color.YELLOW, 4, 5);
                colorBricks(brick, Color.GREEN, 6, 7);
                colorBricks(brick, Color.CYAN, 8, 9);

                startX += BRICK_WIDTH + BRICK_SEP;
            }

            startY += BRICK_HEIGHT + BRICK_SEP;
        }
    }

    private void colorBricks(GRect brick, Color color, int fromRowNumber,
            int toRowNumber) {
        //this will make it so that if the bricks are between two y coordinates
        //then the method will set it to a certain color and color it.
        if (brick.getY() >= BRICK_Y_OFFSET + fromRowNumber
                * (BRICK_HEIGHT + BRICK_SEP)
                && brick.getY() <= BRICK_Y_OFFSET + toRowNumber
                        * (BRICK_HEIGHT + BRICK_SEP)) {
            brick.setColor(color);
            brick.setFilled(true);
        }
    }

    private void addBall() {
        ball = new GOval(getWidth() / 2, getHeight() / 2, BALL_RADIUS,
                BALL_RADIUS);
        ball.setFilled(true);
        add(ball);
    }

    private void moveBall() {
        double borderX = ball.getX();
        double borderY = ball.getY();

        if (borderX == 0 || borderX == getWidth() - BALL_RADIUS) {
            ballVX = -ballVX;
        }
        if (borderY == 0 || borderY == getHeight() - BALL_RADIUS) {
            ballVY = -ballVY;
        }

        ball.move(ballVX, ballVY);
    }

    private GOval ball;
    private double ballVX;
    private double ballVY;
}

谢谢大家!

最佳答案

当然,可以做很多事情来增强您的程序。但是为了解决你的下一个问题,我认为你必须了解一点你所依赖的类的“魔力”。

我没有深入研究您的 API,但看起来您的调用 add(brick); 将您的砖 block 添加到内部存储在 GraphicsProgram 中的数组/集合中(如果您可以获得您所依赖的类的源代码,那么阅读和理解代码可能会有所帮助)。您可以稍后使用 getElementAt 访问您添加的对象。因此,如果您在 (10,20) 位置添加一 block 砖,然后调用 getElementAt(10,20),它应该会返回这 block 砖。

您应该修改您的 moveBall 方法来检查球的新位置是否包含砖 block ,如果是,则采取相应的行动。像这样:

private void moveBall() {
    double borderX = ball.getX();
    double borderY = ball.getY();

    GRect brick = getElementAt(borderX, borderY);
    if (brick != null) {
        doSomethingWithBall();
    } else {
        if (borderX == 0 || borderX == getWidth() - BALL_RADIUS) {
            ballVX = -ballVX;
        }
        if (borderY == 0 || borderY == getHeight() - BALL_RADIUS) {
            ballVY = -ballVY;
        }
    }

    ball.move(ballVX, ballVY);
}

您可能需要稍微调整一下传递给 getElementAt 的值,以及当您找到一 block 砖头时您究竟做了什么。你必须考虑到砖 block 不是点而是有高度和宽度,球也在移动而不是点......

编辑:您的球也被添加到 Collection 中。所以有可能返回球而不是砖。您不应将球的实际位置传递给 getElementAt 方法,而应将球在没有砖 block 阻挡时移动半个球半径后所处的值传递给该方法。

关于java - 初学者 Java 问题 - "Breakout"游戏。我的下一步是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5381218/

有关java - 初学者 Java 问题 - "Breakout"游戏。我的下一步是什么?的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  3. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  4. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  5. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  6. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  7. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  8. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  9. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  10. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

随机推荐