继承,静态和混乱

时间:2016-08-09 11:25:37

标签: java

我有3本Java书籍,并使用在线资源,包括本网站上的帖子,但有些东西只是没有点击。新的编程一般而不是最亮的灯泡,所以如果可能的话,请尽量减少响应。我会尽力详细解释,如果这是一篇很长的帖子,那就很抱歉,感谢您的时间。另外,我正在使用IntelliJ IDEA IDE

目标: 我试图创建一个简单的游戏"实现GUI时,单击3个JButtons中的1个来执行操作,JButtons上方是用于将所有信息中继到用户的JTextArea。

问题: 我没有正确引用其他类中的对象并创建静态方法和变量来补偿(我认为)但是请看看并让我知道我还做错了什么我需要那些知道什么的人的评论和批评。

SIDE注意: 它的马车和很多已经变成了一个静态的"方法或变量,以便在类之间使用。什么时候创建一个新的" Level"由于它的静态性质,我无法回收我的敌人ArrayList并在其中加载新的敌人。我将发布工作版本,但我已经开始重建它,以便练习完美,并可能升级我的代码。

  • 就结构而言,每个" Level"应该是它自己的类,如果所有级别都在像敌人一样的ArrayList中,我应该有1个类作为游戏循环吗?

    • 在制作某些东西时是否有通用的最佳方式,或者只要它起作用并不重要? (意见请)

我有 6个套餐 13个类 这是很多代码,所以我只会打印我相信这些课程对这种情况很重要。

主要类别:

package Primary;
import GUI.PrimaryFrame;
import Game.Loop;
/**
* Created by Thunderfoot on 8/4/2016. Keep Growing!
*/
public class Alpha {
public static void main(String[] args) {

    //Instantiate our GUI
    PrimaryFrame frameGUI = new PrimaryFrame();
    frameGUI.buildGUI();
    //Instantiate our game loop
    Loop.newGame();
   }
}

GUI:

package GUI;

import javax.swing.*;
import java.awt.*;

/**
* Graphical User Interface requires:
* 1 JFrame (PrimaryFrame)
* 4 JPanel (outputPanel, characterStatsPanel, topButtonPanel, bottomButtonPanel)
* 3 JTextArea (output, playerStats, enemyStats)
* 1 JScrollPane (output)
* 3 JButton (attackButton, kickButton, powAttButton)
*/
public class PrimaryFrame extends JFrame {

private OutputPanel outPanel = new OutputPanel();
private StatsPanel statPanel = new StatsPanel();
private TopButtons topPanel = new TopButtons();
private BottomButtons botPanel = new BottomButtons();

//Constructor
public PrimaryFrame() {
    //frame
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
    Dimension FRAME_MIN = new Dimension(400, 600);
    setMinimumSize(FRAME_MIN);
    Dimension FRAME_MAX = new Dimension(600, 800);
    setMaximumSize(FRAME_MAX);
    setTitle("Generic Fighting Game");
    getContentPane().setBackground(Color.BLACK);

}

public void buildGUI() {

    //Add components and spacing
    add(Box.createRigidArea(new Dimension(8, 8)));
    add(outPanel);
    add(Box.createRigidArea(new Dimension(8, 8)));
    add(statPanel);
    add(Box.createRigidArea(new Dimension(8, 8)));
    add(topPanel);
    add(Box.createRigidArea(new Dimension(8, 8)));
    add(botPanel);
    add(Box.createRigidArea(new Dimension(8, 8)));


    //Set attributes
    pack();
    setLocationRelativeTo(null);
    setVisible(true);


   }

}

输出面板:

package GUI;

import javax.swing.*;
import javax.swing.text.DefaultCaret;
import java.awt.*;

/**
* Created by Thunderfoot on 8/4/2016. Keep Growing!
*/
public class OutputPanel extends JPanel {

//Class variables
public static JTextArea output;


OutputPanel() {

    Font myFont = new Font("Serif", Font.BOLD, 16);
    BoxLayout outFlow = new BoxLayout(this, BoxLayout.X_AXIS);
    setLayout(outFlow);
    setBackground(Color.GRAY);
    setMinimumSize(new Dimension(400, 100));
    setMaximumSize(new Dimension(600, 300));

    //TextArea
    output = new JTextArea(1,50);
    output.setLineWrap(true);
    output.setWrapStyleWord(true);
    output.setEditable(false);
    output.setFont(myFont);
    JScrollPane outputScroll = new JScrollPane(output, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    outputScroll.isWheelScrollingEnabled();
    //TextArea always scroll to bottom after update
    DefaultCaret caret = (DefaultCaret)output.getCaret();
    caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);

    //Add components and spacing
    add(Box.createRigidArea(new Dimension(8, 8)));
    add(outputScroll, CENTER_ALIGNMENT);
    add(Box.createRigidArea(new Dimension(8, 8)));

   }
}

游戏循环:

package Game;

import Characters.BasicEnemy;
import Characters.UserCharacter;
import GUI.BottomButtons;
import GUI.TopButtons;
import Levels.Level_One;
import Levels.Tutorial;

import java.util.ArrayList;

public class Loop {

//Class variables
public static UserCharacter player;
public static ArrayList<BasicEnemy> enemyList;
public static int currLevel = 0;

public static void newGame() {
    combatDisabled();
    switch (currLevel) {
        case 0:
            Tutorial tutorial = new Tutorial();
            tutorial.runTutorial();
            combatEnabled();
            break;
        case 1:
            Level_One lvl1 = new Level_One();
            lvl1.runLevelOne();
            combatEnabled();
            break;
    }
}

public static void combatEnabled() {
    TopButtons.attackButton.setEnabled(true);
    TopButtons.kickButton.setEnabled(true);
}

public static void combatDisabled() {
    TopButtons.attackButton.setEnabled(false);
    TopButtons.kickButton.setEnabled(false);
    BottomButtons.powAttButton.setEnabled(false);
  }
}

第1级:

package Levels;

import Characters.BasicEnemy;
import Characters.UserCharacter;
import CombatSystem.Combat;
import GUI.OutputPanel;
import Game.Loop;

import java.util.ArrayList;

public class Tutorial {

public void runTutorial() {

    //Instance variables
    Loop.player = new UserCharacter(100, 10);
    BasicEnemy enemy0 = new BasicEnemy(100, 5);
    BasicEnemy enemy1 = new BasicEnemy(100, 5);
    BasicEnemy enemy2 = new BasicEnemy(100, 5);
    Loop.enemyList = new ArrayList<>();
    Loop.enemyList.add(enemy0);
    Loop.enemyList.add(enemy1);
    Loop.enemyList.add(enemy2);
    OutputPanel.output.append("Greetings player! Use the buttons at the bottom of the screen to fight your opponent.");
    Combat.statusUpdate();
    Loop.combatEnabled();
  }
}

处理战斗的类:

package CombatSystem;

import GUI.BottomButtons;
import GUI.OutputPanel;
import GUI.StatsPanel;
import Game.Loop;

import java.util.Random;

public class Combat {

//Player stats
private static int playerCurrHealth = Loop.player.getHealth();
private static int playerCurrRage = Loop.player.getRageMeter();
private static int playerAttack = Loop.player.getAttackPower();
private static int playerKick = Loop.player.getKickPower();
private static int playerPowAttack = Loop.player.getRagePower();

//Enemy stats
private static int enemyCurrHealth = Loop.enemyList.get(0).getHealth();
private static int enemyCurrRage = Loop.enemyList.get(0).getRageMeter();
private static int enemyAttack = Loop.enemyList.get(0).getAttackPower();

//Fighting
private static boolean fighting = true;

public Combat() {

}


//Update status fields
public static void statusUpdate() {
    StatsPanel.playerStats.setText(" <" + playerCurrHealth + "> [" + playerCurrRage + "] ");
    StatsPanel.enemyStats.setText(" <" + enemyCurrHealth + "> [" + enemyCurrRage + "] ");
}

//Basic attack
public static void basicAttack() {
    if (fighting) {
        playerBasicAttack();
        if (enemyCurrHealth <= 0) {
            death();
        } else {
            enemyBasicAttack();
            if (playerCurrHealth <= 0) {
                death();
            }
        }
    }
}

//Player combat systems
private static void playerBasicAttack() {
    OutputPanel.output.append("\n Your attack does " + playerAttack + " damage to the enemy!");
    enemyCurrHealth -= playerAttack;
    gainPlayerRage();
    gainEnemyRage();
    statusUpdate();
}

//Player kick attack
public static void playerKickAttack() {
    OutputPanel.output.append("\n Your kick does " + playerKick + " damage to the enemy!");
    enemyCurrHealth -= playerKick;
    gainPlayerRage();
    gainEnemyRage();
    statusUpdate();
    Random random = new Random();
    int kickChance = random.nextInt(100) + 1;
    if (kickChance >= 60) {
        OutputPanel.output.append("\n Your kick has stunned the enemy!");
    } else {
        enemyBasicAttack();
        gainEnemyRage();
        gainPlayerRage();
        statusUpdate();
    }
}


//Player power attack
public static void playerPowAttack() {
    OutputPanel.output.append("\n Your POWER ATTACK does " + playerPowAttack + " damage to the enemy!");
    enemyCurrHealth -= playerPowAttack;
    playerCurrRage = 0;
    gainEnemyRage();
    statusUpdate();
    BottomButtons.powAttButton.setEnabled(false);
}


private static void gainPlayerRage() {
    if (playerCurrRage < 100) {
        playerCurrRage += 5;
        if (playerCurrRage >= 100) {
            playerCurrRage = 100;
            BottomButtons.powAttButton.setEnabled(true);
        } else {
            BottomButtons.powAttButton.setEnabled(false);
        }
    }
}

//Enemy combat systems
private static void enemyBasicAttack() {
    OutputPanel.output.append("\n Enemy's attack does " + enemyAttack + " damage to you!");
    playerCurrHealth -= enemyAttack;
    gainEnemyRage();
    gainPlayerRage();
    statusUpdate();

}

private static void gainEnemyRage() {
    if (enemyCurrRage < 100) {
        enemyCurrRage += 5;
    } else {
        enemyCurrRage = 100;
    }
}

//END GAME
private static void death() {
    if (playerCurrHealth <= 0) {
        Loop.combatDisabled();
        fighting = false;
        loseGame();
    } else if (enemyCurrHealth <= 0) {
        if (!Loop.enemyList.isEmpty()) {
            Loop.enemyList.remove(0);
            OutputPanel.output.append("\nYou have killed an enemy!");
            statusUpdate();
            fighting = true;
        } else {
            fighting = false;
            Loop.combatDisabled();
            winGame();
        }
    }
}

private static void winGame() {
    OutputPanel.output.setText("You won!");
    Loop.combatDisabled();
    Loop.currLevel++;
    Loop.enemyList.clear();
    Loop.newGame();
}

private static void loseGame() {
    OutputPanel.output.setText("You lost!");
    Loop.combatDisabled();
  }
}

2 个答案:

答案 0 :(得分:0)

通常,正确的方法是创建一个名为 controller 的类的实例。控制器是一个对象,它处理对其他对象的引用并处理要完成的任务。所以,在你的主要部分,你会做类似

的事情
GameController cont = new GameController();

然后,如果您需要控制器需要访问的内容,只需将其链接到控制器内:

GUI gui = new GUI();
cont.setGUI(gui);

此外,每当需要访问控制器来完成其工作时,您需要为其提供控制器:

gui.setController(controller);

这样,你提供抽象 - 你不会打电话给eg。从您的玩家角色中进行GUI绘制,您只需在控制器中创建方法,例如说handlePlayerInput(...),并且控制器知道要调用的对象以及要处理的方法。

答案 1 :(得分:0)

&#34;一切静止&#34;这本身并不是一个糟糕的编程范式,但它通常表示重度耦合和不灵活的架构。例如,如果你有两个enemyLists,你会怎么做?另一个静态字段可能会这样做但是现在需要对使用enemyList的所有内容进行大量复制粘贴。复制粘贴通常是您想要避免的事情,以便使长期维护更容易。

更好的体系结构将事物封装到有意义的抽象中,无论是面向对象还是以某种方式表示具有单一职责的模块。游戏逻辑和渲染通常是分开的东西。正如@PiotrWilkin的另一个回答所述,许多实现将顶级组件封装到控制器中,而这些组件本身则管理其他相关事物。

如果您对软件设计和架构感兴趣,我建议您阅读以下两个经典之作:

    罗伯特·C·马丁的
  • Principles and Patterns,详细解释了SOLID设计原则,简单易学,但很难掌握这些概念,这些概念共同构成了坚如磐石的软件架构。
  • Design Patterns由Erich Gamma,Richard Helm,Ralph Johnson和John Vlissides撰写,由Grady Booch撰写。这是一本类似字典的书,描述了软件设计中常用的模式。