From 44f90f01e3b0b2cbb9c68f6301ed8bcd4f44e705 Mon Sep 17 00:00:00 2001 From: Meshulam Silk Date: Thu, 21 Nov 2013 19:22:15 +0200 Subject: [PATCH 01/11] Cleaned up the main menu panel code --- .../Grame/Essentials/GrameManager.java | 366 +++++++++--------- 1 file changed, 188 insertions(+), 178 deletions(-) diff --git a/src/com/moomoohk/Grame/Essentials/GrameManager.java b/src/com/moomoohk/Grame/Essentials/GrameManager.java index d25f67b..fe07777 100644 --- a/src/com/moomoohk/Grame/Essentials/GrameManager.java +++ b/src/com/moomoohk/Grame/Essentials/GrameManager.java @@ -860,6 +860,11 @@ public void actionPerformed(ActionEvent arg0) } }); + public MenuButton() + { + this("Default", Color.red, new Color(255, 127, 0), Color.blue, "Default"); + } + public MenuButton(String text, Color startColor, Color endColor, Color clickColor, String helpText) { super(text); @@ -904,6 +909,26 @@ public void mouseEntered(MouseEvent arg0) }); } + public void setStartColor(Color c) + { + this.startColor = c; + } + + public void setEndColor(Color c) + { + this.endColor = c; + } + + public void setClickColor(Color c) + { + this.clickColor = c; + } + + public void setHelpText(String helpText) + { + this.helpText = helpText; + } + public String getHelpText() { return this.helpText; @@ -952,19 +977,16 @@ protected void paintComponent(Graphics g) } } - public static class LoadGamePanel extends JPanel + public abstract static class MenuPanel extends JPanel { - private static final long serialVersionUID = -2270645491547851288L; - - private String savePath; - private HashMap saves; - private JScrollPane scrollPane; - private MenuButton btnLoad, btnDeleteSave; - private JLabel noSaves = new JLabel("No saves found"); - private JPanel selectedPanel; - private String selectedEngineStateName; - - public LoadGamePanel(String savePath) + private static final long serialVersionUID = 8536992209102721367L; + protected String savePath; + protected HashMap saves; + protected JScrollPane scrollPane; + protected MenuButton btnConfirm, btnCancel; + protected JLabel noSaves = new JLabel("No saves found"); + + public MenuPanel(String savePath) { this.savePath = savePath; this.saves = new HashMap(); @@ -975,7 +997,7 @@ public LoadGamePanel(String savePath) SpringLayout springLayout = new SpringLayout(); setLayout(springLayout); - JLabel lblSelectSaveFile = new JLabel("Select save file to load:"); + JLabel lblSelectSaveFile = new JLabel(); lblSelectSaveFile.setFont(new Font("Lucida Grande", Font.BOLD, 13)); springLayout.putConstraint(SpringLayout.NORTH, lblSelectSaveFile, 20, SpringLayout.NORTH, this); springLayout.putConstraint(SpringLayout.WEST, lblSelectSaveFile, 20, SpringLayout.WEST, this); @@ -990,35 +1012,25 @@ public LoadGamePanel(String savePath) springLayout.putConstraint(SpringLayout.EAST, scrollPane, -20, SpringLayout.EAST, this); add(scrollPane); - btnLoad = new MenuButton("Load", Color.red, Color.yellow, Color.blue, "Load the selected save"); - btnLoad.addActionListener(new ActionListener() + btnConfirm = new MenuButton(); + springLayout.putConstraint(SpringLayout.SOUTH, btnConfirm, -20, SpringLayout.SOUTH, this); + springLayout.putConstraint(SpringLayout.EAST, btnConfirm, 0, SpringLayout.EAST, lblSelectSaveFile); + springLayout.putConstraint(SpringLayout.SOUTH, scrollPane, -20, SpringLayout.NORTH, btnConfirm); + btnConfirm.setPreferredSize(new Dimension(100, 30)); + btnConfirm.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent arg0) + public void actionPerformed(ActionEvent paramActionEvent) { - mainMenu.dispose(); - paused = true; - GrameUtils.console.setVisible(true); - RenderManager.dispose(); - RenderManager.initialize(); - RenderManager.clearAllText(); - engineState = saves.get(selectedEngineStateName); - RenderManager.render(engineState.getMainBase(), engineState.getMainRender()); - RenderManager.setVisible(true); - start(); - paused = false; + confirm(); } }); - springLayout.putConstraint(SpringLayout.SOUTH, btnLoad, -20, SpringLayout.SOUTH, this); - springLayout.putConstraint(SpringLayout.EAST, btnLoad, 0, SpringLayout.EAST, lblSelectSaveFile); - springLayout.putConstraint(SpringLayout.SOUTH, scrollPane, -20, SpringLayout.NORTH, btnLoad); - btnLoad.setPreferredSize(new Dimension(100, 30)); - add(btnLoad); - - MenuButton btnClose = new MenuButton("Cancel", Color.red, Color.yellow, Color.blue, "Close this panel"); - springLayout.putConstraint(SpringLayout.WEST, btnClose, 0, SpringLayout.WEST, lblSelectSaveFile); - springLayout.putConstraint(SpringLayout.SOUTH, btnClose, 0, SpringLayout.SOUTH, btnLoad); - btnClose.setPreferredSize(new Dimension(100, 30)); - btnClose.addActionListener(new ActionListener() + add(btnConfirm); + + btnCancel = new MenuButton("Cancel", Color.red, Color.yellow, Color.blue, "Close this panel"); + springLayout.putConstraint(SpringLayout.WEST, btnCancel, 0, SpringLayout.WEST, lblSelectSaveFile); + springLayout.putConstraint(SpringLayout.SOUTH, btnCancel, 0, SpringLayout.SOUTH, btnConfirm); + btnCancel.setPreferredSize(new Dimension(100, 30)); + btnCancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { @@ -1026,35 +1038,12 @@ public void actionPerformed(ActionEvent arg0) lblMadeWithGrame.setText(""); } }); - add(btnClose); + add(btnCancel); - btnDeleteSave = new MenuButton("Delete", Color.red, Color.yellow, Color.blue, "Delete selected save"); - btnDeleteSave.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent arg0) - { - if (JOptionPane.showConfirmDialog(mainMenu, "Delete this save?", "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE) == JOptionPane.YES_OPTION) - try - { - FileUtils.delete(new File(GrameManager.savePath.toString() + "/" + selectedEngineStateName + ".GrameSave")); - loadInfo(); - updateGUI(); - } - catch (IOException e) - { - e.printStackTrace(); - } - } - }); - springLayout.putConstraint(SpringLayout.SOUTH, btnDeleteSave, 0, SpringLayout.SOUTH, btnLoad); - springLayout.putConstraint(SpringLayout.WEST, btnDeleteSave, 20, SpringLayout.EAST, btnClose); - springLayout.putConstraint(SpringLayout.EAST, btnDeleteSave, -20, SpringLayout.WEST, btnLoad); - springLayout.putConstraint(SpringLayout.NORTH, btnDeleteSave, 0, SpringLayout.NORTH, btnLoad); - add(btnDeleteSave); + btnConfirm.addMouseListener(helpTextListener); + btnCancel.addMouseListener(helpTextListener); - btnLoad.addMouseListener(helpTextListener); - btnClose.addMouseListener(helpTextListener); - btnDeleteSave.addMouseListener(helpTextListener); + initGUI(); } public void loadInfo() @@ -1086,11 +1075,93 @@ public boolean accept(File paramFile, String paramString) } } - private void updateGUI() + protected SpringLayout getSpringLayout() + { + return (SpringLayout) getLayout(); + } + + protected abstract void confirm(); + + protected abstract void initGUI(); + + protected abstract void updateGUI(); + } + + public static class LoadGamePanel extends MenuPanel + { + private static final long serialVersionUID = 5362729999369047215L; + private MenuButton btnDeleteSave; + private JPanel selectedPanel; + private String selectedEngineStateName; + + public LoadGamePanel(String savePath) + { + super(savePath); + } + + @Override + protected void confirm() + { + mainMenu.dispose(); + paused = true; + GrameUtils.console.setVisible(true); + RenderManager.dispose(); + RenderManager.initialize(); + RenderManager.clearAllText(); + engineState = saves.get(selectedEngineStateName); + RenderManager.render(engineState.getMainBase(), engineState.getMainRender()); + RenderManager.setVisible(true); + start(); + paused = false; + } + + protected void initGUI() + { + btnConfirm.setText("Load"); + btnConfirm.setStartColor(Color.red); + btnConfirm.setEndColor(Color.yellow); + btnConfirm.setClickColor(Color.blue); + btnConfirm.setHelpText("Load the selected save"); + + JLabel lblSelectSaveFile = new JLabel("Select save file to load:"); + lblSelectSaveFile.setFont(new Font("Lucida Grande", Font.BOLD, 13)); + getSpringLayout().putConstraint(SpringLayout.NORTH, lblSelectSaveFile, 20, SpringLayout.NORTH, this); + getSpringLayout().putConstraint(SpringLayout.WEST, lblSelectSaveFile, 20, SpringLayout.WEST, this); + getSpringLayout().putConstraint(SpringLayout.EAST, lblSelectSaveFile, -20, SpringLayout.EAST, this); + add(lblSelectSaveFile); + + getSpringLayout().putConstraint(SpringLayout.NORTH, scrollPane, 10, SpringLayout.SOUTH, lblSelectSaveFile); + + btnDeleteSave = new MenuButton("Delete", Color.red, Color.yellow, Color.blue, "Delete selected save"); + getSpringLayout().putConstraint(SpringLayout.SOUTH, btnDeleteSave, 0, SpringLayout.SOUTH, btnConfirm); + getSpringLayout().putConstraint(SpringLayout.WEST, btnDeleteSave, 20, SpringLayout.EAST, btnCancel); + getSpringLayout().putConstraint(SpringLayout.EAST, btnDeleteSave, -20, SpringLayout.WEST, btnConfirm); + getSpringLayout().putConstraint(SpringLayout.NORTH, btnDeleteSave, 0, SpringLayout.NORTH, btnConfirm); + btnDeleteSave.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent arg0) + { + if (JOptionPane.showConfirmDialog(mainMenu, "Delete this save?", "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE) == JOptionPane.YES_OPTION) + try + { + FileUtils.delete(new File(GrameManager.savePath.toString() + "/" + selectedEngineStateName + ".GrameSave")); + loadInfo(); + updateGUI(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + }); + add(btnDeleteSave); + } + + public void updateGUI() { if (this.saves.size() == 0) { - this.btnLoad.setEnabled(false); + this.btnConfirm.setEnabled(false); this.btnDeleteSave.setEnabled(false); scrollPane.setViewportView(noSaves); } @@ -1131,7 +1202,7 @@ public void mousePressed(MouseEvent arg0) selectedPanel = savePanel; selectedEngineStateName = key; savePanel.setBorder(BorderFactory.createMatteBorder(1, 5, 1, 1, Color.gray)); - btnLoad.setEnabled(true); + btnConfirm.setEnabled(true); btnDeleteSave.setEnabled(true); } }); @@ -1165,58 +1236,71 @@ public void mousePressed(MouseEvent arg0) } catch (Exception e) { - System.out.println("Conflict"); + System.out.println("Conflict"); //TODO: Handle conflicts } - btnLoad.setEnabled(false); + btnConfirm.setEnabled(false); btnDeleteSave.setEnabled(false); - // scrollPane.setViewportView(saveList); scrollPane.setViewportView(savesListPanel); } } } - public static class SaveGamePanel extends JPanel + public static class SaveGamePanel extends MenuPanel { - private static final long serialVersionUID = -2270645491547851288L; + private static final long serialVersionUID = 812980996331735043L; - private String savePath; - private HashMap saves; - private JScrollPane scrollPane; - private MenuButton btnSave; - private JLabel noSaves = new JLabel("No saves found"); private JTextField saveField; + private JLabel lblSelectSaveFile; public SaveGamePanel(String savePath) { - this.savePath = savePath; - this.saves = new HashMap(); - this.noSaves.setHorizontalAlignment(SwingConstants.CENTER); - this.noSaves.setFont(new Font("Lucida Grande", Font.BOLD | Font.ITALIC, 15)); - this.noSaves.setForeground(Color.lightGray); + super(savePath); + } - SpringLayout springLayout = new SpringLayout(); - setLayout(springLayout); + public void showPanel() + { + saveField.setText(""); + updateGUI(); + } - JLabel lblSelectSaveFile = new JLabel("Name your save:"); + @Override + protected void confirm() + { + if (saveEngineState(saveField.getText(), false, mainMenu)) + saveField.setText(""); + loadInfo(); + updateGUI(); + } + + @Override + protected void initGUI() + { + btnConfirm.setText("Save"); + btnConfirm.setStartColor(Color.red); + btnConfirm.setEndColor(Color.yellow); + btnConfirm.setClickColor(Color.blue); + btnConfirm.setHelpText("Save your game"); + + lblSelectSaveFile = new JLabel("Name your save:"); lblSelectSaveFile.setFont(new Font("Lucida Grande", Font.BOLD, 13)); - springLayout.putConstraint(SpringLayout.NORTH, lblSelectSaveFile, 20, SpringLayout.NORTH, this); - springLayout.putConstraint(SpringLayout.WEST, lblSelectSaveFile, 20, SpringLayout.WEST, this); - springLayout.putConstraint(SpringLayout.EAST, lblSelectSaveFile, -20, SpringLayout.EAST, this); + getSpringLayout().putConstraint(SpringLayout.NORTH, lblSelectSaveFile, 20, SpringLayout.NORTH, this); + getSpringLayout().putConstraint(SpringLayout.WEST, lblSelectSaveFile, 20, SpringLayout.WEST, this); + getSpringLayout().putConstraint(SpringLayout.EAST, lblSelectSaveFile, -20, SpringLayout.EAST, this); add(lblSelectSaveFile); saveField = new JTextField(); - springLayout.putConstraint(SpringLayout.WEST, saveField, 0, SpringLayout.WEST, lblSelectSaveFile); - springLayout.putConstraint(SpringLayout.EAST, saveField, 0, SpringLayout.EAST, lblSelectSaveFile); - springLayout.putConstraint(SpringLayout.NORTH, saveField, 10, SpringLayout.SOUTH, lblSelectSaveFile); + getSpringLayout().putConstraint(SpringLayout.WEST, saveField, 0, SpringLayout.WEST, lblSelectSaveFile); + getSpringLayout().putConstraint(SpringLayout.EAST, saveField, 0, SpringLayout.EAST, lblSelectSaveFile); + getSpringLayout().putConstraint(SpringLayout.NORTH, saveField, 10, SpringLayout.SOUTH, lblSelectSaveFile); saveField.addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent arg0) { if (saveField.getText().trim().length() == 0) - btnSave.setEnabled(false); + btnConfirm.setEnabled(false); else - btnSave.setEnabled(true); + btnConfirm.setEnabled(true); } @Override @@ -1225,90 +1309,19 @@ public void keyPressed(KeyEvent arg0) if (arg0.getKeyCode() == 27) saveField.setText(""); if (arg0.getKeyCode() == 10) - btnSave.doClick(); + btnConfirm.doClick(); } }); add(saveField); - scrollPane = new JScrollPane(); - scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); - springLayout.putConstraint(SpringLayout.NORTH, scrollPane, 10, SpringLayout.SOUTH, saveField); - springLayout.putConstraint(SpringLayout.WEST, scrollPane, 20, SpringLayout.WEST, this); - springLayout.putConstraint(SpringLayout.SOUTH, scrollPane, -100, SpringLayout.SOUTH, this); - springLayout.putConstraint(SpringLayout.EAST, scrollPane, -20, SpringLayout.EAST, this); - add(scrollPane); - - btnSave = new MenuButton("Save", Color.red, Color.yellow, Color.blue, "Save your game"); - btnSave.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent arg0) - { - if (saveEngineState(saveField.getText(), false, mainMenu)) - saveField.setText(""); - loadInfo(); - updateGUI(); - } - }); - springLayout.putConstraint(SpringLayout.SOUTH, btnSave, -20, SpringLayout.SOUTH, this); - springLayout.putConstraint(SpringLayout.EAST, btnSave, 0, SpringLayout.EAST, lblSelectSaveFile); - springLayout.putConstraint(SpringLayout.SOUTH, scrollPane, -20, SpringLayout.NORTH, btnSave); - btnSave.setPreferredSize(new Dimension(100, 30)); - add(btnSave); - - MenuButton btnClose = new MenuButton("Cancel", Color.red, Color.yellow, Color.blue, "Close this panel1"); - springLayout.putConstraint(SpringLayout.WEST, btnClose, 0, SpringLayout.WEST, lblSelectSaveFile); - springLayout.putConstraint(SpringLayout.SOUTH, btnClose, 0, SpringLayout.SOUTH, btnSave); - btnClose.setPreferredSize(new Dimension(100, 30)); - btnClose.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent arg0) - { - sidePanel.setViewportView(null); - lblMadeWithGrame.setText(""); - } - }); - add(btnClose); - - btnSave.addMouseListener(helpTextListener); - btnClose.addMouseListener(helpTextListener); + getSpringLayout().putConstraint(SpringLayout.NORTH, scrollPane, 10, SpringLayout.SOUTH, saveField); + getSpringLayout().putConstraint(SpringLayout.WEST, scrollPane, 20, SpringLayout.WEST, this); + getSpringLayout().putConstraint(SpringLayout.SOUTH, scrollPane, -10, SpringLayout.NORTH, btnConfirm); + getSpringLayout().putConstraint(SpringLayout.EAST, scrollPane, -20, SpringLayout.EAST, this); } - public void loadInfo() - { - File f = new File(savePath); - if (!f.exists()) - return; - saves = new HashMap(); - for (File child : f.listFiles(new FilenameFilter() - { - @Override - public boolean accept(File paramFile, String paramString) - { - return paramString.endsWith(".GrameSave"); - } - })) - { - String name = child.toString().substring(f.toString().length() + 1, child.toString().lastIndexOf(".")); - try - { - Object save = ObjectUtils.load(f.toString(), name, "GrameSave"); - if (save != null) - this.saves.put(name, ((EngineState) save)); - } - catch (IOException e) - { - e.printStackTrace(); - } - } - } - - private void showPanel() - { - saveField.setText(""); - updateGUI(); - } - - private void updateGUI() + @Override + protected void updateGUI() { if (this.saves.size() == 0) { @@ -1345,7 +1358,7 @@ public void mouseEntered(MouseEvent paramMouseEvent) public void mousePressed(MouseEvent arg0) { saveField.setText(key); - btnSave.setEnabled(true); + btnConfirm.setEnabled(true); } }); @@ -1380,14 +1393,11 @@ public void mousePressed(MouseEvent arg0) { System.out.println("Conflict"); } - btnSave.setEnabled(false); - // scrollPane.setViewportView(saveList); + btnConfirm.setEnabled(false); scrollPane.setViewportView(savesListPanel); } if (saveField.getText().trim().length() == 0) - { - btnSave.setEnabled(false); - } + btnConfirm.setEnabled(false); } } } From 0b2aa9f9101c2c0ec5d22a0e6c2d39c0aaf3caf0 Mon Sep 17 00:00:00 2001 From: Meshulam Silk Date: Sat, 23 Nov 2013 18:31:37 +0200 Subject: [PATCH 02/11] Added main menu color skinning - Fixed the delete button not showing help text --- .../Grame/Essentials/CrashManager.class | Bin 11266 -> 11266 bytes .../Grame/Essentials/GrameManager$1.class | Bin 1090 -> 1133 bytes .../Grame/Essentials/GrameManager.class | Bin 13841 -> 14473 bytes .../Grame/Graphics/RenderManager.class | Bin 8321 -> 10028 bytes .../Grame/Essentials/GrameManager.java | 99 +++--- .../MainMenuPanels/LoadGamePanel.java | 94 ----- .../Grame/Graphics/RenderManager.java | 42 ++- src/com/moomoohk/Grame/test/MainMenu.java | 331 ------------------ .../Grame/test/MenuConfiguration.java | 28 ++ src/com/moomoohk/Grame/test/SaveTest.java | 11 +- src/com/moomoohk/Grame/test/UpdateLibs.java | 10 +- 11 files changed, 139 insertions(+), 476 deletions(-) delete mode 100644 src/com/moomoohk/Grame/Essentials/MainMenuPanels/LoadGamePanel.java delete mode 100644 src/com/moomoohk/Grame/test/MainMenu.java create mode 100644 src/com/moomoohk/Grame/test/MenuConfiguration.java diff --git a/bin/com/moomoohk/Grame/Essentials/CrashManager.class b/bin/com/moomoohk/Grame/Essentials/CrashManager.class index fbf84cc7f917d030b5f21bc9407b5357f1fb35da..2c9753d45aca93333744979a271040b0880f6737 100644 GIT binary patch delta 14 VcmZpQXo}eIl%3IN^D}lC6#y+_1!MpK delta 14 VcmZpQXo}eIl%3IV^D}lC6#y+<1!DjJ diff --git a/bin/com/moomoohk/Grame/Essentials/GrameManager$1.class b/bin/com/moomoohk/Grame/Essentials/GrameManager$1.class index 52c8f00151f01b65cbd6075f50829c59f4ac5dbc..05e9186bf1aa38cc8ebce58b3a2ac6593cb88421 100644 GIT binary patch delta 80 zcmX@a@s?x57beD-$zPfDwS1EEbM2mt)B3qb$? diff --git a/bin/com/moomoohk/Grame/Essentials/GrameManager.class b/bin/com/moomoohk/Grame/Essentials/GrameManager.class index 6cf77aa384afd26574c5867d46456a79ac601c29..02839e8b577223347c7a79a3228bf749aa977a87 100644 GIT binary patch literal 14473 zcmb_j34B!5)j#KDk~cFvAP|VGIv`6(AVE+Nf=D*PKo%qc3NAQg9?3{D6K5s_YSk8( zT3fYRTZLL{wUsWm#l(gnt@~1KZELl4Z*9NYy40@P)|Kyn?tL@!CK*J(uk&N_-n;MK zd-mm?Gd%kKop%w@0%M~|22*KUtgE6c7Q?@e?G^R$P?ud%mq^&rWF*v?&;yO3XsF$e zo8)0CJSVgxRM8oVwpTQ7J;!cKnpD6vHZ!`eCmIcH?X;OjZKzw<5^QeT(zL#@x^5k2 zHDso>B;%22dnMDznpiZE3`LV0LY+Ofmqswd;yau9EqR6bX-FY9IHc#NL!+! zHWJ4kGEwFyBVB;YL8cLrXhbN8eB2IWWHUzWXnQ1TwM&!nA5R@7ytVP`XL zN5ghJ!BnJ??@2~FD^`UP9gU%Gy!W+4+M}UlPaJzT4xh1XIK{aD2ct7Ij+gp1uFftrT zh$PoSQb}OqNpy$0@H!Ih?nyGu%|(ezb%HW&RVW(nv_(b*$&R=k!uD=0XjNlE>$Yw{ z7#X&=g?c)Znh8v^a)B7mEGBOvw8LH-N_If&G`}LTij|R08(Vw3LXl{r9qnN{Dc623 zl$H8B+CHPvS%xjffOkF6(`}LVo_Hu3iA9;pa_yxwNML1679^Inb&5(Z2dO1hEO~r&uY+5 zc?AA=k{zP=M^i7itiWJ@#^9MwD9I%pm*R+Q)dn@4p+ur`&IXgtWSWzMy4(`=(;2kf z4+77&XfuVF&iIHBbK#d86p(|P5gk^zGL`3Adt};1kWK9-Z39Phkaxs&7IjbrUbEd! z)~B7txRN=;9h$IVyG5M@-!LNKo<6>0_-tWy?5JVK?K}Jw)yfpNXc|p7NqkQZQjTQD zC-^BL!s?}6Chg3MVA}my^l>_mX*zJP)&6IFv@O)r-jS@^*=Bc(xjSwQ%y*Ndm(MuT zY)H;e=hKBIU68U_6*mzfB~V%PN%|BN7aVp*n8s%@*cq-g>7tKD@&Z5Y)+AplPT|u` z$GGvvzA8jJ2!6(*%jvT)(oi_u($SL)$9kiyVzKRlj!S@!uNI=NpsP%}lBpz142`iE zf+NB%!dP?5dfcb47JZ(sX0kwQO-~##HQC(4Q~_!~><%-UTPl6@1^S{%*TVUJgk=_e ziLQfNS>F`=7}LCu1kt2Dz*@OmC!m=0WpHz79#h>D=|q|!ocW4HH;Uy<1g*8ZqM@!x zTT3z)M*<}tPn5||H_^=|eJx8Bbv|U#E%bE+HN$3Sxh0?zuF9M?xR-7fQFnRi zn~0<3?JALzsF@mkry zXq9nbcRSPt(04&oHpO}Z;aGHbG9Uzm;(=r=(1G0pE~N`ZB$4dww8PW@StjumnY&xS}dXTB5-cAN0*gm;5(2-1bCze)Jv`3O1JzL9SK8dr)%_h({vBZrhIR*a`Ic zkV!l#L1MX={)qQF!47D5B5wI*!R-}u# z4NQx(JxOj^4Bw{GPyeR3O#07I_xS-ESoAi%gUnkgEK`GIa-aO%}#)Tf~8vBzwjASqw|5aqq>qbU0<_A}0IdE4z> zOvdTZW#*9~>s^HXOsC(aYpjxy9&8MO~-}Ijb#RBUpN|t=0!F6(k!V;(nPv;X97MYuq)e>zaXp`A@j5C54}-OSZsiRouSW`a^u-o$WTX*A(1j#& z@`MXj2oVTu_G9%XpCFBZBY)`P*7f-W$_mA@7_patvYbaU`Vv}5#eo{#bH_L zNuYG$=WX0!GS1>UjH&c7os?P}5gi__yn^z&t#Q;4psondMtkfCXVlz$hUd=P8idL_ zQ8*iv5_`AB=Q8x$8$rYiA*W#~&eD>gGhR7@lf1)ZoVayiNGVC`t;M~(69h)>oluhO zBZZ?QB9V!*$$1ukLYQTCgc41d@8=8nlO|ty)B{9KT$N~4-OA!m@oog3L`SSQ%{-IHXw96Um#=4vt*mOTYFHXj)(~(!a3C5( zN|lMg(*odyo}%Tf6E>+dN?M!P{I)TDL=bP|>Vrm1jn6nRWT z?!dQL{B=nH^6S>EYhEW9+-mU``35f|<1VNQhwX5{%il)5Qj${GmGCQHjTf@~R}#;Eee_dk%54L^ zr!9U)tg^s9w+9Ub+2uKlpXV3gUR2rmWVhRO7P@l$l+_L&^73yHE>dc!MW(%_Sm*C7 z{=Kr!+PdoX^%7oS<-#_*3%PARL{k-1r```1h^tU8nQ9*GH~E#^nYv2_GON7&8q_F- zWK~cj2o(=OhNVYQ$;>v0#^Y2u9v;(WTS$cK`EM5gU5;(}Y63jTHuykg0IF(lMiRAB zzsDJg|7Fo+@;dgBUCbYiY1tzt_GnQR{(?wC-$+{MF2zZ3I9i6~o)0n#util6$#uH4 zr4%gFL21d-NN4<`_f1^9lirD{s-;>t&Ho(`j-ku;MW9M+swBk?Xe~+WL1P1M0!TI0J?^s%QBk9A_HGI+e1W6^UMW?TXdS zs+hVq6tyiQU`&HMlANqY8Y}UxTD0q8NOezfNXW)_xIb`>IE3Q(6EuzEQ3l9(vii8) z9z&BMS`+GoKAfLO&d+i=t{RckL0zvarK+2%?k!`XaUy(|u##zw zTcpDsrbGL1ZVVrpv)OAb0(V+F?6@814J87h01mvU`*evcAtDsct~XA$j3uf96}CI= zB!pRsLx`~~mFS{A7i>=F%fc3*shf$uw3&Widiv?4ynb4Y z`z42{a?=4irJq)$@2c^x7T=ZluEKXUz76;`9ip|EyRM&FZpU^8t;gTxXz>y?k%!g+ z=ms!qBT)Pp*s%%C*v%-Vp8<5v1R`hAiL`}Irn6}owb2R+(`u^23fYN(D!RT7!g6Jd z<(D3yjTuk{YEUn+^aKFfgo!=?IvpcI?NTL0BCGTeodI;u8l)|mJ^TvTb{c_3pMci; zShN)=>3u?aAHEctkcY9~_0i%zgO;57&7oI@1F*4_Pd?jcIxu4j;T4ALhK zQSYWhv>O8#AD~MH=(0ijTpwL?D=j=k*W=CJO@nm9Abs@!ePist0s5BS4>x1Ki$4SO z{R7n3PyPF7)$sX0_@Ma{8vE$L*dGnh-Ew^Z*StY`sE_&w=+V98S2sV~Sk_OEAEGBV zfvvylr>FYpDbD~sb2|uLMmN(p=miigGF_*Xxtj{;To^(e%t~OS2lCtjd0vRwmqT)& z#mE&{brs!8SJU_C8X7=j>rVP2+7e%)N9j8H8TtUv&>ngbof~0xKr_@~Hdsr)g}O4< zkHehbK{UU|tdUe;zC&Get4(@g+-TSgs^VHE=%9KqfoNVI)jBe%)jVhL{10PaIzWHw zr&s&v)dBkR*uV7A-v;SlB79BPv7m;~)+(T{;_fEU^)=9RGfe9i=;+tex+qw{6_~KC zchj(gz(GERfW24igBVC{X8U4QO8zFc{}#6YHn#r`jN`W9+cLeE+Lmv}^ikOM3wg^% z1qbQ<#h!6&EGfuaVbfoiNr)97@lM+iNl?esY0`b((V zla$1|^XO@Gl%JuC=vlfHdw-6ehl;%b_4)hI9k8MjAmtf&1dK`{*Rk+3>6IsmjNe6}BwgL%u#P#XwnM zm42vD54HMXfqK}eA5KyavZh$i9({<*HW{7+e6stEELCqj={K@L)*2(V#(9%jlYUd8 zfdaRMWrZ{K18~E`Z2bV-@Gwh105?3y8o-g+Zrn0&WT_iBXM?OY8iUN6%$oF@$=If- ztZ;H(D_ri%w3A91@y&2S1UY%(7cBY%Wcm_>^+!a~Kf#b+Mpy6^=-;cfm|jD0`ZLwi z>u_j)LHPMAeE#2PC;DfX(m$Y2|AY&81NQkZ>PIi@ApHlL`xZ3yZF-E}p(kMb&qDAo z()(C_nBGQA@}i*x^W^EA$K~unO+O!PfCAL-y(nt>P*L~u7Pge07Hhq5^b{H*jU{M} zXjl=AnQB?qM0{{j*JAQZFG;HvRMAkr^8CEYePqLm2e@+509W0^^$leYQ^7uh!^dFo zAw=p^_R)eVgWOPd2d^FAmOV7BY=AfIp-Iq5x$E9bqj5cRFL}$R4Di_(8w{5qs|R@N z*A72?F)^kJ2=#pJKJu<99bj7m1HmSHd7I-v7fJR5H1l~J6`{Lz3>VWRK8B9x2~@%p zshKBHEAGRX)5}xwGnM1$6Fg1vqf}W+oX>&8gafDXcJ2g(ndtg-Va$MJJoF+*m2?Rn z$M-G(y^9}$01!RBymjKi^JP1(cn(E4uEn)_13#v1q0 zgt-S9S>-+4>M+s-Yj$Dq<4k)GzXaMF$_DxT();&OLFxT>-ww))phs2UK@qKj2SXl3 zjq0j{$^vL1@l5i;zxd%IXpoHJVF^(FQ95Zkyhe;6E9BdM=6cqix~W; zYKL~MAGPH5A4VRUXL2=}oFwR9p?Wg8)p^d#dJD~xxr#67YhCg-*x}<(r`QAEEx9ex zmLk4Phea^uAqt9qEtbTjh%ZN0qB*5Ct@RH6+yGyJtR%evDuZ{Q-;sx`IuJ3$ilv*XTTUdVKAVGzvFD6(h1kg+kmZBf>{!jxCOr9= z$`ue%T)5BH{S8{^17HM(Al*T?dgQ=hEaXFcBQUrL7~D*A(La%FRylZ>xyE8N0+2W_ zZNM3P?&L!bJ_~Ub>hckFT?Z(2BH{1jN9p@r#O3o3)d|nXKjOQb4Q8n2P?tVx*^iC% z0Zg5W_@G)V4KLdXVp7{H*Ez0e+}3P`G7)A8F{L6$AX(L4KU6 zX&=p*r=26+gz&Or?f^e|58ta+rPe+rX*XsmZ}}u9l|i|lbs18bvZCLlc=}>i0$vK^ zCVl|4J_y(T5KZKVX#pAojr<7w;={C&AEmSTCv-mlRM8U<;lpq=FD8=B{{y#z9~;vY z{sZpxfdPIp|1i$U9+U5tv|c$#amX+6A05`c=`doaX2byhX($`2U2K@?W<#}R!^>C$ zQn4$3$kZ@Ei;qjeFa>9nP&2C+X1q1+26-+AS=_9xa?q+_$ap>yq~cH`6;inA`P;%pWhq; z(twGeteq(aECR@JSs-=Y$H)K4Mdj)t zR2oxVAm7RfvSBF55`dhO1yYxod@SkiFvd0v1-ZZl@*RG6_=9Eb%9$CIS&9GVGasCGtz0p5<=PBP!{9R2)qhO+#0NT`SNOaUd-Ml>*BPNRtMP{Gn2akZGKwR_el&SEasCZ)u=7d(3vQH3eJ4 zI}~u#1sJ`R9Dqv)j1fZtCjdC<25gMf@kKf?IRTFz%G;eTz+;TDdJ$iZqDKKJehx*3 z<#J$~yvQ?oFKtZ~u%z^46gf37sdAM{fH1~s?}&OADpY%D{#+H6jbfFG$%F}dLXj~k z&lohO>?PB)k34yc@VCIT$TQxvhr(dcA!GWc1ICO2W9EP{2hSQ@X^}B+(5TqBk5(+r zmqgJx3CYukN6A>cabo^}v2-fv8Sl9bq$cQEy3VMC2bBU@wIm+K`7o&q$ZK3kBaBbd zXya3~+}KUqjf*L2TtW%sGP=n43|4)X_83>t&Bm4VbK@#{(zu$QHm*_3T&`JXoFd7x zFws~JZzl@$oN=nL0?Oo}r;s*|1>6zz3u7VfJSeDD(u+nF7%#rIkP6;IVB{6-G0@+r zTvq5cs*M^g9=Ead4-qK-LxtnGu%gze8@}T4p)1;5D^?oy!&f{tbj3E;idCqVXcL}^ zYbq65l2KKa%HY79L2I?KW;l=~LxH$gG^CF_Gr%1Acm|Eep)hVp!63tE!W_eBHrC?0 q00K$KB7Ao13km^joQA~Z@APkD-HM4QJzZh6te9xDQm?V0!1uqrw>nw? literal 13841 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 diff --git a/bin/com/moomoohk/Grame/Graphics/RenderManager.class b/bin/com/moomoohk/Grame/Graphics/RenderManager.class index 3a5de32221e59a10e55bb63a17cf82b85a05af81..38e899cd0de18cc552085805e06cb89ab1b355ac 100644 GIT binary patch delta 4196 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 X7?5|x#OJUinl4>0*@aIuPm=q8CvDX$ delta 2438 zcmZ8iYfzNu6@H#&mycaOa9MU)b^*C9goVXL;-#QsMAV?*g_}{+m_=4uU08%wte2pv zZBv_&*tcnG(=@fol%&&U6w(c9CX-G&ZOu$)lK$x>>9n0`V@zXfo8Dql>G^gI((r@# z>^bK>?{l8>yzlq@jVD&wU%PqnWdQYjQiF-`t2fNK%Fev=4L38F{|Q$#yiH{94IK;x zL!R2>3tm7SACCt6i17X76_W#jk8vabU)wtbVkb!Fit891|f7MZduwng8$KUb3 zT5k6{@lV1OC^5YMHoX5KY87p{>S24qYTS^$ek1mgj{hP=WW-~g@!`ne9vhy=j84Es zXnm29q1cF&ewHSkX@<`{(jObuXi;z4-^t19jE8pZYYz=|g?gi5jkbwJX!ZI4^ zi}%~;XN|_{k6DX`2KNNpL-Br{0oD>}1Cc?=t!i!cw_53AP-mU7JH0;~+0!4lVU+bc z@5E*4Y$P1-j2sq@xl6sCYwlj6GmmZ?YWOLg4Om0uOG-<4cj!PgzB(!-Y#Is=hvI_C zNLr?IIad(6Bz1&GB8QFsg`BGG{vIQ~Qs-Sdx*-UeC~I-3cHQG?cAnwJN6US zP+wn1c(5-#tnpr{SLfY1l{NjQKcwFNck(C_Tfp{bu>HHEN6759><2@l!yba_dI>!zA zt-GS(&~R7yP&|_-`Iyer>Ua76d_J!8s|KCc;qXB0V0cwDD(zuLm3Z2e@{C#TfCa_M z?X73ATJIewt$_^zI8h5X7N8VCRGY7UNF!EAL9n3gn|JO?H=58R*;^%YkNnz>`>+FH+>6~}9l=hi-ixsb^x-*i zeGmOOhX{UxefTA!xPk#(!yw*AOz!%AHe-ani1Tp_@)-pKgR1Q{5|GCYb^cuf7E)a_b?Y+<1U z<;Ei>xyz)5I`!+)>aoRBsGG!sv;>!?mPT17QI}xTRdsrDWR?h`82bDmfutZ~*I46QWbbC6GOs0J~>CKZJkn?ZNT`ZZq zsx9|6bPM9G)4b;rcZl_Au|8SI^!#y zmwh{m9Km(j=UZF=GYgac6rUD`;7BsFm-~d_Jh7)lx`rCs4OP`77*%Bz0S>866?tR( zZx7HbXW^r4Lv$pflWMP{jOXPgI;Lu{8p987lC&QV-N8jTwu)6@eJ zIV59C0g20Ma8Nyo$^<`ifyd;F+%^Gc%>{mzcm?Y=R44ewX+A8DN7YP)YpGvgRHKA` zkwwjHpB`xZGL^tJ4$6jU2J;NEcoL#&E63G_%G$c21ctYMVr~pdvAWqpkQXc^6)T~h ztt{I4m890ccAJ*uP2y&xvqNa ais = new HashMap(); private static String gameName; private static boolean running = false; - private static boolean paused = false; + public static boolean paused = false; private static boolean debug = false; private static boolean disablePrints = false; private static boolean spam = false; @@ -98,8 +100,14 @@ public class GrameManager implements Runnable private static Render defaultRender = new GridRender(); private static File savePath; private static MainMenu mainMenu; + private static MenuConfiguration menuConfiguration; public static void initialize(MainGrameClass mainClass) + { + initialize(mainClass, new MenuConfiguration()); + } + + public static void initialize(MainGrameClass mainClass, MenuConfiguration menuConfig) { if (initialized) return; @@ -127,7 +135,10 @@ public void run() })); try { - savePath = new File(OSUtils.getDynamicStorageLocation() + "Grame/Saves/" + mainClass.getGameName() + "/"); + if (OSUtils.getCurrentOS() == OS.UNIX) + savePath = new File(OSUtils.getDynamicStorageLocation() + ".grame/saves/" + mainClass.getGameName() + "/"); + else + savePath = new File(OSUtils.getDynamicStorageLocation() + "Grame/Saves/" + mainClass.getGameName() + "/"); } catch (Error e) { @@ -137,6 +148,7 @@ public void run() } if (!savePath.exists()) savePath.mkdirs(); + menuConfiguration = menuConfig; mainMenu = new MainMenu(mainClass); mainMenu.setVisible(true); } @@ -146,7 +158,7 @@ private static void start() if (running) return; running = true; - thread = new Thread(new GrameManager(), "Game"); + thread = new Thread(new GrameManager(), "Engine Thread"); thread.start(); GrameUtils.print("Grame " + VERSION_NUMBER + " is initialized.", MessageLevel.NORMAL); } @@ -189,19 +201,20 @@ public void run() prev += 1000L; frames = 0; } - if (engineState != null && !paused) + if (engineState != null) { - tick(input.key); + if (!paused) + { + tick(input.key); + tickGrameObjects(); + tickBases(); + } RenderManager.tick(); - tickGrameObjects(); - tickBases(); } } if (ticked) - { frames++; - } frames++; } RenderManager.dispose(); @@ -673,7 +686,7 @@ public MainMenu(final MainGrameClass mainClass) setUndecorated(true); setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setSize(600, 400); + setSize(600, 600); setLocationRelativeTo(null); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); @@ -686,7 +699,7 @@ public MainMenu(final MainGrameClass mainClass) lblGameName.setBounds(20, 6, 560, 33); contentPane.add(lblGameName); - btnResume = new MenuButton("Resume Game", Color.red, Color.yellow, Color.blue, "Unpause the game"); + btnResume = new MenuButton("Resume Game", menuConfiguration.menuButtonStartColor, menuConfiguration.menuButtonEndColor, menuConfiguration.menuButtonClickColor, "Unpause the game"); btnResume.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) @@ -697,7 +710,7 @@ public void actionPerformed(ActionEvent arg0) }); contentPane.add(btnResume); - btnNewGame = new MenuButton("New Game", Color.red, Color.yellow, Color.blue, "Start a new game"); + btnNewGame = new MenuButton("New Game", menuConfiguration.menuButtonStartColor, menuConfiguration.menuButtonEndColor, menuConfiguration.menuButtonClickColor, "Start a new game"); btnNewGame.setBounds(BUTTON1); btnNewGame.addActionListener(new ActionListener() { @@ -717,7 +730,7 @@ public void actionPerformed(ActionEvent arg0) }); contentPane.add(btnNewGame); - btnSaveGame = new MenuButton("Save Game", Color.red, Color.yellow, Color.blue, "Save your game to file"); + btnSaveGame = new MenuButton("Save Game", menuConfiguration.menuButtonStartColor, menuConfiguration.menuButtonEndColor, menuConfiguration.menuButtonClickColor, "Save your game to file"); btnSaveGame.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) @@ -729,7 +742,7 @@ public void actionPerformed(ActionEvent arg0) }); contentPane.add(btnSaveGame); - btnLoadGame = new MenuButton("Load Game", Color.red, Color.yellow, Color.blue, "Load a saved game"); + btnLoadGame = new MenuButton("Load Game", menuConfiguration.menuButtonStartColor, menuConfiguration.menuButtonEndColor, menuConfiguration.menuButtonClickColor, "Load a saved game"); btnLoadGame.setBounds(BUTTON2); btnLoadGame.addActionListener(new ActionListener() { @@ -745,12 +758,12 @@ public void actionPerformed(ActionEvent arg0) }); contentPane.add(btnLoadGame); - btnSettings = new MenuButton("Settings", Color.red, Color.yellow, Color.blue, "Show the settings (not yet implemented)"); + btnSettings = new MenuButton("Settings", menuConfiguration.menuButtonStartColor, menuConfiguration.menuButtonEndColor, menuConfiguration.menuButtonClickColor, "Show the settings (not yet implemented)"); btnSettings.setBounds(BUTTON3); btnSettings.setEnabled(false); contentPane.add(btnSettings); - btnEndGame = new MenuButton("End Game", Color.red, Color.yellow, Color.blue, "Abandon the current game"); + btnEndGame = new MenuButton("End Game", menuConfiguration.menuButtonStartColor, menuConfiguration.menuButtonEndColor, menuConfiguration.menuButtonClickColor, "Abandon the current game"); btnEndGame.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) @@ -765,7 +778,7 @@ public void actionPerformed(ActionEvent arg0) sidePanel = new JScrollPane(); sidePanel.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null)); - sidePanel.setBounds(150, 50, 430, 290); + sidePanel.setBounds(150, 50, 430, 490); contentPane.add(sidePanel); lblMadeWithGrame = new JLabel(); @@ -783,11 +796,11 @@ public void mouseExited(MouseEvent me) }); lblMadeWithGrame.setFont(new Font("Lucida Grande", Font.BOLD | Font.ITALIC, 11)); lblMadeWithGrame.setForeground(Color.DARK_GRAY); - lblMadeWithGrame.setBounds(18, 353, 421, 37); + lblMadeWithGrame.setBounds(20, 553, 560, 37); contentPane.add(lblMadeWithGrame); - MenuButton btnQuit = new MenuButton("Quit", Color.red, Color.yellow, Color.blue, "Quit the game"); - btnQuit.setBounds(450, 350, 130, 40); + MenuButton btnQuit = new MenuButton("Quit", menuConfiguration.quitButtonStartColor, menuConfiguration.quitButtonEndColor, menuConfiguration.quitButtonClickColor, "Quit the game"); + btnQuit.setBounds(10, 500, 130, 40); btnQuit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) @@ -862,7 +875,7 @@ public void actionPerformed(ActionEvent arg0) public MenuButton() { - this("Default", Color.red, new Color(255, 127, 0), Color.blue, "Default"); + this("Default", Color.black, Color.black, Color.black, "Default"); } public MenuButton(String text, Color startColor, Color endColor, Color clickColor, String helpText) @@ -963,7 +976,7 @@ protected void paintComponent(Graphics g) g2.setPaint(fill); } else - g2.setPaint(Color.LIGHT_GRAY); + g2.setPaint(menuConfiguration.disabledButtonColor); g2.fillRoundRect(0, 0, getWidth(), getHeight(), 6, 6); g2.setPaint(Color.black); if (mouseOn && isEnabled()) @@ -1026,7 +1039,7 @@ public void actionPerformed(ActionEvent paramActionEvent) }); add(btnConfirm); - btnCancel = new MenuButton("Cancel", Color.red, Color.yellow, Color.blue, "Close this panel"); + btnCancel = new MenuButton("Cancel", menuConfiguration.cancelButtonStartColor, menuConfiguration.cancelButtonEndColor, menuConfiguration.cancelButtonClickColor, "Close this panel"); springLayout.putConstraint(SpringLayout.WEST, btnCancel, 0, SpringLayout.WEST, lblSelectSaveFile); springLayout.putConstraint(SpringLayout.SOUTH, btnCancel, 0, SpringLayout.SOUTH, btnConfirm); btnCancel.setPreferredSize(new Dimension(100, 30)); @@ -1116,23 +1129,23 @@ protected void confirm() } protected void initGUI() - { + { btnConfirm.setText("Load"); - btnConfirm.setStartColor(Color.red); - btnConfirm.setEndColor(Color.yellow); - btnConfirm.setClickColor(Color.blue); + btnConfirm.setStartColor(menuConfiguration.confirmButtonStartColor); + btnConfirm.setEndColor(menuConfiguration.confirmButtonEndColor); + btnConfirm.setClickColor(menuConfiguration.confirmButtonClickColor); btnConfirm.setHelpText("Load the selected save"); - + JLabel lblSelectSaveFile = new JLabel("Select save file to load:"); lblSelectSaveFile.setFont(new Font("Lucida Grande", Font.BOLD, 13)); - getSpringLayout().putConstraint(SpringLayout.NORTH, lblSelectSaveFile, 20, SpringLayout.NORTH, this); - getSpringLayout().putConstraint(SpringLayout.WEST, lblSelectSaveFile, 20, SpringLayout.WEST, this); - getSpringLayout().putConstraint(SpringLayout.EAST, lblSelectSaveFile, -20, SpringLayout.EAST, this); + getSpringLayout().putConstraint(SpringLayout.NORTH, lblSelectSaveFile, 20, SpringLayout.NORTH, this); + getSpringLayout().putConstraint(SpringLayout.WEST, lblSelectSaveFile, 20, SpringLayout.WEST, this); + getSpringLayout().putConstraint(SpringLayout.EAST, lblSelectSaveFile, -20, SpringLayout.EAST, this); add(lblSelectSaveFile); - + getSpringLayout().putConstraint(SpringLayout.NORTH, scrollPane, 10, SpringLayout.SOUTH, lblSelectSaveFile); - btnDeleteSave = new MenuButton("Delete", Color.red, Color.yellow, Color.blue, "Delete selected save"); + btnDeleteSave = new MenuButton("Delete", menuConfiguration.otherButtonStartColor, menuConfiguration.otherButtonEndColor, menuConfiguration.otherButtonClickColor, "Delete selected save"); getSpringLayout().putConstraint(SpringLayout.SOUTH, btnDeleteSave, 0, SpringLayout.SOUTH, btnConfirm); getSpringLayout().putConstraint(SpringLayout.WEST, btnDeleteSave, 20, SpringLayout.EAST, btnCancel); getSpringLayout().putConstraint(SpringLayout.EAST, btnDeleteSave, -20, SpringLayout.WEST, btnConfirm); @@ -1155,6 +1168,7 @@ public void actionPerformed(ActionEvent arg0) } }); add(btnDeleteSave); + btnDeleteSave.addMouseListener(helpTextListener); } public void updateGUI() @@ -1175,6 +1189,7 @@ public void updateGUI() { GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = GridBagConstraints.REMAINDER; + gbc.anchor = GridBagConstraints.NORTH; gbc.insets = new Insets(3, 0, 3, 0); final JPanel savePanel = new JPanel(); savePanel.setLayout(null); @@ -1193,7 +1208,7 @@ public void mouseExited(MouseEvent paramMouseEvent) public void mouseEntered(MouseEvent paramMouseEvent) { if (!selectedPanel.equals(savePanel)) - savePanel.setBorder(BorderFactory.createMatteBorder(1, 5, 1, 1, Color.black)); + savePanel.setBorder(BorderFactory.createMatteBorder(2, 5, 2, 2, Color.black)); } public void mousePressed(MouseEvent arg0) @@ -1201,7 +1216,7 @@ public void mousePressed(MouseEvent arg0) selectedPanel.setBorder(BorderFactory.createLineBorder(Color.black)); selectedPanel = savePanel; selectedEngineStateName = key; - savePanel.setBorder(BorderFactory.createMatteBorder(1, 5, 1, 1, Color.gray)); + savePanel.setBorder(BorderFactory.createMatteBorder(2, 5, 2, 2, Color.gray.darker().darker())); btnConfirm.setEnabled(true); btnDeleteSave.setEnabled(true); } @@ -1213,7 +1228,7 @@ public void mousePressed(MouseEvent arg0) savePanel.add(lblName); JSeparator separator = new JSeparator(JSeparator.HORIZONTAL); - separator.setBounds(10, 20, 340, 30); + separator.setBounds(10, 25, 340, 30); savePanel.add(separator); JLabel lblSavedTitle = new JLabel("Last saved:"); @@ -1276,9 +1291,9 @@ protected void confirm() protected void initGUI() { btnConfirm.setText("Save"); - btnConfirm.setStartColor(Color.red); - btnConfirm.setEndColor(Color.yellow); - btnConfirm.setClickColor(Color.blue); + btnConfirm.setStartColor(menuConfiguration.confirmButtonStartColor); + btnConfirm.setEndColor(menuConfiguration.confirmButtonEndColor); + btnConfirm.setClickColor(menuConfiguration.confirmButtonClickColor); btnConfirm.setHelpText("Save your game"); lblSelectSaveFile = new JLabel("Name your save:"); @@ -1368,7 +1383,7 @@ public void mousePressed(MouseEvent arg0) savePanel.add(lblName); JSeparator separator = new JSeparator(JSeparator.HORIZONTAL); - separator.setBounds(10, 20, 340, 30); + separator.setBounds(10, 25, 340, 30); savePanel.add(separator); JLabel lblSavedTitle = new JLabel("Last saved:"); @@ -1401,4 +1416,4 @@ public void mousePressed(MouseEvent arg0) } } } -} +} \ No newline at end of file diff --git a/src/com/moomoohk/Grame/Essentials/MainMenuPanels/LoadGamePanel.java b/src/com/moomoohk/Grame/Essentials/MainMenuPanels/LoadGamePanel.java deleted file mode 100644 index 2af3e63..0000000 --- a/src/com/moomoohk/Grame/Essentials/MainMenuPanels/LoadGamePanel.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.moomoohk.Grame.Essentials.MainMenuPanels; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; -import java.util.ArrayList; - -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.ScrollPaneConstants; -import javax.swing.SpringLayout; -import javax.swing.SwingConstants; - -import com.moomoohk.Grame.test.EngineState; -import com.moomoohk.Grame.test.MainMenu; -import com.moomoohk.Grame.test.MainMenu.MenuButton; - -public class LoadGamePanel extends JPanel -{ - private static final long serialVersionUID = -2270645491547851288L; - - private String savePath; - private ArrayList saves; - private JLabel noSaves = new JLabel("No saves found"); - - public LoadGamePanel(String savePath) - { - this.savePath = savePath; - this.saves = new ArrayList(); - this.noSaves.setHorizontalAlignment(SwingConstants.CENTER); - this.noSaves.setFont(new Font("Lucida Grande", Font.BOLD | Font.ITALIC, 15)); - this.noSaves.setForeground(Color.lightGray); - loadInfo(); - - SpringLayout springLayout = new SpringLayout(); - setLayout(springLayout); - - JLabel lblSelectSaveFile = new JLabel("Select save file to load:"); - lblSelectSaveFile.setFont(new Font("Lucida Grande", Font.BOLD, 13)); - springLayout.putConstraint(SpringLayout.NORTH, lblSelectSaveFile, 20, SpringLayout.NORTH, this); - springLayout.putConstraint(SpringLayout.WEST, lblSelectSaveFile, 20, SpringLayout.WEST, this); - springLayout.putConstraint(SpringLayout.EAST, lblSelectSaveFile, -20, SpringLayout.EAST, this); - add(lblSelectSaveFile); - - JScrollPane scrollPane = new JScrollPane(); - scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); - springLayout.putConstraint(SpringLayout.NORTH, scrollPane, 10, SpringLayout.SOUTH, lblSelectSaveFile); - springLayout.putConstraint(SpringLayout.WEST, scrollPane, 20, SpringLayout.WEST, this); - springLayout.putConstraint(SpringLayout.SOUTH, scrollPane, -100, SpringLayout.SOUTH, this); - springLayout.putConstraint(SpringLayout.EAST, scrollPane, -20, SpringLayout.EAST, this); - add(scrollPane); - - if (this.saves.size() == 0) - scrollPane.setViewportView(noSaves); - - MenuButton btnLoad = new MenuButton("Load", Color.red, Color.yellow, Color.blue, "Load the selected save"); - springLayout.putConstraint(SpringLayout.SOUTH, btnLoad, -20, SpringLayout.SOUTH, this); - springLayout.putConstraint(SpringLayout.EAST, btnLoad, 0, SpringLayout.EAST, lblSelectSaveFile); - springLayout.putConstraint(SpringLayout.SOUTH, scrollPane, -20, SpringLayout.NORTH, btnLoad); - btnLoad.setPreferredSize(new Dimension(100, 30)); - add(btnLoad); - - MenuButton btnCancel = new MenuButton("Cancel", Color.red, Color.yellow, Color.blue, "Cancels this operation"); - springLayout.putConstraint(SpringLayout.WEST, btnCancel, 0, SpringLayout.WEST, lblSelectSaveFile); - springLayout.putConstraint(SpringLayout.SOUTH, btnCancel, 0, SpringLayout.SOUTH, btnLoad); - btnCancel.setPreferredSize(new Dimension(100, 30)); - btnCancel.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent arg0) - { - MainMenu.sidePanel.setViewportView(null); - } - }); - add(btnCancel); - - btnLoad.addMouseListener(MainMenu.helpTextListener); - btnCancel.addMouseListener(MainMenu.helpTextListener); - } - - public void loadInfo() - { - System.out.println("Loading save info..."); - File f = new File(savePath); - if (!f.exists()) - return; - for (File child : f.listFiles()) - System.out.println(child); - System.out.println("Done"); - } -} diff --git a/src/com/moomoohk/Grame/Graphics/RenderManager.java b/src/com/moomoohk/Grame/Graphics/RenderManager.java index 37c2051..bd7028c 100644 --- a/src/com/moomoohk/Grame/Graphics/RenderManager.java +++ b/src/com/moomoohk/Grame/Graphics/RenderManager.java @@ -3,10 +3,15 @@ import java.awt.Canvas; import java.awt.Color; import java.awt.Font; +import java.awt.FontMetrics; import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; +import java.awt.geom.Rectangle2D; import java.awt.image.BufferStrategy; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; @@ -77,11 +82,10 @@ public static void render(final int bID, Render render) if (bID != mainBase) GrameManager.setMainBase(bID); mainBase = bID; - // mainFrame.setTitle("Rendering Base number " + mainBase); mainFrame.setTitle(GrameManager.getGameName()); if (render == null) render = GrameManager.getDefaultRender(); - if(!render.equals(renders.get(bID))) + if (!render.equals(renders.get(bID))) GrameManager.setMainRender(render); renders.put(bID, render); BufferStrategy bs = mainCanvas.getBufferStrategy(); @@ -116,6 +120,40 @@ public static void render(final int bID, Render render) g.drawString(text.get(bID).getText(new Coordinates(x, y)), y * squaresize, (x + 1) * (squaresize) - ((squaresize / 2) - 5)); } } + if (GrameManager.paused) + { + Graphics2D g2 = (Graphics2D) g.create(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g2.setColor(new Color(Color.gray.getRed(), Color.gray.getGreen(), Color.gray.getBlue(), 127)); + g2.fillRect(0, 0, mainCanvas.getWidth(), mainCanvas.getHeight()); + + int textCenterX = mainCanvas.getWidth() / 2, textCenterY = mainCanvas.getHeight() / 2; + String text = "Paused"; + g2.setFont(new Font("LucidaTypewriter", Font.BOLD, 40)); + FontMetrics fm = g2.getFontMetrics(); + Rectangle2D textBounds = fm.getStringBounds(text, g2); + Rectangle fixed = new Rectangle((int) (textCenterX - (textBounds.getWidth() / 2)), (int) (textCenterY - (textBounds.getHeight() / 2)), (int) textBounds.getWidth(), (int) textBounds.getHeight()); + + int inPadUp = 10, inPadDown = 10, inPadRight = 10, inPadLeft = 10; + Rectangle back = new Rectangle((int) fixed.getX() - inPadLeft, (int) fixed.getY() - inPadUp, (int) (fixed.getWidth()) + inPadRight + inPadLeft, (int) (fixed.getHeight()) + inPadDown + inPadUp); + g2.setColor(Color.black); + g2.fillRoundRect((int) back.getX(), (int) back.getY(), (int) back.getWidth(), (int) back.getHeight(), (inPadRight + inPadLeft) / 2, (inPadUp + inPadDown) / 2); + g2.setColor(new Color(255, 255, 255, 200)); + g2.drawString(text, (int) (fixed.getX()), (int) (fixed.getY()+Math.max(fm.getMaxAscent(), fm.getMaxDescent()))); + +// g2.setColor(Color.cyan); +// g2.draw(new Ellipse2D.Double(textCenterX - 5, textCenterY - 5, 10, 10)); +// g2.setColor(Color.blue); +// g2.draw(back); +// g2.setColor(Color.green); +// g2.draw(textBounds); +// g2.setColor(Color.red); +// g2.draw(fixed); +// g2.fill(new Ellipse2D.Double(fixed.getCenterX() - 2, fixed.getCenterY() - 2, 4, 4)); + + g2.dispose(); + } if (drawCoordinates) { diff --git a/src/com/moomoohk/Grame/test/MainMenu.java b/src/com/moomoohk/Grame/test/MainMenu.java deleted file mode 100644 index 65e6bf6..0000000 --- a/src/com/moomoohk/Grame/test/MainMenu.java +++ /dev/null @@ -1,331 +0,0 @@ -package com.moomoohk.Grame.test; - -import java.awt.Color; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.RenderingHints; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; - -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.SwingConstants; -import javax.swing.Timer; -import javax.swing.border.BevelBorder; -import javax.swing.border.EmptyBorder; - -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Essentials.GrameUtils; -import com.moomoohk.Grame.Essentials.MainMenuPanels.LoadGamePanel; -import com.moomoohk.Grame.Graphics.RenderManager; -import com.moomoohk.Grame.Interfaces.MainGrameClass; -import com.moomoohk.Mootilities.FrameDragger.FrameDragger; -import com.moomoohk.Mootilities.OSUtils.OSUtils; - -public class MainMenu extends JFrame -{ - private static final long serialVersionUID = -2989260620184596791L; - private static JPanel contentPane; - private static MenuButton btnResume, btnNewGame, btnSaveGame, btnLoadGame, btnSettings, btnEndGame; - private static JLabel lblMadeWithGrame; - public static JScrollPane sidePanel; - public static MouseListener helpTextListener = (new MouseAdapter() - { - public void mouseEntered(MouseEvent me) - { - lblMadeWithGrame.setText(((MenuButton) me.getSource()).getHelpText()); - } - - public void mouseExited(MouseEvent me) - { - lblMadeWithGrame.setText(""); - } - - public void mouseReleased(MouseEvent me) - { - if (((MenuButton) me.getSource()).isEnabled()) - lblMadeWithGrame.setText(""); - } - }); - private static String savePath = OSUtils.getDynamicStorageLocation() + "Grame/Saves/Test/"; - private static boolean paused = false; - private static final Rectangle BUTTON1 = new Rectangle(10, 50, 130, 30), BUTTON2 = new Rectangle(20, 90, 110, 30), BUTTON3 = new Rectangle(20, 130, 110, 30), BUTTON4 = new Rectangle(20, 170, 110, 30), BUTTON5 = new Rectangle(20, 210, 110, 30); - private static JPanel loadGamePanel = new LoadGamePanel(savePath); - - public static void main(String[] args) - { - new MainMenu(null).setVisible(true); - paused = true; - new MainMenu(null).setVisible(true); - } - - public MainMenu(final MainGrameClass mainClass) - { - setUndecorated(true); - setResizable(false); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setSize(600, 400); - setLocationRelativeTo(null); - contentPane = new JPanel(); - contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); - setContentPane(contentPane); - contentPane.setLayout(null); - - JLabel lblGameName = new JLabel("Game Name"); - lblGameName.setFont(new Font("Lucida Grande", Font.BOLD, 22)); - lblGameName.setHorizontalAlignment(SwingConstants.CENTER); - lblGameName.setBounds(20, 6, 560, 33); - contentPane.add(lblGameName); - - btnResume = new MenuButton("Resume Game", Color.red, Color.yellow, Color.blue, "Unpause the game"); - btnResume.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent arg0) - { - dispose(); - paused = false; - } - }); - contentPane.add(btnResume); - - btnNewGame = new MenuButton("New Game", Color.red, Color.yellow, Color.blue, "Start a new game"); - btnNewGame.setBounds(BUTTON1); - btnNewGame.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent arg0) - { - dispose(); - GrameUtils.console.setVisible(true); - RenderManager.clearAllText(); -// engineState = new EngineState(); - mainClass.newGame(); -// if (!running) -// start(); - paused = false; - } - }); - contentPane.add(btnNewGame); - - btnSaveGame = new MenuButton("Save Game", Color.red, Color.yellow, Color.blue, "Save your game to file"); - btnSaveGame.setEnabled(false); - contentPane.add(btnSaveGame); - - btnLoadGame = new MenuButton("Load Game", Color.red, Color.yellow, Color.blue, "Load a saved game"); - btnLoadGame.setBounds(BUTTON2); - btnLoadGame.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent arg0) - { - System.out.println("Path: " + savePath); - sidePanel.setViewportView(loadGamePanel); - } - }); - contentPane.add(btnLoadGame); - - btnSettings = new MenuButton("Settings", Color.red, Color.yellow, Color.blue, "Show the settings"); - btnSettings.setBounds(BUTTON3); - btnSettings.setEnabled(false); - contentPane.add(btnSettings); - - btnEndGame = new MenuButton("End Game", Color.red, Color.yellow, Color.blue, "Abandon the current game"); - btnEndGame.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent arg0) - { - paused = false; -// stop(); - updateButtons(); - } - }); - contentPane.add(btnEndGame); - - sidePanel = new JScrollPane(); - sidePanel.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null)); - sidePanel.setBounds(150, 50, 430, 290); - contentPane.add(sidePanel); - - lblMadeWithGrame = new JLabel(); - lblMadeWithGrame.addMouseListener(new MouseAdapter() - { - public void mouseEntered(MouseEvent me) - { - lblMadeWithGrame.setText("Made with moomoohk's Grame (v" + GrameManager.VERSION_NUMBER + ")"); - } - - public void mouseExited(MouseEvent me) - { - lblMadeWithGrame.setText(""); - } - }); - lblMadeWithGrame.setFont(new Font("Lucida Grande", Font.BOLD | Font.ITALIC, 11)); - lblMadeWithGrame.setForeground(Color.DARK_GRAY); - lblMadeWithGrame.setBounds(18, 353, 421, 37); - contentPane.add(lblMadeWithGrame); - - MenuButton btnQuit = new MenuButton("Quit", Color.red, Color.yellow, Color.blue, "Quit the game"); - btnQuit.setBounds(450, 350, 130, 40); - btnQuit.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent arg0) - { - System.exit(0); - } - }); - contentPane.add(btnQuit); - - btnResume.addMouseListener(helpTextListener); - btnNewGame.addMouseListener(helpTextListener); - btnSaveGame.addMouseListener(helpTextListener); - btnLoadGame.addMouseListener(helpTextListener); - btnSettings.addMouseListener(helpTextListener); - btnEndGame.addMouseListener(helpTextListener); - btnQuit.addMouseListener(helpTextListener); - - new FrameDragger().applyTo(this); - } - - public void updateButtons() - { - if (paused) - { - btnResume.setBounds(BUTTON1); - btnNewGame.setBounds(BUTTON2); - btnLoadGame.setBounds(BUTTON3); - btnSettings.setBounds(BUTTON4); - btnEndGame.setBounds(BUTTON5); - } - else - { - btnResume.setBounds(0, 0, 0, 0); - btnNewGame.setBounds(BUTTON1); - btnSaveGame.setBounds(BUTTON2); - btnLoadGame.setBounds(BUTTON3); - btnSettings.setBounds(BUTTON4); - btnEndGame.setBounds(0, 0, 0, 0); - } - } - - public void setVisible(boolean f) - { - updateButtons(); - super.setVisible(f); - } - - public static class MenuButton extends JButton - { - private static final long serialVersionUID = -2192610213120657509L; - - public boolean mouseOn = false, mouseDown = false; - private double animTime = 0; - private Color startColor, endColor, clickColor, fill; - private String helpText; - private Timer t = new Timer(10, new ActionListener() - { - public void actionPerformed(ActionEvent arg0) - { - repaint(); - animTime += 0.03; - } - }); - - public MenuButton(String text, Color startColor, Color endColor, Color clickColor, String helpText) - { - super(text); - this.startColor = startColor; - this.endColor = endColor; - this.clickColor = clickColor; - this.fill = this.startColor; - this.helpText = helpText; - addMouseListener(new MouseAdapter() - { - public void mouseReleased(MouseEvent arg0) - { - mouseDown = false; - repaint(); - t.stop(); - } - - @Override - public void mousePressed(MouseEvent arg0) - { - mouseDown = true; - repaint(); - animTime = 0; - t.start(); - } - - @Override - public void mouseExited(MouseEvent arg0) - { - mouseOn = false; - repaint(); - } - - @Override - public void mouseEntered(MouseEvent arg0) - { - mouseOn = true; - repaint(); - animTime = 0; - t.start(); - } - }); - } - - public String getHelpText() - { - return this.helpText; - } - - protected void paintComponent(Graphics g) - { - super.paintComponent(g); - Graphics2D g2 = (Graphics2D) g.create(); - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - if (isEnabled()) - { - if (mouseDown && mouseOn) - fill = clickColor; - else - if (mouseOn) - fill = new Color((int) (endColor.getRed() * Math.abs(Math.sin(animTime)) + startColor.getRed() * (1 - Math.abs(Math.sin(animTime)))), (int) (endColor.getGreen() * Math.abs(Math.sin(animTime)) + startColor.getGreen() * (1 - Math.abs(Math.sin(animTime)))), - (int) (endColor.getBlue() * Math.abs(Math.sin(animTime)) + startColor.getBlue() * (1 - Math.abs(Math.sin(animTime))))); - else - { - fill = new Color((int) (fill.getRed() * Math.abs(Math.sin(animTime)) + startColor.getRed() * (1 - Math.abs(Math.sin(animTime)))), (int) (fill.getGreen() * Math.abs(Math.sin(animTime)) + startColor.getGreen() * (1 - Math.abs(Math.sin(animTime)))), (int) (fill.getBlue() - * Math.abs(Math.sin(animTime)) + startColor.getBlue() * (1 - Math.abs(Math.sin(animTime))))); - if (fill.equals(startColor)) - { - t.stop(); - if (mouseDown) - fill = clickColor; - else - fill = startColor; - } - } - g2.setPaint(fill); - } - else - g2.setPaint(Color.LIGHT_GRAY); - g2.fillRoundRect(0, 0, getWidth(), getHeight(), 6, 6); - g2.setPaint(Color.black); - if (mouseOn && isEnabled()) - g2.fillRoundRect(2, 2, getWidth() - 4, getHeight() - 4, 6, 6); - else - g2.fillRoundRect(3, 3, getWidth() - 6, getHeight() - 6, 6, 6); - g2.setPaint(Color.white); - FontMetrics fm = g2.getFontMetrics(); - g2.drawString(getText(), (getWidth() / 2) - (fm.stringWidth(getText()) / 2), (getHeight() / 2) + 4); - g2.dispose(); - } - } -} \ No newline at end of file diff --git a/src/com/moomoohk/Grame/test/MenuConfiguration.java b/src/com/moomoohk/Grame/test/MenuConfiguration.java new file mode 100644 index 0000000..35d5e86 --- /dev/null +++ b/src/com/moomoohk/Grame/test/MenuConfiguration.java @@ -0,0 +1,28 @@ +package com.moomoohk.Grame.test; + +import java.awt.Color; + +public class MenuConfiguration +{ + public Color menuButtonStartColor = Color.red; + public Color menuButtonEndColor = Color.yellow; + public Color menuButtonClickColor = Color.blue; + + public Color confirmButtonStartColor = Color.red; + public Color confirmButtonEndColor = Color.yellow; + public Color confirmButtonClickColor = Color.blue; + + public Color cancelButtonStartColor = Color.red; + public Color cancelButtonEndColor = Color.yellow; + public Color cancelButtonClickColor = Color.blue; + + public Color otherButtonStartColor = Color.red; + public Color otherButtonEndColor = Color.yellow; + public Color otherButtonClickColor = Color.blue; + + public Color quitButtonStartColor = Color.red; + public Color quitButtonEndColor = Color.yellow; + public Color quitButtonClickColor = Color.blue; + + public Color disabledButtonColor = Color.gray; +} diff --git a/src/com/moomoohk/Grame/test/SaveTest.java b/src/com/moomoohk/Grame/test/SaveTest.java index 081aaa4..fa8711f 100644 --- a/src/com/moomoohk/Grame/test/SaveTest.java +++ b/src/com/moomoohk/Grame/test/SaveTest.java @@ -1,5 +1,7 @@ package com.moomoohk.Grame.test; +import java.awt.Color; + import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Essentials.Base; import com.moomoohk.Grame.Essentials.GrameManager; @@ -11,14 +13,19 @@ public class SaveTest implements MainGrameClass { public static void main(String[] args) { + MenuConfiguration menuConfig = new MenuConfiguration(); + menuConfig.menuButtonStartColor = Color.cyan; + menuConfig.menuButtonEndColor = Color.blue; + menuConfig.otherButtonStartColor = Color.green; + menuConfig.otherButtonEndColor = Color.red; GrameUtils.loadBasicCommands(); - GrameManager.initialize(new SaveTest()); + GrameManager.initialize(new SaveTest(), menuConfig); } @Override public void newGame() { - Base b = new Base(20, 20); + Base b = new Base(30, 30); Entity e = new Entity(); e.makePlayer(1, true, b.ID); b.addGrameObject(e, GrameUtils.randomCoordinates(b)); diff --git a/src/com/moomoohk/Grame/test/UpdateLibs.java b/src/com/moomoohk/Grame/test/UpdateLibs.java index bac293a..222865d 100644 --- a/src/com/moomoohk/Grame/test/UpdateLibs.java +++ b/src/com/moomoohk/Grame/test/UpdateLibs.java @@ -17,18 +17,18 @@ public static void main(String[] args) { File workspace = new File("/Users/MeshulamSilk/Documents/workspace"); File target = new File("/Users/MeshulamSilk/Documents/workspace/Grame/res/Libraries"); - String[] libraries={"MooCommands", "MooConsole"}; - for(int i=0; i 0) outStream.write(buffer, 0, length); inStream.close(); outStream.close(); - System.out.println(libraries[i]+" updated successfully!"); + System.out.println(libraries[i] + " updated successfully!"); } } catch (IOException e) From 5abd18a8d16f4781ecb2ce42188a995bffa22673 Mon Sep 17 00:00:00 2001 From: Meshulam Silk Date: Sun, 24 Nov 2013 05:22:12 +0200 Subject: [PATCH 03/11] Updated to MooCommands 2.0 --- .../Grame/Essentials/GrameManager.java | 5 + .../moomoohk/Grame/Essentials/GrameUtils.java | 47 ++++----- .../Grame/Graphics/RenderManager.java | 2 +- .../Grame/commands/AddEntityAICommand.java | 83 ++++++++++++---- .../Grame/commands/AddGrameObjectCommand.java | 68 +++++++++++-- .../Grame/commands/ClearEntityAI.java | 61 ++++++++++-- .../Grame/commands/CreateEntityCommand.java | 81 ++++++++++------ .../commands/DrawCoordinatesCommand.java | 60 ++++++++++-- .../moomoohk/Grame/commands/HelpCommand.java | 29 ------ .../Grame/commands/MakePlayerCommand.java | 66 ++++++++++--- .../commands/MoveGrameObjectCommand.java | 85 +++++++++++++---- .../Grame/commands/PrintEntityAICommand.java | 62 ++++++++++-- .../moomoohk/Grame/commands/QuitCommand.java | 43 +++++++-- .../Grame/commands/RenderBaseCommand.java | 75 +++++++++++---- .../commands/SetEntityOverrideAICommand.java | 95 ++++++++++++++----- .../Grame/commands/SetObjectSpeedCommand.java | 22 ----- .../Grame/commands/SetSpriteCommand.java | 69 ++++++++++---- .../Grame/commands/SetWraparoundCommand.java | 66 +++++++++++-- .../Grame/commands/isOccupiedCommand.java | 66 ++++++++++--- .../Grame/commands/setVisibleCommand.java | 62 ++++++++++-- .../Grame/test/MenuConfiguration.java | 22 ++--- src/com/moomoohk/Grame/test/SaveTest.java | 8 +- 22 files changed, 882 insertions(+), 295 deletions(-) delete mode 100644 src/com/moomoohk/Grame/commands/HelpCommand.java delete mode 100644 src/com/moomoohk/Grame/commands/SetObjectSpeedCommand.java diff --git a/src/com/moomoohk/Grame/Essentials/GrameManager.java b/src/com/moomoohk/Grame/Essentials/GrameManager.java index cbcbaf7..b27567b 100644 --- a/src/com/moomoohk/Grame/Essentials/GrameManager.java +++ b/src/com/moomoohk/Grame/Essentials/GrameManager.java @@ -601,6 +601,11 @@ public static int getObjectListLength() { return engineState.getGrameObjects().size(); } + + public static int getBaseListLength() + { + return engineState.getBases().size(); + } /** * Gets the current FPS (Frames Per Second) count. diff --git a/src/com/moomoohk/Grame/Essentials/GrameUtils.java b/src/com/moomoohk/Grame/Essentials/GrameUtils.java index e14635b..bc9d3a7 100644 --- a/src/com/moomoohk/Grame/Essentials/GrameUtils.java +++ b/src/com/moomoohk/Grame/Essentials/GrameUtils.java @@ -38,19 +38,20 @@ import com.moomoohk.Grame.commands.ClearEntityAI; import com.moomoohk.Grame.commands.CreateEntityCommand; import com.moomoohk.Grame.commands.DrawCoordinatesCommand; -import com.moomoohk.Grame.commands.HelpCommand; +import com.moomoohk.Grame.commands.IsOccupiedCommand; import com.moomoohk.Grame.commands.MakePlayerCommand; import com.moomoohk.Grame.commands.MoveGrameObjectCommand; import com.moomoohk.Grame.commands.PrintEntityAICommand; import com.moomoohk.Grame.commands.QuitCommand; import com.moomoohk.Grame.commands.RenderBaseCommand; import com.moomoohk.Grame.commands.SetEntityOverrideAICommand; -import com.moomoohk.Grame.commands.SetObjectSpeedCommand; +import com.moomoohk.Grame.commands.SetSpeedCommand; import com.moomoohk.Grame.commands.SetSpriteCommand; -import com.moomoohk.Grame.commands.IsOccupiedCommand; import com.moomoohk.Grame.commands.SetVisibleCommand; -import com.moomoohk.MooCommands.Command; +import com.moomoohk.Grame.commands.SetWraparoundCommand; +import com.moomoohk.MooCommands.CommandsManager; import com.moomoohk.MooConsole.Console; +import com.moomoohk.MooConsole.HelpCommand; /** * The Grame Utils class provides useful utilities. @@ -460,25 +461,25 @@ public void mouseClicked(MouseEvent arg0) */ public static void loadBasicCommands() { - ArrayList> commands = new ArrayList>(); - commands.add(new SetVisibleCommand(console, "setvisible", "Toggles the visibility of the main window. Usage: setvisible [true/false]", 0, 1)); - commands.add(new MoveGrameObjectCommand(console, "move", "Moves a Grame Object. Usage: move ", 3, 4)); - commands.add(new HelpCommand(console, "help", "Will print the help of a command. Leave blank for all the commands. Usage: help [command name]", 0, 1)); - commands.add(new RenderBaseCommand(console, "render", "Will render a base using a render in the Render list. Usage: render ", 2, 2)); - commands.add(new QuitCommand(console, "quit", "Quits the program. Usage: quit", 0, 0)); - commands.add(new CreateEntityCommand(console, "createentity", "Creates a new Entity. Usage: createentity [n:name] [t:type] [l:level] [c:color]", 0, 4)); - commands.add(new AddGrameObjectCommand(console, "addobject", "Adds a Grame Object to a Base. Usage: addobject ", 4, 4)); - commands.add(new AddEntityAICommand(console, "addentityai", "Adds a MovememntAI to an Entity's AI list. Usage: addentityai ", 3, 3)); - commands.add(new MakePlayerCommand(console, "makeplayer", "Turns an Entity into a controllable \"player\". Usage: makeplayer ", 4, 4)); - commands.add(new SetEntityOverrideAICommand(console, "setentityoverrideai", "Sets the override AI for a given Entity. Usage: setentityoverrideai ", 3, 3)); - commands.add(new ClearEntityAI(console, "clearentityai", "Clears the AI list of an Entity. Usage: clearentityai ", 1, 1)); - commands.add(new PrintEntityAICommand(console, "printentityai", "Prints the AI list for a given Entity. Usage: printentityai ", 1, 1)); - commands.add(new IsOccupiedCommand(console, "isoccupied", "Checks whether Coordinates in a Base are occupied by a Grame object. Usage: isoccupied ", 3, 3)); - commands.add(new DrawCoordinatesCommand(console, "drawcoordinates", "Draws the coordinates in each square. Usage: drawcoordinates ", 1, 1)); - commands.add(new SetObjectSpeedCommand(console, "setspeed", "Sets the speed of an object.", 2, 2)); - commands.add(new SetSpriteCommand(console, "setsprite", "Sets a certain sprite. Usage: setsprite ", 2, -1)); - console.loadCommands(commands); - print("Loaded " + Command.commands.size() + " commands.", MessageLevel.DEBUG); + int prevLength = CommandsManager.getAllCommands().size(); + new HelpCommand(); + new SetVisibleCommand(); + new MoveGrameObjectCommand(); + new RenderBaseCommand(); + new QuitCommand(); + new CreateEntityCommand(); + new AddGrameObjectCommand(); + new AddEntityAICommand(); + new MakePlayerCommand(); + new SetEntityOverrideAICommand(); + new ClearEntityAI(); + new PrintEntityAICommand(); + new IsOccupiedCommand(); + new DrawCoordinatesCommand(); + new SetSpeedCommand(); + new SetSpriteCommand(); + new SetWraparoundCommand(); + print("Loaded " + (CommandsManager.getAllCommands().size() - prevLength) + " commands.", MessageLevel.DEBUG); } /** diff --git a/src/com/moomoohk/Grame/Graphics/RenderManager.java b/src/com/moomoohk/Grame/Graphics/RenderManager.java index bd7028c..e1ce7ad 100644 --- a/src/com/moomoohk/Grame/Graphics/RenderManager.java +++ b/src/com/moomoohk/Grame/Graphics/RenderManager.java @@ -109,7 +109,7 @@ public static void render(final int bID, Render render) g.drawImage(img, 0, 0, mainCanvas.getWidth(), mainCanvas.getHeight(), null); g.setFont(new Font("LucidaTypewriter", 1, 8)); - int squaresize = mainCanvas.getWidth() / GrameManager.findBase(bID).getColumns(); //TODO: Fix nullpointer + int squaresize = mainCanvas.getWidth() / GrameManager.findBase(bID).getColumns(); //FIXME: Nullpointer for (int x = 0; x < GrameManager.findBase(bID).getColumns(); x++) for (int y = 0; y < GrameManager.findBase(bID).getRows(); y++) if (text.get(bID) != null) diff --git a/src/com/moomoohk/Grame/commands/AddEntityAICommand.java b/src/com/moomoohk/Grame/commands/AddEntityAICommand.java index 63fc788..ff9b63f 100644 --- a/src/com/moomoohk/Grame/commands/AddEntityAICommand.java +++ b/src/com/moomoohk/Grame/commands/AddEntityAICommand.java @@ -1,35 +1,82 @@ package com.moomoohk.Grame.commands; -import com.moomoohk.Grame.Essentials.GrameManager; +import java.awt.Color; + import com.moomoohk.Grame.Basics.Entity; +import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; -public class AddEntityAICommand extends Command +public class AddEntityAICommand extends Command { - public AddEntityAICommand(Console handler, String command, String help, int minParams, int maxParams) + public AddEntityAICommand() { - super(handler, command, help, minParams, maxParams); + super(); } - @Override - public void execute(Console arg0, String[] arg1) + protected boolean check(String[] params) { - if(GrameManager.getAIs().size()==0) + if (GrameManager.getAIs().size() == 0) { - this.message="No AIs loaded!"; - return; + this.outputMessage = "No AIs loaded!"; + this.outputColor = Color.red; + return false; } - if(GrameManager.getAIs().get(arg1[2])==null) + if (GrameManager.getAIs().get(params[2]) == null) { - this.message="Valid AIs: "; - for(String name:GrameManager.getAIs().keySet()) - this.message+=name+ " "; - return; + this.outputMessage = "Valid AIs: "; + for (String name : GrameManager.getAIs().keySet()) + this.outputMessage += name + " "; + return false; } - this.message=""; - ((Entity)(GrameManager.findGrameObject(Integer.parseInt(arg1[0])))).addAI(GrameManager.getAIs().get(arg1[2]), Integer.parseInt(arg1[1])); + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) + { + this.outputMessage = "Grame Object with ID:" + params[0] + " does not exist!"; + this.outputColor = Color.red; + return false; + } + if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof Entity)) + { + this.outputMessage = "Grame Object with ID:" + params[0] + " is not an Entity!"; + this.outputColor = Color.red; + return false; + } + return super.check(params); + } + + @Override + public void execute(String[] params) + { + ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).addAI(GrameManager.getAIs().get(params[2]), Integer.parseInt(params[1])); + } + + @Override + public String getCommand() + { + return "addentityai"; } -} + @Override + public String getHelpMessage() + { + return "Adds a MovememntAI to an Entity's AI list"; + } + + @Override + public String getUsage() + { + return "addentityai "; + } + + @Override + public int getMaxParams() + { + return 3; + } + + @Override + public int getMinParams() + { + return 3; + } +} diff --git a/src/com/moomoohk/Grame/commands/AddGrameObjectCommand.java b/src/com/moomoohk/Grame/commands/AddGrameObjectCommand.java index 52356e8..d63ffef 100644 --- a/src/com/moomoohk/Grame/commands/AddGrameObjectCommand.java +++ b/src/com/moomoohk/Grame/commands/AddGrameObjectCommand.java @@ -1,23 +1,75 @@ - package com.moomoohk.Grame.commands; +import java.awt.Color; + import com.moomoohk.Grame.Essentials.Coordinates; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; -public class AddGrameObjectCommand extends Command +public class AddGrameObjectCommand extends Command { - public AddGrameObjectCommand(Console handler, String command, String help, int minParams, int maxParams) + public AddGrameObjectCommand() { - super(handler, command, help, minParams, maxParams); + super(); + } + + public boolean check(String[] params) + { + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) + { + this.outputMessage = "Grame Object with ID:" + params[0] + " does not exist!"; + this.outputColor = Color.red; + return false; + } + if (GrameManager.findBase(Integer.parseInt(params[1])) == null) + { + this.outputMessage = "Base with ID:" + params[1] + " does not exist!"; + this.outputColor = Color.red; + return false; + } + if (!GrameManager.findBase(Integer.parseInt(params[1])).isInBase(new Coordinates(Integer.parseInt(params[1]), Integer.parseInt(params[2])))) + { + this.outputMessage = "Coordinates (" + params[1] + ", " + params[2] + ") are not in Base with ID:" + params[1]; + this.outputColor = Color.red; + return false; + } + return super.check(params); } @Override - public void execute(Console arg0, String[] arg1) + public void execute(String[] params) { - GrameManager.findBase(Integer.parseInt(arg1[1])).addGrameObject(GrameManager.findGrameObject(Integer.parseInt(arg1[0])), new Coordinates(Integer.parseInt(arg1[2]), Integer.parseInt(arg1[3]))); + GrameManager.findBase(Integer.parseInt(params[1])).addGrameObject(GrameManager.findGrameObject(Integer.parseInt(params[0])), new Coordinates(Integer.parseInt(params[2]), Integer.parseInt(params[3]))); + } + + @Override + public String getCommand() + { + return "addobject"; + } + + @Override + public String getHelpMessage() + { + return "Adds a Grame Object to a Base"; } -} + @Override + public String getUsage() + { + return "addobject "; + } + + @Override + public int getMaxParams() + { + return 4; + } + + @Override + public int getMinParams() + { + return 4; + } +} diff --git a/src/com/moomoohk/Grame/commands/ClearEntityAI.java b/src/com/moomoohk/Grame/commands/ClearEntityAI.java index 393d144..76ffc83 100644 --- a/src/com/moomoohk/Grame/commands/ClearEntityAI.java +++ b/src/com/moomoohk/Grame/commands/ClearEntityAI.java @@ -1,23 +1,68 @@ - package com.moomoohk.Grame.commands; +import java.awt.Color; + import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; -public class ClearEntityAI extends Command +public class ClearEntityAI extends Command { + public boolean check(String[] params) + { + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) + { + this.outputMessage = "Grame Object with ID:" + params[0] + " does not exist!"; + this.outputColor = Color.red; + return false; + } + if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof Entity)) + { + this.outputMessage = "Grame Object with ID:" + params[0] + " is not an Entity!"; + this.outputColor = Color.red; + return false; + } + return super.check(params); + } - public ClearEntityAI(Console handler, String command, String help, int minParams, int maxParams) + public ClearEntityAI() { - super(handler, command, help, minParams, maxParams); + super(); } @Override - public void execute(Console arg0, String[] arg1) + public void execute(String[] params) { - ((Entity)(GrameManager.findGrameObject(Integer.parseInt(arg1[0])))).clearAI(); + ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).clearAI(); + } + + @Override + public String getCommand() + { + return "clearentityai"; + } + + @Override + public String getHelpMessage() + { + return "Clears the AI list of an Entity"; } -} + @Override + public String getUsage() + { + return "clearentityai "; + } + + @Override + public int getMaxParams() + { + return 1; + } + + @Override + public int getMinParams() + { + return 1; + } +} diff --git a/src/com/moomoohk/Grame/commands/CreateEntityCommand.java b/src/com/moomoohk/Grame/commands/CreateEntityCommand.java index ac0200e..d41f08b 100644 --- a/src/com/moomoohk/Grame/commands/CreateEntityCommand.java +++ b/src/com/moomoohk/Grame/commands/CreateEntityCommand.java @@ -1,4 +1,3 @@ - package com.moomoohk.Grame.commands; import java.awt.Color; @@ -8,42 +7,70 @@ import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Essentials.GrameUtils; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; +import com.moomoohk.MooCommands.CommandsManager; -public class CreateEntityCommand extends Command +public class CreateEntityCommand extends Command { - public CreateEntityCommand(Console handler, String command, String help, int minParams, int maxParams) + public CreateEntityCommand() { - super(handler, command, help, minParams, maxParams); + super(); } @Override - public void execute(Console arg0, String[] arg1) - { - this.message=""; - String type=new DefaultRandomGen().typeGen(), name=new DefaultRandomGen().nameGen(); - int level=0; - Color color=GrameUtils.randomColor(); - HashMap flags=Command.parseFlags(arg1); - if(flags.get("t")!=null) - type=flags.get("t"); - if(flags.get("n")!=null) - name=flags.get("n"); - if(flags.get("l")!=null) - level=Integer.parseInt(flags.get("l")); + public void execute(String[] arg1) + { + String type = new DefaultRandomGen().typeGen(), name = new DefaultRandomGen().nameGen(); + int level = 0; + Color color = GrameUtils.randomColor(); + HashMap flags = CommandsManager.parseFlags(arg1); + if (flags.get("t") != null) + type = flags.get("t"); + if (flags.get("n") != null) + name = flags.get("n"); + if (flags.get("l") != null) + level = Integer.parseInt(flags.get("l")); new Entity(type, name, level, color); } - public boolean check(Console handler, String[] params) + + public boolean check(String[] params) { - boolean f=true; - for(String arg:params) - if(!arg.contains(":")) + for (String arg : params) + if (!arg.contains(":")) { - this.message="Incorrect syntax!"; - f=false; - break; + this.outputMessage = "Incorrect syntax!"; + this.outputColor = Color.red; + return false; } - return super.check(handler, params)&&f; + return super.check(params); + } + + @Override + public String getCommand() + { + return "createentity"; + } + + @Override + public String getHelpMessage() + { + return "Creates a new Entity"; } -} + @Override + public String getUsage() + { + return "createentity [n:name] [t:type] [l:level] [c:color]"; + } + + @Override + public int getMaxParams() + { + return 4; + } + + @Override + public int getMinParams() + { + return 0; + } +} diff --git a/src/com/moomoohk/Grame/commands/DrawCoordinatesCommand.java b/src/com/moomoohk/Grame/commands/DrawCoordinatesCommand.java index 37e0bfc..ba61b81 100644 --- a/src/com/moomoohk/Grame/commands/DrawCoordinatesCommand.java +++ b/src/com/moomoohk/Grame/commands/DrawCoordinatesCommand.java @@ -1,21 +1,65 @@ - package com.moomoohk.Grame.commands; +import java.awt.Color; + import com.moomoohk.Grame.Graphics.RenderManager; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; -public class DrawCoordinatesCommand extends Command +public class DrawCoordinatesCommand extends Command { - public DrawCoordinatesCommand(Console handler, String command, String help, int minParams, int maxParams) + public DrawCoordinatesCommand() { - super(handler, command, help, minParams, maxParams); + super(); + } + + public boolean check(String[] params) + { + try + { + Boolean.parseBoolean(params[0]); + } + catch (Exception e) + { + this.outputMessage = "Only true or false are accepted inputs!"; + this.outputColor = Color.red; + return false; + } + return super.check(params); } @Override - public void execute(Console arg0, String[] arg1) + public void execute(String[] params) { - RenderManager.drawCoordinates(Boolean.parseBoolean(arg1[0])); + RenderManager.drawCoordinates(Boolean.parseBoolean(params[0])); + } + + @Override + public String getCommand() + { + return "drawcoordinates"; + } + + @Override + public String getHelpMessage() + { + return "Draws the coordinates in each square"; } -} + @Override + public String getUsage() + { + return "drawcoordinates "; + } + + @Override + public int getMaxParams() + { + return 1; + } + + @Override + public int getMinParams() + { + return 1; + } +} diff --git a/src/com/moomoohk/Grame/commands/HelpCommand.java b/src/com/moomoohk/Grame/commands/HelpCommand.java deleted file mode 100644 index 46ccef6..0000000 --- a/src/com/moomoohk/Grame/commands/HelpCommand.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.moomoohk.Grame.commands; - -import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; - -public class HelpCommand extends Command -{ - - public HelpCommand(Console handler, String command, String help, int minParams, int maxParams) - { - super(handler, command, help, minParams, maxParams); - } - - @Override - public void execute(Console handler, String[] params) - { - if (params.length == 0) - { - this.message = getAllHelp(false); - return; - } - if (Command.getCommand(params[0]) == null) - { - this.message = "Command not found!"; - return; - } - this.message = Command.getCommand(params[0]).getCommand() + ": " + Command.getCommand(params[0]).getHelp(); - } -} diff --git a/src/com/moomoohk/Grame/commands/MakePlayerCommand.java b/src/com/moomoohk/Grame/commands/MakePlayerCommand.java index f2f0392..d42a3f5 100644 --- a/src/com/moomoohk/Grame/commands/MakePlayerCommand.java +++ b/src/com/moomoohk/Grame/commands/MakePlayerCommand.java @@ -1,30 +1,70 @@ - package com.moomoohk.Grame.commands; +import java.awt.Color; + import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; -public class MakePlayerCommand extends Command +public class MakePlayerCommand extends Command { - public MakePlayerCommand(Console handler, String command, String help, int minParams, int maxParams) + public MakePlayerCommand() { - super(handler, command, help, minParams, maxParams); + super(); + } + + public boolean check(String[] params) + { + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) + { + this.outputMessage = "Grame Object with ID:" + params[0] + " does not exist!"; + this.outputColor = Color.red; + return false; + } + return super.check(params); } @Override - public void execute(Console arg0, String[] arg1) + public void execute(String[] params) { - if(arg1[0].equalsIgnoreCase("all")) + if (params[0].equalsIgnoreCase("all")) { - for(int i=0; i "; + } + + @Override + public int getMaxParams() + { + return 4; } -} + @Override + public int getMinParams() + { + return 4; + } +} diff --git a/src/com/moomoohk/Grame/commands/MoveGrameObjectCommand.java b/src/com/moomoohk/Grame/commands/MoveGrameObjectCommand.java index 1983da1..2a424ff 100644 --- a/src/com/moomoohk/Grame/commands/MoveGrameObjectCommand.java +++ b/src/com/moomoohk/Grame/commands/MoveGrameObjectCommand.java @@ -1,34 +1,85 @@ - package com.moomoohk.Grame.commands; +import java.awt.Color; + import com.moomoohk.Grame.Basics.Dir; import com.moomoohk.Grame.Essentials.Coordinates; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; -public class MoveGrameObjectCommand extends Command +public class MoveGrameObjectCommand extends Command { - public MoveGrameObjectCommand(Console handler, String command, String help, int minParams, int maxParams) + public MoveGrameObjectCommand() { - super(handler, command, help, minParams, maxParams); + super(); + } + + public boolean check(String[] params) + { + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) + { + this.outputMessage = "Grame Object with ID:" + params[0] + " does not exist!"; + this.outputColor = Color.red; + return false; + } + if (GrameManager.findBase(Integer.parseInt(params[1])) == null) + { + this.outputMessage = "Base with ID:" + params[1] + " does not exist!"; + this.outputColor = Color.red; + return false; + } + if (params.length == 3 && !GrameManager.findBase(Integer.parseInt(params[1])).isInBase(GrameManager.findGrameObject(Integer.parseInt(params[0])).getPos(Integer.parseInt(params[1])).addDir(new Dir(params[2])))) + { + this.outputMessage = "Can't move there!"; + this.outputColor = Color.red; + return false; + } + if (params.length == 4 && !GrameManager.findBase(Integer.parseInt(params[1])).isInBase(new Coordinates(Integer.parseInt(params[2]), Integer.parseInt(params[3])))) + { + this.outputMessage = "Can't move there!"; + this.outputColor = Color.red; + return false; + } + return super.check(params); } @Override - public void execute(Console arg0, String[] arg1) + public void execute(String[] params) { - if(arg1.length==3) - if(GrameManager.findBase(Integer.parseInt(arg1[1])).isInBase(GrameManager.findGrameObject(Integer.parseInt(arg1[0])).getPos(Integer.parseInt(arg1[1])).addDir(new Dir(arg1[2])))) - GrameManager.findGrameObject(Integer.parseInt(arg1[0])).setPos(Integer.parseInt(arg1[1]), GrameManager.findGrameObject(Integer.parseInt(arg1[0])).getPos(Integer.parseInt(arg1[1])).addDir(new Dir(arg1[2]))); - else - this.message="Can't move there!"; - if(arg1.length==4) - if(GrameManager.findBase(Integer.parseInt(arg1[1])).isInBase(new Coordinates(Integer.parseInt(arg1[2]), Integer.parseInt(arg1[3])))) - GrameManager.findGrameObject(Integer.parseInt(arg1[0])).setPos(Integer.parseInt(arg1[1]), new Coordinates(Integer.parseInt(arg1[2]), Integer.parseInt(arg1[3]))); - else - this.message="Can't move there!"; + if (params.length == 3) + GrameManager.findGrameObject(Integer.parseInt(params[0])).setPos(Integer.parseInt(params[1]), GrameManager.findGrameObject(Integer.parseInt(params[0])).getPos(Integer.parseInt(params[1])).addDir(new Dir(params[2]))); + if (params.length == 4) + GrameManager.findGrameObject(Integer.parseInt(params[0])).setPos(Integer.parseInt(params[1]), new Coordinates(Integer.parseInt(params[2]), Integer.parseInt(params[3]))); } -} + @Override + public String getCommand() + { + return "move"; + } + + @Override + public String getHelpMessage() + { + return "Moves a Grame Object."; + } + @Override + public String getUsage() + { + return "move "; + } + + @Override + public int getMaxParams() + { + return 4; + } + + @Override + public int getMinParams() + { + return 3; + } +} diff --git a/src/com/moomoohk/Grame/commands/PrintEntityAICommand.java b/src/com/moomoohk/Grame/commands/PrintEntityAICommand.java index 33ea526..b6d4031 100644 --- a/src/com/moomoohk/Grame/commands/PrintEntityAICommand.java +++ b/src/com/moomoohk/Grame/commands/PrintEntityAICommand.java @@ -1,23 +1,69 @@ - package com.moomoohk.Grame.commands; +import java.awt.Color; + import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; -public class PrintEntityAICommand extends Command +public class PrintEntityAICommand extends Command { - public PrintEntityAICommand(Console handler, String command, String help, int minParams, int maxParams) + public PrintEntityAICommand() { - super(handler, command, help, minParams, maxParams); + super(); + } + + public boolean check(String[] params) + { + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) + { + this.outputMessage = "Grame Object with ID:" + params[0] + " does not exist!"; + this.outputColor = Color.red; + return false; + } + if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof Entity)) + { + this.outputMessage = "Grame Object with ID:" + params[0] + " is not an Entity!"; + this.outputColor = Color.red; + return false; + } + return super.check(params); } @Override - public void execute(Console arg0, String[] arg1) + public void execute(String[] params) { - ((Entity)(GrameManager.findGrameObject(Integer.parseInt(arg1[0])))).printAI(); + ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).printAI(); + } + + @Override + public String getCommand() + { + return "printentityai"; + } + + @Override + public String getHelpMessage() + { + return "Prints the AI list for a given Entity"; } -} + @Override + public int getMaxParams() + { + return 1; + } + + @Override + public int getMinParams() + { + return 1; + } + + @Override + public String getUsage() + { + return "printentityai "; + } +} diff --git a/src/com/moomoohk/Grame/commands/QuitCommand.java b/src/com/moomoohk/Grame/commands/QuitCommand.java index 2360da1..b5a912d 100644 --- a/src/com/moomoohk/Grame/commands/QuitCommand.java +++ b/src/com/moomoohk/Grame/commands/QuitCommand.java @@ -1,21 +1,48 @@ - package com.moomoohk.Grame.commands; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; -public class QuitCommand extends Command +public class QuitCommand extends Command { - public QuitCommand(Console handler, String command, String help, int minParams, int maxParams) + public QuitCommand() { - super(handler, command, help, minParams, maxParams); + super(); } @Override - public void execute(Console arg0, String[] arg1) + public void execute(String[] params) { - System.exit(0); + System.exit(0); + } + + @Override + public String getCommand() + { + return "quit"; + } + + @Override + public String getHelpMessage() + { + return "Quits the game"; + } + + @Override + public String getUsage() + { + return "quit"; } -} + @Override + public int getMaxParams() + { + return 0; + } + + @Override + public int getMinParams() + { + return 0; + } +} diff --git a/src/com/moomoohk/Grame/commands/RenderBaseCommand.java b/src/com/moomoohk/Grame/commands/RenderBaseCommand.java index e2fa609..ea259db 100644 --- a/src/com/moomoohk/Grame/commands/RenderBaseCommand.java +++ b/src/com/moomoohk/Grame/commands/RenderBaseCommand.java @@ -1,37 +1,76 @@ - package com.moomoohk.Grame.commands; +import java.awt.Color; + import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.Grame.Graphics.RenderManager; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; -public class RenderBaseCommand extends Command +public class RenderBaseCommand extends Command { - public RenderBaseCommand(Console handler, String command, String help, int minParams, int maxParams) + public RenderBaseCommand() { - super(handler, command, help, minParams, maxParams); + super(); } - @Override - public void execute(Console arg0, String[] arg1) + public boolean check(String[] params) { - if(GrameManager.getRenders().size()==0) + if (GrameManager.getRenders().size() == 0) + { + this.outputMessage = "No renders loaded!"; + this.outputColor = Color.red; + return false; + } + if (GrameManager.getRenders().get(params[1]) == null) { - this.message="No renders loaded!"; - return; + this.outputMessage = "Valid renders: "; + for (String name : GrameManager.getRenders().keySet()) + this.outputMessage += name + " "; + return false; } - if(GrameManager.getRenders().get(arg1[1])==null) + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) { - this.message="Valid renders: "; - for(String name:GrameManager.getRenders().keySet()) - this.message+=name+ " "; - return; + this.outputMessage = "Base with ID:" + params[1] + " does not exist!"; + this.outputColor = Color.red; + return false; } - this.message=""; - RenderManager.render(Integer.parseInt(arg1[0]), GrameManager.getRenders().get(arg1[1])); + return super.check(params); } -} + @Override + public void execute(String[] params) + { + RenderManager.render(Integer.parseInt(params[0]), GrameManager.getRenders().get(params[1])); + } + @Override + public String getCommand() + { + return "render"; + } + + @Override + public String getHelpMessage() + { + return "Renders a base using a render in the Render list"; + } + + @Override + public String getUsage() + { + return "render "; + } + + @Override + public int getMaxParams() + { + return 2; + } + + @Override + public int getMinParams() + { + return 2; + } +} diff --git a/src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java b/src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java index 9f2843e..26cc26f 100644 --- a/src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java +++ b/src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java @@ -1,41 +1,92 @@ - package com.moomoohk.Grame.commands; +import java.awt.Color; + import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; -public class SetEntityOverrideAICommand extends Command +public class SetEntityOverrideAICommand extends Command { - public SetEntityOverrideAICommand(Console handler, String command, String help, int minParams, int maxParams) + public SetEntityOverrideAICommand() { - super(handler, command, help, minParams, maxParams); + super(); } - @Override - public void execute(Console arg0, String[] arg1) + protected boolean check(String[] params) { - if(GrameManager.getAIs().size()==0) + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) + { + this.outputMessage = "Grame Object with ID:" + params[0] + " does not exist!"; + this.outputColor = Color.red; + return false; + } + if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof Entity)) + { + this.outputMessage = "Grame Object with ID:" + params[0] + " is not an Entity!"; + this.outputColor = Color.red; + return false; + } + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) + { + this.outputMessage = "Base with ID:" + params[1] + " does not exist!"; + this.outputColor = Color.red; + return false; + } + if (GrameManager.getAIs().size() == 0) { - this.message="No AIs loaded!"; - return; + this.outputMessage = "No AIs loaded!"; + this.outputColor = Color.red; + return false; } - if(!arg1[2].equalsIgnoreCase("null")) + if (GrameManager.getAIs().get(params[2]) == null || (GrameManager.getAIs().get(params[2]) != null && !GrameManager.getAIs().get(params[2]).isOverride())) { - if(GrameManager.getAIs().get(arg1[2])==null||(GrameManager.getAIs().get(arg1[2])!=null&&!GrameManager.getAIs().get(arg1[2]).isOverride())) - { - this.message="Valid AIs: "; - for(String name:GrameManager.getAIs().keySet()) - if(GrameManager.getAIs().get(name).isOverride()) - this.message+=name+ " "; - return; - } - ((Entity)(GrameManager.findGrameObject(Integer.parseInt(arg1[0])))).setOverrideAI(GrameManager.getAIs().get(arg1[2]), Integer.parseInt(arg1[1])); + this.outputMessage = "Valid AIs: "; + for (String name : GrameManager.getAIs().keySet()) + if (GrameManager.getAIs().get(name).isOverride()) + this.outputMessage += name + " "; + return false; } + return super.check(params); + } + + @Override + public void execute(String[] params) + { + if (!params[2].equalsIgnoreCase("null")) + ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).setOverrideAI(GrameManager.getAIs().get(params[2]), Integer.parseInt(params[1])); else - ((Entity)(GrameManager.findGrameObject(Integer.parseInt(arg1[0])))).setOverrideAI(null, Integer.parseInt(arg1[1])); + ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).setOverrideAI(null, Integer.parseInt(params[1])); + } + + @Override + public String getCommand() + { + return "setentityoverrideai"; + } + + @Override + public String getHelpMessage() + { + return "Sets the override AI for a given Entity"; + } + + @Override + public String getUsage() + { + return "setentityoverrideai "; } -} + @Override + public int getMaxParams() + { + return 3; + } + + @Override + public int getMinParams() + { + return 3; + } +} diff --git a/src/com/moomoohk/Grame/commands/SetObjectSpeedCommand.java b/src/com/moomoohk/Grame/commands/SetObjectSpeedCommand.java deleted file mode 100644 index 6d2edd8..0000000 --- a/src/com/moomoohk/Grame/commands/SetObjectSpeedCommand.java +++ /dev/null @@ -1,22 +0,0 @@ - -package com.moomoohk.Grame.commands; - -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; - -public class SetObjectSpeedCommand extends Command -{ - - public SetObjectSpeedCommand(Console handler, String command, String help, int minParams, int maxParams) - { - super(handler, command, help, minParams, maxParams); - } - - @Override - public void execute(Console arg0, String[] arg1) - { - GrameManager.findGrameObject(Integer.parseInt(arg1[0])).setSpeed(Integer.parseInt(arg1[1])); - } -} - diff --git a/src/com/moomoohk/Grame/commands/SetSpriteCommand.java b/src/com/moomoohk/Grame/commands/SetSpriteCommand.java index 71b63ea..a97bc28 100644 --- a/src/com/moomoohk/Grame/commands/SetSpriteCommand.java +++ b/src/com/moomoohk/Grame/commands/SetSpriteCommand.java @@ -1,6 +1,6 @@ - package com.moomoohk.Grame.commands; +import java.awt.Color; import java.io.File; import java.io.IOException; @@ -8,35 +8,70 @@ import com.moomoohk.Grame.test.SpriteRender; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; +import com.moomoohk.MooCommands.CommandsManager; -public class SetSpriteCommand extends Command +public class SetSpriteCommand extends Command { - public SetSpriteCommand(Console handler, String command, String help, int minParams, int maxParams) + public SetSpriteCommand() { - super(handler, command, help, minParams, maxParams); + super(); } - @Override - public void execute(Console arg0, String[] arg1) + public boolean check(String[] params) { - if(!SpriteRender.sprites.containsKey(arg1[0])) + if (!SpriteRender.sprites.containsKey(params[0])) { - this.message="Available sprites:"; - for(String sprite:SpriteRender.sprites.keySet()) - this.message+=" "+sprite; - return; + this.outputMessage = "Available sprites:"; + for (String sprite : SpriteRender.sprites.keySet()) + this.outputMessage += " " + sprite; + return false; } - String path=Command.stringParams(arg1, 1); + return super.check(params); + } + + @Override + public void execute(String[] params) + { + String path = CommandsManager.stringParams(params, 1); try { - SpriteRender.sprites.put(arg1[0], ImageIO.read(new File(path))); + SpriteRender.sprites.put(params[0], ImageIO.read(new File(path))); } - catch (IOException e2) + catch (IOException e) { - this.message="Invalid path!"; + this.outputMessage = "Invalid path!"; + this.outputColor = Color.red; } } -} + @Override + public String getCommand() + { + return "setsprite"; + } + + @Override + public String getHelpMessage() + { + return "Sets a certain sprite (NOT SUPPORTED/IN DEVELOPMENT)"; + } + + @Override + public String getUsage() + { + return "setsprite "; + } + + @Override + public int getMaxParams() + { + return -1; + } + + @Override + public int getMinParams() + { + return 2; + } +} diff --git a/src/com/moomoohk/Grame/commands/SetWraparoundCommand.java b/src/com/moomoohk/Grame/commands/SetWraparoundCommand.java index aa5147d..e25a0b5 100644 --- a/src/com/moomoohk/Grame/commands/SetWraparoundCommand.java +++ b/src/com/moomoohk/Grame/commands/SetWraparoundCommand.java @@ -1,21 +1,71 @@ package com.moomoohk.Grame.commands; -import com.moomoohk.Grame.Essentials.Base; +import java.awt.Color; + import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; -public class SetWraparoundCommand extends Command +public class SetWraparoundCommand extends Command { - public SetWraparoundCommand(Console handler, String command, String help, int minParams, int maxParams) + public SetWraparoundCommand() + { + super(); + } + + public boolean check(String[] params) + { + try + { + Boolean.parseBoolean(params[1]); + } + catch (Exception e) + { + this.outputMessage = "Only true or false are accepted inputs!"; + this.outputColor = Color.red; + return false; + } + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) + { + this.outputMessage = "Base with ID:" + params[1] + " does not exist!"; + this.outputColor = Color.red; + return false; + } + return super.check(params); + } + + @Override + public void execute(String[] params) + { + GrameManager.findBase(Integer.parseInt(params[0])).setWraparound(Boolean.parseBoolean(params[1])); + } + + @Override + public String getCommand() + { + return "setwraparound"; + } + + @Override + public String getHelpMessage() + { + return "Sets whether the specified Base supports wraparound"; + } + + @Override + public String getUsage() + { + return "setwraparound "; + } + + @Override + public int getMaxParams() { - super(handler, command, help, minParams, maxParams); + return 2; } @Override - public void execute(Console arg0, String[] arg1) + public int getMinParams() { - Base b = GrameManager.findBase(Integer.parseInt(arg1[0])); - b.setWraparound(Boolean.parseBoolean(arg1[1])); + return 2; } } diff --git a/src/com/moomoohk/Grame/commands/isOccupiedCommand.java b/src/com/moomoohk/Grame/commands/isOccupiedCommand.java index 8d6adda..1fa0f4d 100644 --- a/src/com/moomoohk/Grame/commands/isOccupiedCommand.java +++ b/src/com/moomoohk/Grame/commands/isOccupiedCommand.java @@ -1,29 +1,69 @@ - package com.moomoohk.Grame.commands; +import java.awt.Color; + import com.moomoohk.Grame.Essentials.Coordinates; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; -public class IsOccupiedCommand extends Command +public class IsOccupiedCommand extends Command { - public IsOccupiedCommand(Console handler, String command, String help, int minParams, int maxParams) + public IsOccupiedCommand() { - super(handler, command, help, minParams, maxParams); + super(); } - @Override - public void execute(Console arg0, String[]arg1) + public boolean check(String[] params) { - if(!GrameManager.findBase(Integer.parseInt(arg1[0])).isInBase(new Coordinates(Integer.parseInt(arg1[1]), Integer.parseInt(arg1[1])))) + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) + { + this.outputMessage = "Base with ID:" + params[1] + " does not exist!"; + this.outputColor = Color.red; + return false; + } + if (!GrameManager.findBase(Integer.parseInt(params[0])).isInBase(new Coordinates(Integer.parseInt(params[1]), Integer.parseInt(params[2])))) { - this.message="Coordinates "+new Coordinates(Integer.parseInt(arg1[1]), Integer.parseInt(arg1[1])).toString()+" isn't in Base ID:"+arg1[0]; - return; + this.outputMessage = "Coordinates (" + params[1] + ", " + params[2] + ") are not in Base ID:" + params[0]; + this.outputColor = Color.red; + return false; } - boolean isOccupied=GrameManager.findBase(Integer.parseInt(arg1[0])).isOccupied(new Coordinates(Integer.parseInt(arg1[1]), Integer.parseInt(arg1[1]))); - this.message=""+isOccupied; + return super.check(params); + } + + @Override + public void execute(String[] params) + { + this.outputMessage = "" + GrameManager.findBase(Integer.parseInt(params[0])).isOccupied(new Coordinates(Integer.parseInt(params[1]), Integer.parseInt(params[2]))); + } + + @Override + public String getCommand() + { + return "isinbase"; + } + + @Override + public String getHelpMessage() + { + return "Checks whether Coordinates in a Base are occupied by a Grame object"; + } + + @Override + public String getUsage() + { + return "isoccupied "; } -} + @Override + public int getMaxParams() + { + return 3; + } + + @Override + public int getMinParams() + { + return 3; + } +} diff --git a/src/com/moomoohk/Grame/commands/setVisibleCommand.java b/src/com/moomoohk/Grame/commands/setVisibleCommand.java index 4efa0cb..2916376 100644 --- a/src/com/moomoohk/Grame/commands/setVisibleCommand.java +++ b/src/com/moomoohk/Grame/commands/setVisibleCommand.java @@ -1,25 +1,69 @@ - package com.moomoohk.Grame.commands; +import java.awt.Color; + import com.moomoohk.Grame.Graphics.RenderManager; import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; -public class SetVisibleCommand extends Command +public class SetVisibleCommand extends Command { - public SetVisibleCommand(Console handler, String command, String help, int minParams, int maxParams) + public SetVisibleCommand() { - super(handler, command, help, minParams, maxParams); + super(); + } + + public boolean check(String[] params) + { + try + { + Boolean.parseBoolean(params[0]); + } + catch (Exception e) + { + this.outputMessage = "Only true or false are accepted inputs!"; + this.outputColor = Color.red; + return false; + } + return super.check(params); } @Override - public void execute(Console arg0, String[] arg1) + public void execute(String[] params) { - if(arg1.length==0) + if (params.length == 0) RenderManager.setVisible(!RenderManager.isVisible()); else - RenderManager.setVisible(Boolean.parseBoolean(arg1[0])); + RenderManager.setVisible(Boolean.parseBoolean(params[0])); + } + + @Override + public String getCommand() + { + return "setvisible"; + } + + @Override + public String getHelpMessage() + { + return "Toggles the visibility of the main window"; } -} + @Override + public String getUsage() + { + return "setvisible [true/false]"; + } + + @Override + public int getMaxParams() + { + return 1; + } + + @Override + public int getMinParams() + { + return 0; + } +} diff --git a/src/com/moomoohk/Grame/test/MenuConfiguration.java b/src/com/moomoohk/Grame/test/MenuConfiguration.java index 35d5e86..ff6cb7b 100644 --- a/src/com/moomoohk/Grame/test/MenuConfiguration.java +++ b/src/com/moomoohk/Grame/test/MenuConfiguration.java @@ -4,25 +4,25 @@ public class MenuConfiguration { - public Color menuButtonStartColor = Color.red; - public Color menuButtonEndColor = Color.yellow; + public Color menuButtonStartColor = Color.gray.brighter(); + public Color menuButtonEndColor = Color.darkGray.darker(); public Color menuButtonClickColor = Color.blue; - public Color confirmButtonStartColor = Color.red; - public Color confirmButtonEndColor = Color.yellow; + public Color confirmButtonStartColor = Color.gray.brighter(); + public Color confirmButtonEndColor = Color.darkGray.darker(); public Color confirmButtonClickColor = Color.blue; - public Color cancelButtonStartColor = Color.red; - public Color cancelButtonEndColor = Color.yellow; + public Color cancelButtonStartColor = Color.gray.brighter(); + public Color cancelButtonEndColor = Color.darkGray.darker(); public Color cancelButtonClickColor = Color.blue; - public Color otherButtonStartColor = Color.red; - public Color otherButtonEndColor = Color.yellow; + public Color otherButtonStartColor = Color.gray.brighter(); + public Color otherButtonEndColor = Color.darkGray.darker(); public Color otherButtonClickColor = Color.blue; - public Color quitButtonStartColor = Color.red; - public Color quitButtonEndColor = Color.yellow; + public Color quitButtonStartColor = Color.gray.brighter(); + public Color quitButtonEndColor = Color.red; public Color quitButtonClickColor = Color.blue; - public Color disabledButtonColor = Color.gray; + public Color disabledButtonColor = Color.gray.darker(); } diff --git a/src/com/moomoohk/Grame/test/SaveTest.java b/src/com/moomoohk/Grame/test/SaveTest.java index fa8711f..91f7107 100644 --- a/src/com/moomoohk/Grame/test/SaveTest.java +++ b/src/com/moomoohk/Grame/test/SaveTest.java @@ -1,7 +1,5 @@ package com.moomoohk.Grame.test; -import java.awt.Color; - import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Essentials.Base; import com.moomoohk.Grame.Essentials.GrameManager; @@ -14,10 +12,6 @@ public class SaveTest implements MainGrameClass public static void main(String[] args) { MenuConfiguration menuConfig = new MenuConfiguration(); - menuConfig.menuButtonStartColor = Color.cyan; - menuConfig.menuButtonEndColor = Color.blue; - menuConfig.otherButtonStartColor = Color.green; - menuConfig.otherButtonEndColor = Color.red; GrameUtils.loadBasicCommands(); GrameManager.initialize(new SaveTest(), menuConfig); } @@ -25,7 +19,7 @@ public static void main(String[] args) @Override public void newGame() { - Base b = new Base(30, 30); + Base b = new Base(20, 20); Entity e = new Entity(); e.makePlayer(1, true, b.ID); b.addGrameObject(e, GrameUtils.randomCoordinates(b)); From d66c6b17f5ebd961e2125f2a8abebcda711c80a0 Mon Sep 17 00:00:00 2001 From: Meshulam Silk Date: Sun, 24 Nov 2013 06:06:46 +0200 Subject: [PATCH 04/11] Applied a gaussian blur to the game window when it's paused --- .../Grame/Essentials/GrameManager.java | 3 +- .../Grame/Graphics/GaussianFilter.java | 127 ++++++++++++++++++ .../Grame/Graphics/RenderManager.java | 27 ++-- .../Grame/commands/SetSpeedCommand.java | 67 +++++++++ 4 files changed, 211 insertions(+), 13 deletions(-) create mode 100644 src/com/moomoohk/Grame/Graphics/GaussianFilter.java create mode 100644 src/com/moomoohk/Grame/commands/SetSpeedCommand.java diff --git a/src/com/moomoohk/Grame/Essentials/GrameManager.java b/src/com/moomoohk/Grame/Essentials/GrameManager.java index b27567b..d5da4de 100644 --- a/src/com/moomoohk/Grame/Essentials/GrameManager.java +++ b/src/com/moomoohk/Grame/Essentials/GrameManager.java @@ -1207,12 +1207,13 @@ public void mouseExited(MouseEvent paramMouseEvent) { if (!selectedPanel.equals(savePanel)) savePanel.setBorder(BorderFactory.createLineBorder(Color.black)); + else + savePanel.setBorder(BorderFactory.createMatteBorder(2, 5, 2, 2, Color.gray.darker().darker())); } @Override public void mouseEntered(MouseEvent paramMouseEvent) { - if (!selectedPanel.equals(savePanel)) savePanel.setBorder(BorderFactory.createMatteBorder(2, 5, 2, 2, Color.black)); } diff --git a/src/com/moomoohk/Grame/Graphics/GaussianFilter.java b/src/com/moomoohk/Grame/Graphics/GaussianFilter.java new file mode 100644 index 0000000..9075827 --- /dev/null +++ b/src/com/moomoohk/Grame/Graphics/GaussianFilter.java @@ -0,0 +1,127 @@ +package com.moomoohk.Grame.Graphics; + +import java.awt.image.BufferedImage; +import java.awt.image.Kernel; + +public class GaussianFilter +{ + protected Kernel kernel; + + public GaussianFilter() + { + setRadius(10.0f); + } + + public void setRadius(float radius) + { + kernel = makeKernel(radius); + } + + public BufferedImage filter(BufferedImage src) + { + int width = src.getWidth(); + int height = src.getHeight(); + + int[] inPixels = new int[width * height]; + int[] outPixels = new int[width * height]; + src.getRGB(0, 0, width, height, inPixels, 0, width); + + convolveAndTranspose(kernel, inPixels, outPixels, width, height, true, 1); + convolveAndTranspose(kernel, outPixels, inPixels, height, width, true, 1); + + BufferedImage temp = src; + temp.setRGB(0, 0, width, height, inPixels, 0, width); + return temp; + } + + public static void convolveAndTranspose(Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, boolean alpha, int edgeAction) + { + float[] matrix = kernel.getKernelData(null); + int cols = kernel.getWidth(); + int cols2 = cols / 2; + + for (int y = 0; y < height; y++) + { + int index = y; + int ioffset = y * width; + for (int x = 0; x < width; x++) + { + float r = 0, g = 0, b = 0, a = 0; + int moffset = cols2; + for (int col = -cols2; col <= cols2; col++) + { + float f = matrix[moffset + col]; + + if (f != 0) + { + int ix = x + col; + if (ix < 0) + { + if (edgeAction == 1) + ix = 0; + } + else + if (ix >= width) + { + if (edgeAction == 1) + ix = width - 1; + } + int rgb = inPixels[ioffset + ix]; + a += f * ((rgb >> 24) & 0xff); + r += f * ((rgb >> 16) & 0xff); + g += f * ((rgb >> 8) & 0xff); + b += f * (rgb & 0xff); + } + } + int ia = alpha ? clamp((int) (a + 0.5)) : 0xff; + int ir = clamp((int) (r + 0.5)); + int ig = clamp((int) (g + 0.5)); + int ib = clamp((int) (b + 0.5)); + outPixels[index] = (ia << 24) | (ir << 16) | (ig << 8) | ib; + index += height; + } + } + } + + public static int clamp(int c) + { + if (c < 0) + return 0; + if (c > 255) + return 255; + return c; + } + + public static Kernel makeKernel(float radius) + { + int r = (int) Math.ceil(radius); + int rows = r * 2 + 1; + float[] matrix = new float[rows]; + float sigma = radius / 3; + float sigma22 = 2 * sigma * sigma; + float sigmaPi2 = 2 * (float) Math.PI * sigma; + float sqrtSigmaPi2 = (float) Math.sqrt(sigmaPi2); + float radius2 = radius * radius; + float total = 0; + int index = 0; + for (int row = -r; row <= r; row++) + { + float distance = row * row; + if (distance > radius2) + matrix[index] = 0; + else + matrix[index] = (float) Math.exp(-(distance) / sigma22) / sqrtSigmaPi2; + total += matrix[index]; + index++; + } + for (int i = 0; i < rows; i++) + matrix[i] /= total; + + return new Kernel(rows, 1, matrix); + } + + public String toString() + { + return "Blur/Gaussian Blur..."; + } +} \ No newline at end of file diff --git a/src/com/moomoohk/Grame/Graphics/RenderManager.java b/src/com/moomoohk/Grame/Graphics/RenderManager.java index e1ce7ad..35a173c 100644 --- a/src/com/moomoohk/Grame/Graphics/RenderManager.java +++ b/src/com/moomoohk/Grame/Graphics/RenderManager.java @@ -106,7 +106,6 @@ public static void render(final int bID, Render render) return; } Graphics g = bs.getDrawGraphics(); - g.drawImage(img, 0, 0, mainCanvas.getWidth(), mainCanvas.getHeight(), null); g.setFont(new Font("LucidaTypewriter", 1, 8)); int squaresize = mainCanvas.getWidth() / GrameManager.findBase(bID).getColumns(); //FIXME: Nullpointer @@ -122,6 +121,8 @@ public static void render(final int bID, Render render) } if (GrameManager.paused) { + g.drawImage(new GaussianFilter().filter(img), 0, 0, mainCanvas.getWidth(), mainCanvas.getHeight(), null); + Graphics2D g2 = (Graphics2D) g.create(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); @@ -140,20 +141,22 @@ public static void render(final int bID, Render render) g2.setColor(Color.black); g2.fillRoundRect((int) back.getX(), (int) back.getY(), (int) back.getWidth(), (int) back.getHeight(), (inPadRight + inPadLeft) / 2, (inPadUp + inPadDown) / 2); g2.setColor(new Color(255, 255, 255, 200)); - g2.drawString(text, (int) (fixed.getX()), (int) (fixed.getY()+Math.max(fm.getMaxAscent(), fm.getMaxDescent()))); - -// g2.setColor(Color.cyan); -// g2.draw(new Ellipse2D.Double(textCenterX - 5, textCenterY - 5, 10, 10)); -// g2.setColor(Color.blue); -// g2.draw(back); -// g2.setColor(Color.green); -// g2.draw(textBounds); -// g2.setColor(Color.red); -// g2.draw(fixed); -// g2.fill(new Ellipse2D.Double(fixed.getCenterX() - 2, fixed.getCenterY() - 2, 4, 4)); + g2.drawString(text, (int) (fixed.getX()), (int) (fixed.getY() + Math.max(fm.getMaxAscent(), fm.getMaxDescent()))); + + // g2.setColor(Color.cyan); + // g2.draw(new Ellipse2D.Double(textCenterX - 5, textCenterY - 5, 10, 10)); + // g2.setColor(Color.blue); + // g2.draw(back); + // g2.setColor(Color.green); + // g2.draw(textBounds); + // g2.setColor(Color.red); + // g2.draw(fixed); + // g2.fill(new Ellipse2D.Double(fixed.getCenterX() - 2, fixed.getCenterY() - 2, 4, 4)); g2.dispose(); } + else + g.drawImage(img, 0, 0, mainCanvas.getWidth(), mainCanvas.getHeight(), null); if (drawCoordinates) { diff --git a/src/com/moomoohk/Grame/commands/SetSpeedCommand.java b/src/com/moomoohk/Grame/commands/SetSpeedCommand.java new file mode 100644 index 0000000..8d02a14 --- /dev/null +++ b/src/com/moomoohk/Grame/commands/SetSpeedCommand.java @@ -0,0 +1,67 @@ +package com.moomoohk.Grame.commands; + +import java.awt.Color; + +import com.moomoohk.Grame.Essentials.GrameManager; +import com.moomoohk.MooCommands.Command; + +public class SetSpeedCommand extends Command +{ + + public SetSpeedCommand() + { + super(); + } + + public boolean check(String[] params) + { + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) + { + this.outputMessage = "Grame Object with ID:" + params[0] + " does not exist!"; + this.outputColor = Color.red; + return false; + } + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) + { + this.outputMessage = "Base with ID:" + params[1] + " does not exist!"; + this.outputColor = Color.red; + return false; + } + return super.check(params); + } + @Override + public void execute(String[] params) + { + GrameManager.findGrameObject(Integer.parseInt(params[0])).setSpeed(Integer.parseInt(params[1])); + } + + @Override + public String getCommand() + { + return "setspeed"; + } + + @Override + public String getHelpMessage() + { + return "Sets the speed of a specified Grame Object in a specified Base"; + } + + @Override + public String getUsage() + { + return "setspeed "; + } + + @Override + public int getMaxParams() + { + return 2; + } + + @Override + public int getMinParams() + { + return 2; + } +} From 79ae8e7e1e75e095530aa0e6727f3543e9ae7353 Mon Sep 17 00:00:00 2001 From: Meshulam Silk Date: Sun, 24 Nov 2013 07:20:13 +0200 Subject: [PATCH 05/11] Started rewriting Entity class - Fixed .gitignore --- .DS_Store | Bin 6148 -> 6148 bytes .classpath | 2 +- .gitignore | 2 + .settings/org.eclipse.jdt.core.prefs | 8 +- .../moomoohk/Grame/AI/PlayerMovementAI.class | Bin 2811 -> 0 bytes bin/com/moomoohk/Grame/Essentials/Base.class | Bin 8808 -> 0 bytes .../Grame/Essentials/ColorLayer.class | Bin 2402 -> 0 bytes .../Grame/Essentials/Coordinates.class | Bin 3835 -> 0 bytes .../Grame/Essentials/CrashManager$1.class | Bin 1038 -> 0 bytes .../Grame/Essentials/CrashManager$2.class | Bin 747 -> 0 bytes .../Grame/Essentials/CrashManager$3$1.class | Bin 964 -> 0 bytes .../Grame/Essentials/CrashManager$3.class | Bin 2033 -> 0 bytes .../Grame/Essentials/CrashManager$4.class | Bin 1150 -> 0 bytes .../Grame/Essentials/CrashManager$5.class | Bin 1041 -> 0 bytes .../Grame/Essentials/CrashManager$6.class | Bin 1166 -> 0 bytes .../Grame/Essentials/CrashManager$7.class | Bin 1299 -> 0 bytes .../Grame/Essentials/CrashManager$8.class | Bin 2752 -> 0 bytes .../Essentials/CrashManager$Emailer$1$1.class | Bin 1048 -> 0 bytes .../Essentials/CrashManager$Emailer$1.class | Bin 2576 -> 0 bytes .../Essentials/CrashManager$Emailer$2.class | Bin 3799 -> 0 bytes .../Essentials/CrashManager$Emailer$3.class | Bin 968 -> 0 bytes .../Essentials/CrashManager$Emailer.class | Bin 5233 -> 0 bytes .../Grame/Essentials/CrashManager.class | Bin 11266 -> 0 bytes .../Grame/Essentials/GrameManager$1.class | Bin 1133 -> 0 bytes .../Grame/Essentials/GrameManager.class | Bin 14473 -> 0 bytes .../Grame/Essentials/GrameObjectLayer.class | Bin 3070 -> 0 bytes .../Grame/Essentials/GrameUtils$1.class | Bin 2258 -> 0 bytes .../Grame/Essentials/GrameUtils.class | Bin 15010 -> 0 bytes .../Grame/Essentials/InputHandler.class | Bin 2011 -> 0 bytes .../moomoohk/Grame/Graphics/GridRender.class | Bin 1674 -> 0 bytes .../Grame/Graphics/PlainGridRender.class | Bin 2044 -> 0 bytes .../Grame/Graphics/RandomRender.class | Bin 924 -> 0 bytes .../Grame/Graphics/RenderManager.class | Bin 10028 -> 0 bytes .../Grame/Interfaces/EntityGenerator.class | Bin 200 -> 0 bytes .../Grame/Interfaces/GrameObject.class | Bin 2932 -> 0 bytes .../Grame/Interfaces/MovementAI.class | Bin 2940 -> 0 bytes .../moomoohk/Grame/Interfaces/Render.class | Bin 231 -> 0 bytes .../Grame/AI/AStarPathfindingMovementAI.java | 7 +- src/com/moomoohk/Grame/Basics/Entity.java | 312 +++---------- src/com/moomoohk/Grame/Basics/OldEntity.java | 416 ++++++++++++++++++ .../Grame/Essentials/GrameManager.java | 4 +- .../moomoohk/Grame/Essentials/GrameUtils.java | 2 + .../Grame/Interfaces/EntityGenerator.java | 4 +- .../Grame/commands/AddEntityAICommand.java | 2 +- .../Grame/commands/AddGrameObjectCommand.java | 2 +- .../Grame/commands/ClearEntityAI.java | 8 +- .../Grame/commands/CreateEntityCommand.java | 5 +- .../commands/DrawCoordinatesCommand.java | 2 +- .../Grame/commands/MakePlayerCommand.java | 12 +- .../commands/MoveGrameObjectCommand.java | 2 +- .../Grame/commands/PrintEntityAICommand.java | 8 +- .../Grame/commands/RenderBaseCommand.java | 2 +- .../commands/SetEntityOverrideAICommand.java | 8 +- .../Grame/commands/SetSpeedCommand.java | 2 +- .../Grame/commands/SetSpriteCommand.java | 2 +- .../Grame/commands/SetWraparoundCommand.java | 8 +- .../Grame/commands/isOccupiedCommand.java | 2 +- .../Grame/commands/setVisibleCommand.java | 2 +- src/com/moomoohk/Grame/test/AISystemTest.java | 16 +- src/com/moomoohk/Grame/test/ConsumeTest.java | 4 +- .../moomoohk/Grame/test/GrameObjectsTest.java | 4 +- src/com/moomoohk/Grame/test/SaveTest.java | 1 + src/com/moomoohk/Grame/test/TestScript.java | 6 +- 63 files changed, 536 insertions(+), 319 deletions(-) delete mode 100644 bin/com/moomoohk/Grame/AI/PlayerMovementAI.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/Base.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/ColorLayer.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/Coordinates.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager$1.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager$2.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager$3$1.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager$3.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager$4.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager$5.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager$6.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager$7.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager$8.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer$1$1.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer$1.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer$2.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer$3.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/CrashManager.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/GrameManager$1.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/GrameManager.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/GrameObjectLayer.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/GrameUtils$1.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/GrameUtils.class delete mode 100644 bin/com/moomoohk/Grame/Essentials/InputHandler.class delete mode 100644 bin/com/moomoohk/Grame/Graphics/GridRender.class delete mode 100644 bin/com/moomoohk/Grame/Graphics/PlainGridRender.class delete mode 100644 bin/com/moomoohk/Grame/Graphics/RandomRender.class delete mode 100644 bin/com/moomoohk/Grame/Graphics/RenderManager.class delete mode 100644 bin/com/moomoohk/Grame/Interfaces/EntityGenerator.class delete mode 100644 bin/com/moomoohk/Grame/Interfaces/GrameObject.class delete mode 100644 bin/com/moomoohk/Grame/Interfaces/MovementAI.class delete mode 100644 bin/com/moomoohk/Grame/Interfaces/Render.class create mode 100644 src/com/moomoohk/Grame/Basics/OldEntity.java diff --git a/.DS_Store b/.DS_Store index 92ac62ffb1f5db1a4fa4b353db155bf42f5df462..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 100644 GIT binary patch delta 70 zcmZoMXfc=|#>AjHu~2NHo+1YW5HK<@2y9-+n8vnw1EUw?W_AvK4xj>{$am(+{342+ UKzW7)kiy9(Jj$D6L{=~Z04H+~3jhEB delta 222 zcmZoMXfc=|#>B`mF;Q%yo}wrd0|Nsi1A_oVl22)INfD5z%Mdy-ad|yRf|((SA(J7m zpafZxp_n0+p$JIoGx!2o#S9q?r3^U?i43_6!9dkH4B0>#7lwR>WT1F1P(>a?30QSG zP^<_jTg*@ZRGkcz(PwZ6ihy*2*vR(z@j+b!b;8EPe74C3A}pJ^Ik-81uHTsWoq009 Uh$1V - + diff --git a/.gitignore b/.gitignore index 1692932..839d7ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ bin/* +bin/ +*.class JavaDoc/* *.class \ No newline at end of file diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 66fa003..2487c9b 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,6 +1,10 @@ -#Sun Apr 07 19:12:34 IDT 2013 +#Sun Nov 24 07:00:48 IST 2013 eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.autoboxing=ignore org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning org.eclipse.jdt.core.compiler.problem.deadCode=warning @@ -9,6 +13,7 @@ org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled org.eclipse.jdt.core.compiler.problem.discouragedReference=warning org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore @@ -65,3 +70,4 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disa org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/bin/com/moomoohk/Grame/AI/PlayerMovementAI.class b/bin/com/moomoohk/Grame/AI/PlayerMovementAI.class deleted file mode 100644 index 726b3347b9d03dffc4993856bf2447deb7ef9039..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2811 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 diff --git a/bin/com/moomoohk/Grame/Essentials/ColorLayer.class b/bin/com/moomoohk/Grame/Essentials/ColorLayer.class deleted file mode 100644 index bd9cb32afad3f5f3c0728e57f9f738c61e995127..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2402 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 F`#)U6K6C&8 diff --git a/bin/com/moomoohk/Grame/Essentials/CrashManager$1.class b/bin/com/moomoohk/Grame/Essentials/CrashManager$1.class deleted file mode 100644 index fed24242eec38865eba9463e3af84e15e68354e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1038 zcmb7DT~8B16g@**R_Y=jiYTC>qLzwX5kFJoOR1)$C`q9vz76d_SGGIN>|z^V{4u`r zVq!4y!5`p{GM?EsSRPDtv%7O==FU0yo_pu#ukSwqJis#tBLXW8-S*mA^KBh?uZ(Of zuN*}xjC~nIUdhO)wJAfnugub_gS5cRd-*~3yr}Dk``*U3>cv|!R05NcGCWgPCh~Q- zQ&|@f8v^4c9Y(PX8fs!K$3>@!D2dY`H?`O`ag*j1s3;JTx%E|1PPdtjf1G}t8Pb|_^scJ zTS;K=vJklFViuPKGCZ{SBFLD1ai-_LhMwESEY;~<7dNrQkh}d< zM8zg@+r=H^1ja14G(=`{gJhE9tW_*2yI~%AtT?zk41Tif;vNbDj+HQp{1nKa2wDAF zOkp==XHczdO&^+udgCuzBTCrn|QGlBECz`q4}LqH3#kUz!@zsp~7 zjl->DEYtdoO!_Ew#QhX3t_=kEG=#Y@!1NLyF-OPyG)J(?+YSb>hDUfx%eI0&%;z^9 Cv;PbL diff --git a/bin/com/moomoohk/Grame/Essentials/CrashManager$2.class b/bin/com/moomoohk/Grame/Essentials/CrashManager$2.class deleted file mode 100644 index 00a7880be1667f3385deb737bfa7e91102cf6ba0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 747 zcmb7CU2oGc6g_U!1wzI?fbq34U_5jaTBPwbsko#v`$j<9+ZCcz_?n z6Nm?X06z+Gl2!;1LJ--$zSsAjoa5`S-#&iErGk4EtAq(j{H^f#K}@6gQ`-- zYgtrD-^nUJkVa0GyR#P}5LiBx$1*9TnI_N1hbr?S76dk$s66qBI%aY5DD&EyR99XZ z!O4+cKh zmB4QLKeT&cgPMMCdlcaUE`_-Gi{RlK>M3Ka;W9O-Q|)QG z`?VrL%IklF6o`iQ$YtuWuH~)#e6_nZ6|x+dtgw|f(*xymI|*?^VCUbZ#<+=F0*h5{ zPX?!%dR_N`2y>}T&wj*vGqO!^=pBDb)dKOpVZ-``=nJU+})!U zw4I%gh(0vOG1sU`dy9aFi}d4J63%0Z9xoFsTx);_v^8X>{RykT1H2=^`vzcbmNW-o eIS2z*EE_Dh#`+o+J~kY33)%Tf-+J8I+|^ zR`Q}u`i7VJ9#?!UO#CeFhNv<$kNFu-3a-Y<{^(ewHbjjf_9#EMNyaU=hO6>On519G z=}2>v?Vl@Q7-}|`W!$C6!(~GEi1|V)XFgO;b?GxaSt^6LOX;r^y0l(|GM7_^cb(yX z6zeT;IGAbc((1X~SErl`ccC=H)&k~*3+2=Dr1`g~h6{M}UPNtt(x)aBZ={o{HQyt< z?n@-*K&A9usm6Q4<~j?p!SHyQdPms81A2(3R%-Q8m?Lc_B4gN?lTDmapC+%p%fOwz z8qs@2oz^cnwQ-3}s(C=`5?Hh8N>9ySp;bqN&?|I$PPRiDJCD90+WC&vuimHSFn{CN zpV1~eB923^;u`G?*KuR^$}6%1hy5ehyz>`N-28hvBRc9$-17Gfw{eHU1h`A|3hv=P V?NzK(>JRDECTyK{H(YQUe*o=R`&R$} diff --git a/bin/com/moomoohk/Grame/Essentials/CrashManager$3.class b/bin/com/moomoohk/Grame/Essentials/CrashManager$3.class deleted file mode 100644 index 11b1a5b8c7dcec8a22d910dc1a5d75f34fe6f052..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2033 zcmb7FYgZFT7=DIC7s4tSZ`Eo=jcpQWwn(Yes8y1H*hFX((qgZ}W*`fjUEG}j{*8WU zPruY&enER`VuzVAHm?U}#+{^L&o*RiQ#fMLRPYevm= z=~vw}<~?2$M$Y$zBQ0+GM#kfQwZI*|F1*;3hA_kE2H)m}&7E~)adktOQo~V(i@_@2 zk%rhNW#gVHE!W9gz7&q|7>2jG9jgi7Crb>`e8)&pdX}@EW*Af=kL#9XI34Wo8vYJ# z84qUbQo0U_9KB^Zmb}A|jQ`uhfjWsYLpbAB#1I%pbZ8h$YrdFr11fnpM;#PM#(4j*dxOr!pm_;u9+2TE@1vR$cB< z#;$g2Rk-BR3Jfkg?*6=RFwRTJNNHy!dC~RsSYLN)0@Sdu{8&viO#3WJH@IIB= z%R|%Kr?JThW{_4^Z!t{9Uy(DqcvJ_R8#-89`K8*;Pg);&|qS&H~hbeBa+okskXb4=UyiHZtBR^5t@byOLS z`Bir(w`+3b%_2)FfbZbgmc!tsBb3}g)1W(gD5-5<9_y%Wat`tceXYm@1 z6m*<#nfhKGM{5hw*MGysJzU*Gq5_bK>^1q k!3)78{Q*=UXbe;NtihtM^Ffs8gPxh@Ko>;}8+XtB18=b{$p8QV diff --git a/bin/com/moomoohk/Grame/Essentials/CrashManager$4.class b/bin/com/moomoohk/Grame/Essentials/CrashManager$4.class deleted file mode 100644 index 99fd06f1bb606295d2dbe138dc587d3a1911f2e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmbVMU2oGc6g_UcrOm>c6&MUQR-i!JjbwZy6(L}h2`Pn1V|{m1(`F>`#eb{;3GoOK>WRAM=nWf5@C7s|4%0#0FG!)b;ahto(k*^E6usM-aVa!0x15h=njGm2;>_9VfZ zq3g>;yOxOivTI-kSIB-*U+y+vx?(%=I8hz#z>j!iyors+A$<_5K6yfr35`)rNei+v zjR`Qblz5!J)C`RRbc#;V+ihAW5xu_j5k~zJrr)J!W|COClVra_iPi??B+;WdMl%@^ zvqKbTh+>vbyvN)g7V95i?BT)z)->?|UK4{iDB^93H=E*{Lp;Dl9ZQ6m#WJ1E;4&qm@iHRa7-b zr8bcb6D?)Z)YoJxw^cU9jJ&|L9l0-~hD^7kH=8>uwgq$vO!%lgu#wtlaGi zs#IkHUC)y=u`dL2rSgVAeo1es06FxAD4<(lpq8ZSb*s6lvbS=xp#+LG9m~ds%o4Y5 z2lKX`7=hW^|FEtI^nCDiw6Ow{rP`mkRvqn1c_Y9OZWM4`VEW&Sgc!z%K(~xzWz5vP zz(}d=%N$1LAYrRkU$(5(X(hlI#tXP9FyvTV*$y#*Tcn$qYU-}NoawIP(6&*o=tR0DcYL(sXLEX&Y1b&y3Ghe{dkR6DQ9k}Avwl|O=A!Fb#mx){5Wo0 z_0U_O6||kxCkQ^%=|ISTKnr|Ao|}F2!m~r@#{gHHe+=^P0N&HOvty?y9%J+f#Zyck z&3Vv%U;7J+;6a>t;Ni36HZWl@jmLzX@mXS&?vwLciwwG2;(}-w4*=gT eVTp4rw#;MYFzXW|%+cmKNAq|_FJP|A=JN|gHtt>k diff --git a/bin/com/moomoohk/Grame/Essentials/CrashManager$6.class b/bin/com/moomoohk/Grame/Essentials/CrashManager$6.class deleted file mode 100644 index 06ff2361e5d3a6ed06fe1586d794948ebc16e03d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1166 zcmb7EOH&g;5dNA37Q!L|hKE6Xp(cndh~OjW!5Ap5pq5x1yba5cEF?R)GXegJKf?=B z9xM-*mLB{`mOY#BN?DesvNJtB-Cw`H-5m0#DT zKpPp#h|sYRgn@ZPNMv)Xgk(Xj%M=pmcHy9t&|3;Z`Mh3RlhJFjR+WVQlJZ4$RYZY3 zHoG!Y! zgv-YF&6CrImA_5b1=?bJQX6ob#WaxxFuz2UMXc>ijccK(h78V#aKDqbTC0k zpTasca50Hn%nB{d6S*PkRnw@GFx+T!OM!8NN8q`bwu5&g`L-^#iTT3B5K(!Wkon7i z2t6xC_*=_jyUB{Kc)BH}4S~3r)QYM{zFZ6}kNQqhc*>T*Y%7L-RcW5evNRR7?&1NM zB|W;Lc8hzy+%|y;@$un2Q8Rs!>}<6Ye2J;@Zlj|G-e>}$RG_Z#WS6i5I7 diff --git a/bin/com/moomoohk/Grame/Essentials/CrashManager$7.class b/bin/com/moomoohk/Grame/Essentials/CrashManager$7.class deleted file mode 100644 index 58e0451ccd42af48e76a5a24b4cd18304581bdec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1299 zcmb7DT~pIg5IwgI1kwPddLl`xtqOb&+eYxe*N|N3xH`nQ4wR9Fx{F_b6xsXw~gl> zuL+~*`@#tE;hR!{1r{7t^E;9_3B=W%U_bp<0u_g|JC3#a|=#a3o>j;K{R@AfIAaEUm zw9i?N6)Z4JWm*wuJgxpHGP};8EV^aU35FgWDmtXqtD_T|hB*3kB+$Xodu_z7@9Mz9?(BhU+TE7zWRmTgMIDWKb(2kkT>qXR;0MaI&j` zN8>4IxP?0^ZZqWmy+s`vWT{DRn!@+fvoy`9$!6;8hK6xWs+ee5sYYTQc^EWpTR4@V z8ctI__hJLGwjWbmWLgTP3p*YPcG3b9;sFL{rm9r#BvzCNbKo zyX%=^$&y3vZC>}h%tEVBbWGdzNsSc|RNbfs*nvM(NFP<&>gM7)g=O9ijUK zS3eS3n)svK w59qE9@exg>GGo!1CKuV2Ym3dB<+&5eDuNpq|1FyQb}nABx@#f&Ypet+2`APe|!G?`?uc#9L3if z+8BoNUL{@eJi1Ed^rX)#BAp2W;f6MMg7mo0gVHp2c~SWNCp1JEx^D7Co_4rfOkd31 z6!}oYR)+mb%9p~lSfs`2v-!~W+^ijh!WBNlmPPLL7Z`f7QgJyQEZJn>`~>ad6-OA_ z)q7hw7Q?RfI&)$F~pT(!93>^{l8R)<+hDbs#>de}%n5k8A!k^)2n9RG}r#Yl2K29vPM zRJiRBNU2n+9S6~`;U$J+Pu^T*#Ffx?g8u0S>{$x1W8h^RqNq+}#;!~<9Dm9Y{=>?M zjsylZBpDLV>V|>C7^0o46z-5A+dR3-$7T*Zr!&cU9Vr~qkfs=KlBEV-!BGZ15aGNX z*eb5k#5K9>HN39j7(?&6W&h@uf#W#ApcO?ZWenYkQDGrx>Lru46UZv81t6c-z2b z%o3tR2Q_h#c;!&*F&exyvMI(hxFTzHB8IDsYFEE3s?KdQ^iG*NX0Tx38m<%4yjm45 zRn~B;-DZAmwA*xz@_7_D47?|!y@v5gY4-yITnR(3VI+n;!`?OG4f2v_b6z-Flr@?n zh+`nyFf7jvOFUneOc6toGKa{oRC9QxRDPtZV-mJJ)lG)w#8cA0H62DaX5sTmR25`E zywHIP#jX{#%Qe@PtVcYgBLmMsRZ``aAmn}+gU{IE>vMEIlP>O>ycT*D9tz8B@_fpi zDwwyunpxtD!gM{;wgfkqN<1_rENWTKtA#^m*>)`orez1dD01IwycZJE8~R*{yXC+n z$~39HS;T{;?Ml18sn9p65vBC00mm^zUuJ|^u$Re#Fmtt{nd1R@#IBA<-ks@c9R=um;QrW|(2NUbWT(y-ch$W(heB2*^JuD6uZ^gBEK{zETQ%y{kCpOT4P2uh#{J?EhJB6DZr&rPJt&+S zg}%PEHe|$0MvDqDVaIGpsX5K7&3>lO5}0{$&Xyf-M{Ay?WGz$U%D8#Q3kdpY5tcm5 zz~_>UbYg?EmgN&8(H>JSeK05<5H!`A6hbdr`wvWNzY)5(Akr0=of)7f^=0*>u1w!J zZFF~FJ85;&XpH7jdUg*Uet@pQp$CW$4nLsj3VMH5+PmprSF30Ri(wDV4O&fWuowI2 zN#8kmp<$1Wk*>7&Q~ba$cySd2gTJCHQpYeo<8{1R$I0)}(VVQ}&4lvb!W}!##XT&nU6yXZV6fdsJ*`K)*?nen~n9>09Be(cS+5BV_$^ diff --git a/bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer$1$1.class b/bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer$1$1.class deleted file mode 100644 index 3d839fd922f0fb2da505461ce96dfecb0da47421..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1048 zcmbVL+iuf95IvKGx-o{Nr4%SFEnsMpLQNxtih@8W3KdccNK|>>I7_m{UZb^BK86SQ z1s=GF2R?w0Ld-gmxCo(=m95#C**Uv&_UyOsU%mopB5+V3+zFF7h?9iB(aT`Zh*$=l zG?hA2B1(g{5$R}OXfc$=@5DkyYgA0Vl@hS9h5vzoG5r#5N{ab{kT79xleuW1kBgLTQ;u1C- ztp9eslbnakmY%ZGnKWknDq|Lf88Xu9zs^f=pC@Az%15jo!oshb+O~Z%1sxqmNvia4 zUuL6Z;Gjmhef-{jO4CClzd|$C1n;qC$+aWFf=(UWBsBjYli*B+j}4Yfk^d8*YSpTS zA5ww;GF*F!HsUt6KEP{y!s++Z H2p&HG^R5c2 diff --git a/bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer$1.class b/bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer$1.class deleted file mode 100644 index 98366e802e96490096fbdc7bbc63f02df77cc60a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2576 zcmb_dTUQ%Z6#h1WCX7c3sin0Qtu-PEl>ogP6oyV_=*$G#dZ}7{ z_sIu+toLiHHLzqYe}E7E1OI{VE`4yhPi7VYRv#ow7Fp-a-skMw_np0e{paUj0QBL# zC>jWd3r;Chavc7jzmz%S%96?qd7iR;Q(9go>q>8aOxkizxyhlDG%a3xqi7_=7vz%6 zSkj)$jL$Bpf*-{WLZT*}EZer6wG?58KW}=;UiOyTzPo zDXL}=?iGk4W*~wVfo8-BkxqS}C1={|T)8x>-02|dM9wKlD=%GBe}}?GoeJS-9dRUk zIhBZ8wxifh*r^M3CF3odT)@$RvhO=~3=eR!S!oxPWuOiFbc7EQc6H`zWu5X}zS5t{ zNAVB`vi*W4dy~Be+Oc0-e}r(No}zLxsl1NyQGp~LBecq5@pQpA9Xn@wzOt1|I1t7y zm;H=dVoqf?pQtAB_|{qsGV`1{1085FkjB9%x(I#S&r{$DbQ5B-P*9$i>>=dp$+W*( z`*oy(=&H%5(Ie1{zM2oF_}RLAr0(h@hQkD7O4&t5yt}(w*W{?cG0lmXr~GNtx0Dv1 z5O@;IE-f5$iqc}jcV5r{b>Jz1Q(7ljH>o`Hnr5?BJR@)#1B5-S7*rQ!+48fNv(b;`bhtcIuqX9S+b2%(uR1uDY64cG^=u#HqfKO1(6 z^|DS#TXTLCW15vC8u)R637oGLm+M?#aW~ht>ZuyU6z9I_6;8O$oXcDpkgkErfPQ&_ z=kY=!!?W?7yjVgh{R4U)J1R z5?IC+?y;J?-0(H=CzZwPlA3l1yYCuR@U%*tO`+PY`Tk~ngNCky;xOHU8s^E#O>*Nr z?bh7m!82qR_}TFbA5;FkQxw>xr;-@4xrb&g$-~%-;$1@ezqdfnHyqa3&oeK=za~&T zu16ma{|5dw!(iz>ygSa{T4JQTeu7A^;J(|{Gp$-y)$ncl5DESkd`C-n;(lH^Ys3R9 zbb~#x6^g8(Z6>j21$%Q{YiOTgdkxx0OVS^5&o^cCKxukitWgPZg%ZqavGqwnz>-NNs58-LIb_>+F52D(#) xp)DwN2!nyYa1F0B5D~n=ur%OJyv1uHKj`atn|FIzlg2x^!8#3~{%a4Ge*t8K%Ju*N diff --git a/bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer$2.class b/bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer$2.class deleted file mode 100644 index 7e24bb2b881a452d543f9ba6d0d01cd64c6fa00a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3799 zcmbtXdw3jG76092+u2NSNmxUmMP(>KH`_ET0ou}3XqzT&U_(kbjkZ;BcJ{J6?d;4l zGn@HWYi0qK(3EMYy%gYYBx>p|6 zZM`Ji?xBiqS~T`6NHBC9(kJz-rQ4fDg3JkYLo4&XYucs7 z?L5*o9h;#uzFj_)lG4hprfvEcGhCBC8KdKyHnnlNVeuu4cJxdzBnF+LXamEGI20u1 z>@JPfnH=qSF+*!wE^p77wz#}jDF}Bw3`Z*G7`io~yQX}O zgb5iVhK(n2+3tSwSF2mI6`aFxPP6EYL}A)qEV|@k73bpR3SP$0|H1*mkwyiIwAei(;C1g6hFLW!dB$g|g5x~& zGqjA4F|3ORx2g7kiVLt&!G#QG#ddCn9ga=d%)s?xv2h^7MWMY>UNk==ZbcM|fu4yZ zwlK5>sjgX0NgA@1El6)EzJz0&6e}bi7t?+cI|!d%#jmQ^iD3mp5d%b4 zL@?&qh23OuiB`F~?NuGuXUH^jaNNR%?m!ZkGMpmM=_|>!?<3Sm4COdR<5<`vg<~9h z;=;`;_F`N?o^n0r*~ac1`#^c37>;cdjWs-Z0&6VC!g5K^g!Iv?IrifK@gv=KyJa;Z zM9Fn}y60g0f{P)L2EK;lwRjzI9dU0liXKC6v!D(%-9(dREbXYYLza=u;DqQ-o!)-yvx9Pq*XpgO`e@3F7-u-ZwI(EKsQ5T;S8&@R zs!v?N@ri)h0+(4-%0Ahkvgn4xvN=+51ZO7kX@-0APDN1Bv`bpSbq)({s!Tbg`RM$w9giGu|4w) z*^Lz(f7=oXj=7qrPe!ZcCeitNNjGiH(y2S@OX4m9+rF|kR#tHj?p5%ah!q;)84EId zk8V@dx)1j=oa&XGsVG~*&@ya|aH>!F*+HjLb!@7112G;9`@py)>bXW_gpcC$3O+}? z|NLnZZ#gAazYy?dM4M44cGP^|u_?yKsBlFw-a_2<04`B5_iXHi+Vbr@$HF22hl1v` zDD8TP z!8}>$I}y_}oEzu=MsXiGu|1-8s?A?2lwI*Pjj}~bj0ikJf6#|FD4O1_4$^*9uSWfy zns;ihA%+Q~6y3O!`y|K9N?^;HK~NecSUW|IvxDo8P*rpXEuDT8Pzh6_9|7c-IF~B; zaU)%VzPwQxRyPWu?1`XJr`k%N6-ab+$aWU!NXce47^#&FMrvf~H%beA+R;JUr_yXU zJ+Gi~ZD#!(QkmX4bY?cpp)0c{F^4lU^H@6@ta%B2tHD}w4toMGrDsli&`O*|=Y!^S zvv5~-BNAi}@RQ?Mw?Fd$QVZywMwJm!?v)vyNBQaj>_JEAPQ%?l=njQ^k2)MZ1>jsHCo@uR6SAm|Vb{ zNci?}i)&l!cy~0dnmV9!!Ko z9ba0&SLosEv$MgyucYc(rdvwS96%R2;HPM3Kf_w~b86V1Mjv~I`pI7)$9{=}>{lqT zUsK=k8!A!1#kK5rxQYE9x3WLr4)#aPvOnQL_Gdi8{(?u@U-3Bm8=ho;$5ZSdfu}R% zPx5Bu>2~Dt4SbWV*o+Lmg-0na23&j_-yzv!q`3+$|3pDS`ClY%#dk^6g74vR8WU8l izKJiZEL6<{}G-<+kXJi`(nTV diff --git a/bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer$3.class b/bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer$3.class deleted file mode 100644 index 2b6011df2e21ce79b7b7bf334806e82e20b6dcf5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 968 zcmbVKO>Yx15Pg$fy3KZJ)0C!se+Edlz={?DQW2LBD3G=ipd7e48!K_yc+q+T{4FFX zhyy=>zrz8zAjV;(_P~KgvSs^u=K1-}eEa?7D}Xgz_fR6-iqlavN>d)gSJ9(PjAYa{ zM(SLN#6+!3nBkVtVj#16dn8oC>$(S*P}vo4M3e|Uh<19rGR{5B5UTs=v$58qmq@}) zK2)ZDlV9r`{<#g#zo)dy?-TAcrXgr{32rOx%Q6T@19+JA;b0*^85M%lumKAlrRDZ` z)RWnZzpAU9G!{u$WXhfk(6wJ7+@3;5eVxDJWMl1P1t&ZlC#)UbjsPcdiZCnUSel8c zPp31bV=MJ8GH(@E@W}%%cRJYcaR%o+oFy#%<2t~3Tp;*H=3Qmfq_%G3WwUG3E(NGt zJH5U#uT#Ti_n)WZES3+sX$Xr4Tj_=+XV2R@PEx}Hwq!m``vI0ML-1H@nY9wZeP}$a z62kxYi3JpW%3|4Xo<~5Himf{LeTiooKBIHIyUS;b_~GhD1mP#lzn{b`T5NK|+4LP% zJ_np*(Ip(?m8{f)Ws@WAT`l~8;4^B@9!?kAJzU&poM$zlADE+`Sf*bGSZf8VgUifQ Y!WCTQ)#W~Epvk)`V=D-8t$2x{KUF{TmjD0& diff --git a/bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer.class b/bin/com/moomoohk/Grame/Essentials/CrashManager$Emailer.class deleted file mode 100644 index 2466b1737557c2fb25381b6845e5a0fcccdc92c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5233 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 diff --git a/bin/com/moomoohk/Grame/Essentials/GrameManager.class b/bin/com/moomoohk/Grame/Essentials/GrameManager.class deleted file mode 100644 index 02839e8b577223347c7a79a3228bf749aa977a87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14473 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 diff --git a/bin/com/moomoohk/Grame/Essentials/GrameObjectLayer.class b/bin/com/moomoohk/Grame/Essentials/GrameObjectLayer.class deleted file mode 100644 index eeb54859da46a5ac07344723cb56a3061c092f07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3070 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 diff --git a/bin/com/moomoohk/Grame/Graphics/PlainGridRender.class b/bin/com/moomoohk/Grame/Graphics/PlainGridRender.class deleted file mode 100644 index 831b7042b2880b43f1e6a8774228f46147677874..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2044 zcmb7FT~ixX7=8{U*$}s-P*SCZQYh9?KB9<-&{~C3OiKYt8%t?RH_4JLY<9!$hL2u2 z<4mu;(hD!_3^UF!y{ldX$Ikcz{2%^_PRIJ3P0(PYj5FCiXW#R@U(frVH^2Sy%dY^2 zv7?|tpg&_5;sx90FTWn2akPRi-^IL_x+9{%1;eT*J0*C$0*J z>jKB7Y|HgD%S&lyNe{Ms|LFIT@v$!jLYEB7@IDr3jP<1i0#kNYkDw8)DvqOBpn2A? z^tnsrFps=K?lw%=oIMrZyo7DMHkKqL>SwY zZI%iagCjc$X{1NRd3mVtaM9kP;dZ<&sk$H#j4`y7l*Cl@NmPKSJ5tcEVgQ2_xD;@S zRe^C8?;Ze`Byd>8`v*V@I`DytQG6&6Hr#|IqZ1g49YIq~;uC#$rIn9VjDviKD>>PY zz~%pCW!CRDZOe<365E-G;4-c#VBZ`+e4^qLnNUdbGc(zQNnBMhb*SBwJFce}R7~R< ziM30fK(u0?-Mru!mY4J#T`No|_)OrGBPuzC>b>^1#F!P z&L?4dJEIpp&IsmItX{!}eQ&V#Nk-k!pD-HmRY~46|0j+-o!ah+b}i-TKq}7lH;gdar{}! zIFfeB$>`S%IUd{oF^Y#Iap(pc5e*1J;qEk=5aId;$9n@*p0LZ&%=ZaO;#>vS;KhBk z{OChY@*VPpEokFjtpE_kDSokq@fP1y7GDw9MA_5E(cm7QG>(S$@bz=FFGYi$17(~s z&1fhZ;I7*=_t879v@2!2BTsg5yj_u-K(>sFQamJK2jXries4g^N4~>Ye>4~kb><)X zg0V6#&F|s-c=#uL`W!QK_A?Uum~UMy<5p)Gcgk2UW94y3NbkF^HXa8B1KNF+?tjL> zSFiyOS@Iwg9VZuHN+BktlB*cbV1y&)3OaEEXW8Oi)aao`FE()j-w^kN_&tt9NzT0r z0abEH1y+&s344k>3^FcdYgng0xih&7aQ_1e+y$xqEiCRr^lZXLku}?--wikj!=+9K z!Y}z>`Vv7t!wT9@-B*x(fv$!Z)E12FL8TlRqLM diff --git a/bin/com/moomoohk/Grame/Graphics/RandomRender.class b/bin/com/moomoohk/Grame/Graphics/RandomRender.class deleted file mode 100644 index 74c635b07bea89bc3e87e74cd6e6a63c18588170..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 924 zcma)5%Wl&^6g`u~ahs-(grw ze#}QguVY_&iPPcXAR2WA?ub?ZI1fD5SDSe;#{DHl_@ z=Sl`i5o=gyScpyW_M#w)DU({gZEDBQlwYv})(K1ePaR%|5W+W2ITKzM%XG7Z2Z9tYS6K-~IaD z{6ObfgIPw7^a^>b5k>_YSU31P6O0s}&~O#kOw1~-6ZMRafSb5QI9l5zEl2t~Zj)x= n4(-w-`ay3%Q@x8?N^hH_&MjN6YZlX)Ri`q`{>`juZf*SrC27e4 diff --git a/bin/com/moomoohk/Grame/Graphics/RenderManager.class b/bin/com/moomoohk/Grame/Graphics/RenderManager.class deleted file mode 100644 index 38e899cd0de18cc552085805e06cb89ab1b355ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10028 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 diff --git a/bin/com/moomoohk/Grame/Interfaces/EntityGenerator.class b/bin/com/moomoohk/Grame/Interfaces/EntityGenerator.class deleted file mode 100644 index dde7e1a5561fff8133dc0cb4e2ef9d5dd661e4e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 200 zcmZ9GK?=e!5Ji8gHrka751|VUxOJ^X5M1;GF^sjfO(aI4S99S3Jd`-Wg&+(J%zuCW zf4v`1083;NiNM^rR<+LYoX#rux+S%>f&5V$x~jDeRp@fEc4|=q_I%E8NW++EfiO{r7(nt*L-Ok2?Yh#|@Ao#>%)^ I8OA$CA0F#8HUIzs diff --git a/bin/com/moomoohk/Grame/Interfaces/GrameObject.class b/bin/com/moomoohk/Grame/Interfaces/GrameObject.class deleted file mode 100644 index 3e4d7ba622cdcba117cab5ac1557dc509b019d6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2932 zcmbVOU3U{z6y3K?laMu~5GV*KkRnPFpuq~F6e~0o45kzs8U+=cCPOmagRw@YP@7A7Q!gohcpD6vVD}?wvd5p1sdG`<~lBpZxX*fMMKC zpi3ZMcjk-pj>F%%>&4TqK5rDuwr{vs^}68&3zIX~jJlsdOkl$`eL*i;x;`h}onekglwtRejgAXGa8jyry9^IMyA@aS0L_={NjhNv_Z&-qc&3v=Nv1a?G?% ze^g*^Zne8|`{qme8sSS$!$_eU+cflJyFhm?Ut0%(0S)WXCuch~Y(TG^Wi@O>TF!QB z*o4g~?7^!EydqHOklJz2Gi;wZ3R63w+xo2GYS@b$ar6dR59KNyc6KhxNWLtg3mP=^ z3iMS>+c?{rpE2AEK@HLsr>Cl|Rb4jc@~cxx18>=& zzeB2JVv}@H4a&!qvd~Fx2^V6y^0JAlBg?-G6RoY>5q{qkqO5$D4n&>WPy%2fbE=+6 z(>oU`g0NB(l^n-yn6~a4-iWMiNyABulloQDZj9+3b-MTYUZf$n zpGG->cPW()1&&}!YYk`cp1`KMWBa;kd+KNgXHEuI&R>%5CN!MI34x7_C}P3j5;!NY zwfz8%wM?sFxJgX$97>q%4bz{?mQNl{VGvQfOR?i>@2H%P5Y+h?U^tRChFh|9Hf6HaqAG|DvaNRWuLp5#M*>OC*YV=) zLW&Ka-Inv1ybjdJ%Rr613e?Dpfa7}Z>Bkm6xAN^i_x5nyU3i3-3i}q3DGV%PN8!LC zb`|<#ix?~v9^>Ujl%GS`vFTR6Ik2#dU{orp&w{u)F^SR_g07~Wpxi$M*x`?^hEch>NA zjAfR-M)6MQE1KQG_Uzv47}Rl`2shuSdSsbPna3ETPV!4Q^&R?F-YO4%$K=KI`A4W` zmN1>ZxP%V_yXo|0&X@4XFQ`9;DP%somAumwBJdTJ@HG$FHw61O5>4r;R!VSGiJEGs z*iKHL!VQ@@bS9NOu)>ARHY~sGUxN2gCN2v3Jt2P}+&RAOA3Z&Q&j0`b diff --git a/bin/com/moomoohk/Grame/Interfaces/MovementAI.class b/bin/com/moomoohk/Grame/Interfaces/MovementAI.class deleted file mode 100644 index 73fcba5f7cc2d2dcdfbe5b8f224d8e8c04b1ad1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2940 zcmdT`OH&+G7(JI67?^4vK_D6)2@u1~@R&$qOfs0r+ld2&M|SXQOnxUmYWEP`4^l^Yi>{SEG1>e}+$?jf|M2~N4P3cBy(-1B|k`A&Dw&wqZu z4`2}QMNlCS%bDxRb<^bE+Wq9DrLJqqwBcyh`)W?JlT+rVwyqh@a5{ppK*K$CQ%x3B zV>LOma!<=S5mX5@xvRRFoYyQ}E$APqD+P^U+nr`L%hpZfR(ec8+z_Z8H4WQQ4JWG> zidtpMr@eE3eD|GBOgh$Q17DWgR3KY~v(TJu9UJytGq&#lh%#y)v zuZAhrP**ieK{HweD%E^`I4#g0%LJSaEH@=nsL$wzHeFm_(X0iprpAn!Qwv#@b+X3N zV%S;JZRYjw$pxZYmb#%@X3@wCJPORqSJQ}UYpEc5A7<1vt-Nlij%Ei!$)V@$hYPHchubdDRrad$V$7Q=lKYJ9w@x8X>Mjg z^gfI~p&+O)lXQ8`x{l!p-VkUHXwV_6f)R|;O}ag%tE+Cemt=Rw6-;1Kpjx-nhAc#2 z;JAAIwZvVPw1OLWi>=q~nOv^8p=(q;Sq@LyBbrh$E%U6US#CdlxTCm^n+j$zN6Xk7 z1>K<^WAWuO5@&8`;lIO)u&9dBQI67|@ zt(-QY%WrD^;Rks@wm;lSqlEZh$^TP`pqlp@e%~t)&R=ISZVYNQoCBC*3@#EY)pzFoBMqPyZtbeG0G9H0CF z9gB%wB*J-Kli~am4DR@_od;OC`xuRf@Q@!V86KnK08C;R8G4q}L$)0tJ=$7H8~Pg~ zDVh(1_3om_7f)vH?sC2Rs2B|{=|4|;0o^@$_%P-Ul?y>CJb@Fu_EFh>UI#FVB(gY< z5BP!kgg?fLi0V_t<8_PxqSLJ$Ekm_Ap<9xW~OnN1XR>dIVm=tiV%t z1PvT#X!a>ueH!O5Lxpcrky*Za=Q&!yGH#(jy|=K4kFkV@TzQ1I@ip#Z5AV3DCOlOR zRK@;*svLQ$QZw>o8CU9CgGg=1Kxs4cZ$zu;REn&>!~RY#{*+CvW$jXxSus(TBPj%wlNkj;@#nr?- hOEaHoe>p~Fu0bGF{R=?FW7W|>i5H;h9nVzy2tOw>Jx2fl diff --git a/src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java b/src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java index ee5a792..23b1aad 100644 --- a/src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java +++ b/src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java @@ -5,6 +5,7 @@ import com.moomoohk.Grame.Basics.Dir; import com.moomoohk.Grame.Basics.Entity; +import com.moomoohk.Grame.Basics.OldEntity; import com.moomoohk.Grame.Basics.Schematic; import com.moomoohk.Grame.Essentials.Base; import com.moomoohk.Grame.Essentials.Coordinates; @@ -39,9 +40,7 @@ public String author() public Coordinates getNext(Coordinates pos, Coordinates targetPos, Base b, Entity ent1, Entity ent2) { if (ent1.getPos(b.ID).distance(ent2.getPos(b.ID)) == 1) - { return pos; - } if (cachedTargetPos != null) if (cachedTargetPos.equals(targetPos)) { @@ -250,8 +249,8 @@ public void newGame() { Base b = new Base(20, 20); b.setWraparound(true); - Entity player = new Entity("Player", Color.gray); - Entity monster = new Entity("Monster", Color.red); + OldEntity player = new OldEntity("Player", Color.gray); + OldEntity monster = new OldEntity("Monster", Color.red); b.addGrameObjectLayer(new GrameObjectLayer(b.getColumns(), b.getRows()), 1); player.makePlayer(1, true, b.ID); player.setSpeed(1); diff --git a/src/com/moomoohk/Grame/Basics/Entity.java b/src/com/moomoohk/Grame/Basics/Entity.java index c7ac4e7..5692c36 100644 --- a/src/com/moomoohk/Grame/Basics/Entity.java +++ b/src/com/moomoohk/Grame/Basics/Entity.java @@ -5,102 +5,86 @@ import java.util.HashMap; import com.moomoohk.Grame.AI.PlayerMovementAI; -import com.moomoohk.Grame.Essentials.Base; import com.moomoohk.Grame.Essentials.Coordinates; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.Grame.Essentials.GrameUtils; import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; +import com.moomoohk.Grame.GrassMuncher.Coin; import com.moomoohk.Grame.Interfaces.EntityGenerator; import com.moomoohk.Grame.Interfaces.GrameObject; import com.moomoohk.Grame.Interfaces.MovementAI; -/** - * Entities are ready to use {@link GrameObject}s which have a lot of configurable aspects. - * - * @author Meshulam Silk - * @version 1.0 - * @since 2013-04-05 - */ public class Entity extends GrameObject { - private static final long serialVersionUID = 2137967921422181555L; - private String type; - private int level; - private int range; - private int points; private HashMap player; - private int targetID; - protected EntityGenerator randomGen; private HashMap activeAI; private HashMap overrideAI; private HashMap> AI; + private int points; + private int range; + private int targetID; - /** - * Constructor. - */ public Entity() { - this(new DefaultRandomGen().nameGen(), new DefaultRandomGen().typeGen(), 1, GrameUtils.randomColor()); + this(new DefaultRandomGen()); + } + + public Entity(String name) + { + this(name, GrameUtils.randomColor(), 5); + } + + public Entity(String name, int speed) + { + this(name, GrameUtils.randomColor(), speed); } - /** - * Constructor. - * - * @param c - * Entity color. - */ public Entity(Color c) { - this(new DefaultRandomGen().nameGen(), new DefaultRandomGen().typeGen(), 1, c); + this(new DefaultRandomGen().nameGen(), c, 5); } - /** - * Constructor. - * - * @param entGen - * {@link EntityGenerator} to use. - */ - public Entity(EntityGenerator entGen) + public Entity(Color c, int speed) { - this(entGen.nameGen(), entGen.typeGen(), 1, GrameUtils.randomColor()); + this(new DefaultRandomGen().nameGen(), c, speed); + } + + public Entity(String name, Color c) + { + this(name, c, 5); } - public Entity(String name) + public Entity(EntityGenerator entGen) { - this(name, "", 0, GrameUtils.randomColor()); + this(entGen.nameGen(), GrameUtils.randomColor(), 5); } - public Entity(String name, Color color) + public Entity(EntityGenerator entGen, int speed) { - this(name, "", 0, color); + this(entGen.nameGen(), GrameUtils.randomColor(), speed); } - /** - * Constructor. - * - * @param name - * Entity name. - * @param type - * Entity type. - * @param level - * Starting level. - * @param color - * Entity color. - */ - public Entity(String name, String type, int level, Color color) + public Entity(String name, Color c, int speed) { - super(name, 5, color, false); - this.setType(type); - this.setLevel(level); + super(name, speed, c, false); this.player = new HashMap(); this.targetID = -1; this.range = 5; - this.setPoints(0); + this.points = 0; this.AI = new HashMap>(); this.activeAI = new HashMap(); this.overrideAI = new HashMap(); } + private static final long serialVersionUID = -4997365624920436027L; + + @Override + public boolean isCollidable() + { + return true; + } + + @Override public void tick(int bID) { determineAI(bID); @@ -110,7 +94,7 @@ public void tick(int bID) target = GrameManager.findGrameObject(this.targetID).getPos(bID); if (this.activeAI.size() != 0 && this.activeAI.get(bID) != null) c = this.activeAI.get(bID).getNext(getPos(bID), target, GrameManager.findBase(bID), this, (Entity) GrameManager.findGrameObject(targetID)); - GrameManager.findBase(bID).moveGrameObject(ID, c); + setPos(bID, c); } private void determineAI(int bID) @@ -140,49 +124,7 @@ private void determineAI(int bID) this.activeAI.put(bID, this.overrideAI.get(bID)); } } - - /** - * Prints the {@link MovementAI} list of this Entity. - */ - public void printAI() - { - GrameUtils.print("Override AIs:", MessageLevel.NORMAL); - if (overrideAI.size() != 0) - for (int bID : overrideAI.keySet()) - GrameUtils.print(bID + ": " + overrideAI.get(bID) + " (" + overrideAI.get(bID).author() + ")", MessageLevel.NORMAL); - else - GrameUtils.print("[Empty]", MessageLevel.NORMAL); - GrameUtils.print("Active AIs:", MessageLevel.NORMAL); - if (activeAI.size() != 0) - for (int bID : activeAI.keySet()) - GrameUtils.print(bID + ": " + activeAI.get(bID) + " (" + activeAI.get(bID).author() + ")", MessageLevel.NORMAL); - else - GrameUtils.print("[Empty]", MessageLevel.NORMAL); - for (int bID : AI.keySet()) - { - GrameUtils.print("For base ID:" + bID, MessageLevel.NORMAL); - String st = "null"; - if (this.AI.size() == 0) - GrameUtils.print("My AI list is empty!", MessageLevel.ERROR); - else - for (int i = 0; i < this.AI.size(); i++) - { - st = "null"; - if (this.AI.get(i) != null) - st = this.AI.get(i) + " (" + ((MovementAI) this.AI.get(bID).get(i)).author() + ")"; - GrameUtils.print(i + 1 + ") " + st, MessageLevel.NORMAL); - } - } - } - - /** - * Adds a {@link MovementAI} to this Entity's AI list. - * - * @param AI - * {@link MovementAI} to add. - * @param bID - * The {@link Base#ID} of the {@link Base} in which to apply the {@link MovementAI}. - */ + public void addAI(MovementAI AI, int bID) { if (!AI.isOverride()) @@ -195,24 +137,13 @@ public void addAI(MovementAI AI, int bID) GrameUtils.print(AI + " is an override AI, it doens't belong in my AI list!", MessageLevel.ERROR); } - /** - * Clears this Entity's AI list. - */ public void clearAI() { this.AI = new HashMap>(); this.activeAI = null; this.overrideAI = null; } - - /** - * Sets the override for this Entity. - * - * @param mai - * {@link MovementAI} which is an override AI. - * @param bID - * The {@link Base#ID} of the {@link Base} in which to apply the {@link MovementAI}. - */ + public void setOverrideAI(MovementAI mai, int bID) { if (mai.isOverride()) @@ -221,43 +152,13 @@ public void setOverrideAI(MovementAI mai, int bID) GrameUtils.print(mai + " is not an override AI!", MessageLevel.ERROR); } - /** - * Checks whether this Entity has reached its target. - * - * @param bID - * {@link Base#ID} of the {@link Base} in which to check. - * @return True if this Entity reached its target, else false. - */ - public boolean reachedTarget(int bID) - { - return (targetID != -1) && (this.getPos(bID).distance(GrameManager.findGrameObject(targetID).getPos(bID)) == 1); - } - - public Coordinates getPos(int bID) - { - if (GrameManager.findBase(bID).containsGrameObject(ID)) - return GrameManager.findBase(bID).getGrameObjectPos(ID); - GrameUtils.print("Base with ID:" + bID + " does not contain Entity with ID:" + ID + ". Returning null.", MessageLevel.ERROR); - return null; - } - - public void setPos(int bID, Coordinates pos) + @Override + public void consume(GrameObject go) { - if (GrameManager.findBase(bID).containsGrameObject(ID)) - { - GrameManager.findBase(bID).moveGrameObject(ID, pos); - return; - } + if (go instanceof Coin) + this.points += ((Coin) go).getWorth(); } - /** - * Checks whether or not this Entity is a "player" (controllable by the keyboard). - * - * @param bID - * The {@link Base#ID} of the {@link Base} in which to check. - * @return True if this Entity is a "player", else false. - * @see Entity#makePlayer(int, boolean, int) - */ public boolean isPlayer(int bID) { if (this.player.get(bID) == null) @@ -265,17 +166,6 @@ public boolean isPlayer(int bID) return this.player.get(bID); } - /** - * Turns this Entity into a "player". - * - * @param player - * 1 for wasd control, 2 for arrow keys control. - * @param f - * True to turn this Entity into a "player", else false. - * @param bID - * The {@link Base#ID} of the {@link Base} in which to turn this Entity into a "player". - * @see Entity#isPlayer(int) - */ public void makePlayer(int player, boolean f, int bID) { if (f) @@ -293,122 +183,26 @@ public void makePlayer(int player, boolean f, int bID) GrameUtils.print("Not a player!", MessageLevel.ERROR); } - /** - * Sets the target of this Entity. - * - * @param eID - * The {@link GrameObject#ID} of the {@link GrameObject}/Entity to set as target. - */ - public void setTarget(int eID) - { - if (GrameManager.findGrameObject(eID) != null) - this.targetID = eID; - else - GrameUtils.print("Cannot set that Entity (ID:" + eID + ") as target for Entity with ID:" + ID + " (Entity not found)", MessageLevel.ERROR); - } - - /** - * Returns this Entity's target. - * - * @return This Entity's target. - */ - public Entity getTarget() - { - return (Entity) (GrameManager.findGrameObject(this.targetID)); - } - - /** - * Gets the range of this Entity. - * - * @return The range of this Entity. - */ public int getRange() { return this.range; } - /** - * Sets the range of this Entity. - * - * @param range - * The range to set. - */ public void setRange(int range) { this.range = range; } - public boolean isCollidable() - { - return true; - } - - /** - * Sets the type of this Entity. - * - * @param type - * The type to set. - */ - public void setType(String type) - { - this.type = type; - } - - /** - * Gets the type of this Entity. - * - * @return The type of this Entity. - */ - public String getType() - { - return type; - } - - /** - * Sets the level of this Entity. - * - * @param level - * The level to set. - */ - public void setLevel(int level) - { - this.level = level; - } - - /** - * Gets the level of this Entity. - * - * @return The level of this Entity. - */ - public int getLevel() - { - return level; - } - - /** - * Sets the points of this Entity. - * - * @param points - * The points to set. - */ - public void setPoints(int points) - { - this.points = points; - } - - /** - * Gets the points of this Entity. - * - * @return The points of this Entity. - */ - public int getPoints() + public void setTarget(int eID) { - return points; + if (GrameManager.findGrameObject(eID) != null) + this.targetID = eID; + else + GrameUtils.print("Cannot set that Entity (ID:" + eID + ") as target for Entity with ID:" + ID + " (Entity not found)", MessageLevel.ERROR); } - @Override - public void consume(GrameObject go) + public OldEntity getTarget() { - + return (OldEntity) (GrameManager.findGrameObject(this.targetID)); } } diff --git a/src/com/moomoohk/Grame/Basics/OldEntity.java b/src/com/moomoohk/Grame/Basics/OldEntity.java new file mode 100644 index 0000000..9d804c2 --- /dev/null +++ b/src/com/moomoohk/Grame/Basics/OldEntity.java @@ -0,0 +1,416 @@ +package com.moomoohk.Grame.Basics; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.HashMap; + +import com.moomoohk.Grame.AI.PlayerMovementAI; +import com.moomoohk.Grame.Essentials.Base; +import com.moomoohk.Grame.Essentials.Coordinates; +import com.moomoohk.Grame.Essentials.GrameManager; +import com.moomoohk.Grame.Essentials.GrameUtils; +import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; +import com.moomoohk.Grame.GrassMuncher.Coin; +import com.moomoohk.Grame.Interfaces.EntityGenerator; +import com.moomoohk.Grame.Interfaces.GrameObject; +import com.moomoohk.Grame.Interfaces.MovementAI; + +/** + * Entities are ready to use {@link GrameObject}s which have a lot of configurable aspects. + * + * @author Meshulam Silk + * @version 1.0 + * @since 2013-04-05 + */ +public class OldEntity extends GrameObject +{ + private static final long serialVersionUID = 2137967921422181555L; + private String type; + private int level; + private int range; + private int points; + private HashMap player; + private int targetID; + protected EntityGenerator randomGen; + private HashMap activeAI; + private HashMap overrideAI; + private HashMap> AI; + + /** + * Constructor. + */ + public OldEntity() + { + this(new DefaultRandomGen().nameGen(), new DefaultRandomGen().typeGen(), 1, GrameUtils.randomColor()); + } + + /** + * Constructor. + * + * @param c + * Entity color. + */ + public OldEntity(Color c) + { + this(new DefaultRandomGen().nameGen(), new DefaultRandomGen().typeGen(), 1, c); + } + + /** + * Constructor. + * + * @param entGen + * {@link EntityGenerator} to use. + */ + public OldEntity(EntityGenerator entGen) + { + this(entGen.nameGen(), entGen.typeGen(), 1, GrameUtils.randomColor()); + } + + public OldEntity(String name) + { + this(name, "", 0, GrameUtils.randomColor()); + } + + public OldEntity(String name, Color color) + { + this(name, "", 0, color); + } + + /** + * Constructor. + * + * @param name + * Entity name. + * @param type + * Entity type. + * @param level + * Starting level. + * @param color + * Entity color. + */ + public OldEntity(String name, String type, int level, Color color) + { + super(name, 5, color, false); + this.setType(type); + this.setLevel(level); + this.player = new HashMap(); + this.targetID = -1; + this.range = 5; + this.setPoints(0); + this.AI = new HashMap>(); + this.activeAI = new HashMap(); + this.overrideAI = new HashMap(); + } + + public void tick(int bID) + { + determineAI(bID); + Coordinates c = getPos(bID); + Coordinates target = null; + if (this.targetID != -1) + target = GrameManager.findGrameObject(this.targetID).getPos(bID); + if (this.activeAI.size() != 0 && this.activeAI.get(bID) != null) + c = this.activeAI.get(bID).getNext(getPos(bID), target, GrameManager.findBase(bID), this, (OldEntity) GrameManager.findGrameObject(targetID)); + setPos(bID, c); + } + + private void determineAI(int bID) + { + if (!GrameManager.findBase(bID).containsGrameObject(ID) || (this.AI.get(bID) == null && this.overrideAI.get(bID) == null) || (this.AI.get(bID) != null && this.AI.get(bID).size() == 0 && this.overrideAI.get(bID) == null)) + { + this.activeAI.remove(bID); + return; + } + if (this.overrideAI.size() == 0 || this.overrideAI.get(bID) == null) + { + MovementAI temp = null; + for (int i = 0; i < this.AI.get(bID).size(); i++) + { + Coordinates target = null; + if (targetID != -1) + target = GrameManager.findGrameObject(targetID).getPos(bID); + if (!this.AI.get(bID).get(i).isValid(getPos(bID), target, GrameManager.findBase(bID), this, (OldEntity) GrameManager.findGrameObject(targetID))) + continue; + temp = (MovementAI) this.AI.get(bID).get(i); + break; + } + this.activeAI.put(bID, temp); + } + else + { + this.activeAI.put(bID, this.overrideAI.get(bID)); + } + } + + /** + * Prints the {@link MovementAI} list of this Entity. + */ + public void printAI() + { + GrameUtils.print("Override AIs:", MessageLevel.NORMAL); + if (overrideAI.size() != 0) + for (int bID : overrideAI.keySet()) + GrameUtils.print(bID + ": " + overrideAI.get(bID) + " (" + overrideAI.get(bID).author() + ")", MessageLevel.NORMAL); + else + GrameUtils.print("[Empty]", MessageLevel.NORMAL); + GrameUtils.print("Active AIs:", MessageLevel.NORMAL); + if (activeAI.size() != 0) + for (int bID : activeAI.keySet()) + GrameUtils.print(bID + ": " + activeAI.get(bID) + " (" + activeAI.get(bID).author() + ")", MessageLevel.NORMAL); + else + GrameUtils.print("[Empty]", MessageLevel.NORMAL); + for (int bID : AI.keySet()) + { + GrameUtils.print("For base ID:" + bID, MessageLevel.NORMAL); + String st = "null"; + if (this.AI.size() == 0) + GrameUtils.print("My AI list is empty!", MessageLevel.ERROR); + else + for (int i = 0; i < this.AI.size(); i++) + { + st = "null"; + if (this.AI.get(i) != null) + st = this.AI.get(i) + " (" + ((MovementAI) this.AI.get(bID).get(i)).author() + ")"; + GrameUtils.print(i + 1 + ") " + st, MessageLevel.NORMAL); + } + } + } + + /** + * Adds a {@link MovementAI} to this Entity's AI list. + * + * @param AI + * {@link MovementAI} to add. + * @param bID + * The {@link Base#ID} of the {@link Base} in which to apply the {@link MovementAI}. + */ + public void addAI(MovementAI AI, int bID) + { + if (!AI.isOverride()) + { + if (this.AI.get(bID) == null) + this.AI.put(bID, new ArrayList()); + this.AI.get(bID).add(AI); + } + else + GrameUtils.print(AI + " is an override AI, it doens't belong in my AI list!", MessageLevel.ERROR); + } + + /** + * Clears this Entity's AI list. + */ + public void clearAI() + { + this.AI = new HashMap>(); + this.activeAI = null; + this.overrideAI = null; + } + + /** + * Sets the override for this Entity. + * + * @param mai + * {@link MovementAI} which is an override AI. + * @param bID + * The {@link Base#ID} of the {@link Base} in which to apply the {@link MovementAI}. + */ + public void setOverrideAI(MovementAI mai, int bID) + { + if (mai.isOverride()) + this.overrideAI.put(bID, mai); + else + GrameUtils.print(mai + " is not an override AI!", MessageLevel.ERROR); + } + + /** + * Checks whether this Entity has reached its target. + * + * @param bID + * {@link Base#ID} of the {@link Base} in which to check. + * @return True if this Entity reached its target, else false. + */ + public boolean reachedTarget(int bID) + { + return (targetID != -1) && (this.getPos(bID).distance(GrameManager.findGrameObject(targetID).getPos(bID)) == 1); + } + + public Coordinates getPos(int bID) + { + if (GrameManager.findBase(bID).containsGrameObject(ID)) + return GrameManager.findBase(bID).getGrameObjectPos(ID); + GrameUtils.print("Base with ID:" + bID + " does not contain Entity with ID:" + ID + ". Returning null.", MessageLevel.ERROR); + return null; + } + + public void setPos(int bID, Coordinates pos) + { + if (GrameManager.findBase(bID).containsGrameObject(ID)) + { + GrameManager.findBase(bID).moveGrameObject(ID, pos); + return; + } + } + + /** + * Checks whether or not this Entity is a "player" (controllable by the keyboard). + * + * @param bID + * The {@link Base#ID} of the {@link Base} in which to check. + * @return True if this Entity is a "player", else false. + * @see OldEntity#makePlayer(int, boolean, int) + */ + public boolean isPlayer(int bID) + { + if (this.player.get(bID) == null) + return false; + return this.player.get(bID); + } + + /** + * Turns this Entity into a "player". + * + * @param player + * 1 for wasd control, 2 for arrow keys control. + * @param f + * True to turn this Entity into a "player", else false. + * @param bID + * The {@link Base#ID} of the {@link Base} in which to turn this Entity into a "player". + * @see OldEntity#isPlayer(int) + */ + public void makePlayer(int player, boolean f, int bID) + { + if (f) + { + this.player.put(bID, true); + this.overrideAI.put(bID, new PlayerMovementAI(player)); + } + else + if (this.player.get(bID)) + { + this.player.put(bID, false); + this.overrideAI.remove(bID); + } + else + GrameUtils.print("Not a player!", MessageLevel.ERROR); + } + + /** + * Sets the target of this Entity. + * + * @param eID + * The {@link GrameObject#ID} of the {@link GrameObject}/Entity to set as target. + */ + public void setTarget(int eID) + { + if (GrameManager.findGrameObject(eID) != null) + this.targetID = eID; + else + GrameUtils.print("Cannot set that Entity (ID:" + eID + ") as target for Entity with ID:" + ID + " (Entity not found)", MessageLevel.ERROR); + } + + /** + * Returns this Entity's target. + * + * @return This Entity's target. + */ + public OldEntity getTarget() + { + return (OldEntity) (GrameManager.findGrameObject(this.targetID)); + } + + /** + * Gets the range of this Entity. + * + * @return The range of this Entity. + */ + public int getRange() + { + return this.range; + } + + /** + * Sets the range of this Entity. + * + * @param range + * The range to set. + */ + public void setRange(int range) + { + this.range = range; + } + + public boolean isCollidable() + { + return true; + } + + /** + * Sets the type of this Entity. + * + * @param type + * The type to set. + */ + public void setType(String type) + { + this.type = type; + } + + /** + * Gets the type of this Entity. + * + * @return The type of this Entity. + */ + public String getType() + { + return type; + } + + /** + * Sets the level of this Entity. + * + * @param level + * The level to set. + */ + public void setLevel(int level) + { + this.level = level; + } + + /** + * Gets the level of this Entity. + * + * @return The level of this Entity. + */ + public int getLevel() + { + return level; + } + + /** + * Sets the points of this Entity. + * + * @param points + * The points to set. + */ + public void setPoints(int points) + { + this.points = points; + } + + /** + * Gets the points of this Entity. + * + * @return The points of this Entity. + */ + public int getPoints() + { + return points; + } + + @Override + public void consume(GrameObject go) + { + if (go instanceof Coin) + this.points += ((Coin) go).getWorth(); + } +} diff --git a/src/com/moomoohk/Grame/Essentials/GrameManager.java b/src/com/moomoohk/Grame/Essentials/GrameManager.java index d5da4de..61282f7 100644 --- a/src/com/moomoohk/Grame/Essentials/GrameManager.java +++ b/src/com/moomoohk/Grame/Essentials/GrameManager.java @@ -601,7 +601,7 @@ public static int getObjectListLength() { return engineState.getGrameObjects().size(); } - + public static int getBaseListLength() { return engineState.getBases().size(); @@ -1214,7 +1214,7 @@ public void mouseExited(MouseEvent paramMouseEvent) @Override public void mouseEntered(MouseEvent paramMouseEvent) { - savePanel.setBorder(BorderFactory.createMatteBorder(2, 5, 2, 2, Color.black)); + savePanel.setBorder(BorderFactory.createMatteBorder(2, 5, 2, 2, Color.black)); } public void mousePressed(MouseEvent arg0) diff --git a/src/com/moomoohk/Grame/Essentials/GrameUtils.java b/src/com/moomoohk/Grame/Essentials/GrameUtils.java index bc9d3a7..3e86dbb 100644 --- a/src/com/moomoohk/Grame/Essentials/GrameUtils.java +++ b/src/com/moomoohk/Grame/Essentials/GrameUtils.java @@ -28,6 +28,7 @@ import javax.swing.JLabel; import javax.swing.JOptionPane; +import com.moomoohk.Grame.AI.AStarPathfindingMovementAI; import com.moomoohk.Grame.AI.PlayerMovementAI; import com.moomoohk.Grame.AI.PlayerSimAI; import com.moomoohk.Grame.AI.SimpleChaseAI; @@ -491,6 +492,7 @@ public static void loadBasicAIs() GrameManager.addAI(new PlayerMovementAI(1)); GrameManager.addAI(new SimpleChaseAI()); GrameManager.addAI(new PlayerSimAI()); + GrameManager.addAI(new AStarPathfindingMovementAI()); } /** diff --git a/src/com/moomoohk/Grame/Interfaces/EntityGenerator.java b/src/com/moomoohk/Grame/Interfaces/EntityGenerator.java index ec575c1..bb619b7 100644 --- a/src/com/moomoohk/Grame/Interfaces/EntityGenerator.java +++ b/src/com/moomoohk/Grame/Interfaces/EntityGenerator.java @@ -1,12 +1,12 @@ package com.moomoohk.Grame.Interfaces; -import com.moomoohk.Grame.Basics.Entity; +import com.moomoohk.Grame.Basics.OldEntity; /** * This interface is used to create generators which generate names and types * for Entities. * - * @see Entity + * @see OldEntity * @author Meshulam Silk * @version 1.0 * @since 2013-04-05 diff --git a/src/com/moomoohk/Grame/commands/AddEntityAICommand.java b/src/com/moomoohk/Grame/commands/AddEntityAICommand.java index ff9b63f..c40b452 100644 --- a/src/com/moomoohk/Grame/commands/AddEntityAICommand.java +++ b/src/com/moomoohk/Grame/commands/AddEntityAICommand.java @@ -41,7 +41,7 @@ protected boolean check(String[] params) this.outputColor = Color.red; return false; } - return super.check(params); + return true; } @Override diff --git a/src/com/moomoohk/Grame/commands/AddGrameObjectCommand.java b/src/com/moomoohk/Grame/commands/AddGrameObjectCommand.java index d63ffef..c776146 100644 --- a/src/com/moomoohk/Grame/commands/AddGrameObjectCommand.java +++ b/src/com/moomoohk/Grame/commands/AddGrameObjectCommand.java @@ -34,7 +34,7 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - return super.check(params); + return true; } @Override diff --git a/src/com/moomoohk/Grame/commands/ClearEntityAI.java b/src/com/moomoohk/Grame/commands/ClearEntityAI.java index 76ffc83..2950596 100644 --- a/src/com/moomoohk/Grame/commands/ClearEntityAI.java +++ b/src/com/moomoohk/Grame/commands/ClearEntityAI.java @@ -2,7 +2,7 @@ import java.awt.Color; -import com.moomoohk.Grame.Basics.Entity; +import com.moomoohk.Grame.Basics.OldEntity; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; @@ -16,13 +16,13 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof Entity)) + if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof OldEntity)) { this.outputMessage = "Grame Object with ID:" + params[0] + " is not an Entity!"; this.outputColor = Color.red; return false; } - return super.check(params); + return true; } public ClearEntityAI() @@ -33,7 +33,7 @@ public ClearEntityAI() @Override public void execute(String[] params) { - ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).clearAI(); + ((OldEntity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).clearAI(); } @Override diff --git a/src/com/moomoohk/Grame/commands/CreateEntityCommand.java b/src/com/moomoohk/Grame/commands/CreateEntityCommand.java index d41f08b..a288ab8 100644 --- a/src/com/moomoohk/Grame/commands/CreateEntityCommand.java +++ b/src/com/moomoohk/Grame/commands/CreateEntityCommand.java @@ -5,6 +5,7 @@ import com.moomoohk.Grame.Basics.DefaultRandomGen; import com.moomoohk.Grame.Basics.Entity; +import com.moomoohk.Grame.Basics.OldEntity; import com.moomoohk.Grame.Essentials.GrameUtils; import com.moomoohk.MooCommands.Command; import com.moomoohk.MooCommands.CommandsManager; @@ -29,7 +30,7 @@ public void execute(String[] arg1) name = flags.get("n"); if (flags.get("l") != null) level = Integer.parseInt(flags.get("l")); - new Entity(type, name, level, color); + new Entity(name, color); } public boolean check(String[] params) @@ -41,7 +42,7 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - return super.check(params); + return true; } @Override diff --git a/src/com/moomoohk/Grame/commands/DrawCoordinatesCommand.java b/src/com/moomoohk/Grame/commands/DrawCoordinatesCommand.java index ba61b81..08a0bc7 100644 --- a/src/com/moomoohk/Grame/commands/DrawCoordinatesCommand.java +++ b/src/com/moomoohk/Grame/commands/DrawCoordinatesCommand.java @@ -24,7 +24,7 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - return super.check(params); + return true; } @Override diff --git a/src/com/moomoohk/Grame/commands/MakePlayerCommand.java b/src/com/moomoohk/Grame/commands/MakePlayerCommand.java index d42a3f5..fb4074d 100644 --- a/src/com/moomoohk/Grame/commands/MakePlayerCommand.java +++ b/src/com/moomoohk/Grame/commands/MakePlayerCommand.java @@ -2,7 +2,7 @@ import java.awt.Color; -import com.moomoohk.Grame.Basics.Entity; +import com.moomoohk.Grame.Basics.OldEntity; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; @@ -21,7 +21,7 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - return super.check(params); + return true; } @Override @@ -30,12 +30,12 @@ public void execute(String[] params) if (params[0].equalsIgnoreCase("all")) { for (int i = 0; i < GrameManager.getObjectListLength(); i++) - if (GrameManager.findGrameObject(i) instanceof Entity) - ((Entity) (GrameManager.findGrameObject(i))).makePlayer(Integer.parseInt(params[1]), Boolean.parseBoolean(params[3]), Integer.parseInt(params[2])); + if (GrameManager.findGrameObject(i) instanceof OldEntity) + ((OldEntity) (GrameManager.findGrameObject(i))).makePlayer(Integer.parseInt(params[1]), Boolean.parseBoolean(params[3]), Integer.parseInt(params[2])); } else - if (GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof Entity) - ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).makePlayer(Integer.parseInt(params[1]), Boolean.parseBoolean(params[3]), Integer.parseInt(params[2])); + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof OldEntity) + ((OldEntity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).makePlayer(Integer.parseInt(params[1]), Boolean.parseBoolean(params[3]), Integer.parseInt(params[2])); } @Override diff --git a/src/com/moomoohk/Grame/commands/MoveGrameObjectCommand.java b/src/com/moomoohk/Grame/commands/MoveGrameObjectCommand.java index 2a424ff..7dc8b9c 100644 --- a/src/com/moomoohk/Grame/commands/MoveGrameObjectCommand.java +++ b/src/com/moomoohk/Grame/commands/MoveGrameObjectCommand.java @@ -41,7 +41,7 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - return super.check(params); + return true; } @Override diff --git a/src/com/moomoohk/Grame/commands/PrintEntityAICommand.java b/src/com/moomoohk/Grame/commands/PrintEntityAICommand.java index b6d4031..0a4776c 100644 --- a/src/com/moomoohk/Grame/commands/PrintEntityAICommand.java +++ b/src/com/moomoohk/Grame/commands/PrintEntityAICommand.java @@ -2,7 +2,7 @@ import java.awt.Color; -import com.moomoohk.Grame.Basics.Entity; +import com.moomoohk.Grame.Basics.OldEntity; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; @@ -22,19 +22,19 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof Entity)) + if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof OldEntity)) { this.outputMessage = "Grame Object with ID:" + params[0] + " is not an Entity!"; this.outputColor = Color.red; return false; } - return super.check(params); + return true; } @Override public void execute(String[] params) { - ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).printAI(); + ((OldEntity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).printAI(); } @Override diff --git a/src/com/moomoohk/Grame/commands/RenderBaseCommand.java b/src/com/moomoohk/Grame/commands/RenderBaseCommand.java index ea259db..8a24134 100644 --- a/src/com/moomoohk/Grame/commands/RenderBaseCommand.java +++ b/src/com/moomoohk/Grame/commands/RenderBaseCommand.java @@ -35,7 +35,7 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - return super.check(params); + return true; } @Override diff --git a/src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java b/src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java index 26cc26f..26f7239 100644 --- a/src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java +++ b/src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java @@ -2,7 +2,7 @@ import java.awt.Color; -import com.moomoohk.Grame.Basics.Entity; +import com.moomoohk.Grame.Basics.OldEntity; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; @@ -22,7 +22,7 @@ protected boolean check(String[] params) this.outputColor = Color.red; return false; } - if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof Entity)) + if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof OldEntity)) { this.outputMessage = "Grame Object with ID:" + params[0] + " is not an Entity!"; this.outputColor = Color.red; @@ -55,9 +55,9 @@ protected boolean check(String[] params) public void execute(String[] params) { if (!params[2].equalsIgnoreCase("null")) - ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).setOverrideAI(GrameManager.getAIs().get(params[2]), Integer.parseInt(params[1])); + ((OldEntity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).setOverrideAI(GrameManager.getAIs().get(params[2]), Integer.parseInt(params[1])); else - ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).setOverrideAI(null, Integer.parseInt(params[1])); + ((OldEntity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).setOverrideAI(null, Integer.parseInt(params[1])); } @Override diff --git a/src/com/moomoohk/Grame/commands/SetSpeedCommand.java b/src/com/moomoohk/Grame/commands/SetSpeedCommand.java index 8d02a14..e73aff8 100644 --- a/src/com/moomoohk/Grame/commands/SetSpeedCommand.java +++ b/src/com/moomoohk/Grame/commands/SetSpeedCommand.java @@ -27,7 +27,7 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - return super.check(params); + return true; } @Override public void execute(String[] params) diff --git a/src/com/moomoohk/Grame/commands/SetSpriteCommand.java b/src/com/moomoohk/Grame/commands/SetSpriteCommand.java index a97bc28..2a132cd 100644 --- a/src/com/moomoohk/Grame/commands/SetSpriteCommand.java +++ b/src/com/moomoohk/Grame/commands/SetSpriteCommand.java @@ -27,7 +27,7 @@ public boolean check(String[] params) this.outputMessage += " " + sprite; return false; } - return super.check(params); + return true; } @Override diff --git a/src/com/moomoohk/Grame/commands/SetWraparoundCommand.java b/src/com/moomoohk/Grame/commands/SetWraparoundCommand.java index e25a0b5..57ca44f 100644 --- a/src/com/moomoohk/Grame/commands/SetWraparoundCommand.java +++ b/src/com/moomoohk/Grame/commands/SetWraparoundCommand.java @@ -14,11 +14,7 @@ public SetWraparoundCommand() public boolean check(String[] params) { - try - { - Boolean.parseBoolean(params[1]); - } - catch (Exception e) + if (!params[1].equalsIgnoreCase("true") && !params[1].equalsIgnoreCase("false")) { this.outputMessage = "Only true or false are accepted inputs!"; this.outputColor = Color.red; @@ -30,7 +26,7 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - return super.check(params); + return true; } @Override diff --git a/src/com/moomoohk/Grame/commands/isOccupiedCommand.java b/src/com/moomoohk/Grame/commands/isOccupiedCommand.java index 1fa0f4d..60e871a 100644 --- a/src/com/moomoohk/Grame/commands/isOccupiedCommand.java +++ b/src/com/moomoohk/Grame/commands/isOccupiedCommand.java @@ -28,7 +28,7 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - return super.check(params); + return true; } @Override diff --git a/src/com/moomoohk/Grame/commands/setVisibleCommand.java b/src/com/moomoohk/Grame/commands/setVisibleCommand.java index 2916376..5eceef6 100644 --- a/src/com/moomoohk/Grame/commands/setVisibleCommand.java +++ b/src/com/moomoohk/Grame/commands/setVisibleCommand.java @@ -25,7 +25,7 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - return super.check(params); + return true; } @Override diff --git a/src/com/moomoohk/Grame/test/AISystemTest.java b/src/com/moomoohk/Grame/test/AISystemTest.java index 52a2b70..af76cfe 100644 --- a/src/com/moomoohk/Grame/test/AISystemTest.java +++ b/src/com/moomoohk/Grame/test/AISystemTest.java @@ -5,7 +5,7 @@ import com.moomoohk.Grame.AI.PlayerSimAI; import com.moomoohk.Grame.AI.SimpleChaseAI; import com.moomoohk.Grame.AI.SimpleStrollAI; -import com.moomoohk.Grame.Basics.Entity; +import com.moomoohk.Grame.Basics.OldEntity; import com.moomoohk.Grame.Basics.Wall; import com.moomoohk.Grame.Essentials.Base; import com.moomoohk.Grame.Essentials.Coordinates; @@ -27,7 +27,7 @@ public static void generateStrollers(int amount, Base b) { for (int i = 0; i < amount; i++) { - Entity ent = new Entity(); + OldEntity ent = new OldEntity(); ent.addAI(new SimpleStrollAI(), b.ID); ent.setSpeed(5); ent.setColor(Color.blue); @@ -38,11 +38,11 @@ public static void generateStrollers(int amount, Base b) } } - public static void generateChasers(Base b, int amount, Entity target) + public static void generateChasers(Base b, int amount, OldEntity target) { for (int i = 1; i <= amount; i++) { - Entity ent = new Entity(Color.red); + OldEntity ent = new OldEntity(Color.red); ent.addAI(new SimpleChaseAI(), b.ID); ent.setRange(b.getDiagonal()); ent.setTarget(target.ID); @@ -59,7 +59,7 @@ public static void generatePlayers(int number, int amount, Base b) { for (int i = 1; i <= amount; i++) { - Entity ent = new Entity(); + OldEntity ent = new OldEntity(); ent.makePlayer(number, true, b.ID); ent.setSpeed(1); ent.setColor(Color.green); @@ -74,7 +74,7 @@ public static void generatePlayerSims(int amount, Base b) { for (int i = 1; i <= amount; i++) { - Entity ent = new Entity(); + OldEntity ent = new OldEntity(); ent.setColor(Color.yellow); ent.setOverrideAI(new PlayerSimAI(), b.ID); ent.setSpeed(1); @@ -106,8 +106,8 @@ public void newGame() generatePlayers(1, 1, b); generatePlayerSims(1, b); generateStrollers(5, b); - generateChasers(b, 3, (Entity) GrameManager.findGrameObject(1)); - generateChasers(b, 3, (Entity) GrameManager.findGrameObject(0)); + generateChasers(b, 3, (OldEntity) GrameManager.findGrameObject(1)); + generateChasers(b, 3, (OldEntity) GrameManager.findGrameObject(0)); RenderManager.render(b.ID); RenderManager.setVisible(true); RenderManager.setText(b.ID, new Coordinates(6, 6), "test", Color.red); diff --git a/src/com/moomoohk/Grame/test/ConsumeTest.java b/src/com/moomoohk/Grame/test/ConsumeTest.java index 09c591c..4517028 100644 --- a/src/com/moomoohk/Grame/test/ConsumeTest.java +++ b/src/com/moomoohk/Grame/test/ConsumeTest.java @@ -1,6 +1,6 @@ package com.moomoohk.Grame.test; -import com.moomoohk.Grame.Basics.Entity; +import com.moomoohk.Grame.Basics.OldEntity; import com.moomoohk.Grame.Essentials.Base; import com.moomoohk.Grame.Essentials.Coordinates; import com.moomoohk.Grame.Essentials.GrameManager; @@ -12,7 +12,7 @@ public class ConsumeTest implements MainGrameClass { - public static class Player extends Entity + public static class Player extends OldEntity { private static final long serialVersionUID = -3253634438661661214L; diff --git a/src/com/moomoohk/Grame/test/GrameObjectsTest.java b/src/com/moomoohk/Grame/test/GrameObjectsTest.java index 3b0eab9..d7043b0 100644 --- a/src/com/moomoohk/Grame/test/GrameObjectsTest.java +++ b/src/com/moomoohk/Grame/test/GrameObjectsTest.java @@ -1,6 +1,6 @@ package com.moomoohk.Grame.test; -import com.moomoohk.Grame.Basics.Entity; +import com.moomoohk.Grame.Basics.OldEntity; import com.moomoohk.Grame.Essentials.Base; import com.moomoohk.Grame.Essentials.Coordinates; import com.moomoohk.Grame.Essentials.GrameUtils; @@ -14,7 +14,7 @@ public static void main(String[] args) Base b=new Base(20, 20); GrameUtils.loadBasicCommands(); GrameUtils.loadBasicAIs(); - Entity ent=new Entity(); + OldEntity ent=new OldEntity(); b.addGrameObject(ent, new Coordinates(10, 10)); b.setWraparound(true); ent.makePlayer(1, true, b.ID); diff --git a/src/com/moomoohk/Grame/test/SaveTest.java b/src/com/moomoohk/Grame/test/SaveTest.java index 91f7107..97acdc5 100644 --- a/src/com/moomoohk/Grame/test/SaveTest.java +++ b/src/com/moomoohk/Grame/test/SaveTest.java @@ -13,6 +13,7 @@ public static void main(String[] args) { MenuConfiguration menuConfig = new MenuConfiguration(); GrameUtils.loadBasicCommands(); + GrameUtils.loadBasicAIs(); GrameManager.initialize(new SaveTest(), menuConfig); } diff --git a/src/com/moomoohk/Grame/test/TestScript.java b/src/com/moomoohk/Grame/test/TestScript.java index a1c3fe2..1c052de 100644 --- a/src/com/moomoohk/Grame/test/TestScript.java +++ b/src/com/moomoohk/Grame/test/TestScript.java @@ -5,7 +5,7 @@ import com.moomoohk.Grame.AI.SimpleChaseAI; import com.moomoohk.Grame.AI.SimpleStrollAI; -import com.moomoohk.Grame.Basics.Entity; +import com.moomoohk.Grame.Basics.OldEntity; import com.moomoohk.Grame.Essentials.Base; import com.moomoohk.Grame.Essentials.Coordinates; import com.moomoohk.Grame.Essentials.GrameManager; @@ -20,9 +20,9 @@ public static void main(String[] args) GrameUtils.loadBasicCommands(); Base b=new Base(20, 20); b.setWraparound(true); - Entity ent=new Entity(Color.blue); + OldEntity ent=new OldEntity(Color.blue); ent.setSpeed(1); - Entity ent2=new Entity(); + OldEntity ent2=new OldEntity(); ent2.setTarget(ent.ID); ent2.setSpeed(7); ent2.setRange(b.getDiagonal()); From f6180e29975a1060b9e6d99541af0fdf3b52ad50 Mon Sep 17 00:00:00 2001 From: Meshulam Silk Date: Sun, 24 Nov 2013 11:30:28 +0200 Subject: [PATCH 06/11] Fixed Schematics not loading into Bases - Fixed a few commands - Fixed NullPointerException in the Render Manager when exiting the engine - Finalized the Entity rewrite --- .../Grame/AI/AStarPathfindingMovementAI.java | 9 +- src/com/moomoohk/Grame/Basics/Dir.java | 10 +- src/com/moomoohk/Grame/Basics/Entity.java | 42 +- src/com/moomoohk/Grame/Basics/OldEntity.java | 416 ------------------ src/com/moomoohk/Grame/Basics/Schematic.java | 9 +- .../{test => Essentials}/EngineState.java | 3 +- .../Grame/Essentials/GrameManager.java | 1 - .../moomoohk/Grame/Essentials/GrameUtils.java | 12 +- .../Grame/Graphics/RenderManager.java | 101 +++-- .../Grame/GrassMuncher/MainScript.java | 1 - .../Grame/Interfaces/EntityGenerator.java | 1 - .../Grame/commands/ClearEntityAI.java | 6 +- .../Grame/commands/CreateEntityCommand.java | 14 +- .../Grame/commands/MakePlayerCommand.java | 10 +- .../Grame/commands/PrintEntityAICommand.java | 6 +- .../commands/SetEntityOverrideAICommand.java | 8 +- .../Grame/commands/setVisibleCommand.java | 21 +- src/com/moomoohk/Grame/test/AISystemTest.java | 18 +- src/com/moomoohk/Grame/test/ConsumeTest.java | 6 +- .../moomoohk/Grame/test/GrameObjectsTest.java | 31 +- src/com/moomoohk/Grame/test/SaveTest.java | 2 - src/com/moomoohk/Grame/test/TestCommand.java | 23 - src/com/moomoohk/Grame/test/TestScript.java | 34 +- 23 files changed, 195 insertions(+), 589 deletions(-) delete mode 100644 src/com/moomoohk/Grame/Basics/OldEntity.java rename src/com/moomoohk/Grame/{test => Essentials}/EngineState.java (95%) delete mode 100644 src/com/moomoohk/Grame/test/TestCommand.java diff --git a/src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java b/src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java index 23b1aad..5262569 100644 --- a/src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java +++ b/src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java @@ -5,7 +5,6 @@ import com.moomoohk.Grame.Basics.Dir; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Basics.OldEntity; import com.moomoohk.Grame.Basics.Schematic; import com.moomoohk.Grame.Essentials.Base; import com.moomoohk.Grame.Essentials.Coordinates; @@ -240,7 +239,6 @@ public String toString() public static void main(String[] args) { - GrameUtils.loadBasicCommands(); GrameManager.initialize(new AStarPathfindingMovementAI()); } @@ -249,8 +247,8 @@ public void newGame() { Base b = new Base(20, 20); b.setWraparound(true); - OldEntity player = new OldEntity("Player", Color.gray); - OldEntity monster = new OldEntity("Monster", Color.red); + Entity player = new Entity("Player", Color.gray); + Entity monster = new Entity("Monster", Color.red); b.addGrameObjectLayer(new GrameObjectLayer(b.getColumns(), b.getRows()), 1); player.makePlayer(1, true, b.ID); player.setSpeed(1); @@ -262,6 +260,9 @@ public void newGame() b.addGrameObject(monster, new Coordinates(18, 10), 1); for (int i = 1; i <= 10; i++) new Schematic().load(b, GrameUtils.randomCoordinates(b)); +// Schematic s = new Schematic(1); +// System.out.println(s.toString()); +// s.load(b, new Coordinates(10, 10)); RenderManager.render(b.ID, new PlainGridRender()); RenderManager.setVisible(true); aStar.showVisualization = true; diff --git a/src/com/moomoohk/Grame/Basics/Dir.java b/src/com/moomoohk/Grame/Basics/Dir.java index 7b3a126..f793f46 100644 --- a/src/com/moomoohk/Grame/Basics/Dir.java +++ b/src/com/moomoohk/Grame/Basics/Dir.java @@ -11,6 +11,7 @@ */ public class Dir extends Coordinates { + private static final long serialVersionUID = -8957814328221236455L; /** * Up Dir. */ @@ -140,8 +141,7 @@ public String toString() * * @param key * Key code of key to parse. - * @return A Dir representing the key. If the parse fails, null will be - * returned. + * @return A Dir representing the key. If the parse fails, null will be returned. */ public static Dir parseKey(int key) { @@ -172,8 +172,7 @@ public boolean isDiag() /** * Splits diagonal Dirs into two non-diagonal Dirs. *

- * If this Dir is not diagonal the array that is returned will contain this - * Dir. + * If this Dir is not diagonal the array that is returned will contain this Dir. * * @return A Dir[] containing two non-diagonal Dirs. */ @@ -214,7 +213,6 @@ public boolean equals(Dir d) */ public static Dir[] getAllDirs() { - return new Dir[] - { UP, DOWN, LEFT, RIGHT, new Dir(1, 1), new Dir(1, -1), new Dir(-1, -1), new Dir(-1, 1) }; + return new Dir[] { UP, DOWN, LEFT, RIGHT, new Dir(1, 1), new Dir(1, -1), new Dir(-1, -1), new Dir(-1, 1) }; } } diff --git a/src/com/moomoohk/Grame/Basics/Entity.java b/src/com/moomoohk/Grame/Basics/Entity.java index 5692c36..02dba5b 100644 --- a/src/com/moomoohk/Grame/Basics/Entity.java +++ b/src/com/moomoohk/Grame/Basics/Entity.java @@ -48,7 +48,7 @@ public Entity(Color c, int speed) { this(new DefaultRandomGen().nameGen(), c, speed); } - + public Entity(String name, Color c) { this(name, c, 5); @@ -124,7 +124,7 @@ private void determineAI(int bID) this.activeAI.put(bID, this.overrideAI.get(bID)); } } - + public void addAI(MovementAI AI, int bID) { if (!AI.isOverride()) @@ -136,6 +136,38 @@ public void addAI(MovementAI AI, int bID) else GrameUtils.print(AI + " is an override AI, it doens't belong in my AI list!", MessageLevel.ERROR); } + + public void printAI() + { + GrameUtils.print("Override AIs:", MessageLevel.NORMAL); + if (overrideAI.size() != 0) + for (int bID : overrideAI.keySet()) + GrameUtils.print(bID + ": " + overrideAI.get(bID) + " (" + overrideAI.get(bID).author() + ")", MessageLevel.NORMAL); + else + GrameUtils.print("[Empty]", MessageLevel.NORMAL); + GrameUtils.print("Active AIs:", MessageLevel.NORMAL); + if (activeAI.size() != 0) + for (int bID : activeAI.keySet()) + GrameUtils.print(bID + ": " + activeAI.get(bID) + " (" + activeAI.get(bID).author() + ")", MessageLevel.NORMAL); + else + GrameUtils.print("[Empty]", MessageLevel.NORMAL); + for (int bID : AI.keySet()) + { + GrameUtils.print("For base ID:" + bID, MessageLevel.NORMAL); + String st = "null"; + if (this.AI.size() == 0) + GrameUtils.print("My AI list is empty!", MessageLevel.ERROR); + else + for (int i = 0; i < this.AI.size(); i++) + { + st = "null"; + if (this.AI.get(i) != null) + st = this.AI.get(i) + " (" + ((MovementAI) this.AI.get(bID).get(i)).author() + ")"; + GrameUtils.print(i + 1 + ") " + st, MessageLevel.NORMAL); + } + } + } + public void clearAI() { @@ -143,7 +175,7 @@ public void clearAI() this.activeAI = null; this.overrideAI = null; } - + public void setOverrideAI(MovementAI mai, int bID) { if (mai.isOverride()) @@ -201,8 +233,8 @@ public void setTarget(int eID) GrameUtils.print("Cannot set that Entity (ID:" + eID + ") as target for Entity with ID:" + ID + " (Entity not found)", MessageLevel.ERROR); } - public OldEntity getTarget() + public Entity getTarget() { - return (OldEntity) (GrameManager.findGrameObject(this.targetID)); + return (Entity) (GrameManager.findGrameObject(this.targetID)); } } diff --git a/src/com/moomoohk/Grame/Basics/OldEntity.java b/src/com/moomoohk/Grame/Basics/OldEntity.java deleted file mode 100644 index 9d804c2..0000000 --- a/src/com/moomoohk/Grame/Basics/OldEntity.java +++ /dev/null @@ -1,416 +0,0 @@ -package com.moomoohk.Grame.Basics; - -import java.awt.Color; -import java.util.ArrayList; -import java.util.HashMap; - -import com.moomoohk.Grame.AI.PlayerMovementAI; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Essentials.GrameUtils; -import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; -import com.moomoohk.Grame.GrassMuncher.Coin; -import com.moomoohk.Grame.Interfaces.EntityGenerator; -import com.moomoohk.Grame.Interfaces.GrameObject; -import com.moomoohk.Grame.Interfaces.MovementAI; - -/** - * Entities are ready to use {@link GrameObject}s which have a lot of configurable aspects. - * - * @author Meshulam Silk - * @version 1.0 - * @since 2013-04-05 - */ -public class OldEntity extends GrameObject -{ - private static final long serialVersionUID = 2137967921422181555L; - private String type; - private int level; - private int range; - private int points; - private HashMap player; - private int targetID; - protected EntityGenerator randomGen; - private HashMap activeAI; - private HashMap overrideAI; - private HashMap> AI; - - /** - * Constructor. - */ - public OldEntity() - { - this(new DefaultRandomGen().nameGen(), new DefaultRandomGen().typeGen(), 1, GrameUtils.randomColor()); - } - - /** - * Constructor. - * - * @param c - * Entity color. - */ - public OldEntity(Color c) - { - this(new DefaultRandomGen().nameGen(), new DefaultRandomGen().typeGen(), 1, c); - } - - /** - * Constructor. - * - * @param entGen - * {@link EntityGenerator} to use. - */ - public OldEntity(EntityGenerator entGen) - { - this(entGen.nameGen(), entGen.typeGen(), 1, GrameUtils.randomColor()); - } - - public OldEntity(String name) - { - this(name, "", 0, GrameUtils.randomColor()); - } - - public OldEntity(String name, Color color) - { - this(name, "", 0, color); - } - - /** - * Constructor. - * - * @param name - * Entity name. - * @param type - * Entity type. - * @param level - * Starting level. - * @param color - * Entity color. - */ - public OldEntity(String name, String type, int level, Color color) - { - super(name, 5, color, false); - this.setType(type); - this.setLevel(level); - this.player = new HashMap(); - this.targetID = -1; - this.range = 5; - this.setPoints(0); - this.AI = new HashMap>(); - this.activeAI = new HashMap(); - this.overrideAI = new HashMap(); - } - - public void tick(int bID) - { - determineAI(bID); - Coordinates c = getPos(bID); - Coordinates target = null; - if (this.targetID != -1) - target = GrameManager.findGrameObject(this.targetID).getPos(bID); - if (this.activeAI.size() != 0 && this.activeAI.get(bID) != null) - c = this.activeAI.get(bID).getNext(getPos(bID), target, GrameManager.findBase(bID), this, (OldEntity) GrameManager.findGrameObject(targetID)); - setPos(bID, c); - } - - private void determineAI(int bID) - { - if (!GrameManager.findBase(bID).containsGrameObject(ID) || (this.AI.get(bID) == null && this.overrideAI.get(bID) == null) || (this.AI.get(bID) != null && this.AI.get(bID).size() == 0 && this.overrideAI.get(bID) == null)) - { - this.activeAI.remove(bID); - return; - } - if (this.overrideAI.size() == 0 || this.overrideAI.get(bID) == null) - { - MovementAI temp = null; - for (int i = 0; i < this.AI.get(bID).size(); i++) - { - Coordinates target = null; - if (targetID != -1) - target = GrameManager.findGrameObject(targetID).getPos(bID); - if (!this.AI.get(bID).get(i).isValid(getPos(bID), target, GrameManager.findBase(bID), this, (OldEntity) GrameManager.findGrameObject(targetID))) - continue; - temp = (MovementAI) this.AI.get(bID).get(i); - break; - } - this.activeAI.put(bID, temp); - } - else - { - this.activeAI.put(bID, this.overrideAI.get(bID)); - } - } - - /** - * Prints the {@link MovementAI} list of this Entity. - */ - public void printAI() - { - GrameUtils.print("Override AIs:", MessageLevel.NORMAL); - if (overrideAI.size() != 0) - for (int bID : overrideAI.keySet()) - GrameUtils.print(bID + ": " + overrideAI.get(bID) + " (" + overrideAI.get(bID).author() + ")", MessageLevel.NORMAL); - else - GrameUtils.print("[Empty]", MessageLevel.NORMAL); - GrameUtils.print("Active AIs:", MessageLevel.NORMAL); - if (activeAI.size() != 0) - for (int bID : activeAI.keySet()) - GrameUtils.print(bID + ": " + activeAI.get(bID) + " (" + activeAI.get(bID).author() + ")", MessageLevel.NORMAL); - else - GrameUtils.print("[Empty]", MessageLevel.NORMAL); - for (int bID : AI.keySet()) - { - GrameUtils.print("For base ID:" + bID, MessageLevel.NORMAL); - String st = "null"; - if (this.AI.size() == 0) - GrameUtils.print("My AI list is empty!", MessageLevel.ERROR); - else - for (int i = 0; i < this.AI.size(); i++) - { - st = "null"; - if (this.AI.get(i) != null) - st = this.AI.get(i) + " (" + ((MovementAI) this.AI.get(bID).get(i)).author() + ")"; - GrameUtils.print(i + 1 + ") " + st, MessageLevel.NORMAL); - } - } - } - - /** - * Adds a {@link MovementAI} to this Entity's AI list. - * - * @param AI - * {@link MovementAI} to add. - * @param bID - * The {@link Base#ID} of the {@link Base} in which to apply the {@link MovementAI}. - */ - public void addAI(MovementAI AI, int bID) - { - if (!AI.isOverride()) - { - if (this.AI.get(bID) == null) - this.AI.put(bID, new ArrayList()); - this.AI.get(bID).add(AI); - } - else - GrameUtils.print(AI + " is an override AI, it doens't belong in my AI list!", MessageLevel.ERROR); - } - - /** - * Clears this Entity's AI list. - */ - public void clearAI() - { - this.AI = new HashMap>(); - this.activeAI = null; - this.overrideAI = null; - } - - /** - * Sets the override for this Entity. - * - * @param mai - * {@link MovementAI} which is an override AI. - * @param bID - * The {@link Base#ID} of the {@link Base} in which to apply the {@link MovementAI}. - */ - public void setOverrideAI(MovementAI mai, int bID) - { - if (mai.isOverride()) - this.overrideAI.put(bID, mai); - else - GrameUtils.print(mai + " is not an override AI!", MessageLevel.ERROR); - } - - /** - * Checks whether this Entity has reached its target. - * - * @param bID - * {@link Base#ID} of the {@link Base} in which to check. - * @return True if this Entity reached its target, else false. - */ - public boolean reachedTarget(int bID) - { - return (targetID != -1) && (this.getPos(bID).distance(GrameManager.findGrameObject(targetID).getPos(bID)) == 1); - } - - public Coordinates getPos(int bID) - { - if (GrameManager.findBase(bID).containsGrameObject(ID)) - return GrameManager.findBase(bID).getGrameObjectPos(ID); - GrameUtils.print("Base with ID:" + bID + " does not contain Entity with ID:" + ID + ". Returning null.", MessageLevel.ERROR); - return null; - } - - public void setPos(int bID, Coordinates pos) - { - if (GrameManager.findBase(bID).containsGrameObject(ID)) - { - GrameManager.findBase(bID).moveGrameObject(ID, pos); - return; - } - } - - /** - * Checks whether or not this Entity is a "player" (controllable by the keyboard). - * - * @param bID - * The {@link Base#ID} of the {@link Base} in which to check. - * @return True if this Entity is a "player", else false. - * @see OldEntity#makePlayer(int, boolean, int) - */ - public boolean isPlayer(int bID) - { - if (this.player.get(bID) == null) - return false; - return this.player.get(bID); - } - - /** - * Turns this Entity into a "player". - * - * @param player - * 1 for wasd control, 2 for arrow keys control. - * @param f - * True to turn this Entity into a "player", else false. - * @param bID - * The {@link Base#ID} of the {@link Base} in which to turn this Entity into a "player". - * @see OldEntity#isPlayer(int) - */ - public void makePlayer(int player, boolean f, int bID) - { - if (f) - { - this.player.put(bID, true); - this.overrideAI.put(bID, new PlayerMovementAI(player)); - } - else - if (this.player.get(bID)) - { - this.player.put(bID, false); - this.overrideAI.remove(bID); - } - else - GrameUtils.print("Not a player!", MessageLevel.ERROR); - } - - /** - * Sets the target of this Entity. - * - * @param eID - * The {@link GrameObject#ID} of the {@link GrameObject}/Entity to set as target. - */ - public void setTarget(int eID) - { - if (GrameManager.findGrameObject(eID) != null) - this.targetID = eID; - else - GrameUtils.print("Cannot set that Entity (ID:" + eID + ") as target for Entity with ID:" + ID + " (Entity not found)", MessageLevel.ERROR); - } - - /** - * Returns this Entity's target. - * - * @return This Entity's target. - */ - public OldEntity getTarget() - { - return (OldEntity) (GrameManager.findGrameObject(this.targetID)); - } - - /** - * Gets the range of this Entity. - * - * @return The range of this Entity. - */ - public int getRange() - { - return this.range; - } - - /** - * Sets the range of this Entity. - * - * @param range - * The range to set. - */ - public void setRange(int range) - { - this.range = range; - } - - public boolean isCollidable() - { - return true; - } - - /** - * Sets the type of this Entity. - * - * @param type - * The type to set. - */ - public void setType(String type) - { - this.type = type; - } - - /** - * Gets the type of this Entity. - * - * @return The type of this Entity. - */ - public String getType() - { - return type; - } - - /** - * Sets the level of this Entity. - * - * @param level - * The level to set. - */ - public void setLevel(int level) - { - this.level = level; - } - - /** - * Gets the level of this Entity. - * - * @return The level of this Entity. - */ - public int getLevel() - { - return level; - } - - /** - * Sets the points of this Entity. - * - * @param points - * The points to set. - */ - public void setPoints(int points) - { - this.points = points; - } - - /** - * Gets the points of this Entity. - * - * @return The points of this Entity. - */ - public int getPoints() - { - return points; - } - - @Override - public void consume(GrameObject go) - { - if (go instanceof Coin) - this.points += ((Coin) go).getWorth(); - } -} diff --git a/src/com/moomoohk/Grame/Basics/Schematic.java b/src/com/moomoohk/Grame/Basics/Schematic.java index 6f16533..ef5b4a1 100644 --- a/src/com/moomoohk/Grame/Basics/Schematic.java +++ b/src/com/moomoohk/Grame/Basics/Schematic.java @@ -37,7 +37,6 @@ public Schematic() */ public Schematic(int type) { - System.out.println(type); this.type = type; this.map = new Color[5][5]; this.height = this.map.length; @@ -416,14 +415,8 @@ public void load(Base b, Coordinates loc) for (int j = loc.getX(); j < loc.getX() + this.width; j++) { mapx = j; - //System.out.println((this.map[sy][sx]==null)+" "+!b.isOccupied(new Coordinates(mapx, mapy))+" "+b.isInMap(new Coordinates(mapx, mapy))+" "+new Coordinates(mapx, mapy)); - if (this.map[sy][sx] == null) - continue; - if (b.isInBase(new Coordinates(mapx, mapy)) && !b.isOccupied(new Coordinates(mapx, mapy))) - { - // System.out.println("hi"); + if (this.map[sy][sx] != null && b.isInBase(new Coordinates(mapx, mapy)) && !b.isOccupied(new Coordinates(mapx, mapy))) b.addGrameObject(new Wall(getColor(new Coordinates(sx, sy))), new Coordinates(mapx, mapy)); - } sx++; } sx = 0; diff --git a/src/com/moomoohk/Grame/test/EngineState.java b/src/com/moomoohk/Grame/Essentials/EngineState.java similarity index 95% rename from src/com/moomoohk/Grame/test/EngineState.java rename to src/com/moomoohk/Grame/Essentials/EngineState.java index 3f64835..8b45af5 100644 --- a/src/com/moomoohk/Grame/test/EngineState.java +++ b/src/com/moomoohk/Grame/Essentials/EngineState.java @@ -1,4 +1,4 @@ -package com.moomoohk.Grame.test; +package com.moomoohk.Grame.Essentials; import java.io.Serializable; import java.text.SimpleDateFormat; @@ -7,7 +7,6 @@ import java.util.Date; import java.util.GregorianCalendar; -import com.moomoohk.Grame.Essentials.Base; import com.moomoohk.Grame.Interfaces.GrameObject; import com.moomoohk.Grame.Interfaces.Render; diff --git a/src/com/moomoohk/Grame/Essentials/GrameManager.java b/src/com/moomoohk/Grame/Essentials/GrameManager.java index 61282f7..85e7ea1 100644 --- a/src/com/moomoohk/Grame/Essentials/GrameManager.java +++ b/src/com/moomoohk/Grame/Essentials/GrameManager.java @@ -49,7 +49,6 @@ import com.moomoohk.Grame.Interfaces.MainGrameClass; import com.moomoohk.Grame.Interfaces.MovementAI; import com.moomoohk.Grame.Interfaces.Render; -import com.moomoohk.Grame.test.EngineState; import com.moomoohk.Grame.test.MenuConfiguration; import com.moomoohk.Mootilities.FileUtils.FileUtils; import com.moomoohk.Mootilities.FrameDragger.FrameDragger; diff --git a/src/com/moomoohk/Grame/Essentials/GrameUtils.java b/src/com/moomoohk/Grame/Essentials/GrameUtils.java index 3e86dbb..00e33c0 100644 --- a/src/com/moomoohk/Grame/Essentials/GrameUtils.java +++ b/src/com/moomoohk/Grame/Essentials/GrameUtils.java @@ -91,6 +91,8 @@ public class GrameUtils System.out.println("Get it at: https://github.com/moomoohk/MooConsole/raw/master/Build/MooConsole.jar"); System.exit(0); } + loadBasicCommands(); + loadBasicAIs(); } /** @@ -457,10 +459,7 @@ public void mouseClicked(MouseEvent arg0) return link; } - /** - * Loads some basic commands. - */ - public static void loadBasicCommands() + private static void loadBasicCommands() { int prevLength = CommandsManager.getAllCommands().size(); new HelpCommand(); @@ -483,10 +482,7 @@ public static void loadBasicCommands() print("Loaded " + (CommandsManager.getAllCommands().size() - prevLength) + " commands.", MessageLevel.DEBUG); } - /** - * Loads some basic AIs. - */ - public static void loadBasicAIs() + private static void loadBasicAIs() { GrameManager.addAI(new SimpleStrollAI()); GrameManager.addAI(new PlayerMovementAI(1)); diff --git a/src/com/moomoohk/Grame/Graphics/RenderManager.java b/src/com/moomoohk/Grame/Graphics/RenderManager.java index 35a173c..8e49204 100644 --- a/src/com/moomoohk/Grame/Graphics/RenderManager.java +++ b/src/com/moomoohk/Grame/Graphics/RenderManager.java @@ -4,7 +4,6 @@ import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; -import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.RenderingHints; @@ -79,7 +78,7 @@ public static void render(final int bID, Render render) if (bID < 0) return; setupFrame(bID); - if (bID != mainBase) + if (bID != mainBase || GrameManager.findBase(bID) == null) GrameManager.setMainBase(bID); mainBase = bID; mainFrame.setTitle(GrameManager.getGameName()); @@ -105,71 +104,79 @@ public static void render(final int bID, Render render) { return; } - Graphics g = bs.getDrawGraphics(); + Graphics2D g2 = (Graphics2D) bs.getDrawGraphics().create(); - g.setFont(new Font("LucidaTypewriter", 1, 8)); - int squaresize = mainCanvas.getWidth() / GrameManager.findBase(bID).getColumns(); //FIXME: Nullpointer + g2.setFont(new Font("LucidaTypewriter", 1, 8)); + int squaresize = mainCanvas.getWidth() / GrameManager.findBase(bID).getColumns(); for (int x = 0; x < GrameManager.findBase(bID).getColumns(); x++) for (int y = 0; y < GrameManager.findBase(bID).getRows(); y++) if (text.get(bID) != null) { if (text.get(bID).getText(new Coordinates(x, y)) != null && text.get(bID).getText(new Coordinates(x, y)).trim().length() != 0) { - g.setColor(text.get(bID).getColor(new Coordinates(x, y))); - g.drawString(text.get(bID).getText(new Coordinates(x, y)), y * squaresize, (x + 1) * (squaresize) - ((squaresize / 2) - 5)); + g2.setColor(text.get(bID).getColor(new Coordinates(x, y))); + g2.drawString(text.get(bID).getText(new Coordinates(x, y)), y * squaresize, (x + 1) * (squaresize) - ((squaresize / 2) - 5)); } } - if (GrameManager.paused) + if (!GrameManager.paused) + g2.drawImage(img, 0, 0, mainCanvas.getWidth(), mainCanvas.getHeight(), null); + else { - g.drawImage(new GaussianFilter().filter(img), 0, 0, mainCanvas.getWidth(), mainCanvas.getHeight(), null); - - Graphics2D g2 = (Graphics2D) g.create(); - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - - g2.setColor(new Color(Color.gray.getRed(), Color.gray.getGreen(), Color.gray.getBlue(), 127)); - g2.fillRect(0, 0, mainCanvas.getWidth(), mainCanvas.getHeight()); - - int textCenterX = mainCanvas.getWidth() / 2, textCenterY = mainCanvas.getHeight() / 2; - String text = "Paused"; - g2.setFont(new Font("LucidaTypewriter", Font.BOLD, 40)); - FontMetrics fm = g2.getFontMetrics(); - Rectangle2D textBounds = fm.getStringBounds(text, g2); - Rectangle fixed = new Rectangle((int) (textCenterX - (textBounds.getWidth() / 2)), (int) (textCenterY - (textBounds.getHeight() / 2)), (int) textBounds.getWidth(), (int) textBounds.getHeight()); - - int inPadUp = 10, inPadDown = 10, inPadRight = 10, inPadLeft = 10; - Rectangle back = new Rectangle((int) fixed.getX() - inPadLeft, (int) fixed.getY() - inPadUp, (int) (fixed.getWidth()) + inPadRight + inPadLeft, (int) (fixed.getHeight()) + inPadDown + inPadUp); - g2.setColor(Color.black); - g2.fillRoundRect((int) back.getX(), (int) back.getY(), (int) back.getWidth(), (int) back.getHeight(), (inPadRight + inPadLeft) / 2, (inPadUp + inPadDown) / 2); - g2.setColor(new Color(255, 255, 255, 200)); - g2.drawString(text, (int) (fixed.getX()), (int) (fixed.getY() + Math.max(fm.getMaxAscent(), fm.getMaxDescent()))); - - // g2.setColor(Color.cyan); - // g2.draw(new Ellipse2D.Double(textCenterX - 5, textCenterY - 5, 10, 10)); - // g2.setColor(Color.blue); - // g2.draw(back); - // g2.setColor(Color.green); - // g2.draw(textBounds); - // g2.setColor(Color.red); - // g2.draw(fixed); - // g2.fill(new Ellipse2D.Double(fixed.getCenterX() - 2, fixed.getCenterY() - 2, 4, 4)); - - g2.dispose(); + applyGaussianBlur(g2, img); + setOverlayColor(Color.gray.brighter(), g2); + showMainText("Paused", g2); } - else - g.drawImage(img, 0, 0, mainCanvas.getWidth(), mainCanvas.getHeight(), null); if (drawCoordinates) { - // squaresize = mainCanvas.getWidth() / GrameManager.findBase(bID).getColumns(); - g.setColor(Color.blue); + g2.setColor(Color.blue); for (int x = 0; x < GrameManager.findBase(bID).getColumns(); x++) for (int y = 0; y < GrameManager.findBase(bID).getRows(); y++) - g.drawString("(" + y + ", " + x + ")", y * squaresize, (x + 1) * (squaresize) - ((squaresize / 2) - 5)); + g2.drawString("(" + y + ", " + x + ")", y * squaresize, (x + 1) * (squaresize) - ((squaresize / 2) - 5)); } - g.dispose(); + g2.dispose(); bs.show(); } + public static void applyGaussianBlur(Graphics2D g2, BufferedImage img) + { + g2.drawImage(new GaussianFilter().filter(img), 0, 0, mainCanvas.getWidth(), mainCanvas.getHeight(), null); + } + + public static void showMainText(String text, Graphics2D g2) + { + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + int textCenterX = mainCanvas.getWidth() / 2, textCenterY = mainCanvas.getHeight() / 2; + g2.setFont(new Font("PT Sans", Font.BOLD, 40)); + FontMetrics fm = g2.getFontMetrics(); + Rectangle2D textBounds = fm.getStringBounds(text, g2); + Rectangle fixed = new Rectangle((int) (textCenterX - (textBounds.getWidth() / 2)), (int) (textCenterY - (textBounds.getHeight() / 2)), (int) textBounds.getWidth(), (int) textBounds.getHeight()); + + int inPadUp = 10, inPadDown = 10, inPadRight = 10, inPadLeft = 10; + Rectangle back = new Rectangle((int) fixed.getX() - inPadLeft, (int) fixed.getY() - inPadUp, (int) (fixed.getWidth()) + inPadRight + inPadLeft, (int) (fixed.getHeight()) + inPadDown + inPadUp); + g2.setColor(new Color(0, 0, 0, 200)); + g2.fillRoundRect((int) back.getX(), (int) back.getY(), (int) back.getWidth(), (int) back.getHeight(), (inPadRight + inPadLeft) / 2, (inPadUp + inPadDown) / 2); + g2.setColor(new Color(255, 255, 255, 200)); + g2.drawString(text, (int) (fixed.getX()), (int) (fixed.getY() + Math.max(fm.getMaxAscent(), fm.getMaxDescent()))); + + // g2.setColor(Color.cyan); + // g2.draw(new Ellipse2D.Double(textCenterX - 5, textCenterY - 5, 10, 10)); + // g2.setColor(Color.blue); + // g2.draw(back); + // g2.setColor(Color.green); + // g2.draw(textBounds); + // g2.setColor(Color.red); + // g2.draw(fixed); + // g2.fill(new Ellipse2D.Double(fixed.getCenterX() - 2, fixed.getCenterY() - 2, 4, 4)); + } + + public static void setOverlayColor(Color color, Graphics2D g2) + { + g2.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 127)); + g2.fillRect(0, 0, mainCanvas.getWidth(), mainCanvas.getHeight()); + } + /** * Generates a blank {@link Canvas} which is of the required size. * diff --git a/src/com/moomoohk/Grame/GrassMuncher/MainScript.java b/src/com/moomoohk/Grame/GrassMuncher/MainScript.java index 09b8e40..4cec59b 100644 --- a/src/com/moomoohk/Grame/GrassMuncher/MainScript.java +++ b/src/com/moomoohk/Grame/GrassMuncher/MainScript.java @@ -25,7 +25,6 @@ public class MainScript implements MainGrameClass public static void main(String[] args) { - GrameUtils.loadBasicCommands(); GrameManager.initialize(new MainScript()); } diff --git a/src/com/moomoohk/Grame/Interfaces/EntityGenerator.java b/src/com/moomoohk/Grame/Interfaces/EntityGenerator.java index bb619b7..25a5050 100644 --- a/src/com/moomoohk/Grame/Interfaces/EntityGenerator.java +++ b/src/com/moomoohk/Grame/Interfaces/EntityGenerator.java @@ -1,6 +1,5 @@ package com.moomoohk.Grame.Interfaces; -import com.moomoohk.Grame.Basics.OldEntity; /** * This interface is used to create generators which generate names and types diff --git a/src/com/moomoohk/Grame/commands/ClearEntityAI.java b/src/com/moomoohk/Grame/commands/ClearEntityAI.java index 2950596..1762af2 100644 --- a/src/com/moomoohk/Grame/commands/ClearEntityAI.java +++ b/src/com/moomoohk/Grame/commands/ClearEntityAI.java @@ -2,7 +2,7 @@ import java.awt.Color; -import com.moomoohk.Grame.Basics.OldEntity; +import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; @@ -16,7 +16,7 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof OldEntity)) + if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof Entity)) { this.outputMessage = "Grame Object with ID:" + params[0] + " is not an Entity!"; this.outputColor = Color.red; @@ -33,7 +33,7 @@ public ClearEntityAI() @Override public void execute(String[] params) { - ((OldEntity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).clearAI(); + ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).clearAI(); } @Override diff --git a/src/com/moomoohk/Grame/commands/CreateEntityCommand.java b/src/com/moomoohk/Grame/commands/CreateEntityCommand.java index a288ab8..ae8a8b4 100644 --- a/src/com/moomoohk/Grame/commands/CreateEntityCommand.java +++ b/src/com/moomoohk/Grame/commands/CreateEntityCommand.java @@ -5,7 +5,6 @@ import com.moomoohk.Grame.Basics.DefaultRandomGen; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Basics.OldEntity; import com.moomoohk.Grame.Essentials.GrameUtils; import com.moomoohk.MooCommands.Command; import com.moomoohk.MooCommands.CommandsManager; @@ -20,16 +19,17 @@ public CreateEntityCommand() @Override public void execute(String[] arg1) { - String type = new DefaultRandomGen().typeGen(), name = new DefaultRandomGen().nameGen(); - int level = 0; +// String type = new DefaultRandomGen().typeGen(), + String name = new DefaultRandomGen().nameGen(); +// int level = 0; Color color = GrameUtils.randomColor(); HashMap flags = CommandsManager.parseFlags(arg1); - if (flags.get("t") != null) - type = flags.get("t"); +// if (flags.get("t") != null) +// type = flags.get("t"); if (flags.get("n") != null) name = flags.get("n"); - if (flags.get("l") != null) - level = Integer.parseInt(flags.get("l")); +// if (flags.get("l") != null) +// level = Integer.parseInt(flags.get("l")); new Entity(name, color); } diff --git a/src/com/moomoohk/Grame/commands/MakePlayerCommand.java b/src/com/moomoohk/Grame/commands/MakePlayerCommand.java index fb4074d..3575915 100644 --- a/src/com/moomoohk/Grame/commands/MakePlayerCommand.java +++ b/src/com/moomoohk/Grame/commands/MakePlayerCommand.java @@ -2,7 +2,7 @@ import java.awt.Color; -import com.moomoohk.Grame.Basics.OldEntity; +import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; @@ -30,12 +30,12 @@ public void execute(String[] params) if (params[0].equalsIgnoreCase("all")) { for (int i = 0; i < GrameManager.getObjectListLength(); i++) - if (GrameManager.findGrameObject(i) instanceof OldEntity) - ((OldEntity) (GrameManager.findGrameObject(i))).makePlayer(Integer.parseInt(params[1]), Boolean.parseBoolean(params[3]), Integer.parseInt(params[2])); + if (GrameManager.findGrameObject(i) instanceof Entity) + ((Entity) (GrameManager.findGrameObject(i))).makePlayer(Integer.parseInt(params[1]), Boolean.parseBoolean(params[3]), Integer.parseInt(params[2])); } else - if (GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof OldEntity) - ((OldEntity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).makePlayer(Integer.parseInt(params[1]), Boolean.parseBoolean(params[3]), Integer.parseInt(params[2])); + if (GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof Entity) + ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).makePlayer(Integer.parseInt(params[1]), Boolean.parseBoolean(params[3]), Integer.parseInt(params[2])); } @Override diff --git a/src/com/moomoohk/Grame/commands/PrintEntityAICommand.java b/src/com/moomoohk/Grame/commands/PrintEntityAICommand.java index 0a4776c..9ba0513 100644 --- a/src/com/moomoohk/Grame/commands/PrintEntityAICommand.java +++ b/src/com/moomoohk/Grame/commands/PrintEntityAICommand.java @@ -2,7 +2,7 @@ import java.awt.Color; -import com.moomoohk.Grame.Basics.OldEntity; +import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; @@ -22,7 +22,7 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof OldEntity)) + if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof Entity)) { this.outputMessage = "Grame Object with ID:" + params[0] + " is not an Entity!"; this.outputColor = Color.red; @@ -34,7 +34,7 @@ public boolean check(String[] params) @Override public void execute(String[] params) { - ((OldEntity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).printAI(); + ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).printAI(); } @Override diff --git a/src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java b/src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java index 26f7239..26cc26f 100644 --- a/src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java +++ b/src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java @@ -2,7 +2,7 @@ import java.awt.Color; -import com.moomoohk.Grame.Basics.OldEntity; +import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.MooCommands.Command; @@ -22,7 +22,7 @@ protected boolean check(String[] params) this.outputColor = Color.red; return false; } - if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof OldEntity)) + if (!(GrameManager.findGrameObject(Integer.parseInt(params[0])) instanceof Entity)) { this.outputMessage = "Grame Object with ID:" + params[0] + " is not an Entity!"; this.outputColor = Color.red; @@ -55,9 +55,9 @@ protected boolean check(String[] params) public void execute(String[] params) { if (!params[2].equalsIgnoreCase("null")) - ((OldEntity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).setOverrideAI(GrameManager.getAIs().get(params[2]), Integer.parseInt(params[1])); + ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).setOverrideAI(GrameManager.getAIs().get(params[2]), Integer.parseInt(params[1])); else - ((OldEntity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).setOverrideAI(null, Integer.parseInt(params[1])); + ((Entity) (GrameManager.findGrameObject(Integer.parseInt(params[0])))).setOverrideAI(null, Integer.parseInt(params[1])); } @Override diff --git a/src/com/moomoohk/Grame/commands/setVisibleCommand.java b/src/com/moomoohk/Grame/commands/setVisibleCommand.java index 5eceef6..e8a47e7 100644 --- a/src/com/moomoohk/Grame/commands/setVisibleCommand.java +++ b/src/com/moomoohk/Grame/commands/setVisibleCommand.java @@ -15,16 +15,17 @@ public SetVisibleCommand() public boolean check(String[] params) { - try - { - Boolean.parseBoolean(params[0]); - } - catch (Exception e) - { - this.outputMessage = "Only true or false are accepted inputs!"; - this.outputColor = Color.red; - return false; - } + if (params.length > 0) + try + { + Boolean.parseBoolean(params[0]); + } + catch (Exception e) + { + this.outputMessage = "Only true or false are accepted inputs!"; + this.outputColor = Color.red; + return false; + } return true; } diff --git a/src/com/moomoohk/Grame/test/AISystemTest.java b/src/com/moomoohk/Grame/test/AISystemTest.java index af76cfe..4a6a4d3 100644 --- a/src/com/moomoohk/Grame/test/AISystemTest.java +++ b/src/com/moomoohk/Grame/test/AISystemTest.java @@ -5,7 +5,7 @@ import com.moomoohk.Grame.AI.PlayerSimAI; import com.moomoohk.Grame.AI.SimpleChaseAI; import com.moomoohk.Grame.AI.SimpleStrollAI; -import com.moomoohk.Grame.Basics.OldEntity; +import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Basics.Wall; import com.moomoohk.Grame.Essentials.Base; import com.moomoohk.Grame.Essentials.Coordinates; @@ -18,8 +18,6 @@ public class AISystemTest implements MainGrameClass { public static void main(String[] args) { - GrameUtils.loadBasicCommands(); - GrameUtils.loadBasicAIs(); GrameManager.initialize(new AISystemTest()); } @@ -27,7 +25,7 @@ public static void generateStrollers(int amount, Base b) { for (int i = 0; i < amount; i++) { - OldEntity ent = new OldEntity(); + Entity ent = new Entity(); ent.addAI(new SimpleStrollAI(), b.ID); ent.setSpeed(5); ent.setColor(Color.blue); @@ -38,11 +36,11 @@ public static void generateStrollers(int amount, Base b) } } - public static void generateChasers(Base b, int amount, OldEntity target) + public static void generateChasers(Base b, int amount, Entity target) { for (int i = 1; i <= amount; i++) { - OldEntity ent = new OldEntity(Color.red); + Entity ent = new Entity(Color.red); ent.addAI(new SimpleChaseAI(), b.ID); ent.setRange(b.getDiagonal()); ent.setTarget(target.ID); @@ -59,7 +57,7 @@ public static void generatePlayers(int number, int amount, Base b) { for (int i = 1; i <= amount; i++) { - OldEntity ent = new OldEntity(); + Entity ent = new Entity(); ent.makePlayer(number, true, b.ID); ent.setSpeed(1); ent.setColor(Color.green); @@ -74,7 +72,7 @@ public static void generatePlayerSims(int amount, Base b) { for (int i = 1; i <= amount; i++) { - OldEntity ent = new OldEntity(); + Entity ent = new Entity(); ent.setColor(Color.yellow); ent.setOverrideAI(new PlayerSimAI(), b.ID); ent.setSpeed(1); @@ -106,8 +104,8 @@ public void newGame() generatePlayers(1, 1, b); generatePlayerSims(1, b); generateStrollers(5, b); - generateChasers(b, 3, (OldEntity) GrameManager.findGrameObject(1)); - generateChasers(b, 3, (OldEntity) GrameManager.findGrameObject(0)); + generateChasers(b, 3, (Entity) GrameManager.findGrameObject(1)); + generateChasers(b, 3, (Entity) GrameManager.findGrameObject(0)); RenderManager.render(b.ID); RenderManager.setVisible(true); RenderManager.setText(b.ID, new Coordinates(6, 6), "test", Color.red); diff --git a/src/com/moomoohk/Grame/test/ConsumeTest.java b/src/com/moomoohk/Grame/test/ConsumeTest.java index 4517028..16efb97 100644 --- a/src/com/moomoohk/Grame/test/ConsumeTest.java +++ b/src/com/moomoohk/Grame/test/ConsumeTest.java @@ -1,10 +1,9 @@ package com.moomoohk.Grame.test; -import com.moomoohk.Grame.Basics.OldEntity; +import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Essentials.Base; import com.moomoohk.Grame.Essentials.Coordinates; import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Essentials.GrameUtils; import com.moomoohk.Grame.Graphics.RenderManager; import com.moomoohk.Grame.GrassMuncher.Coin; import com.moomoohk.Grame.Interfaces.GrameObject; @@ -12,7 +11,7 @@ public class ConsumeTest implements MainGrameClass { - public static class Player extends OldEntity + public static class Player extends Entity { private static final long serialVersionUID = -3253634438661661214L; @@ -24,7 +23,6 @@ public void consume(GrameObject go) public static void main(String[] args) { - GrameUtils.loadBasicCommands(); GrameManager.initialize(new ConsumeTest()); } diff --git a/src/com/moomoohk/Grame/test/GrameObjectsTest.java b/src/com/moomoohk/Grame/test/GrameObjectsTest.java index d7043b0..53cdcdf 100644 --- a/src/com/moomoohk/Grame/test/GrameObjectsTest.java +++ b/src/com/moomoohk/Grame/test/GrameObjectsTest.java @@ -1,20 +1,31 @@ package com.moomoohk.Grame.test; -import com.moomoohk.Grame.Basics.OldEntity; +import java.awt.Color; + +import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Essentials.Base; import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameUtils; +import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.Grame.Graphics.PlainGridRender; import com.moomoohk.Grame.Graphics.RenderManager; +import com.moomoohk.Grame.Interfaces.MainGrameClass; -public class GrameObjectsTest +public class GrameObjectsTest implements MainGrameClass { public static void main(String[] args) { - Base b=new Base(20, 20); - GrameUtils.loadBasicCommands(); - GrameUtils.loadBasicAIs(); - OldEntity ent=new OldEntity(); + MenuConfiguration menuConfig = new MenuConfiguration(); + menuConfig.menuButtonStartColor = Color.red; + menuConfig.menuButtonEndColor = Color.blue; + menuConfig.menuButtonClickColor = Color.yellow; + GrameManager.initialize(new GrameObjectsTest(), menuConfig); + } + + @Override + public void newGame() + { + Base b = new Base(20, 20); + Entity ent = new Entity(); b.addGrameObject(ent, new Coordinates(10, 10)); b.setWraparound(true); ent.makePlayer(1, true, b.ID); @@ -22,4 +33,10 @@ public static void main(String[] args) RenderManager.render(b.ID, new PlainGridRender()); RenderManager.setVisible(true); } + + @Override + public String getGameName() + { + return "Test"; + } } diff --git a/src/com/moomoohk/Grame/test/SaveTest.java b/src/com/moomoohk/Grame/test/SaveTest.java index 97acdc5..e8209ef 100644 --- a/src/com/moomoohk/Grame/test/SaveTest.java +++ b/src/com/moomoohk/Grame/test/SaveTest.java @@ -12,8 +12,6 @@ public class SaveTest implements MainGrameClass public static void main(String[] args) { MenuConfiguration menuConfig = new MenuConfiguration(); - GrameUtils.loadBasicCommands(); - GrameUtils.loadBasicAIs(); GrameManager.initialize(new SaveTest(), menuConfig); } diff --git a/src/com/moomoohk/Grame/test/TestCommand.java b/src/com/moomoohk/Grame/test/TestCommand.java deleted file mode 100644 index 8f78a32..0000000 --- a/src/com/moomoohk/Grame/test/TestCommand.java +++ /dev/null @@ -1,23 +0,0 @@ - -package com.moomoohk.Grame.test; - -import com.moomoohk.MooCommands.Command; -import com.moomoohk.MooConsole.Console; - -public class TestCommand extends Command -{ - public TestCommand(Console handler, String command, String help, int minParams, int maxParams) - { - super(handler, command, help, minParams, maxParams); - } - - @Override - public void execute(Console arg0, String[] arg1) - { - System.out.println("Hello world!"); - } -} - - - - diff --git a/src/com/moomoohk/Grame/test/TestScript.java b/src/com/moomoohk/Grame/test/TestScript.java index 1c052de..ea4104d 100644 --- a/src/com/moomoohk/Grame/test/TestScript.java +++ b/src/com/moomoohk/Grame/test/TestScript.java @@ -1,50 +1,55 @@ - package com.moomoohk.Grame.test; import java.awt.Color; import com.moomoohk.Grame.AI.SimpleChaseAI; import com.moomoohk.Grame.AI.SimpleStrollAI; -import com.moomoohk.Grame.Basics.OldEntity; +import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Essentials.Base; import com.moomoohk.Grame.Essentials.Coordinates; import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.Grame.Essentials.GrameUtils; import com.moomoohk.Grame.Graphics.RenderManager; import com.moomoohk.Grame.Interfaces.GrameObject; +import com.moomoohk.Grame.Interfaces.MainGrameClass; -public class TestScript +public class TestScript implements MainGrameClass { public static void main(String[] args) { - GrameUtils.loadBasicCommands(); - Base b=new Base(20, 20); + GrameManager.initialize(new TestScript()); + } + + @Override + public void newGame() + { + Base b = new Base(20, 20); b.setWraparound(true); - OldEntity ent=new OldEntity(Color.blue); + Entity ent = new Entity(Color.blue); ent.setSpeed(1); - OldEntity ent2=new OldEntity(); + Entity ent2 = new Entity(); ent2.setTarget(ent.ID); ent2.setSpeed(7); ent2.setRange(b.getDiagonal()); ent2.addAI(new SimpleChaseAI(), b.ID); ent2.addAI(new SimpleStrollAI(), b.ID); ent.makePlayer(1, true, b.ID); - GrameObject go=new GrameObject("test", 1, Color.black, false) + GrameObject go = new GrameObject("test", 1, Color.black, false) { private static final long serialVersionUID = -7904811686747660223L; @Override public void tick(int bID) { - this.color=GrameUtils.randomColor(); + this.color = GrameUtils.randomColor(); } - + @Override public boolean isCollidable() { return false; } - + @Override public void consume(GrameObject go) { @@ -59,5 +64,10 @@ public void consume(GrameObject go) RenderManager.render(b.ID, new SpriteRender()); RenderManager.setVisible(true); } -} + @Override + public String getGameName() + { + return "test"; + } +} From eadb35ec5d3fc5a0659d830b4afc1e686417f9c8 Mon Sep 17 00:00:00 2001 From: Meshulam Silk Date: Sun, 24 Nov 2013 14:55:46 +0200 Subject: [PATCH 07/11] Made the Node class serializable --- .../Grame/AI/AStarPathfindingMovementAI.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java b/src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java index 5262569..4eca04e 100644 --- a/src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java +++ b/src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java @@ -1,6 +1,7 @@ package com.moomoohk.Grame.AI; import java.awt.Color; +import java.io.Serializable; import java.util.ArrayList; import com.moomoohk.Grame.Basics.Dir; @@ -89,7 +90,7 @@ public Coordinates getNext(Coordinates pos, Coordinates targetPos, Base b, Entit } current = findLowestFCost(open); } - while (current.getPos() != targetPos); + while (current.getPos() != targetPos); //FIXME: NullPointerException when can't reach target Node node = getLast(closed.get(closed.size() - 1)); // visualizationColor = new Color(new Random().nextFloat(), new Random().nextFloat(), new Random().nextFloat()); @@ -181,8 +182,9 @@ public String toString() return "A* Pathfinding AI"; } - private static class Node + private static class Node implements Serializable { + private static final long serialVersionUID = -6786064237047397741L; private Coordinates pos; private Node parent; private double gCost, hCost, fCost; @@ -260,9 +262,9 @@ public void newGame() b.addGrameObject(monster, new Coordinates(18, 10), 1); for (int i = 1; i <= 10; i++) new Schematic().load(b, GrameUtils.randomCoordinates(b)); -// Schematic s = new Schematic(1); -// System.out.println(s.toString()); -// s.load(b, new Coordinates(10, 10)); + // Schematic s = new Schematic(1); + // System.out.println(s.toString()); + // s.load(b, new Coordinates(10, 10)); RenderManager.render(b.ID, new PlainGridRender()); RenderManager.setVisible(true); aStar.showVisualization = true; From 88bb2249d2c13b9a399d77a47625cd2b51103e11 Mon Sep 17 00:00:00 2001 From: Meshulam Silk Date: Sun, 24 Nov 2013 15:16:59 +0200 Subject: [PATCH 08/11] Started work on post processing stuff --- .../Grame/Essentials/GrameManager.java | 2 +- .../Grame/Graphics/PostProcessing/Label.java | 126 ++++++++++++++++++ .../Grame/Graphics/RenderManager.java | 59 ++++---- 3 files changed, 159 insertions(+), 28 deletions(-) create mode 100644 src/com/moomoohk/Grame/Graphics/PostProcessing/Label.java diff --git a/src/com/moomoohk/Grame/Essentials/GrameManager.java b/src/com/moomoohk/Grame/Essentials/GrameManager.java index 85e7ea1..8666d33 100644 --- a/src/com/moomoohk/Grame/Essentials/GrameManager.java +++ b/src/com/moomoohk/Grame/Essentials/GrameManager.java @@ -70,7 +70,7 @@ public class GrameManager implements Runnable /** * The Grame version number. */ - public static final String VERSION_NUMBER = "4.0.2"; + public static final String VERSION_NUMBER = "4.0.3"; /** * The WASD keys parsed to a {@link Dir}. */ diff --git a/src/com/moomoohk/Grame/Graphics/PostProcessing/Label.java b/src/com/moomoohk/Grame/Graphics/PostProcessing/Label.java new file mode 100644 index 0000000..bf04f98 --- /dev/null +++ b/src/com/moomoohk/Grame/Graphics/PostProcessing/Label.java @@ -0,0 +1,126 @@ +package com.moomoohk.Grame.Graphics.PostProcessing; + +import java.awt.Color; +import java.awt.Font; + +public class Label +{ + private int paddingTop, paddingLeft, paddingRight, paddingBottom, centerX, centerY; + private String text; + private Color textColor, backColor; + private Font font; + + public Label(int centerX, int centerY, String text, Font font, Color textColor, Color backColor, int paddingTop, int paddingLeft, int paddingRight, int paddingBottom) + { + this.centerX = centerX; + this.centerY = centerY; + this.text = text; + this.font = font; + this.textColor = textColor; + this.backColor = backColor; + this.paddingTop = paddingTop; + this.paddingLeft = paddingLeft; + this.paddingRight = paddingRight; + this.paddingBottom = paddingBottom; + } + + public void setPaddingRight(int paddingRight) + { + this.paddingRight = paddingRight; + } + + public int getPaddingRight() + { + return paddingRight; + } + + public void setCenterX(int centerX) + { + this.centerX = centerX; + } + + public int getCenterX() + { + return centerX; + } + + public void setPaddingLeft(int paddingLeft) + { + this.paddingLeft = paddingLeft; + } + + public int getPaddingLeft() + { + return paddingLeft; + } + + public void setPaddingBottom(int paddingBottom) + { + this.paddingBottom = paddingBottom; + } + + public int getPaddingBottom() + { + return paddingBottom; + } + + public void setPaddingTop(int paddingTop) + { + this.paddingTop = paddingTop; + } + + public int getPaddingTop() + { + return paddingTop; + } + + public void setText(String text) + { + this.text = text; + } + + public String getText() + { + return text; + } + + public void setTextColor(Color textColor) + { + this.textColor = textColor; + } + + public Color getTextColor() + { + return textColor; + } + + public void setCenterY(int centerY) + { + this.centerY = centerY; + } + + public int getCenterY() + { + return centerY; + } + + public void setBackColor(Color backColor) + { + this.backColor = backColor; + } + + public Color getBackColor() + { + return backColor; + } + + public void setFont(Font font) + { + this.font = font; + } + + public Font getFont() + { + return font; + } +} diff --git a/src/com/moomoohk/Grame/Graphics/RenderManager.java b/src/com/moomoohk/Grame/Graphics/RenderManager.java index 8e49204..22b7db7 100644 --- a/src/com/moomoohk/Grame/Graphics/RenderManager.java +++ b/src/com/moomoohk/Grame/Graphics/RenderManager.java @@ -14,6 +14,7 @@ import java.awt.image.BufferStrategy; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; +import java.util.ArrayList; import java.util.HashMap; import javax.swing.JFrame; @@ -23,6 +24,7 @@ import com.moomoohk.Grame.Essentials.GrameManager; import com.moomoohk.Grame.Essentials.GrameUtils; import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; +import com.moomoohk.Grame.Graphics.PostProcessing.Label; import com.moomoohk.Grame.Interfaces.Render; /** @@ -36,16 +38,20 @@ public class RenderManager { private static HashMap renders; private static HashMap text; + private static ArrayList

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

^uBb9cC`Ph)x#}I-CQSJW<<61j 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�px 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 literal 12292 zcmeI1y>1jS6os$D3RX#k(jcW{8t4O}H>-_M3ZzJRfvjc&LCR)V`_oTB1r+cCya5u= zK#O=C(sHh^1LLuW3KS%cqwyKp_xhfEGdr_RM8u6Y(*u!x5gFo8-P=J|XgaS)*0$nE z1$D@mdOlm&*!@p&jzR(?KmsH{0wnNn5x_fJ+py=oZ?o)4fCTrMkGqaF&koD#rP!jj5%Ji<=J@E4#QuaiKca zuR^#uZ_1toNFXOrVQ5R9%F)HkgOkqwJ&e!hL&AP{r6gbh`Mu`;b$V3GVOYJa;Fs2^6~b=S6wDw zr{$$LCh=nruWdO5jg_3i%^FlDa?$bRb|0f&F|Ot7`g-)lWt@s}sXuSO=QCNt)k4lo z*X+S2u;|1Td<`Xw$vkB-i61#uKf7@qW%gV)pjN}#nJm+L>E8F>#TNYauG_k<*Nl5( zQ@>vQZp%@)vT!Ibz_Etc&VB#zsxPkKv$$TtV=*rEcdGsdxa;6Z)+xV7U)pmmAD>^p z)3jfCt=idKT2DWJUUPBhH>UO(;QL=`u#v#c5x8Zg_jUh&*#Gzcn={DDBtQaxoq!vR zPsSsZiF@m;pzgIR9H%(6Xv=(1Pts*fCNZ@ c1W14cNPq-LfCNZ@1W14cNPq-L;Exjc0fx>3=l}o! diff --git a/src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java b/src/com/moomoohk/Grame/Basics/AI/AStarPathfindingMovementAI.java similarity index 73% rename from src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java rename to src/com/moomoohk/Grame/Basics/AI/AStarPathfindingMovementAI.java index e3df7b7..10cd6b8 100644 --- a/src/com/moomoohk/Grame/AI/AStarPathfindingMovementAI.java +++ b/src/com/moomoohk/Grame/Basics/AI/AStarPathfindingMovementAI.java @@ -1,4 +1,4 @@ -package com.moomoohk.Grame.AI; +package com.moomoohk.Grame.Basics.AI; import java.awt.Color; import java.io.Serializable; @@ -6,16 +6,16 @@ import com.moomoohk.Grame.Basics.Dir; import com.moomoohk.Grame.Basics.Entity; +import com.moomoohk.Grame.Basics.MovementAI; import com.moomoohk.Grame.Basics.Schematic; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Essentials.GrameObjectLayer; -import com.moomoohk.Grame.Essentials.GrameUtils; -import com.moomoohk.Grame.Graphics.PlainGridRender; -import com.moomoohk.Grame.Graphics.RenderManager; -import com.moomoohk.Grame.Interfaces.MainGrameClass; -import com.moomoohk.Grame.Interfaces.MovementAI; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.GrameObjectLayer; +import com.moomoohk.Grame.Core.GrameUtils; +import com.moomoohk.Grame.Core.Grid; +import com.moomoohk.Grame.Core.MainGrameClass; +import com.moomoohk.Grame.Core.Graphics.CleanGridRender; +import com.moomoohk.Grame.Core.Graphics.RenderManager; public class AStarPathfindingMovementAI extends MovementAI implements MainGrameClass { @@ -37,23 +37,23 @@ public String author() } @Override - public Coordinates getNext(Coordinates pos, Coordinates targetPos, Base b, Entity ent1, Entity ent2) + public Coordinates getNext(Coordinates pos, Coordinates targetPos, Grid g, Entity ent1, Entity ent2) { - if (ent1.getPos(b.ID).distance(ent2.getPos(b.ID)) == 1) + if (ent1.getPos(g.ID).distance(ent2.getPos(g.ID)) == 1) return pos; if (cachedTargetPos != null) if (cachedTargetPos.equals(targetPos)) { Node last = getLast(cachedNodePath.get(cachedNodePath.size() - 1)); - if (cachedNodePath.remove(last)) //TODO: Fix this list + if (cachedNodePath.remove(last)) return last.getPos(); } else { if (showVisualization) - b.setFloorColor(Color.white); + g.setFloorColor(Color.white); if (showCosts) - RenderManager.clearText(b.ID); + RenderManager.clearText(g.ID); cachedTargetPos = targetPos; } else @@ -70,11 +70,11 @@ public Coordinates getNext(Coordinates pos, Coordinates targetPos, Base b, Entit if (!current.getPos().equals(pos)) closed.add(current); open.remove(current); - if (current.getPos().distance(ent2.getPos(b.ID)) == 1) + if (current.getPos().distance(ent2.getPos(g.ID)) == 1) break; - for (Coordinates sur : current.getPos().getAllSurrounding(b)) + for (Coordinates sur : current.getPos().getAllSurrounding(g)) { - if (!b.isInBase(sur) || b.isOccupied(sur) || contains(closed, sur)) + if (!g.isInGrid(sur) || g.isOccupied(sur) || contains(closed, sur)) { open.remove(getNodeFromList(open, sur)); continue; @@ -90,18 +90,17 @@ public Coordinates getNext(Coordinates pos, Coordinates targetPos, Base b, Entit } current = findLowestFCost(open); } - while (current.getPos() != targetPos); //FIXME: NullPointerException when can't reach target + while (current.getPos() != targetPos); Node node = getLast(closed.get(closed.size() - 1)); - // visualizationColor = new Color(new Random().nextFloat(), new Random().nextFloat(), new Random().nextFloat()); if (showCosts || showVisualization) for (int i = 0; i < closed.size(); i++) { if (showVisualization) - b.setFloorColor(closed.get(i).getPos(), new Color((255 - ((255 - visualizationColor.getRed()) / closed.size() * i)), (255 - ((255 - visualizationColor.getGreen()) / closed.size() * i)), (255 - ((255 - visualizationColor.getBlue()) / closed.size() * i)))); + g.setFloorColor(closed.get(i).getPos(), new Color((255 - ((255 - visualizationColor.getRed()) / closed.size() * i)), (255 - ((255 - visualizationColor.getGreen()) / closed.size() * i)), (255 - ((255 - visualizationColor.getBlue()) / closed.size() * i)))); if (showCosts) - RenderManager.setText(b.ID, new Coordinates(closed.get(i).getPos().getY(), closed.get(i).getPos().getX()), /*"F" + (int)(calcG(current, closed.get(i).getPos()) + calcH(closed.get(i).getPos(), targetPos))*/ - "G" + (int) calcG(current, closed.get(i).getPos()) + "H" + (int) calcH(closed.get(i).getPos(), targetPos), costColor); + RenderManager.setText(g.ID, new Coordinates(closed.get(i).getPos().getY(), closed.get(i).getPos().getX()), /*"F" + (int)(calcG(current, closed.get(i).getPos()) + calcH(closed.get(i).getPos(), targetPos))*/ + "G" + (int) calcG(current, closed.get(i).getPos()) + "H" + (int) calcH(closed.get(i).getPos(), targetPos), costColor); } cachedNodePath = closed; @@ -166,9 +165,26 @@ private Node findLowestFCost(ArrayList open) } @Override - public boolean isValid(Coordinates pos, Coordinates targetPos, Base b, Entity ent1, Entity ent2) + public boolean isValid(Coordinates pos, Coordinates targetPos, Grid g, Entity ent1, Entity ent2) { - return !pos.isSurrounded(b); + // boolean[][] checked = new boolean[b.getRows()][b.getColumns()]; + // for (int i = 0; i < checked.length; i++) + // for (int j = 0; j < checked[0].length; j++) + // checked[i][j] = false; + // return floodCheck(checked, pos, targetPos, b); + return true; + } + + public boolean floodCheck(boolean[][] checked, Coordinates pos, Coordinates targetPos, Grid g) + { + g.setFloorColor(pos, GrameUtils.randomColor()); + if (pos.equals(targetPos)) + return true; + checked[pos.getY()][pos.getX()] = true; + for (Coordinates sur : pos.getSurrounding(g)) + if (!checked[sur.getY()][sur.getX()]) + return floodCheck(checked, sur, targetPos, g); + return true; } @Override @@ -247,25 +263,25 @@ public static void main(String[] args) @Override public void newGame() { - Base b = new Base(20, 20); - b.setWraparound(true); + Grid g = new Grid(20, 20); + g.setWraparound(true); Entity player = new Entity("Player", Color.gray); Entity monster = new Entity("Monster", Color.red); - b.addGrameObjectLayer(new GrameObjectLayer(b.getColumns(), b.getRows()), 1); - player.makePlayer(1, true, b.ID); + g.addGrameObjectLayer(new GrameObjectLayer(g.getColumns(), g.getRows()), 1); + player.makePlayer(1, true, g.ID); player.setSpeed(1); monster.setTarget(player.ID); AStarPathfindingMovementAI aStar = new AStarPathfindingMovementAI(); - monster.addAI(aStar, b.ID); + monster.addAI(aStar, g.ID); monster.setSpeed(5); - b.addGrameObject(player, new Coordinates(10, 10)); - b.addGrameObject(monster, new Coordinates(18, 10), 1); + g.addGrameObject(player, new Coordinates(10, 10)); + g.addGrameObject(monster, new Coordinates(18, 10), 1); for (int i = 1; i <= 10; i++) - new Schematic().load(b, GrameUtils.randomCoordinates(b)); + new Schematic().load(g, GrameUtils.randomCoordinates(g)); // Schematic s = new Schematic(1); // System.out.println(s.toString()); // s.load(b, new Coordinates(10, 10)); - RenderManager.render(b.ID, new PlainGridRender()); + RenderManager.render(g.ID, new CleanGridRender()); RenderManager.setVisible(true); aStar.showVisualization = true; // for (int i = 0; i < b.getColumns(); i++) diff --git a/src/com/moomoohk/Grame/AI/PlayerMovementAI.java b/src/com/moomoohk/Grame/Basics/AI/PlayerMovementAI.java similarity index 57% rename from src/com/moomoohk/Grame/AI/PlayerMovementAI.java rename to src/com/moomoohk/Grame/Basics/AI/PlayerMovementAI.java index 102c80d..5b00542 100644 --- a/src/com/moomoohk/Grame/AI/PlayerMovementAI.java +++ b/src/com/moomoohk/Grame/Basics/AI/PlayerMovementAI.java @@ -1,12 +1,12 @@ -package com.moomoohk.Grame.AI; +package com.moomoohk.Grame.Basics.AI; import com.moomoohk.Grame.Basics.Dir; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Interfaces.GrameObject; -import com.moomoohk.Grame.Interfaces.MovementAI; +import com.moomoohk.Grame.Basics.MovementAI; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.GrameObject; +import com.moomoohk.Grame.Core.Grid; /** * AI that lets the user control {@link GrameObject}s using the keyboard. @@ -32,27 +32,27 @@ public PlayerMovementAI(int player) this.player = player; } - public Coordinates getNext(Coordinates pos, Coordinates target, Base b, Entity ent1, Entity ent2) + public Coordinates getNext(Coordinates pos, Coordinates target, Grid g, Entity ent1, Entity ent2) { Dir d = player == 1 ? GrameManager.dir1 : player == 2 ? GrameManager.dir2 : null; if (d == null) return pos; int layer = -1; - for (int i = 0; i < b.getGrameObjectLayers().size(); i++) - if (b.getGrameObjectLayers().get(i).contains(ent1.ID)) + for (int i = 0; i < g.getGrameObjectLayers().size(); i++) + if (g.getGrameObjectLayers().get(i).contains(ent1.ID)) layer = i; - if (!b.isInBase(MovementAI.slide(b, pos, d, layer))) - if (b.getWraparound()) - return MovementAI.wraparound(b, MovementAI.slide(b, pos, d, layer), d); + if (!g.isInGrid(MovementAI.slide(g, pos, d, layer))) + if (g.getWraparound()) + return MovementAI.wraparound(g, MovementAI.slide(g, pos, d, layer), d); else return pos; else - return MovementAI.slide(b, pos, d, layer); + return MovementAI.slide(g, pos, d, layer); } - public boolean isValid(Coordinates pos, Coordinates target, Base b, Entity ent1, Entity ent2) + public boolean isValid(Coordinates pos, Coordinates target, Grid g, Entity ent1, Entity ent2) { - return ent1.isPlayer(b.ID); + return ent1.isPlayer(g.ID); } public boolean isOverride() diff --git a/src/com/moomoohk/Grame/AI/PlayerSimAI.java b/src/com/moomoohk/Grame/Basics/AI/PlayerSimAI.java similarity index 71% rename from src/com/moomoohk/Grame/AI/PlayerSimAI.java rename to src/com/moomoohk/Grame/Basics/AI/PlayerSimAI.java index f8d2707..ea7b3ed 100644 --- a/src/com/moomoohk/Grame/AI/PlayerSimAI.java +++ b/src/com/moomoohk/Grame/Basics/AI/PlayerSimAI.java @@ -1,12 +1,12 @@ -package com.moomoohk.Grame.AI; +package com.moomoohk.Grame.Basics.AI; import java.util.Random; import com.moomoohk.Grame.Basics.Dir; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Interfaces.MovementAI; +import com.moomoohk.Grame.Basics.MovementAI; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.Grid; /** * AI that is supposed to simulate a player. @@ -30,7 +30,7 @@ public PlayerSimAI() { super(); this.step = 0; - this.tries=0; + this.tries = 0; } @Override @@ -40,37 +40,37 @@ public String author() } @Override - public Coordinates getNext(Coordinates pos, Coordinates targetPos, Base b, Entity ent1, Entity ent2) + public Coordinates getNext(Coordinates pos, Coordinates targetPos, Grid g, Entity ent1, Entity ent2) { if (this.step == 0) this.direction = generateDir(); Coordinates next = pos.addDir(this.direction); - if (b.getWraparound()) - next = MovementAI.wraparound(b, pos, this.direction); + if (g.getWraparound()) + next = MovementAI.wraparound(g, pos, this.direction); else - if (!b.isInBase(next)) + if (!g.isInGrid(next)) { this.step = 0; return pos; } - if(b.isOccupied(next)) + if (g.isOccupied(next)) { - this.step=0; + this.step = 0; this.tries++; - if(this.tries==10) + if (this.tries == 10) { - this.tries=0; + this.tries = 0; return pos; } - return getNext(pos, targetPos, b, ent1, ent2); + return getNext(pos, targetPos, g, ent1, ent2); } - this.tries=0; + this.tries = 0; this.step--; return next; } @Override - public boolean isValid(Coordinates pos, Coordinates targetPos, Base b, Entity ent1, Entity ent2) + public boolean isValid(Coordinates pos, Coordinates targetPos, Grid g, Entity ent1, Entity ent2) { return true; } @@ -86,7 +86,7 @@ private Dir generateDir() this.step = new Random().nextInt(30) + 10; return Dir.getAllDirs()[new Random().nextInt(Dir.getAllDirs().length)]; } - + public String toString() { return "Player sim"; diff --git a/src/com/moomoohk/Grame/AI/SimpleChaseAI.java b/src/com/moomoohk/Grame/Basics/AI/SimpleChaseAI.java similarity index 65% rename from src/com/moomoohk/Grame/AI/SimpleChaseAI.java rename to src/com/moomoohk/Grame/Basics/AI/SimpleChaseAI.java index 9d503c1..d10d530 100644 --- a/src/com/moomoohk/Grame/AI/SimpleChaseAI.java +++ b/src/com/moomoohk/Grame/Basics/AI/SimpleChaseAI.java @@ -1,12 +1,12 @@ -package com.moomoohk.Grame.AI; +package com.moomoohk.Grame.Basics.AI; import com.moomoohk.Grame.Basics.Dir; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameUtils; -import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; -import com.moomoohk.Grame.Interfaces.MovementAI; +import com.moomoohk.Grame.Basics.MovementAI; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameUtils; +import com.moomoohk.Grame.Core.GrameUtils.MessageLevel; +import com.moomoohk.Grame.Core.Grid; /** * This AI is designed to chase objects. @@ -21,7 +21,7 @@ public class SimpleChaseAI extends MovementAI { private static final long serialVersionUID = 4361422461574615758L; - public Coordinates getNext(Coordinates pos, Coordinates target, Base b, Entity ent1, Entity ent2) + public Coordinates getNext(Coordinates pos, Coordinates target, Grid g, Entity ent1, Entity ent2) { if (target == null) { @@ -29,15 +29,15 @@ public Coordinates getNext(Coordinates pos, Coordinates target, Base b, Entity e return pos; } int layer = -1; - for (int i = 0; i < b.getGrameObjectLayers().size(); i++) - if (b.getGrameObjectLayers().get(i).contains(ent1.ID)) + for (int i = 0; i < g.getGrameObjectLayers().size(); i++) + if (g.getGrameObjectLayers().get(i).contains(ent1.ID)) layer = i; - if (!b.getWraparound()) + if (!g.getWraparound()) { Dir d = new Dir(pos, target); - if (!b.isOccupied(pos.addDir(d))) + if (!g.isOccupied(pos.addDir(d))) return pos.addDir(d); - return MovementAI.slide(b, pos, d, layer); + return MovementAI.slide(g, pos, d, layer); } else { @@ -48,42 +48,42 @@ public Coordinates getNext(Coordinates pos, Coordinates target, Base b, Entity e while (temp.distance(target) > 0) { Dir dir = new Dir(target, temp); - if (!wrapped && !b.isInBase(temp.addDir(dir))) + if (!wrapped && !g.isInGrid(temp.addDir(dir))) { - temp = MovementAI.wraparound(b, MovementAI.slide(b, temp, dir, layer), dir); + temp = MovementAI.wraparound(g, MovementAI.slide(g, temp, dir, layer), dir); wrapped = true; } else if (!wrapped) { Dir dir2 = new Dir(temp, target); - Dir wall = closestWall(temp, b); + Dir wall = closestWall(temp, g); if (wall.getX() != 0) dir2.setX(wall.getX()); if (wall.getY() != 0) dir2.setY(wall.getY()); - temp = MovementAI.slide(b, temp, dir2, layer); + temp = MovementAI.slide(g, temp, dir2, layer); } else - temp = MovementAI.slide(b, temp, new Dir(temp, target), layer); + temp = MovementAI.slide(g, temp, new Dir(temp, target), layer); distanceThroughWall++; } if (normalDistance <= distanceThroughWall) - return MovementAI.slide(b, pos, new Dir(pos, target), layer); + return MovementAI.slide(g, pos, new Dir(pos, target), layer); else { Dir dir2 = new Dir(pos, target); - Dir wall = closestWall(pos, b); + Dir wall = closestWall(pos, g); if (wall.getX() != 0) dir2.setX(wall.getX()); if (wall.getY() != 0) dir2.setY(wall.getY()); - return MovementAI.wraparound(b, /*MovementAI.slide(b, pos, dir2)*/pos, dir2); + return MovementAI.wraparound(g, /*MovementAI.slide(b, pos, dir2)*/pos, dir2); } } } - public boolean isValid(Coordinates pos, Coordinates target, Base b, Entity ent1, Entity ent2) + public boolean isValid(Coordinates pos, Coordinates target, Grid g, Entity ent1, Entity ent2) { if (pos == null) return false; @@ -92,12 +92,12 @@ public boolean isValid(Coordinates pos, Coordinates target, Base b, Entity ent1, GrameUtils.print("Crucial parameters missing! Returning not valid. (" + ent1.getName() + ")", MessageLevel.ERROR); return false; } - if (ent1.getPos(b.ID).distance(ent2.getPos(b.ID)) > ent1.getRange()) + if (ent1.getPos(g.ID).distance(ent2.getPos(g.ID)) > ent1.getRange()) { return false; } - if (ent1.getPos(b.ID).isSurrounded(b)) + if (ent1.getPos(g.ID).isSurrounded(g)) { return false; } @@ -119,7 +119,7 @@ public String author() return "moomoohk"; } - public Dir closestWall(Coordinates pos, Base b) + public Dir closestWall(Coordinates pos, Grid b) { int up = pos.getY(), down = b.getRows() - pos.getY() - 1, left = pos.getX(), right = b.getColumns() - pos.getX() - 1; int min = Math.min(up, Math.min(down, Math.min(left, right))); diff --git a/src/com/moomoohk/Grame/AI/SimpleStrollAI.java b/src/com/moomoohk/Grame/Basics/AI/SimpleStrollAI.java similarity index 54% rename from src/com/moomoohk/Grame/AI/SimpleStrollAI.java rename to src/com/moomoohk/Grame/Basics/AI/SimpleStrollAI.java index a04cc37..8463583 100644 --- a/src/com/moomoohk/Grame/AI/SimpleStrollAI.java +++ b/src/com/moomoohk/Grame/Basics/AI/SimpleStrollAI.java @@ -1,10 +1,10 @@ -package com.moomoohk.Grame.AI; +package com.moomoohk.Grame.Basics.AI; import com.moomoohk.Grame.Basics.Dir; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Interfaces.MovementAI; +import com.moomoohk.Grame.Basics.MovementAI; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.Grid; /** * This AI is designed to simulate neutral random movement. @@ -17,30 +17,30 @@ public class SimpleStrollAI extends MovementAI { private static final long serialVersionUID = 5810610984037692653L; - public Coordinates getNext(Coordinates pos, Coordinates target, Base b, Entity ent1, Entity ent2) + public Coordinates getNext(Coordinates pos, Coordinates target, Grid g, Entity ent1, Entity ent2) { - Coordinates[] sur = pos.getAllSurrounding(b); + Coordinates[] sur = pos.getAllSurrounding(g); Coordinates next = sur[(int) (Math.random() * sur.length)]; try { - if ((int) (Math.random() * 15)>13) - if (b.getWraparound()) + if ((int) (Math.random() * 15) > 13) + if (g.getWraparound()) { - if (!b.isInBase(next)) - next=MovementAI.wraparound(b, next, new Dir(pos, next)); - if (b.isOccupied(next)) + if (!g.isInGrid(next)) + next = MovementAI.wraparound(g, next, new Dir(pos, next)); + if (g.isOccupied(next)) return pos; else return next; } else { - if (b.isOccupied(next)) - for (int i = 0; i < sur.length || (!b.isOccupied(next) && b.isInBase(next)); i++) + if (g.isOccupied(next)) + for (int i = 0; i < sur.length || (!g.isOccupied(next) && g.isInGrid(next)); i++) next = sur[i]; - if(!b.isInBase(next)) - next=pos; + if (!g.isInGrid(next)) + next = pos; } else next = pos; @@ -52,11 +52,11 @@ public Coordinates getNext(Coordinates pos, Coordinates target, Base b, Entity e return next; } - public boolean isValid(Coordinates pos, Coordinates target, Base b, Entity ent1, Entity ent2) + public boolean isValid(Coordinates pos, Coordinates target, Grid g, Entity ent1, Entity ent2) { - if(pos==null) + if (pos == null) return false; - return !pos.isSurrounded(b); + return !pos.isSurrounded(g); } public boolean isOverride() diff --git a/src/com/moomoohk/Grame/Basics/AI/package-info.java b/src/com/moomoohk/Grame/Basics/AI/package-info.java new file mode 100644 index 0000000..5189da3 --- /dev/null +++ b/src/com/moomoohk/Grame/Basics/AI/package-info.java @@ -0,0 +1,7 @@ +/** + * Contains some MovementAI classes. + * + * @author Meshulam Silk (moomoohk@ymail.com) + * @since Feb 6, 2014 + */ +package com.moomoohk.Grame.Basics.AI; \ No newline at end of file diff --git a/src/com/moomoohk/Grame/Basics/DefaultRandomGen.java b/src/com/moomoohk/Grame/Basics/DefaultRandomGen.java index 0526e15..baebe4e 100644 --- a/src/com/moomoohk/Grame/Basics/DefaultRandomGen.java +++ b/src/com/moomoohk/Grame/Basics/DefaultRandomGen.java @@ -1,7 +1,5 @@ package com.moomoohk.Grame.Basics; -import com.moomoohk.Grame.Interfaces.EntityGenerator; - /** * This generator will generate a random name and type. * @@ -32,10 +30,8 @@ public String nameGen() if (i == 0) random = random.toUpperCase(); } - String[] suffixes = - { "tron", "man", "nar", "ram", "berg", "san" }; - char[] vowels = - { 'a', 'e', 'i', 'o', 'u' }; + String[] suffixes = { "tron", "man", "nar", "ram", "berg", "san" }; + char[] vowels = { 'a', 'e', 'i', 'o', 'u' }; boolean lastVowel = false; for (int i = 0; i < vowels.length; i++) if (random.charAt(random.length() - 1) == vowels[i]) @@ -53,8 +49,7 @@ public String nameGen() public String typeGen() { - String[] types = - { "elf", "orc", "human" }; + String[] types = { "elf", "orc", "human" }; return types[(int) (Math.random() * 3)]; } diff --git a/src/com/moomoohk/Grame/Basics/Dir.java b/src/com/moomoohk/Grame/Basics/Dir.java index f793f46..9ebeed6 100644 --- a/src/com/moomoohk/Grame/Basics/Dir.java +++ b/src/com/moomoohk/Grame/Basics/Dir.java @@ -1,6 +1,6 @@ package com.moomoohk.Grame.Basics; -import com.moomoohk.Grame.Essentials.Coordinates; +import com.moomoohk.Grame.Core.Coordinates; /** * Represents directions. diff --git a/src/com/moomoohk/Grame/Basics/Entity.java b/src/com/moomoohk/Grame/Basics/Entity.java index 02dba5b..eed3e33 100644 --- a/src/com/moomoohk/Grame/Basics/Entity.java +++ b/src/com/moomoohk/Grame/Basics/Entity.java @@ -4,15 +4,13 @@ import java.util.ArrayList; import java.util.HashMap; -import com.moomoohk.Grame.AI.PlayerMovementAI; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Essentials.GrameUtils; -import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; +import com.moomoohk.Grame.Basics.AI.PlayerMovementAI; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.GrameObject; +import com.moomoohk.Grame.Core.GrameUtils; +import com.moomoohk.Grame.Core.GrameUtils.MessageLevel; import com.moomoohk.Grame.GrassMuncher.Coin; -import com.moomoohk.Grame.Interfaces.EntityGenerator; -import com.moomoohk.Grame.Interfaces.GrameObject; -import com.moomoohk.Grame.Interfaces.MovementAI; public class Entity extends GrameObject { @@ -85,75 +83,75 @@ public boolean isCollidable() } @Override - public void tick(int bID) + public void tick(int gID) { - determineAI(bID); - Coordinates c = getPos(bID); + determineAI(gID); + Coordinates c = getPos(gID); Coordinates target = null; if (this.targetID != -1) - target = GrameManager.findGrameObject(this.targetID).getPos(bID); - if (this.activeAI.size() != 0 && this.activeAI.get(bID) != null) - c = this.activeAI.get(bID).getNext(getPos(bID), target, GrameManager.findBase(bID), this, (Entity) GrameManager.findGrameObject(targetID)); - setPos(bID, c); + target = GrameManager.findGrameObject(this.targetID).getPos(gID); + if (this.activeAI.size() != 0 && this.activeAI.get(gID) != null) + c = this.activeAI.get(gID).getNext(getPos(gID), target, GrameManager.findGrid(gID), this, (Entity) GrameManager.findGrameObject(targetID)); + setPos(gID, c); } - private void determineAI(int bID) + private void determineAI(int gID) { - if (!GrameManager.findBase(bID).containsGrameObject(ID) || (this.AI.get(bID) == null && this.overrideAI.get(bID) == null) || (this.AI.get(bID) != null && this.AI.get(bID).size() == 0 && this.overrideAI.get(bID) == null)) + if (!GrameManager.findGrid(gID).containsGrameObject(ID) || (this.AI.get(gID) == null && this.overrideAI.get(gID) == null) || (this.AI.get(gID) != null && this.AI.get(gID).size() == 0 && this.overrideAI.get(gID) == null)) { - this.activeAI.remove(bID); + this.activeAI.remove(gID); return; } - if (this.overrideAI.size() == 0 || this.overrideAI.get(bID) == null) + if (this.overrideAI.size() == 0 || this.overrideAI.get(gID) == null) { MovementAI temp = null; - for (int i = 0; i < this.AI.get(bID).size(); i++) + for (int i = 0; i < this.AI.get(gID).size(); i++) { Coordinates target = null; if (targetID != -1) - target = GrameManager.findGrameObject(targetID).getPos(bID); - if (!this.AI.get(bID).get(i).isValid(getPos(bID), target, GrameManager.findBase(bID), this, (Entity) GrameManager.findGrameObject(targetID))) + target = GrameManager.findGrameObject(targetID).getPos(gID); + if (!this.AI.get(gID).get(i).isValid(getPos(gID), target, GrameManager.findGrid(gID), this, (Entity) GrameManager.findGrameObject(targetID))) continue; - temp = (MovementAI) this.AI.get(bID).get(i); + temp = (MovementAI) this.AI.get(gID).get(i); break; } - this.activeAI.put(bID, temp); + this.activeAI.put(gID, temp); } else { - this.activeAI.put(bID, this.overrideAI.get(bID)); + this.activeAI.put(gID, this.overrideAI.get(gID)); } } - public void addAI(MovementAI AI, int bID) + public void addAI(MovementAI AI, int gID) { if (!AI.isOverride()) { - if (this.AI.get(bID) == null) - this.AI.put(bID, new ArrayList()); - this.AI.get(bID).add(AI); + if (this.AI.get(gID) == null) + this.AI.put(gID, new ArrayList()); + this.AI.get(gID).add(AI); } else GrameUtils.print(AI + " is an override AI, it doens't belong in my AI list!", MessageLevel.ERROR); } - + public void printAI() { GrameUtils.print("Override AIs:", MessageLevel.NORMAL); if (overrideAI.size() != 0) - for (int bID : overrideAI.keySet()) - GrameUtils.print(bID + ": " + overrideAI.get(bID) + " (" + overrideAI.get(bID).author() + ")", MessageLevel.NORMAL); + for (int gID : overrideAI.keySet()) + GrameUtils.print(gID + ": " + overrideAI.get(gID) + " (" + overrideAI.get(gID).author() + ")", MessageLevel.NORMAL); else GrameUtils.print("[Empty]", MessageLevel.NORMAL); GrameUtils.print("Active AIs:", MessageLevel.NORMAL); if (activeAI.size() != 0) - for (int bID : activeAI.keySet()) - GrameUtils.print(bID + ": " + activeAI.get(bID) + " (" + activeAI.get(bID).author() + ")", MessageLevel.NORMAL); + for (int gID : activeAI.keySet()) + GrameUtils.print(gID + ": " + activeAI.get(gID) + " (" + activeAI.get(gID).author() + ")", MessageLevel.NORMAL); else GrameUtils.print("[Empty]", MessageLevel.NORMAL); - for (int bID : AI.keySet()) + for (int gID : AI.keySet()) { - GrameUtils.print("For base ID:" + bID, MessageLevel.NORMAL); + GrameUtils.print("For grid ID:" + gID, MessageLevel.NORMAL); String st = "null"; if (this.AI.size() == 0) GrameUtils.print("My AI list is empty!", MessageLevel.ERROR); @@ -162,12 +160,11 @@ public void printAI() { st = "null"; if (this.AI.get(i) != null) - st = this.AI.get(i) + " (" + ((MovementAI) this.AI.get(bID).get(i)).author() + ")"; + st = this.AI.get(i) + " (" + ((MovementAI) this.AI.get(gID).get(i)).author() + ")"; GrameUtils.print(i + 1 + ") " + st, MessageLevel.NORMAL); } } - } - + } public void clearAI() { @@ -176,10 +173,10 @@ public void clearAI() this.overrideAI = null; } - public void setOverrideAI(MovementAI mai, int bID) + public void setOverrideAI(MovementAI mai, int gID) { if (mai.isOverride()) - this.overrideAI.put(bID, mai); + this.overrideAI.put(gID, mai); else GrameUtils.print(mai + " is not an override AI!", MessageLevel.ERROR); } @@ -191,25 +188,25 @@ public void consume(GrameObject go) this.points += ((Coin) go).getWorth(); } - public boolean isPlayer(int bID) + public boolean isPlayer(int gID) { - if (this.player.get(bID) == null) + if (this.player.get(gID) == null) return false; - return this.player.get(bID); + return this.player.get(gID); } - public void makePlayer(int player, boolean f, int bID) + public void makePlayer(int player, boolean f, int gID) { if (f) { - this.player.put(bID, true); - this.overrideAI.put(bID, new PlayerMovementAI(player)); + this.player.put(gID, true); + this.overrideAI.put(gID, new PlayerMovementAI(player)); } else - if (this.player.get(bID)) + if (this.player.get(gID)) { - this.player.put(bID, false); - this.overrideAI.remove(bID); + this.player.put(gID, false); + this.overrideAI.remove(gID); } else GrameUtils.print("Not a player!", MessageLevel.ERROR); diff --git a/src/com/moomoohk/Grame/Interfaces/EntityGenerator.java b/src/com/moomoohk/Grame/Basics/EntityGenerator.java similarity index 81% rename from src/com/moomoohk/Grame/Interfaces/EntityGenerator.java rename to src/com/moomoohk/Grame/Basics/EntityGenerator.java index 25a5050..5704da0 100644 --- a/src/com/moomoohk/Grame/Interfaces/EntityGenerator.java +++ b/src/com/moomoohk/Grame/Basics/EntityGenerator.java @@ -1,11 +1,8 @@ -package com.moomoohk.Grame.Interfaces; - +package com.moomoohk.Grame.Basics; /** - * This interface is used to create generators which generate names and types - * for Entities. + * This interface is used to create generators which generate names and types for Entities. * - * @see OldEntity * @author Meshulam Silk * @version 1.0 * @since 2013-04-05 diff --git a/src/com/moomoohk/Grame/Interfaces/MovementAI.java b/src/com/moomoohk/Grame/Basics/MovementAI.java similarity index 59% rename from src/com/moomoohk/Grame/Interfaces/MovementAI.java rename to src/com/moomoohk/Grame/Basics/MovementAI.java index 2114c8f..416ad29 100644 --- a/src/com/moomoohk/Grame/Interfaces/MovementAI.java +++ b/src/com/moomoohk/Grame/Basics/MovementAI.java @@ -1,12 +1,11 @@ -package com.moomoohk.Grame.Interfaces; +package com.moomoohk.Grame.Basics; import java.io.Serializable; -import com.moomoohk.Grame.Basics.Dir; -import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.GrameObject; +import com.moomoohk.Grame.Core.Grid; /** * Class to calculate the AIs of {@link GrameObject}s. @@ -28,68 +27,68 @@ public MovementAI() } /** - * Wraps {@link Coordinates} around a "wraparound" {@link Base}. + * Wraps {@link Coordinates} around a "wraparound" {@link Grid}. * - * @param b - * The "wraparound" {@link Base}. + * @param g + * The "wraparound" {@link Grid}. * @param pos * The {@link Coordinates} to wrap. * @param d * The {@link Dir} to apply. * @return The wrapped {@link Coordinates}. - * @see Base#getWraparound() + * @see Grid#getWraparound() */ - public static Coordinates wraparound(Base b, Coordinates pos, Dir d) + public static Coordinates wraparound(Grid g, Coordinates pos, Dir d) { if (pos.addDir(d).getX() <= -1 && pos.addDir(d).getY() <= -1) - return new Coordinates(b.getColumns() - 1, b.getRows() - 1); - if (pos.addDir(d).getX() <= -1 && pos.addDir(d).getY() >= b.getRows()) - return new Coordinates(b.getColumns() - 1, 0); - if (pos.addDir(d).getX() >= b.getColumns() && pos.addDir(d).getY() <= -1) - return new Coordinates(0, b.getRows() - 1); - if (pos.addDir(d).getX() >= b.getColumns() && pos.addDir(d).getY() >= b.getRows()) + return new Coordinates(g.getColumns() - 1, g.getRows() - 1); + if (pos.addDir(d).getX() <= -1 && pos.addDir(d).getY() >= g.getRows()) + return new Coordinates(g.getColumns() - 1, 0); + if (pos.addDir(d).getX() >= g.getColumns() && pos.addDir(d).getY() <= -1) + return new Coordinates(0, g.getRows() - 1); + if (pos.addDir(d).getX() >= g.getColumns() && pos.addDir(d).getY() >= g.getRows()) return new Coordinates(0, 0); if (pos.addDir(d).getX() <= -1) - return new Coordinates(b.getColumns() - 1, pos.getY()); + return new Coordinates(g.getColumns() - 1, pos.getY()); if (pos.addDir(d).getY() <= -1) - return new Coordinates(pos.getX(), b.getRows() - 1); - if (pos.addDir(d).getX() >= b.getColumns()) + return new Coordinates(pos.getX(), g.getRows() - 1); + if (pos.addDir(d).getX() >= g.getColumns()) return new Coordinates(0, pos.getY()); - if (pos.addDir(d).getY() >= b.getRows()) + if (pos.addDir(d).getY() >= g.getRows()) return new Coordinates(pos.getX(), 0); return pos.addDir(d); } /** - * Slides {@link Coordinates} on obstacles in a {@link Base}. + * Slides {@link Coordinates} on obstacles in a {@link Grid}. * - * @param b - * The {@link Base}. + * @param g + * The {@link Grid}. * @param pos * The {@link Coordinates} to slide. * @param d * The {@link Dir} to apply. * @return The slided {@link Coordinates}. */ - public static Coordinates slide(Base b, Coordinates pos, Dir d, int layer) + public static Coordinates slide(Grid g, Coordinates pos, Dir d, int layer) { if (!d.isDiag()) return pos.addDir(d); - if (b.isInBase(pos.addDir(d)) && !b.isOccupied(pos.addDir(d), layer)) + if (g.isInGrid(pos.addDir(d)) && !g.isOccupied(pos.addDir(d), layer)) return pos.addDir(d); - if (!b.isInBase(pos.addDir(d))) - if (!b.getWraparound()) + if (!g.isInGrid(pos.addDir(d))) + if (!g.getWraparound()) { - if (b.isInBase(pos.addDir(d.split()[0]))) + if (g.isInGrid(pos.addDir(d.split()[0]))) return pos.addDir(d.split()[0]); - if (b.isInBase(pos.addDir(d.split()[1]))) + if (g.isInGrid(pos.addDir(d.split()[1]))) return pos.addDir(d.split()[1]); } else - return wraparound(b, pos, d); - if (!b.isOccupied(pos.addDir(d.split()[0]), layer)) + return wraparound(g, pos, d); + if (!g.isOccupied(pos.addDir(d.split()[0]), layer)) return pos.addDir(d.split()[0]); - if (!b.isOccupied(pos.addDir(d.split()[1]), layer)) + if (!g.isOccupied(pos.addDir(d.split()[1]), layer)) return pos.addDir(d.split()[1]); return pos.addDir(d); } @@ -108,15 +107,15 @@ public static Coordinates slide(Base b, Coordinates pos, Dir d, int layer) * The current {@link Coordinates} of the {@link GrameObject}. * @param targetPos * The {@link Coordinates} of the {@link GrameObject}'s target. - * @param b - * The {@link Base}. + * @param g + * The {@link Grid}. * @param ent1 * The {@link GrameObject}. * @param ent2 * The {@link GrameObject}'s target. * @return The next {@link Coordinates} to which the {@link GrameObject} should move. */ - public abstract Coordinates getNext(Coordinates pos, Coordinates targetPos, Base b, Entity ent1, Entity ent2); + public abstract Coordinates getNext(Coordinates pos, Coordinates targetPos, Grid g, Entity ent1, Entity ent2); /** * Checks whether this AI is valid. @@ -125,15 +124,15 @@ public static Coordinates slide(Base b, Coordinates pos, Dir d, int layer) * The current {@link Coordinates} of the {@link GrameObject}. * @param targetPos * The {@link Coordinates} of the {@link GrameObject}'s target. - * @param b - * The {@link Base}. + * @param g + * The {@link Grid}. * @param ent1 * The {@link GrameObject}. * @param ent2 * The {@link GrameObject}'s target. * @return True if this AI is valid, else false. */ - public abstract boolean isValid(Coordinates pos, Coordinates targetPos, Base b, Entity ent1, Entity ent2); + public abstract boolean isValid(Coordinates pos, Coordinates targetPos, Grid g, Entity ent1, Entity ent2); /** * Checks whether this AI is an override AI. diff --git a/src/com/moomoohk/Grame/Basics/Schematic.java b/src/com/moomoohk/Grame/Basics/Schematic.java index ef5b4a1..3929fca 100644 --- a/src/com/moomoohk/Grame/Basics/Schematic.java +++ b/src/com/moomoohk/Grame/Basics/Schematic.java @@ -2,10 +2,10 @@ import java.awt.Color; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameUtils; -import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameUtils; +import com.moomoohk.Grame.Core.GrameUtils.MessageLevel; +import com.moomoohk.Grame.Core.Grid; /** * This class is a collection of {@link Wall}s which is arranged in a certain pattern. @@ -46,201 +46,201 @@ public Schematic(int type) this.map[i][j] = null; switch (this.type) { - case 0: - def(2, 0); - def(2, 1); - def(1, 2); - def(2, 2); - def(3, 2); - def(2, 3); - def(2, 4); - break; - case 1: - def(0, 2); - def(1, 2); - def(2, 1); - def(2, 2); - def(2, 3); - def(3, 2); - def(4, 2); - break; - case 2: - def(0, 0); - def(1, 0); - def(2, 0); - def(0, 1); - def(0, 2); - break; - case 3: - def(0, 0); - def(0, 1); - def(0, 2); - def(0, 3); - def(1, 0); - def(2, 0); - def(3, 0); - break; - case 4: - def(0, 0); - def(1, 0); - def(2, 0); - def(4, 0); - def(0, 2); - def(2, 2); - def(3, 2); - def(4, 2); - def(0, 4); - def(1, 4); - def(2, 4); - def(4, 4); - break; - case 5: - def(0, 0); - def(0, 1); - def(0, 2); - def(0, 4); - def(2, 0); - def(2, 2); - def(2, 3); - def(2, 4); - def(4, 0); - def(4, 1); - def(4, 2); - def(4, 4); - break; - case 6: - def(0, 0); - def(1, 0); - def(2, 0); - def(3, 0); - def(4, 0); - def(2, 1); - def(2, 2); - def(2, 3); - def(0, 4); - def(1, 4); - def(2, 4); - def(3, 4); - def(4, 4); - break; - case 7: - def(0, 0); - def(0, 1); - def(0, 2); - def(0, 3); - def(0, 4); - def(1, 2); - def(2, 2); - def(3, 2); - def(4, 0); - def(4, 1); - def(4, 2); - def(4, 3); - def(4, 4); - break; - case 8: - def(0, 0); - def(1, 0); - def(3, 0); - def(4, 0); - def(1, 1); - def(2, 1); - def(3, 1); - def(1, 3); - def(2, 3); - def(3, 3); - def(0, 4); - def(1, 4); - def(3, 4); - def(4, 4); - break; - case 9: - def(0, 0); - def(0, 1); - def(0, 3); - def(0, 4); - def(1, 1); - def(1, 2); - def(1, 3); - def(3, 1); - def(3, 2); - def(3, 3); - def(4, 0); - def(4, 1); - def(4, 3); - def(4, 4); - break; - case 10: - def(1, 0); - def(4, 0); - def(0, 1); - def(1, 1); - def(3, 1); - def(1, 3); - def(3, 3); - def(4, 3); - def(0, 4); - def(3, 4); - break; - case 11: - def(0, 0); - def(3, 0); - def(1, 1); - def(3, 1); - def(4, 1); - def(0, 3); - def(1, 3); - def(3, 3); - def(1, 4); - def(4, 4); - break; - case 12: - def(0, 0); - def(1, 0); - def(3, 0); - def(4, 0); - def(0, 1); - def(4, 1); - def(2, 2); - def(0, 3); - def(4, 3); - def(0, 4); - def(1, 4); - def(3, 4); - def(4, 4); - break; - case 13: - def(0, 0); - def(1, 0); - trig(2, 0); - def(3, 0); - def(4, 0); - def(0, 1); - def(4, 1); - trig(0, 2); - def(0, 3); - def(4, 3); - def(0, 4); - def(1, 4); - trig(2, 4); - def(3, 4); - def(4, 4); - trig(4, 2); - break; - case 14: - def(1, 1); - def(2, 1); - def(3, 1); - def(1, 2); - def(3, 2); - def(1, 3); - def(2, 3); - def(3, 3); - break; - case 15: - for (int i = 0; i < this.map.length; i++) - for (int j = 0; j < this.map.length; j++) - def(i, j); + case 0: + def(2, 0); + def(2, 1); + def(1, 2); + def(2, 2); + def(3, 2); + def(2, 3); + def(2, 4); + break; + case 1: + def(0, 2); + def(1, 2); + def(2, 1); + def(2, 2); + def(2, 3); + def(3, 2); + def(4, 2); + break; + case 2: + def(0, 0); + def(1, 0); + def(2, 0); + def(0, 1); + def(0, 2); + break; + case 3: + def(0, 0); + def(0, 1); + def(0, 2); + def(0, 3); + def(1, 0); + def(2, 0); + def(3, 0); + break; + case 4: + def(0, 0); + def(1, 0); + def(2, 0); + def(4, 0); + def(0, 2); + def(2, 2); + def(3, 2); + def(4, 2); + def(0, 4); + def(1, 4); + def(2, 4); + def(4, 4); + break; + case 5: + def(0, 0); + def(0, 1); + def(0, 2); + def(0, 4); + def(2, 0); + def(2, 2); + def(2, 3); + def(2, 4); + def(4, 0); + def(4, 1); + def(4, 2); + def(4, 4); + break; + case 6: + def(0, 0); + def(1, 0); + def(2, 0); + def(3, 0); + def(4, 0); + def(2, 1); + def(2, 2); + def(2, 3); + def(0, 4); + def(1, 4); + def(2, 4); + def(3, 4); + def(4, 4); + break; + case 7: + def(0, 0); + def(0, 1); + def(0, 2); + def(0, 3); + def(0, 4); + def(1, 2); + def(2, 2); + def(3, 2); + def(4, 0); + def(4, 1); + def(4, 2); + def(4, 3); + def(4, 4); + break; + case 8: + def(0, 0); + def(1, 0); + def(3, 0); + def(4, 0); + def(1, 1); + def(2, 1); + def(3, 1); + def(1, 3); + def(2, 3); + def(3, 3); + def(0, 4); + def(1, 4); + def(3, 4); + def(4, 4); + break; + case 9: + def(0, 0); + def(0, 1); + def(0, 3); + def(0, 4); + def(1, 1); + def(1, 2); + def(1, 3); + def(3, 1); + def(3, 2); + def(3, 3); + def(4, 0); + def(4, 1); + def(4, 3); + def(4, 4); + break; + case 10: + def(1, 0); + def(4, 0); + def(0, 1); + def(1, 1); + def(3, 1); + def(1, 3); + def(3, 3); + def(4, 3); + def(0, 4); + def(3, 4); + break; + case 11: + def(0, 0); + def(3, 0); + def(1, 1); + def(3, 1); + def(4, 1); + def(0, 3); + def(1, 3); + def(3, 3); + def(1, 4); + def(4, 4); + break; + case 12: + def(0, 0); + def(1, 0); + def(3, 0); + def(4, 0); + def(0, 1); + def(4, 1); + def(2, 2); + def(0, 3); + def(4, 3); + def(0, 4); + def(1, 4); + def(3, 4); + def(4, 4); + break; + case 13: + def(0, 0); + def(1, 0); + trig(2, 0); + def(3, 0); + def(4, 0); + def(0, 1); + def(4, 1); + trig(0, 2); + def(0, 3); + def(4, 3); + def(0, 4); + def(1, 4); + trig(2, 4); + def(3, 4); + def(4, 4); + trig(4, 2); + break; + case 14: + def(1, 1); + def(2, 1); + def(3, 1); + def(1, 2); + def(3, 2); + def(1, 3); + def(2, 3); + def(3, 3); + break; + case 15: + for (int i = 0; i < this.map.length; i++) + for (int j = 0; j < this.map.length; j++) + def(i, j); } } @@ -286,13 +286,13 @@ public Color getColor(Coordinates c) } /** - * Shows this Schematic in a {@link Base}. + * Shows this Schematic in a {@link Grid}. *

* For debug purposes. */ public void show() { - Base b = new Base(5, 5, "Schematic " + type); + Grid b = new Grid(5, 5, "Schematic " + type); for (int i = 0; i < 5; i++) for (int j = 0; j < 5; j++) b.setFloorColor(new Coordinates(j, i), this.map[i][j]); @@ -396,14 +396,14 @@ public void setColor(Coordinates pos, Color c) } /** - * Loads the Schematic into a given {@link Base} at given {@link Coordinates}. + * Loads the Schematic into a given {@link Grid} at given {@link Coordinates}. * - * @param b - * {@link Base} in which to load this Schematic. + * @param g + * {@link Grid} in which to load this Schematic. * @param loc * {@link Coordinates} at which to load this Schematic. */ - public void load(Base b, Coordinates loc) + public void load(Grid g, Coordinates loc) { int sx = 0; int sy = 0; @@ -415,8 +415,8 @@ public void load(Base b, Coordinates loc) for (int j = loc.getX(); j < loc.getX() + this.width; j++) { mapx = j; - if (this.map[sy][sx] != null && b.isInBase(new Coordinates(mapx, mapy)) && !b.isOccupied(new Coordinates(mapx, mapy))) - b.addGrameObject(new Wall(getColor(new Coordinates(sx, sy))), new Coordinates(mapx, mapy)); + if (this.map[sy][sx] != null && g.isInGrid(new Coordinates(mapx, mapy)) && !g.isOccupied(new Coordinates(mapx, mapy))) + g.addGrameObject(new Wall(getColor(new Coordinates(sx, sy))), new Coordinates(mapx, mapy)); sx++; } sx = 0; diff --git a/src/com/moomoohk/Grame/Basics/Spriteable.java b/src/com/moomoohk/Grame/Basics/Spriteable.java index 0e96cbe..495d9c5 100644 --- a/src/com/moomoohk/Grame/Basics/Spriteable.java +++ b/src/com/moomoohk/Grame/Basics/Spriteable.java @@ -5,7 +5,7 @@ import javax.imageio.ImageIO; -import com.moomoohk.Grame.Interfaces.GrameObject; +import com.moomoohk.Grame.Core.GrameObject; public abstract class Spriteable extends GrameObject { diff --git a/src/com/moomoohk/Grame/Basics/Wall.java b/src/com/moomoohk/Grame/Basics/Wall.java index a4eb474..37ce8b4 100644 --- a/src/com/moomoohk/Grame/Basics/Wall.java +++ b/src/com/moomoohk/Grame/Basics/Wall.java @@ -2,7 +2,7 @@ import java.awt.Color; -import com.moomoohk.Grame.Interfaces.GrameObject; +import com.moomoohk.Grame.Core.GrameObject; /** * Walls are ready to use {@link GrameObject}s which are supposed to represent ordinary walls. @@ -37,7 +37,7 @@ public boolean isCollidable() } @Override - public void tick(int bID) + public void tick(int gID) { } diff --git a/src/com/moomoohk/Grame/Basics/package-info.java b/src/com/moomoohk/Grame/Basics/package-info.java new file mode 100644 index 0000000..05a5817 --- /dev/null +++ b/src/com/moomoohk/Grame/Basics/package-info.java @@ -0,0 +1,7 @@ +/** + * Contains some helpful classes which utilize the core. + * + * @author Meshulam Silk (moomoohk@ymail.com) + * @since Feb 6, 2014 + */ +package com.moomoohk.Grame.Basics; \ No newline at end of file diff --git a/src/com/moomoohk/Grame/Essentials/ColorLayer.java b/src/com/moomoohk/Grame/Core/ColorLayer.java similarity index 76% rename from src/com/moomoohk/Grame/Essentials/ColorLayer.java rename to src/com/moomoohk/Grame/Core/ColorLayer.java index b2c0032..885f5f1 100644 --- a/src/com/moomoohk/Grame/Essentials/ColorLayer.java +++ b/src/com/moomoohk/Grame/Core/ColorLayer.java @@ -1,12 +1,13 @@ -package com.moomoohk.Grame.Essentials; +package com.moomoohk.Grame.Core; import java.awt.Color; import java.io.Serializable; -import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; +import com.moomoohk.Grame.Core.GrameUtils.MessageLevel; /** * ColorLayers provide an easy way to implement a color matrix. + * * @author Meshulam Silk * @version 1.0 * @since 2013-04-05 @@ -16,23 +17,29 @@ public class ColorLayer implements Serializable private static final long serialVersionUID = 4166643485256534497L; private Color[] colors; private int width, height; - + /** * Constructor - * @param width Width of ColorLayer - * @param height Height of ColorLayer + * + * @param width + * Width of ColorLayer + * @param height + * Height of ColorLayer */ public ColorLayer(int width, int height) { this.width = width; this.height = height; - this.colors=new Color[width*height]; + this.colors = new Color[width * height]; } /** * Sets the color of a place in this layer. - * @param pos {@link Coordinates} of place to set color. - * @param c Color to set. + * + * @param pos + * {@link Coordinates} of place to set color. + * @param c + * Color to set. */ public void setColor(Coordinates pos, Color c) { @@ -44,7 +51,9 @@ public void setColor(Coordinates pos, Color c) /** * Sets the color of all the places in this layer. - * @param c Color to set. + * + * @param c + * Color to set. */ public void setAll(Color c) { @@ -55,7 +64,9 @@ public void setAll(Color c) /** * Gets the color of a place in this layer. - * @param pos {@link Coordinates} of place. + * + * @param pos + * {@link Coordinates} of place. * @return The color of the place. */ public Color getColor(Coordinates pos) @@ -68,6 +79,7 @@ public Color getColor(Coordinates pos) /** * Returns the width of this layer. + * * @return The width of this layer. */ public int getWidth() @@ -77,18 +89,19 @@ public int getWidth() /** * Returns the height of this layer. + * * @return The height of this layer. */ public int getHeight() { return this.height; } - + /** * Prints the dimensions of this layer. */ public String toString() { - return this.width+"x"+this.height; + return this.width + "x" + this.height; } } diff --git a/src/com/moomoohk/Grame/commands/AddEntityAICommand.java b/src/com/moomoohk/Grame/Core/Commands/AddEntityAICommand.java similarity index 91% rename from src/com/moomoohk/Grame/commands/AddEntityAICommand.java rename to src/com/moomoohk/Grame/Core/Commands/AddEntityAICommand.java index c40b452..3b0f6b6 100644 --- a/src/com/moomoohk/Grame/commands/AddEntityAICommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/AddEntityAICommand.java @@ -1,9 +1,9 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.GrameManager; +import com.moomoohk.Grame.Core.GrameManager; import com.moomoohk.MooCommands.Command; public class AddEntityAICommand extends Command @@ -65,7 +65,7 @@ public String getHelpMessage() @Override public String getUsage() { - return "addentityai "; + return "addentityai "; } @Override diff --git a/src/com/moomoohk/Grame/commands/AddGrameObjectCommand.java b/src/com/moomoohk/Grame/Core/Commands/AddGrameObjectCommand.java similarity index 65% rename from src/com/moomoohk/Grame/commands/AddGrameObjectCommand.java rename to src/com/moomoohk/Grame/Core/Commands/AddGrameObjectCommand.java index c776146..a48d59f 100644 --- a/src/com/moomoohk/Grame/commands/AddGrameObjectCommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/AddGrameObjectCommand.java @@ -1,9 +1,9 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; import com.moomoohk.MooCommands.Command; public class AddGrameObjectCommand extends Command @@ -22,15 +22,15 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - if (GrameManager.findBase(Integer.parseInt(params[1])) == null) + if (GrameManager.findGrid(Integer.parseInt(params[1])) == null) { - this.outputMessage = "Base with ID:" + params[1] + " does not exist!"; + this.outputMessage = "Grid with ID:" + params[1] + " does not exist!"; this.outputColor = Color.red; return false; } - if (!GrameManager.findBase(Integer.parseInt(params[1])).isInBase(new Coordinates(Integer.parseInt(params[1]), Integer.parseInt(params[2])))) + if (!GrameManager.findGrid(Integer.parseInt(params[1])).isInGrid(new Coordinates(Integer.parseInt(params[1]), Integer.parseInt(params[2])))) { - this.outputMessage = "Coordinates (" + params[1] + ", " + params[2] + ") are not in Base with ID:" + params[1]; + this.outputMessage = "Coordinates (" + params[1] + ", " + params[2] + ") are not in Grid with ID:" + params[1]; this.outputColor = Color.red; return false; } @@ -40,7 +40,7 @@ public boolean check(String[] params) @Override public void execute(String[] params) { - GrameManager.findBase(Integer.parseInt(params[1])).addGrameObject(GrameManager.findGrameObject(Integer.parseInt(params[0])), new Coordinates(Integer.parseInt(params[2]), Integer.parseInt(params[3]))); + GrameManager.findGrid(Integer.parseInt(params[1])).addGrameObject(GrameManager.findGrameObject(Integer.parseInt(params[0])), new Coordinates(Integer.parseInt(params[2]), Integer.parseInt(params[3]))); } @Override @@ -52,13 +52,13 @@ public String getCommand() @Override public String getHelpMessage() { - return "Adds a Grame Object to a Base"; + return "Adds a Grame Object to a Grid"; } @Override public String getUsage() { - return "addobject "; + return "addobject "; } @Override diff --git a/src/com/moomoohk/Grame/commands/ClearEntityAI.java b/src/com/moomoohk/Grame/Core/Commands/ClearEntityAI.java similarity index 93% rename from src/com/moomoohk/Grame/commands/ClearEntityAI.java rename to src/com/moomoohk/Grame/Core/Commands/ClearEntityAI.java index 1762af2..7b27f32 100644 --- a/src/com/moomoohk/Grame/commands/ClearEntityAI.java +++ b/src/com/moomoohk/Grame/Core/Commands/ClearEntityAI.java @@ -1,9 +1,9 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.GrameManager; +import com.moomoohk.Grame.Core.GrameManager; import com.moomoohk.MooCommands.Command; public class ClearEntityAI extends Command diff --git a/src/com/moomoohk/Grame/commands/CreateEntityCommand.java b/src/com/moomoohk/Grame/Core/Commands/CreateEntityCommand.java similarity index 94% rename from src/com/moomoohk/Grame/commands/CreateEntityCommand.java rename to src/com/moomoohk/Grame/Core/Commands/CreateEntityCommand.java index ae8a8b4..8f60754 100644 --- a/src/com/moomoohk/Grame/commands/CreateEntityCommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/CreateEntityCommand.java @@ -1,11 +1,11 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; import java.util.HashMap; import com.moomoohk.Grame.Basics.DefaultRandomGen; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.GrameUtils; +import com.moomoohk.Grame.Core.GrameUtils; import com.moomoohk.MooCommands.Command; import com.moomoohk.MooCommands.CommandsManager; diff --git a/src/com/moomoohk/Grame/commands/DrawCoordinatesCommand.java b/src/com/moomoohk/Grame/Core/Commands/DrawCoordinatesCommand.java similarity index 90% rename from src/com/moomoohk/Grame/commands/DrawCoordinatesCommand.java rename to src/com/moomoohk/Grame/Core/Commands/DrawCoordinatesCommand.java index 08a0bc7..f2ddb67 100644 --- a/src/com/moomoohk/Grame/commands/DrawCoordinatesCommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/DrawCoordinatesCommand.java @@ -1,8 +1,8 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; -import com.moomoohk.Grame.Graphics.RenderManager; +import com.moomoohk.Grame.Core.Graphics.RenderManager; import com.moomoohk.MooCommands.Command; public class DrawCoordinatesCommand extends Command diff --git a/src/com/moomoohk/Grame/commands/isOccupiedCommand.java b/src/com/moomoohk/Grame/Core/Commands/IsOccupiedCommand.java similarity index 62% rename from src/com/moomoohk/Grame/commands/isOccupiedCommand.java rename to src/com/moomoohk/Grame/Core/Commands/IsOccupiedCommand.java index 60e871a..a2d4ff7 100644 --- a/src/com/moomoohk/Grame/commands/isOccupiedCommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/IsOccupiedCommand.java @@ -1,9 +1,9 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; import com.moomoohk.MooCommands.Command; public class IsOccupiedCommand extends Command @@ -18,13 +18,13 @@ public boolean check(String[] params) { if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) { - this.outputMessage = "Base with ID:" + params[1] + " does not exist!"; + this.outputMessage = "Grid with ID:" + params[1] + " does not exist!"; this.outputColor = Color.red; return false; } - if (!GrameManager.findBase(Integer.parseInt(params[0])).isInBase(new Coordinates(Integer.parseInt(params[1]), Integer.parseInt(params[2])))) + if (!GrameManager.findGrid(Integer.parseInt(params[0])).isInGrid(new Coordinates(Integer.parseInt(params[1]), Integer.parseInt(params[2])))) { - this.outputMessage = "Coordinates (" + params[1] + ", " + params[2] + ") are not in Base ID:" + params[0]; + this.outputMessage = "Coordinates (" + params[1] + ", " + params[2] + ") are not in Grid ID:" + params[0]; this.outputColor = Color.red; return false; } @@ -34,25 +34,25 @@ public boolean check(String[] params) @Override public void execute(String[] params) { - this.outputMessage = "" + GrameManager.findBase(Integer.parseInt(params[0])).isOccupied(new Coordinates(Integer.parseInt(params[1]), Integer.parseInt(params[2]))); + this.outputMessage = "" + GrameManager.findGrid(Integer.parseInt(params[0])).isOccupied(new Coordinates(Integer.parseInt(params[1]), Integer.parseInt(params[2]))); } @Override public String getCommand() { - return "isinbase"; + return "isoccupied"; } @Override public String getHelpMessage() { - return "Checks whether Coordinates in a Base are occupied by a Grame object"; + return "Checks whether Coordinates in a Grid are occupied by a Grame object"; } @Override public String getUsage() { - return "isoccupied "; + return "isoccupied "; } @Override diff --git a/src/com/moomoohk/Grame/commands/MakePlayerCommand.java b/src/com/moomoohk/Grame/Core/Commands/MakePlayerCommand.java similarity index 90% rename from src/com/moomoohk/Grame/commands/MakePlayerCommand.java rename to src/com/moomoohk/Grame/Core/Commands/MakePlayerCommand.java index 3575915..9c6f820 100644 --- a/src/com/moomoohk/Grame/commands/MakePlayerCommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/MakePlayerCommand.java @@ -1,9 +1,9 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.GrameManager; +import com.moomoohk.Grame.Core.GrameManager; import com.moomoohk.MooCommands.Command; public class MakePlayerCommand extends Command @@ -53,7 +53,7 @@ public String getHelpMessage() @Override public String getUsage() { - return "makeplayer "; + return "makeplayer "; } @Override diff --git a/src/com/moomoohk/Grame/commands/MoveGrameObjectCommand.java b/src/com/moomoohk/Grame/Core/Commands/MoveGrameObjectCommand.java similarity index 75% rename from src/com/moomoohk/Grame/commands/MoveGrameObjectCommand.java rename to src/com/moomoohk/Grame/Core/Commands/MoveGrameObjectCommand.java index 7dc8b9c..006ce9b 100644 --- a/src/com/moomoohk/Grame/commands/MoveGrameObjectCommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/MoveGrameObjectCommand.java @@ -1,10 +1,10 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; import com.moomoohk.Grame.Basics.Dir; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; import com.moomoohk.MooCommands.Command; public class MoveGrameObjectCommand extends Command @@ -23,19 +23,19 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - if (GrameManager.findBase(Integer.parseInt(params[1])) == null) + if (GrameManager.findGrid(Integer.parseInt(params[1])) == null) { - this.outputMessage = "Base with ID:" + params[1] + " does not exist!"; + this.outputMessage = "Grid with ID:" + params[1] + " does not exist!"; this.outputColor = Color.red; return false; } - if (params.length == 3 && !GrameManager.findBase(Integer.parseInt(params[1])).isInBase(GrameManager.findGrameObject(Integer.parseInt(params[0])).getPos(Integer.parseInt(params[1])).addDir(new Dir(params[2])))) + if (params.length == 3 && !GrameManager.findGrid(Integer.parseInt(params[1])).isInGrid(GrameManager.findGrameObject(Integer.parseInt(params[0])).getPos(Integer.parseInt(params[1])).addDir(new Dir(params[2])))) { this.outputMessage = "Can't move there!"; this.outputColor = Color.red; return false; } - if (params.length == 4 && !GrameManager.findBase(Integer.parseInt(params[1])).isInBase(new Coordinates(Integer.parseInt(params[2]), Integer.parseInt(params[3])))) + if (params.length == 4 && !GrameManager.findGrid(Integer.parseInt(params[1])).isInGrid(new Coordinates(Integer.parseInt(params[2]), Integer.parseInt(params[3])))) { this.outputMessage = "Can't move there!"; this.outputColor = Color.red; @@ -68,7 +68,7 @@ public String getHelpMessage() @Override public String getUsage() { - return "move

"; + return "move "; } @Override diff --git a/src/com/moomoohk/Grame/commands/PrintEntityAICommand.java b/src/com/moomoohk/Grame/Core/Commands/PrintEntityAICommand.java similarity index 93% rename from src/com/moomoohk/Grame/commands/PrintEntityAICommand.java rename to src/com/moomoohk/Grame/Core/Commands/PrintEntityAICommand.java index 9ba0513..e6dc8f4 100644 --- a/src/com/moomoohk/Grame/commands/PrintEntityAICommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/PrintEntityAICommand.java @@ -1,9 +1,9 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.GrameManager; +import com.moomoohk.Grame.Core.GrameManager; import com.moomoohk.MooCommands.Command; public class PrintEntityAICommand extends Command diff --git a/src/com/moomoohk/Grame/commands/QuitCommand.java b/src/com/moomoohk/Grame/Core/Commands/QuitCommand.java similarity index 92% rename from src/com/moomoohk/Grame/commands/QuitCommand.java rename to src/com/moomoohk/Grame/Core/Commands/QuitCommand.java index b5a912d..d4a957e 100644 --- a/src/com/moomoohk/Grame/commands/QuitCommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/QuitCommand.java @@ -1,4 +1,4 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import com.moomoohk.MooCommands.Command; diff --git a/src/com/moomoohk/Grame/commands/RenderBaseCommand.java b/src/com/moomoohk/Grame/Core/Commands/RenderGridCommand.java similarity index 73% rename from src/com/moomoohk/Grame/commands/RenderBaseCommand.java rename to src/com/moomoohk/Grame/Core/Commands/RenderGridCommand.java index 8a24134..99dbec4 100644 --- a/src/com/moomoohk/Grame/commands/RenderBaseCommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/RenderGridCommand.java @@ -1,15 +1,15 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Graphics.RenderManager; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.Graphics.RenderManager; import com.moomoohk.MooCommands.Command; -public class RenderBaseCommand extends Command +public class RenderGridCommand extends Command { - public RenderBaseCommand() + public RenderGridCommand() { super(); } @@ -31,7 +31,7 @@ public boolean check(String[] params) } if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) { - this.outputMessage = "Base with ID:" + params[1] + " does not exist!"; + this.outputMessage = "Grid with ID:" + params[1] + " does not exist!"; this.outputColor = Color.red; return false; } @@ -53,13 +53,13 @@ public String getCommand() @Override public String getHelpMessage() { - return "Renders a base using a render in the Render list"; + return "Renders a grid using a render in the Render list"; } @Override public String getUsage() { - return "render "; + return "render "; } @Override diff --git a/src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java b/src/com/moomoohk/Grame/Core/Commands/SetEntityOverrideAICommand.java similarity index 90% rename from src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java rename to src/com/moomoohk/Grame/Core/Commands/SetEntityOverrideAICommand.java index 26cc26f..5ff58c4 100644 --- a/src/com/moomoohk/Grame/commands/SetEntityOverrideAICommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/SetEntityOverrideAICommand.java @@ -1,9 +1,9 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.GrameManager; +import com.moomoohk.Grame.Core.GrameManager; import com.moomoohk.MooCommands.Command; public class SetEntityOverrideAICommand extends Command @@ -30,7 +30,7 @@ protected boolean check(String[] params) } if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) { - this.outputMessage = "Base with ID:" + params[1] + " does not exist!"; + this.outputMessage = "Grid with ID:" + params[1] + " does not exist!"; this.outputColor = Color.red; return false; } @@ -75,7 +75,7 @@ public String getHelpMessage() @Override public String getUsage() { - return "setentityoverrideai "; + return "setentityoverrideai "; } @Override diff --git a/src/com/moomoohk/Grame/commands/SetSpeedCommand.java b/src/com/moomoohk/Grame/Core/Commands/SetSpeedCommand.java similarity index 78% rename from src/com/moomoohk/Grame/commands/SetSpeedCommand.java rename to src/com/moomoohk/Grame/Core/Commands/SetSpeedCommand.java index e73aff8..8b94cd6 100644 --- a/src/com/moomoohk/Grame/commands/SetSpeedCommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/SetSpeedCommand.java @@ -1,8 +1,8 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; -import com.moomoohk.Grame.Essentials.GrameManager; +import com.moomoohk.Grame.Core.GrameManager; import com.moomoohk.MooCommands.Command; public class SetSpeedCommand extends Command @@ -21,14 +21,15 @@ public boolean check(String[] params) this.outputColor = Color.red; return false; } - if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) + if (GrameManager.findGrid(Integer.parseInt(params[1])) == null) { - this.outputMessage = "Base with ID:" + params[1] + " does not exist!"; + this.outputMessage = "Grid with ID:" + params[1] + " does not exist!"; this.outputColor = Color.red; return false; } return true; } + @Override public void execute(String[] params) { @@ -44,13 +45,13 @@ public String getCommand() @Override public String getHelpMessage() { - return "Sets the speed of a specified Grame Object in a specified Base"; + return "Sets the speed of a specified Grame Object in a specified Grid"; } @Override public String getUsage() { - return "setspeed "; + return "setspeed "; } @Override diff --git a/src/com/moomoohk/Grame/commands/SetSpriteCommand.java b/src/com/moomoohk/Grame/Core/Commands/SetSpriteCommand.java similarity index 96% rename from src/com/moomoohk/Grame/commands/SetSpriteCommand.java rename to src/com/moomoohk/Grame/Core/Commands/SetSpriteCommand.java index 2a132cd..268bf35 100644 --- a/src/com/moomoohk/Grame/commands/SetSpriteCommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/SetSpriteCommand.java @@ -1,4 +1,4 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; import java.io.File; diff --git a/src/com/moomoohk/Grame/commands/setVisibleCommand.java b/src/com/moomoohk/Grame/Core/Commands/SetVisibleCommand.java similarity index 91% rename from src/com/moomoohk/Grame/commands/setVisibleCommand.java rename to src/com/moomoohk/Grame/Core/Commands/SetVisibleCommand.java index e8a47e7..57ffda4 100644 --- a/src/com/moomoohk/Grame/commands/setVisibleCommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/SetVisibleCommand.java @@ -1,8 +1,8 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; -import com.moomoohk.Grame.Graphics.RenderManager; +import com.moomoohk.Grame.Core.Graphics.RenderManager; import com.moomoohk.MooCommands.Command; public class SetVisibleCommand extends Command diff --git a/src/com/moomoohk/Grame/commands/SetWraparoundCommand.java b/src/com/moomoohk/Grame/Core/Commands/SetWraparoundCommand.java similarity index 74% rename from src/com/moomoohk/Grame/commands/SetWraparoundCommand.java rename to src/com/moomoohk/Grame/Core/Commands/SetWraparoundCommand.java index 57ca44f..e61a36a 100644 --- a/src/com/moomoohk/Grame/commands/SetWraparoundCommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/SetWraparoundCommand.java @@ -1,8 +1,8 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.awt.Color; -import com.moomoohk.Grame.Essentials.GrameManager; +import com.moomoohk.Grame.Core.GrameManager; import com.moomoohk.MooCommands.Command; public class SetWraparoundCommand extends Command @@ -22,7 +22,7 @@ public boolean check(String[] params) } if (GrameManager.findGrameObject(Integer.parseInt(params[0])) == null) { - this.outputMessage = "Base with ID:" + params[1] + " does not exist!"; + this.outputMessage = "Grid with ID:" + params[1] + " does not exist!"; this.outputColor = Color.red; return false; } @@ -32,7 +32,7 @@ public boolean check(String[] params) @Override public void execute(String[] params) { - GrameManager.findBase(Integer.parseInt(params[0])).setWraparound(Boolean.parseBoolean(params[1])); + GrameManager.findGrid(Integer.parseInt(params[0])).setWraparound(Boolean.parseBoolean(params[1])); } @Override @@ -44,13 +44,13 @@ public String getCommand() @Override public String getHelpMessage() { - return "Sets whether the specified Base supports wraparound"; + return "Sets whether the specified Grid supports wraparound"; } @Override public String getUsage() { - return "setwraparound "; + return "setwraparound "; } @Override diff --git a/src/com/moomoohk/Grame/commands/ShowDialogCommand.java b/src/com/moomoohk/Grame/Core/Commands/ShowDialogCommand.java similarity index 83% rename from src/com/moomoohk/Grame/commands/ShowDialogCommand.java rename to src/com/moomoohk/Grame/Core/Commands/ShowDialogCommand.java index c8fad96..3b1cd33 100644 --- a/src/com/moomoohk/Grame/commands/ShowDialogCommand.java +++ b/src/com/moomoohk/Grame/Core/Commands/ShowDialogCommand.java @@ -1,8 +1,8 @@ -package com.moomoohk.Grame.commands; +package com.moomoohk.Grame.Core.Commands; import java.util.ArrayList; -import com.moomoohk.Grame.Essentials.GrameManager; +import com.moomoohk.Grame.Core.GrameManager; import com.moomoohk.Grame.test.Dialog; import com.moomoohk.MooCommands.Command; @@ -18,7 +18,7 @@ public String getCommand() @Override public String getHelpMessage() { - return "DEBUG: Prints some dialog on a speecified Grame Object"; + return "DEBUG: Prints some dialog on a specified Grame Object"; } @Override diff --git a/src/com/moomoohk/Grame/Core/Commands/package-info.java b/src/com/moomoohk/Grame/Core/Commands/package-info.java new file mode 100644 index 0000000..672e729 --- /dev/null +++ b/src/com/moomoohk/Grame/Core/Commands/package-info.java @@ -0,0 +1,7 @@ +/** + * Contains commands for the console. + * + * @author Meshulam Silk (moomoohk@ymail.com) + * @since Feb 6, 2014 + */ +package com.moomoohk.Grame.Core.Commands; \ No newline at end of file diff --git a/src/com/moomoohk/Grame/Essentials/Coordinates.java b/src/com/moomoohk/Grame/Core/Coordinates.java similarity index 72% rename from src/com/moomoohk/Grame/Essentials/Coordinates.java rename to src/com/moomoohk/Grame/Core/Coordinates.java index f19e869..fdeb7ef 100644 --- a/src/com/moomoohk/Grame/Essentials/Coordinates.java +++ b/src/com/moomoohk/Grame/Core/Coordinates.java @@ -1,10 +1,9 @@ -package com.moomoohk.Grame.Essentials; +package com.moomoohk.Grame.Core; import java.io.Serializable; import java.util.ArrayList; import com.moomoohk.Grame.Basics.Dir; -import com.moomoohk.Grame.Interfaces.GrameObject; /** * This class massively simplifies the way coordinates are processed. @@ -121,30 +120,30 @@ public String toString() } /** - * Will return an Coordinates[] which contains all the sets of coordinates which are adjacent to this set in a certain {@link Base} and are also in that same {@link Base}. + * Will return an Coordinates[] which contains all the sets of coordinates which are adjacent to this set in a certain {@link Grid} and are also in that same {@link Grid}. * - * @param b - * The {@link Base} in which to check. - * @return An array containing all the sets of coordinates which are adjacent to this set in a certain {@link Base} and are also in that same {@link Base}. + * @param g + * The {@link Grid} in which to check. + * @return An array containing all the sets of coordinates which are adjacent to this set in a certain {@link Grid} and are also in that same {@link Grid}. */ - public Coordinates[] getSurrounding(Base b) + public Coordinates[] getSurrounding(Grid g) { ArrayList sur = new ArrayList(); - if (b.isInBase(this.addDir(Dir.UP)) && !b.isOccupied(this.addDir(Dir.UP))) + if (g.isInGrid(this.addDir(Dir.UP)) && !g.isOccupied(this.addDir(Dir.UP))) sur.add(this.addDir(Dir.UP)); - if (b.isInBase(this.addDir(Dir.DOWN)) && !b.isOccupied(this.addDir(Dir.DOWN))) + if (g.isInGrid(this.addDir(Dir.DOWN)) && !g.isOccupied(this.addDir(Dir.DOWN))) sur.add(this.addDir(Dir.DOWN)); - if (b.isInBase(this.addDir(Dir.LEFT)) && !b.isOccupied(this.addDir(Dir.LEFT))) + if (g.isInGrid(this.addDir(Dir.LEFT)) && !g.isOccupied(this.addDir(Dir.LEFT))) sur.add(this.addDir(Dir.LEFT)); - if (b.isInBase(this.addDir(Dir.RIGHT)) && !b.isOccupied(this.addDir(Dir.RIGHT))) + if (g.isInGrid(this.addDir(Dir.RIGHT)) && !g.isOccupied(this.addDir(Dir.RIGHT))) sur.add(this.addDir(Dir.RIGHT)); - if (b.isInBase(this.addDir(new Dir(1, 1))) && !b.isOccupied(this.addDir(new Dir(1, 1)))) + if (g.isInGrid(this.addDir(new Dir(1, 1))) && !g.isOccupied(this.addDir(new Dir(1, 1)))) sur.add(this.addDir(new Dir(1, 1))); - if (b.isInBase(this.addDir(new Dir(-1, 1))) && !b.isOccupied(this.addDir(new Dir(-1, 1)))) + if (g.isInGrid(this.addDir(new Dir(-1, 1))) && !g.isOccupied(this.addDir(new Dir(-1, 1)))) sur.add(this.addDir(new Dir(-1, 1))); - if (b.isInBase(this.addDir(new Dir(1, -1))) && !b.isOccupied(this.addDir(new Dir(1, -1)))) + if (g.isInGrid(this.addDir(new Dir(1, -1))) && !g.isOccupied(this.addDir(new Dir(1, -1)))) sur.add(this.addDir(new Dir(1, -1))); - if (b.isInBase(this.addDir(new Dir(-1, -1))) && !b.isOccupied(this.addDir(new Dir(-1, -1)))) + if (g.isInGrid(this.addDir(new Dir(-1, -1))) && !g.isOccupied(this.addDir(new Dir(-1, -1)))) sur.add(this.addDir(new Dir(-1, -1))); Coordinates[] temp = new Coordinates[sur.size()]; for (int i = 0; i < sur.size(); i++) @@ -153,29 +152,29 @@ public Coordinates[] getSurrounding(Base b) } /** - * Will return an Coordinates[] which contains all the sets of coordinates which are adjacent to this set in a certain {@link Base} but are not necessarily in that same {@link Base}. + * Will return an Coordinates[] which contains all the sets of coordinates which are adjacent to this set in a certain {@link Grid} but are not necessarily in that same {@link Grid}. * - * @param b - * The {@link Base} in which to check. - * @return An array containing all the sets of coordinates which are adjacent to this set in a certain {@link Base} but are not necessarily in that same {@link Base}. + * @param g + * The {@link Grid} in which to check. + * @return An array containing all the sets of coordinates which are adjacent to this set in a certain {@link Grid} but are not necessarily in that same {@link Grid}. */ - public Coordinates[] getAllSurrounding(Base b) + public Coordinates[] getAllSurrounding(Grid g) { return new Coordinates[] { this.addDir(Dir.UP), this.addDir(Dir.LEFT), this.addDir(Dir.RIGHT), this.addDir(Dir.DOWN), this.addDir(new Dir(1, 1)), this.addDir(new Dir(-1, 1)), this.addDir(new Dir(1, -1)), this.addDir(new Dir(-1, -1)) }; } /** - * Checks whether all the adjacent sets of coordinates contain a {@link GrameObject} in a certain {@link Base}. + * Checks whether all the adjacent sets of coordinates contain a {@link GrameObject} in a certain {@link Grid}. * - * @param b - * {@link Base} in which to check. + * @param g + * {@link Grid} in which to check. * @return True if all the adjacent sets of coordinates contain a {@link GrameObject}, else false. */ - public boolean isSurrounded(Base b) + public boolean isSurrounded(Grid g) { - Coordinates[] sur = getSurrounding(b); + Coordinates[] sur = getSurrounding(g); for (Coordinates pos : sur) - if (!b.isOccupied(pos)) + if (!g.isOccupied(pos)) return false; return true; } diff --git a/src/com/moomoohk/Grame/Essentials/CrashManager.java b/src/com/moomoohk/Grame/Core/CrashManager.java similarity index 99% rename from src/com/moomoohk/Grame/Essentials/CrashManager.java rename to src/com/moomoohk/Grame/Core/CrashManager.java index d3b438a..06b3ca2 100644 --- a/src/com/moomoohk/Grame/Essentials/CrashManager.java +++ b/src/com/moomoohk/Grame/Core/CrashManager.java @@ -1,4 +1,4 @@ -package com.moomoohk.Grame.Essentials; +package com.moomoohk.Grame.Core; import java.awt.Dimension; import java.awt.EventQueue; @@ -37,7 +37,7 @@ import javax.swing.JTextPane; import javax.swing.KeyStroke; -import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; +import com.moomoohk.Grame.Core.GrameUtils.MessageLevel; /** * Manages crashes and exceptions. diff --git a/src/com/moomoohk/Grame/Core/EngineState.java b/src/com/moomoohk/Grame/Core/EngineState.java new file mode 100644 index 0000000..3353ebd --- /dev/null +++ b/src/com/moomoohk/Grame/Core/EngineState.java @@ -0,0 +1,163 @@ +package com.moomoohk.Grame.Core; + +import java.io.Serializable; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +/** + * Represents the state of the engine. Used for saving games. + * + * @author Meshulam Silk (moomoohk@ymail.com) + * @since Feb 6, 2014 + */ +public class EngineState implements Serializable +{ + private static final long serialVersionUID = 374960940802675271L; + + private ArrayList grids; + private ArrayList grameObjects; + private Calendar dateCreated; + private Date dateSaved; + private int mainGrid; + private Render mainRender; + + /** + * Constructor + */ + public EngineState() + { + this.grids = new ArrayList(); + this.grameObjects = new ArrayList(); + this.dateCreated = new GregorianCalendar(); + this.mainGrid = -1; + this.mainRender = null; + } + + /** + * Adds a {@link GrameObject} to the list of {@link GrameObject}s this state is tracking. + * + * @param go + * {@link GrameObject} to add + */ + public void addGrameObject(GrameObject go) + { + this.grameObjects.add(go); + } + + /** + * Adds a {@link Grid} to the list of {@link Grid}s this state is tracking. + * + * @param g + * {@link Grid} to add + */ + public void addGrid(Grid g) + { + this.grids.add(g); + } + + /** + * Sets the main {@link Grid} of this state. + * + * @param gID + * {@link Grid} to make main + */ + public void setMainGrid(int gID) + { + this.mainGrid = gID; + } + + /** + * Sets the main {@link Render} of this state. + * + * @param r + * {@link Render} to make main + */ + public void setMainRender(Render r) + { + this.mainRender = r; + } + + /** + * Sets the date of the saving of this state. + * + * @param d + * Date to set + */ + public void setSaved(Date d) + { + this.dateSaved = d; + } + + /** + * Gets the list of {@link Grid}s that this state is tracking. + * + * @return A list of {@link Grid}s that this state is tracking + */ + public ArrayList getGrids() + { + return this.grids; + } + + /** + * Gets the list of {@link GrameObject}s that this state is tracking. + * + * @return A list of {@link GrameObject}s that this state is tracking + */ + public ArrayList getGrameObjects() + { + return this.grameObjects; + } + + /** + * Gets the date of this state's creation. + * + * @return The date of this state's creation + */ + public Calendar getDateCreated() + { + return dateCreated; + } + + /** + * Gets the {@link Grid#ID} of the main {@link Grid} of this state. + * + * @return The {@link Grid#ID} of the main {@link Grid} of this state + */ + public int getMainGrid() + { + return this.mainGrid; + } + + /** + * Gets the main {@link Render} of this state. + * + * @return The main {@link Render} of this state + */ + public Render getMainRender() + { + return this.mainRender; + } + + /** + * Gets the date of this state's last save. + * + * @return The date of this state's last save + */ + public Date getSaved() + { + return this.dateSaved; + } + + /** + * Gets some human readable info about this state. + * + * @return Some human readable info about this state + */ + public String details() + { + return "Grids: " + this.grids.size() + ", GrameObjects: " + this.grameObjects.size() + ", Date Created: " + new SimpleDateFormat("hh:mm:ss dd/MM/yyyy").format(dateCreated.getTime()) + ", Main Grid: " + this.mainGrid + ", Main Render: " + this.mainRender; + } +} diff --git a/src/com/moomoohk/Grame/Essentials/GrameManager.java b/src/com/moomoohk/Grame/Core/GrameManager.java similarity index 94% rename from src/com/moomoohk/Grame/Essentials/GrameManager.java rename to src/com/moomoohk/Grame/Core/GrameManager.java index 8666d33..cb86113 100644 --- a/src/com/moomoohk/Grame/Essentials/GrameManager.java +++ b/src/com/moomoohk/Grame/Core/GrameManager.java @@ -1,4 +1,4 @@ -package com.moomoohk.Grame.Essentials; +package com.moomoohk.Grame.Core; import java.awt.Color; import java.awt.Component; @@ -42,13 +42,10 @@ import javax.swing.border.EmptyBorder; import com.moomoohk.Grame.Basics.Dir; -import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; -import com.moomoohk.Grame.Graphics.GridRender; -import com.moomoohk.Grame.Graphics.RenderManager; -import com.moomoohk.Grame.Interfaces.GrameObject; -import com.moomoohk.Grame.Interfaces.MainGrameClass; -import com.moomoohk.Grame.Interfaces.MovementAI; -import com.moomoohk.Grame.Interfaces.Render; +import com.moomoohk.Grame.Basics.MovementAI; +import com.moomoohk.Grame.Core.GrameUtils.MessageLevel; +import com.moomoohk.Grame.Core.Graphics.DefaultGridRender; +import com.moomoohk.Grame.Core.Graphics.RenderManager; import com.moomoohk.Grame.test.MenuConfiguration; import com.moomoohk.Mootilities.FileUtils.FileUtils; import com.moomoohk.Mootilities.FrameDragger.FrameDragger; @@ -59,7 +56,7 @@ /** * The Grame Manager takes care of all the internal Grame operations. *

- * Indexes and ticks any {@link GrameObject}s and {@link Base}s that are created automatically. + * Indexes and ticks any {@link GrameObject}s and {@link Grid}s that are created automatically. * * @author Meshulam Silk * @version 1.0 @@ -70,7 +67,7 @@ public class GrameManager implements Runnable /** * The Grame version number. */ - public static final String VERSION_NUMBER = "4.0.3"; + public static final String VERSION_NUMBER = "4.1"; /** * The WASD keys parsed to a {@link Dir}. */ @@ -96,7 +93,7 @@ public class GrameManager implements Runnable private static InputHandler input; private static Thread thread; private static int fps = 0; - private static Render defaultRender = new GridRender(); + private static Render defaultRender = new DefaultGridRender(); private static File savePath; private static MainMenu mainMenu; private static MenuConfiguration menuConfiguration; @@ -206,7 +203,7 @@ public void run() { tick(input.key); tickGrameObjects(); - tickBases(); + tickGrids(); } RenderManager.tick(); } @@ -275,10 +272,10 @@ private static void tickGrameObjects() GrameObject go = engineState.getGrameObjects().get(i); if (go == null) continue; - if (engineState.getBases() != null) - for (int bID = 0; bID < engineState.getBases().size(); bID++) - if (findBase(bID).containsGrameObject(go.ID) && go.getSpeed() != 0 && time % go.getSpeed() == 0 && !go.isPaused()) - go.tick(bID); + if (engineState.getGrids() != null) + for (int gID = 0; gID < engineState.getGrids().size(); gID++) + if (findGrid(gID).containsGrameObject(go.ID) && go.getSpeed() != 0 && time % go.getSpeed() == 0 && !go.isPaused()) + go.tick(gID); } } catch (Exception e) @@ -287,19 +284,19 @@ private static void tickGrameObjects() } } - private static void tickBases() + private static void tickGrids() { - if (engineState.getBases() == null) + if (engineState.getGrids() == null) return; - synchronized (engineState.getBases()) + synchronized (engineState.getGrids()) { try { - for (Base b : engineState.getBases()) + for (Grid g : engineState.getGrids()) { - if (b == null) + if (g == null) continue; - b.tick(); + g.tick(); } } catch (Exception e) @@ -310,18 +307,18 @@ private static void tickBases() } /** - * Disposes of all the {@link GrameObject}s and {@link Base}s. + * Disposes of all the {@link GrameObject}s and {@link Grid}s. */ public static void disposeAll() { - GrameUtils.print("Disposing of all the Bases in the Base list...", MessageLevel.NORMAL); + GrameUtils.print("Disposing of all the Grids in the Grid list...", MessageLevel.NORMAL); if (engineState != null) - for (int i = 0; i < engineState.getBases().size(); i++) + for (int i = 0; i < engineState.getGrids().size(); i++) { - GrameUtils.print("Disposing of " + engineState.getBases().get(i).ID, MessageLevel.NORMAL); - engineState.getBases().remove(i); + GrameUtils.print("Disposing of " + engineState.getGrids().get(i).ID, MessageLevel.NORMAL); + engineState.getGrids().remove(i); } - GrameUtils.print("Done disposing of Bases.", MessageLevel.NORMAL); + GrameUtils.print("Done disposing of Grids.", MessageLevel.NORMAL); } /** @@ -351,29 +348,29 @@ public static int add(GrameObject go) } /** - * Adds a {@link Base} to the Base list. + * Adds a {@link Grid} to the Grid list. *

* The user should never have to call this method. * - * @param b - * {@link Base} to add. - * @return The ID number for the Base. + * @param g + * {@link Grid} to add. + * @return The ID number for the Grid. */ - public static int add(Base b) + public static int add(Grid g) { if (!initialized) { - System.out.println("FATAL: Grame Manager not initialized! All Base instantiations should be made from in the newGame method."); + System.out.println("FATAL: Grame Manager not initialized! All Grid instantiations should be made in the newGame method."); System.exit(0); } - if (engineState.getBases().contains(b)) + if (engineState.getGrids().contains(g)) { - GrameUtils.print(b.toString() + " already exists in the Grame Object list!", MessageLevel.ERROR); + GrameUtils.print(g.toString() + " already exists in the Grame Object list!", MessageLevel.ERROR); return -1; } - engineState.getBases().add(b); - GrameUtils.print("Added a Base to the Base list (ID:" + (engineState.getBases().size() - 1) + ")", MessageLevel.NORMAL); - return engineState.getBases().size() - 1; + engineState.getGrids().add(g); + GrameUtils.print("Added a Grid to the Grid list (ID:" + (engineState.getGrids().size() - 1) + ")", MessageLevel.NORMAL); + return engineState.getGrids().size() - 1; } /** @@ -399,22 +396,22 @@ public static GrameObject findGrameObject(int id) } /** - * Finds and returns a {@link Base} from the Base list.
- * If the {@link Base} is not found, null will be returned. + * Finds and returns a {@link Grid} from the Grid list.
+ * If the {@link Grid} is not found, null will be returned. * * @param id - * The ID of the {@link Base} to find. - * @return The {@link Base} with that ID. If not in the list, null will be returned. + * The ID of the {@link Grid} to find. + * @return The {@link Grid} with that ID. If not in the list, null will be returned. */ - public static Base findBase(int id) + public static Grid findGrid(int id) { try { - return engineState.getBases().get(id); + return engineState.getGrids().get(id); } catch (Exception e) { - GrameUtils.print("Base with ID:" + id + " not found! Returning null instead.", MessageLevel.ERROR); + GrameUtils.print("Grid with ID:" + id + " not found! Returning null instead.", MessageLevel.ERROR); } return null; } @@ -601,9 +598,9 @@ public static int getObjectListLength() return engineState.getGrameObjects().size(); } - public static int getBaseListLength() + public static int getGridListLength() { - return engineState.getBases().size(); + return engineState.getGrids().size(); } /** @@ -616,14 +613,14 @@ public static int getFPS() return fps; } - public static void setMainBase(int bID) + public static void setMainGrid(int gID) { - engineState.setMainBase(bID); + engineState.setMainGrid(gID); } - public static int getMainBase() + public static int getMainGrid() { - return engineState.getMainBase(); + return engineState.getMainGrid(); } public static void setMainRender(Render r) @@ -1126,7 +1123,7 @@ protected void confirm() RenderManager.initialize(); RenderManager.clearAllText(); engineState = saves.get(selectedEngineStateName); - RenderManager.render(engineState.getMainBase(), engineState.getMainRender()); + RenderManager.render(engineState.getMainGrid(), engineState.getMainRender()); RenderManager.setVisible(true); start(); paused = false; diff --git a/src/com/moomoohk/Grame/Interfaces/GrameObject.java b/src/com/moomoohk/Grame/Core/GrameObject.java similarity index 71% rename from src/com/moomoohk/Grame/Interfaces/GrameObject.java rename to src/com/moomoohk/Grame/Core/GrameObject.java index 20164a8..101e262 100644 --- a/src/com/moomoohk/Grame/Interfaces/GrameObject.java +++ b/src/com/moomoohk/Grame/Core/GrameObject.java @@ -1,17 +1,13 @@ -package com.moomoohk.Grame.Interfaces; +package com.moomoohk.Grame.Core; import java.awt.Color; import java.io.Serializable; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Essentials.GrameObjectLayer; -import com.moomoohk.Grame.Essentials.GrameUtils; -import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; +import com.moomoohk.Grame.Core.GrameUtils.MessageLevel; /** - * Grame Objects are objects which are placed in {@link Base}s. + * Grame Objects are objects which are placed in {@link Grid}s. + * * @author Meshulam Silk * @version 1.0 * @since 2013-04-05 @@ -137,34 +133,34 @@ public boolean isPaused() } /** - * Gets the position of this object in a certain {@link Base}.
- * If this object doesn't exist in the {@link Base} null will be returned. + * Gets the position of this object in a certain {@link Grid}.
+ * If this object doesn't exist in the {@link Grid} null will be returned. * - * @param bID - * {@link Base#ID} of {@link Base}. - * @return {@link Coordinates} of this object in the {@link Base}. If this object isn't in the {@link Base}, null will be returned. + * @param gID + * {@link Grid#ID} of {@link Grid}. + * @return {@link Coordinates} of this object in the {@link Grid}. If this object isn't in the {@link Grid}, null will be returned. */ - public Coordinates getPos(int bID) + public Coordinates getPos(int gID) { - if (GrameManager.findBase(bID).containsGrameObject(ID)) - return GrameManager.findBase(bID).getGrameObjectPos(ID); - GrameUtils.print("Base with ID:" + bID + " does not contain Entity with ID:" + ID + ". Returning null.", MessageLevel.ERROR); + if (GrameManager.findGrid(gID).containsGrameObject(ID)) + return GrameManager.findGrid(gID).getGrameObjectPos(ID); + GrameUtils.print("Grid with ID:" + gID + " does not contain Entity with ID:" + ID + ". Returning null.", MessageLevel.ERROR); return null; } /** - * Sets the position of this object in a certain {@link Base}. + * Sets the position of this object in a certain {@link Grid}. * - * @param bID - * {@link Base#ID} of {@link Base}. + * @param gID + * {@link Grid#ID} of {@link Grid}. * @param pos * New position to set. */ - public void setPos(int bID, Coordinates pos) + public void setPos(int gID, Coordinates pos) { - if (GrameManager.findBase(bID).containsGrameObject(ID)) + if (GrameManager.findGrid(gID).containsGrameObject(ID)) { - GrameManager.findBase(bID).moveGrameObject(ID, pos); + GrameManager.findGrid(gID).moveGrameObject(ID, pos); return; } } @@ -185,10 +181,10 @@ public void setPos(int bID, Coordinates pos) *

* Users will never need to call this method (The {@link GrameManager} takes care of ticking everything). * - * @param bID - * The {@link Base#ID} of the {@link Base} in which to tick. + * @param gID + * The {@link Grid#ID} of the {@link Grid} in which to tick. */ - public abstract void tick(int bID); + public abstract void tick(int gID); /** * This method gets called if this object is collidable and it tries to occupy the position of a non collidable object. diff --git a/src/com/moomoohk/Grame/Essentials/GrameObjectLayer.java b/src/com/moomoohk/Grame/Core/GrameObjectLayer.java similarity index 95% rename from src/com/moomoohk/Grame/Essentials/GrameObjectLayer.java rename to src/com/moomoohk/Grame/Core/GrameObjectLayer.java index 23104a9..c693284 100644 --- a/src/com/moomoohk/Grame/Essentials/GrameObjectLayer.java +++ b/src/com/moomoohk/Grame/Core/GrameObjectLayer.java @@ -1,9 +1,8 @@ -package com.moomoohk.Grame.Essentials; +package com.moomoohk.Grame.Core; import java.io.Serializable; -import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; -import com.moomoohk.Grame.Interfaces.GrameObject; +import com.moomoohk.Grame.Core.GrameUtils.MessageLevel; /** * GrameObjectLayers provide an easy way to store {@link GrameObject}s. diff --git a/src/com/moomoohk/Grame/Essentials/GrameUtils.java b/src/com/moomoohk/Grame/Core/GrameUtils.java similarity index 88% rename from src/com/moomoohk/Grame/Essentials/GrameUtils.java rename to src/com/moomoohk/Grame/Core/GrameUtils.java index bcc956b..b449046 100644 --- a/src/com/moomoohk/Grame/Essentials/GrameUtils.java +++ b/src/com/moomoohk/Grame/Core/GrameUtils.java @@ -1,4 +1,4 @@ -package com.moomoohk.Grame.Essentials; +package com.moomoohk.Grame.Core; import java.awt.Color; import java.awt.Cursor; @@ -28,29 +28,28 @@ import javax.swing.JLabel; import javax.swing.JOptionPane; -import com.moomoohk.Grame.AI.AStarPathfindingMovementAI; -import com.moomoohk.Grame.AI.PlayerMovementAI; -import com.moomoohk.Grame.AI.PlayerSimAI; -import com.moomoohk.Grame.AI.SimpleChaseAI; -import com.moomoohk.Grame.AI.SimpleStrollAI; -import com.moomoohk.Grame.Interfaces.GrameObject; -import com.moomoohk.Grame.commands.AddEntityAICommand; -import com.moomoohk.Grame.commands.AddGrameObjectCommand; -import com.moomoohk.Grame.commands.ClearEntityAI; -import com.moomoohk.Grame.commands.CreateEntityCommand; -import com.moomoohk.Grame.commands.DrawCoordinatesCommand; -import com.moomoohk.Grame.commands.IsOccupiedCommand; -import com.moomoohk.Grame.commands.MakePlayerCommand; -import com.moomoohk.Grame.commands.MoveGrameObjectCommand; -import com.moomoohk.Grame.commands.PrintEntityAICommand; -import com.moomoohk.Grame.commands.QuitCommand; -import com.moomoohk.Grame.commands.RenderBaseCommand; -import com.moomoohk.Grame.commands.SetEntityOverrideAICommand; -import com.moomoohk.Grame.commands.SetSpeedCommand; -import com.moomoohk.Grame.commands.SetSpriteCommand; -import com.moomoohk.Grame.commands.SetVisibleCommand; -import com.moomoohk.Grame.commands.SetWraparoundCommand; -import com.moomoohk.Grame.commands.ShowDialogCommand; +import com.moomoohk.Grame.Basics.AI.AStarPathfindingMovementAI; +import com.moomoohk.Grame.Basics.AI.PlayerMovementAI; +import com.moomoohk.Grame.Basics.AI.PlayerSimAI; +import com.moomoohk.Grame.Basics.AI.SimpleChaseAI; +import com.moomoohk.Grame.Basics.AI.SimpleStrollAI; +import com.moomoohk.Grame.Core.Commands.AddEntityAICommand; +import com.moomoohk.Grame.Core.Commands.AddGrameObjectCommand; +import com.moomoohk.Grame.Core.Commands.ClearEntityAI; +import com.moomoohk.Grame.Core.Commands.CreateEntityCommand; +import com.moomoohk.Grame.Core.Commands.DrawCoordinatesCommand; +import com.moomoohk.Grame.Core.Commands.IsOccupiedCommand; +import com.moomoohk.Grame.Core.Commands.MakePlayerCommand; +import com.moomoohk.Grame.Core.Commands.MoveGrameObjectCommand; +import com.moomoohk.Grame.Core.Commands.PrintEntityAICommand; +import com.moomoohk.Grame.Core.Commands.QuitCommand; +import com.moomoohk.Grame.Core.Commands.RenderGridCommand; +import com.moomoohk.Grame.Core.Commands.SetEntityOverrideAICommand; +import com.moomoohk.Grame.Core.Commands.SetSpeedCommand; +import com.moomoohk.Grame.Core.Commands.SetSpriteCommand; +import com.moomoohk.Grame.Core.Commands.SetVisibleCommand; +import com.moomoohk.Grame.Core.Commands.SetWraparoundCommand; +import com.moomoohk.Grame.Core.Commands.ShowDialogCommand; import com.moomoohk.MooCommands.CommandsManager; import com.moomoohk.MooConsole.Console; import com.moomoohk.MooConsole.HelpCommand; @@ -192,13 +191,13 @@ public static Color randomColor() } /** - * Will generate a random set of {@link Coordinates} which exist in the given {@link Base}. + * Will generate a random set of {@link Coordinates} which exist in the given {@link Grid}. * * @param b - * The {@link Base} in which to get {@link Coordinates}. - * @return A random set of {@link Coordinates} which exist in the given {@link Base}. + * The {@link Grid} in which to get {@link Coordinates}. + * @return A random set of {@link Coordinates} which exist in the given {@link Grid}. */ - public static Coordinates randomCoordinates(Base b) + public static Coordinates randomCoordinates(Grid b) { return new Coordinates(new Random().nextInt(b.getColumns()), new Random().nextInt(b.getRows())); } @@ -466,7 +465,7 @@ private static void loadBasicCommands() new HelpCommand(); new SetVisibleCommand(); new MoveGrameObjectCommand(); - new RenderBaseCommand(); + new RenderGridCommand(); new QuitCommand(); new CreateEntityCommand(); new AddGrameObjectCommand(); diff --git a/src/com/moomoohk/Grame/Core/Graphics/CleanGridRender.java b/src/com/moomoohk/Grame/Core/Graphics/CleanGridRender.java new file mode 100644 index 0000000..7ce37ff --- /dev/null +++ b/src/com/moomoohk/Grame/Core/Graphics/CleanGridRender.java @@ -0,0 +1,47 @@ +package com.moomoohk.Grame.Core.Graphics; + +import java.io.Serializable; + +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.Grid; +import com.moomoohk.Grame.Core.Render; + +/** + * Renders {@link Grid}s in a grid without grouting lines. + * + * @author Meshulam Silk + * @version 1.0 + * @since 2013-04-05 + */ +public class CleanGridRender implements Render, Serializable +{ + private static final long serialVersionUID = 1269305794830678142L; + + public int[] getPixels(int[] pixels, Grid b, int width, int height) + { + for (int x = 0; x < width; x++) + for (int y = 0; y < height; y++) + { + Coordinates currSquare = new Coordinates((x) / ((width) / (b.getColumns())), (y) / (height / b.getRows())); + if (currSquare.getX() >= b.getColumns()) + currSquare.setX(b.getColumns() - 1); + if (currSquare.getY() >= b.getRows()) + currSquare.setY(b.getRows() - 1); + if (b.isInGrid(currSquare)) + try + { + pixels[x + y * width] = b.getColor(currSquare).getRGB(); + } + catch (Exception e) + { + System.out.println(x + " " + width); + } + } + return pixels; + } + + public String getName() + { + return "Clean_grid_render"; + } +} diff --git a/src/com/moomoohk/Grame/Graphics/GridRender.java b/src/com/moomoohk/Grame/Core/Graphics/DefaultGridRender.java similarity index 71% rename from src/com/moomoohk/Grame/Graphics/GridRender.java rename to src/com/moomoohk/Grame/Core/Graphics/DefaultGridRender.java index be97beb..b39cf3a 100644 --- a/src/com/moomoohk/Grame/Graphics/GridRender.java +++ b/src/com/moomoohk/Grame/Core/Graphics/DefaultGridRender.java @@ -1,44 +1,40 @@ -package com.moomoohk.Grame.Graphics; +package com.moomoohk.Grame.Core.Graphics; import java.awt.Color; import java.io.Serializable; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Interfaces.Render; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.Grid; +import com.moomoohk.Grame.Core.Render; /** - * Render {@link Base}s in a grid with grouting lines. + * Render {@link Grid}s in a grid with grouting lines. * * @author Meshulam Silk * @version 1.0 * @since 2013-04-05 */ -public class GridRender implements Render, Serializable +public class DefaultGridRender implements Render, Serializable { private static final long serialVersionUID = 2057716349989082233L; - public int[] getPixels(int[] pixels, Base b, int width, int height) + public int[] getPixels(int[] pixels, Grid b, int width, int height) { for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) { int squareW = (width) / (b.getColumns()), squareH = (height / b.getRows()); - if(squareH==0) + if (squareH == 0) { - pixels[x+y*width]=Color.black.getRGB(); + pixels[x + y * width] = Color.black.getRGB(); continue; } int pixelX = (x) / (squareW), pixelY = y / squareH; Coordinates currSquare = new Coordinates(pixelX, pixelY); - if (b.isInBase(currSquare)) - { + if (b.isInGrid(currSquare)) pixels[x + y * width] = b.getColor(currSquare).getRGB(); - } if (x % (width / b.getColumns()) == 0 || (x + 1) % (width / b.getColumns()) == 0 || y % (height / b.getRows()) == 0 || (y + 1) % (height / b.getRows()) == 0) - { pixels[x + y * width] = Color.black.getRGB(); - } /*else { int squareW = (width) / (b.getColumns()), squareH = (height / b.getRows()); @@ -57,7 +53,7 @@ public int[] getPixels(int[] pixels, Base b, int width, int height) public String getName() { - return "Grid_render"; + return "Default_grid_render"; } } diff --git a/src/com/moomoohk/Grame/Graphics/GaussianFilter.java b/src/com/moomoohk/Grame/Core/Graphics/GaussianFilter.java similarity index 98% rename from src/com/moomoohk/Grame/Graphics/GaussianFilter.java rename to src/com/moomoohk/Grame/Core/Graphics/GaussianFilter.java index 823423f..684dcbf 100644 --- a/src/com/moomoohk/Grame/Graphics/GaussianFilter.java +++ b/src/com/moomoohk/Grame/Core/Graphics/GaussianFilter.java @@ -1,4 +1,4 @@ -package com.moomoohk.Grame.Graphics; +package com.moomoohk.Grame.Core.Graphics; import java.awt.image.BufferedImage; import java.awt.image.Kernel; diff --git a/src/com/moomoohk/Grame/Graphics/PostProcessing/Label.java b/src/com/moomoohk/Grame/Core/Graphics/PostProcessing/Label.java similarity index 87% rename from src/com/moomoohk/Grame/Graphics/PostProcessing/Label.java rename to src/com/moomoohk/Grame/Core/Graphics/PostProcessing/Label.java index a1a7332..a706bcd 100644 --- a/src/com/moomoohk/Grame/Graphics/PostProcessing/Label.java +++ b/src/com/moomoohk/Grame/Core/Graphics/PostProcessing/Label.java @@ -1,4 +1,4 @@ -package com.moomoohk.Grame.Graphics.PostProcessing; +package com.moomoohk.Grame.Core.Graphics.PostProcessing; import java.awt.Color; import java.awt.Font; @@ -10,11 +10,6 @@ public class Label private Color textColor, backColor; private Font font; - public Label() - { - this(0, 0, null, null, null, null, 0, 0, 0, 0); - } - public Label(int centerX, int centerY, String text, Font font, Color textColor, Color backColor, int paddingTop, int paddingLeft, int paddingRight, int paddingBottom) { this.centerX = centerX; @@ -59,14 +54,6 @@ public int getPaddingLeft() return paddingLeft; } - public void setPadding(int padding) - { - this.paddingTop = padding; - this.paddingLeft = padding; - this.paddingRight = padding; - this.paddingBottom = padding; - } - public void setPaddingBottom(int paddingBottom) { this.paddingBottom = paddingBottom; @@ -136,4 +123,4 @@ public Font getFont() { return font; } -} +} \ No newline at end of file diff --git a/src/com/moomoohk/Grame/Core/Graphics/PostProcessing/package-info.java b/src/com/moomoohk/Grame/Core/Graphics/PostProcessing/package-info.java new file mode 100644 index 0000000..e170552 --- /dev/null +++ b/src/com/moomoohk/Grame/Core/Graphics/PostProcessing/package-info.java @@ -0,0 +1,7 @@ +/** + * Contains special override graphics stuff + * + * @author Meshulam Silk (moomoohk@ymail.com) + * @since Feb 6, 2014 + */ +package com.moomoohk.Grame.Core.Graphics.PostProcessing; \ No newline at end of file diff --git a/src/com/moomoohk/Grame/Graphics/RandomRender.java b/src/com/moomoohk/Grame/Core/Graphics/RandomRender.java similarity index 64% rename from src/com/moomoohk/Grame/Graphics/RandomRender.java rename to src/com/moomoohk/Grame/Core/Graphics/RandomRender.java index 89430be..cef6cec 100644 --- a/src/com/moomoohk/Grame/Graphics/RandomRender.java +++ b/src/com/moomoohk/Grame/Core/Graphics/RandomRender.java @@ -1,9 +1,9 @@ -package com.moomoohk.Grame.Graphics; +package com.moomoohk.Grame.Core.Graphics; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.GrameUtils; -import com.moomoohk.Grame.Interfaces.Render; +import com.moomoohk.Grame.Core.Grid; +import com.moomoohk.Grame.Core.GrameUtils; +import com.moomoohk.Grame.Core.Render; /** * Randomizes a bunch of pixels. @@ -16,7 +16,7 @@ */ public class RandomRender implements Render { - public int[] getPixels(int[] pixels, Base b, int width, int height) + public int[] getPixels(int[] pixels, Grid b, int width, int height) { for (int i = 0; i < pixels.length; i++) pixels[i] = GrameUtils.randomColor().getRGB(); diff --git a/src/com/moomoohk/Grame/Graphics/RenderManager.java b/src/com/moomoohk/Grame/Core/Graphics/RenderManager.java similarity index 66% rename from src/com/moomoohk/Grame/Graphics/RenderManager.java rename to src/com/moomoohk/Grame/Core/Graphics/RenderManager.java index fd7385f..3cf3808 100644 --- a/src/com/moomoohk/Grame/Graphics/RenderManager.java +++ b/src/com/moomoohk/Grame/Core/Graphics/RenderManager.java @@ -1,4 +1,4 @@ -package com.moomoohk.Grame.Graphics; +package com.moomoohk.Grame.Core.Graphics; import java.awt.Canvas; import java.awt.Color; @@ -10,6 +10,7 @@ import java.awt.Toolkit; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; +import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferStrategy; import java.awt.image.BufferedImage; @@ -19,13 +20,13 @@ import javax.swing.JFrame; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Essentials.GrameUtils; -import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; -import com.moomoohk.Grame.Graphics.PostProcessing.Label; -import com.moomoohk.Grame.Interfaces.Render; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.GrameUtils; +import com.moomoohk.Grame.Core.GrameUtils.MessageLevel; +import com.moomoohk.Grame.Core.Grid; +import com.moomoohk.Grame.Core.Render; +import com.moomoohk.Grame.Core.Graphics.PostProcessing.Label; /** * Manages all the rendering operations. @@ -61,38 +62,38 @@ public static void initialize() } /** - * Renders a {@link Base}. + * Renders a {@link Grid}. * - * @param bID - * The {@link Base#ID} of the {@link Base} to render. + * @param gID + * The {@link Grid#ID} of the {@link Grid} to render. */ - public static void render(int bID) + public static void render(int gID) { - render(bID, renders.get(bID)); + render(gID, renders.get(gID)); } /** - * Renders a {@link Base} using a given {@link Render}. + * Renders a {@link Grid} using a given {@link Render}. * - * @param bID - * The {@link Base#ID} of the {@link Base} to render. + * @param gID + * The {@link Grid#ID} of the {@link Grid} to render. * @param render * The {@link Render} to use. */ - public static void render(final int bID, Render render) + public static void render(final int gID, Render render) { - if (bID < 0) + if (gID < 0) return; - setupFrame(bID); - if (bID != mainBase || GrameManager.findBase(bID) == null) - GrameManager.setMainBase(bID); - mainBase = bID; + setupFrame(gID); + if (gID != mainBase || GrameManager.findGrid(gID) == null) + GrameManager.setMainGrid(gID); + mainBase = gID; mainFrame.setTitle(GrameManager.getGameName()); if (render == null) render = GrameManager.getDefaultRender(); - if (!render.equals(renders.get(bID))) + if (!render.equals(renders.get(gID))) GrameManager.setMainRender(render); - renders.put(bID, render); + renders.put(gID, render); BufferStrategy bs = mainCanvas.getBufferStrategy(); if (bs == null) { @@ -104,7 +105,7 @@ public static void render(final int bID, Render render) int[] pixels = ((DataBufferInt) img.getRaster().getDataBuffer()).getData(); try { - pixels = render.getPixels(pixels, GrameManager.findBase(bID), mainCanvas.getWidth(), mainCanvas.getHeight()); + pixels = render.getPixels(pixels, GrameManager.findGrid(gID), mainCanvas.getWidth(), mainCanvas.getHeight()); } catch (Exception e) { @@ -113,15 +114,15 @@ public static void render(final int bID, Render render) g2 = (Graphics2D) bs.getDrawGraphics().create(); g2.setFont(new Font("LucidaTypewriter", 1, 8)); - int squaresize = mainCanvas.getWidth() / GrameManager.findBase(bID).getColumns(); - for (int x = 0; x < GrameManager.findBase(bID).getColumns(); x++) - for (int y = 0; y < GrameManager.findBase(bID).getRows(); y++) - if (text.get(bID) != null) + int squaresize = mainCanvas.getWidth() / GrameManager.findGrid(gID).getColumns(); + for (int x = 0; x < GrameManager.findGrid(gID).getColumns(); x++) + for (int y = 0; y < GrameManager.findGrid(gID).getRows(); y++) + if (text.get(gID) != null) { - if (text.get(bID).getText(new Coordinates(x, y)) != null && text.get(bID).getText(new Coordinates(x, y)).trim().length() != 0) + if (text.get(gID).getText(new Coordinates(x, y)) != null && text.get(gID).getText(new Coordinates(x, y)).trim().length() != 0) { - g2.setColor(text.get(bID).getColor(new Coordinates(x, y))); - g2.drawString(text.get(bID).getText(new Coordinates(x, y)), y * squaresize, (x + 1) * (squaresize) - ((squaresize / 2) - 5)); + g2.setColor(text.get(gID).getColor(new Coordinates(x, y))); + g2.drawString(text.get(gID).getText(new Coordinates(x, y)), y * squaresize, (x + 1) * (squaresize) - ((squaresize / 2) - 5)); } } if (!GrameManager.paused) @@ -139,10 +140,11 @@ public static void render(final int bID, Render render) if (drawCoordinates) { g2.setColor(Color.blue); - for (int x = 0; x < GrameManager.findBase(bID).getColumns(); x++) - for (int y = 0; y < GrameManager.findBase(bID).getRows(); y++) + for (int x = 0; x < GrameManager.findGrid(gID).getColumns(); x++) + for (int y = 0; y < GrameManager.findGrid(gID).getRows(); y++) g2.drawString("(" + y + ", " + x + ")", y * squaresize, (x + 1) * (squaresize) - ((squaresize / 2) - 5)); } + drawLabel(new Label(500, 500, "Testing really long string", new Font("LucidaTypewriter", Font.BOLD, 20), Color.white, Color.black, 10, 10, 10, 10)); g2.dispose(); bs.show(); } @@ -159,7 +161,7 @@ public static void drawLabel(Label l) g2.setFont(l.getFont()); FontMetrics fm = g2.getFontMetrics(); Rectangle2D textBounds = fm.getStringBounds(l.getText(), g2); - Rectangle fixed = new Rectangle((int) (l.getCenterX() - (textBounds.getWidth() / 2)), (int) (l.getCenterY() - (textBounds.getHeight() / 2)), (int) textBounds.getWidth(), (int) textBounds.getHeight()); + Rectangle fixed = new Rectangle((int) (Math.min(l.getCenterX(), textBounds.getWidth()) - (textBounds.getWidth() / 2)), (int) (l.getCenterY() - (textBounds.getHeight() / 2)), (int) Math.min(textBounds.getWidth(), mainCanvas.getWidth()), (int) textBounds.getHeight()); Rectangle back = new Rectangle((int) fixed.getX() - l.getPaddingLeft(), (int) fixed.getY() - l.getPaddingTop(), (int) (fixed.getWidth()) + l.getPaddingRight() + l.getPaddingLeft(), (int) (fixed.getHeight()) + l.getPaddingBottom() + l.getPaddingTop()); g2.setColor(new Color(0, 0, 0, 180)); @@ -167,15 +169,15 @@ public static void drawLabel(Label l) g2.setColor(new Color(l.getTextColor().getRed(), l.getTextColor().getGreen(), l.getTextColor().getBlue(), 180)); g2.drawString(l.getText(), (int) (fixed.getX()), (int) (fixed.getY() + Math.max(fm.getMaxAscent(), fm.getMaxDescent()))); - // g2.setColor(Color.cyan); - // g2.draw(new Ellipse2D.Double(textCenterX - 5, textCenterY - 5, 10, 10)); - // g2.setColor(Color.blue); - // g2.draw(back); - // g2.setColor(Color.green); - // g2.draw(textBounds); - // g2.setColor(Color.red); - // g2.draw(fixed); - // g2.fill(new Ellipse2D.Double(fixed.getCenterX() - 2, fixed.getCenterY() - 2, 4, 4)); + g2.setColor(Color.cyan); + g2.draw(new Ellipse2D.Double(l.getCenterX() - 5, l.getCenterY() - 5, 10, 10)); + g2.setColor(Color.blue); + g2.draw(back); + g2.setColor(Color.green); + g2.draw(textBounds); + g2.setColor(Color.red); + g2.draw(fixed); + g2.fill(new Ellipse2D.Double(fixed.getCenterX() - 2, fixed.getCenterY() - 2, 4, 4)); } public static void setOverlayColor(Color color) @@ -187,14 +189,14 @@ public static void setOverlayColor(Color color) /** * Generates a blank {@link Canvas} which is of the required size. * - * @param bID - * {@link Base#ID} of the {@link Base} of which this {@link Canvas} is. + * @param gID + * {@link Grid#ID} of the {@link Grid} of which this {@link Canvas} is. * @return A {@link Canvas}. */ - public static Canvas generateCanvas(int bID) + public static Canvas generateCanvas(int gID) { Canvas c = new Canvas(); - int width = Math.min(squareSize * GrameManager.findBase(bID).getColumns(), Toolkit.getDefaultToolkit().getScreenSize().width), height = Math.min(squareSize * GrameManager.findBase(bID).getRows(), Toolkit.getDefaultToolkit().getScreenSize().height - 50); + int width = Math.min(squareSize * GrameManager.findGrid(gID).getColumns(), Toolkit.getDefaultToolkit().getScreenSize().width), height = Math.min(squareSize * GrameManager.findGrid(gID).getRows(), Toolkit.getDefaultToolkit().getScreenSize().height - 50); c.setSize(width, height); return c; } @@ -202,15 +204,15 @@ public static Canvas generateCanvas(int bID) /** * Sets up the main window. * - * @param bID - * {@link Base#ID} of the {@link Base} which is being rendered. + * @param gID + * {@link Grid#ID} of the {@link Grid} which is being rendered. */ - public static void setupFrame(int bID) + public static void setupFrame(int gID) { - if (bID != mainBase) + if (gID != mainBase) { if (mainCanvas == null) - mainCanvas = generateCanvas(bID); + mainCanvas = generateCanvas(gID); mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); mainFrame.setResizable(false); mainFrame.add(mainCanvas); @@ -234,7 +236,7 @@ public void focusGained(FocusEvent paramFocusEvent) } /** - * Renders the main {@link Base}. + * Renders the main {@link Grid}. */ public synchronized static void tick() { @@ -243,16 +245,16 @@ public synchronized static void tick() } /** - * Attaches a {@link Render} to a {@link Base} for future reference. + * Attaches a {@link Render} to a {@link Grid} for future reference. * - * @param bID - * {@link Base#ID} of {@link Base} to attach the {@link Render} to. + * @param gID + * {@link Grid#ID} of {@link Grid} to attach the {@link Render} to. * @param render * The {@link Render} to attach. */ - public static void setRender(int bID, Render render) + public static void setRender(int gID, Render render) { - renders.put(bID, render); + renders.put(gID, render); } /** @@ -260,8 +262,8 @@ public static void setRender(int bID, Render render) */ private static void loadRenders() { - GrameManager.addRender(new GridRender()); - GrameManager.addRender(new PlainGridRender()); + GrameManager.addRender(new DefaultGridRender()); + GrameManager.addRender(new CleanGridRender()); } /** @@ -306,11 +308,11 @@ public static Canvas getMainCanvas() } /** - * Gets the {@link Base#ID} of the main {@link Base}. + * Gets the {@link Grid#ID} of the main {@link Grid}. * - * @return The {@link Base#ID} of the main {@link Base}. + * @return The {@link Grid#ID} of the main {@link Grid}. */ - public static int getMainBase() + public static int getMainGrid() { return mainBase; } @@ -338,13 +340,13 @@ public static void drawCoordinates(boolean f) drawCoordinates = f; } - public static void setText(int bID, Coordinates pos, String text, Color color) + public static void setText(int gID, Coordinates pos, String text, Color color) { - if (!GrameManager.findBase(bID).isInBase(pos)) + if (!GrameManager.findGrid(gID).isInGrid(pos)) return; - if (RenderManager.text.get(bID) == null) - RenderManager.text.put(bID, new TextLayer(GrameManager.findBase(bID).getRows(), GrameManager.findBase(bID).getColumns())); - RenderManager.text.get(bID).setText(pos, text, color); + if (RenderManager.text.get(gID) == null) + RenderManager.text.put(gID, new TextLayer(GrameManager.findGrid(gID).getRows(), GrameManager.findGrid(gID).getColumns())); + RenderManager.text.get(gID).setText(pos, text, color); } public static void clearAllText() @@ -353,9 +355,9 @@ public static void clearAllText() clearText(i); } - public static void clearText(int bID) + public static void clearText(int gID) { - text.put(bID, new TextLayer(GrameManager.findBase(bID).getRows(), GrameManager.findBase(bID).getColumns())); + text.put(gID, new TextLayer(GrameManager.findGrid(gID).getRows(), GrameManager.findGrid(gID).getColumns())); } private static class TextLayer @@ -399,10 +401,10 @@ public static void addLabel(Label l) { labels.add(l); } - + public static void removeLabel(Label l) { - if(labels.contains(l)) + if (labels.contains(l)) labels.remove(l); } } \ No newline at end of file diff --git a/src/com/moomoohk/Grame/Core/Graphics/package-info.java b/src/com/moomoohk/Grame/Core/Graphics/package-info.java new file mode 100644 index 0000000..7c90ee6 --- /dev/null +++ b/src/com/moomoohk/Grame/Core/Graphics/package-info.java @@ -0,0 +1,7 @@ +/** + * Contains graphics related classes such as Render types. + * + * @author Meshulam Silk (moomoohk@ymail.com) + * @since Feb 6, 2014 + */ +package com.moomoohk.Grame.Core.Graphics; \ No newline at end of file diff --git a/src/com/moomoohk/Grame/Essentials/Base.java b/src/com/moomoohk/Grame/Core/Grid.java similarity index 76% rename from src/com/moomoohk/Grame/Essentials/Base.java rename to src/com/moomoohk/Grame/Core/Grid.java index c64aedc..356ca25 100644 --- a/src/com/moomoohk/Grame/Essentials/Base.java +++ b/src/com/moomoohk/Grame/Core/Grid.java @@ -1,27 +1,26 @@ -package com.moomoohk.Grame.Essentials; +package com.moomoohk.Grame.Core; import java.awt.Color; import java.io.Serializable; import java.util.ArrayList; -import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; -import com.moomoohk.Grame.Interfaces.GrameObject; +import com.moomoohk.Grame.Core.GrameUtils.MessageLevel; /** - * Bases are the backbone of Grame. They serve as the map in which objects move around and interact with each other. + * Grids are the backbone of Grame. They serve as the map in which objects move around and interact with each other. * * @author Meshulam Silk * @version 1.0 * @since 2013-04-05 */ -public class Base implements Serializable +public class Grid implements Serializable { private static final long serialVersionUID = 8132183829206502759L; /** - * The ID of this Base. + * The ID of this Grid. *

* This ID is unique and cannot be changed.
- * It is this Base's place in the {@link GrameManager}'s list of Bases. + * It is this Grid's place in the {@link GrameManager}'s list of Grids. */ public final int ID; private ArrayList layers; @@ -36,11 +35,11 @@ public class Base implements Serializable * Constructor. * * @param width - * Width of the Base. + * Width of the Grid. * @param height - * Height of the Base. + * Height of the Grid. */ - public Base(int width, int height) + public Grid(int width, int height) { this(width, height, Color.white, ""); } @@ -49,13 +48,13 @@ public Base(int width, int height) * Constructor. * * @param width - * Width of the Base. + * Width of the Grid. * @param height - * Height of the Base. + * Height of the Grid. * @param title - * Title of the Base. + * Title of the Grid. */ - public Base(int width, int height, String title) + public Grid(int width, int height, String title) { this(width, height, Color.white, title); } @@ -64,13 +63,13 @@ public Base(int width, int height, String title) * Constructor. * * @param width - * Width of the Base. + * Width of the Grid. * @param height - * Height of the Base. + * Height of the Grid. * @param floorColor - * Floor color of the Base. + * Floor color of the Grid. */ - public Base(int width, int height, Color floorColor) + public Grid(int width, int height, Color floorColor) { this(width, height, floorColor, ""); } @@ -79,15 +78,15 @@ public Base(int width, int height, Color floorColor) * Constructor. * * @param width - * Width of the Base. + * Width of the Grid. * @param height - * Height of the Base. + * Height of the Grid. * @param floorColor - * Floor color of the Base. + * Floor color of the Grid. * @param title - * Title of the Base. + * Title of the Grid. */ - public Base(int width, int height, Color floorColor, String title) + public Grid(int width, int height, Color floorColor, String title) { this.layers = new ArrayList(); this.colors = new Color[width * height]; @@ -107,7 +106,7 @@ public Base(int width, int height, Color floorColor, String title) } /** - * Ticks the Base. + * Ticks the Grid. *

* Users will never need to call this method (The {@link GrameManager} takes care of ticking everything). */ @@ -123,7 +122,7 @@ public void tick() } /** - * Calculates the color of a square based on the objects that are occupying it. + * Calculates the color of a square gridd on the objects that are occupying it. * * @param pos * Set of {@link Coordinates} to calculate the color of. @@ -145,7 +144,7 @@ private Color calcColor(Coordinates pos) */ /** - * Gets the number of rows (height) of this Base. + * Gets the number of rows (height) of this Grid. * * @return Row count. */ @@ -155,7 +154,7 @@ public int getRows() } /** - * Gets the number of columns (width) of this Base. + * Gets the number of columns (width) of this Grid. * * @return Column count. */ @@ -165,19 +164,19 @@ public int getColumns() } /** - * Checks whether a set of {@link Coordinates} are in this Base. + * Checks whether a set of {@link Coordinates} are in this Grid. * * @param pos * {@link Coordinates} to check. - * @return True if the {@link Coordinates} are in this Base, else false. + * @return True if the {@link Coordinates} are in this Grid, else false. */ - public boolean isInBase(Coordinates pos) + public boolean isInGrid(Coordinates pos) { return (pos.y >= 0) && (pos.y <= this.height - 1) && (pos.x >= 0) && (pos.x <= this.width - 1); } /** - * Gets the current color of a square in this Base. + * Gets the current color of a square in this Grid. * * @param pos * {@link Coordinates} of square to get color of. @@ -189,12 +188,12 @@ public Color getColor(Coordinates pos) } /** - * Adds a {@link GrameObjectLayer} to this base at a specified layer. + * Adds a {@link GrameObjectLayer} to this grid at a specified layer. * * @param gol * {@link GrameObjectLayer} to add. * @param place - * Place within this Base's list of {@link GrameObjectLayer}s. + * Place within this Grid's list of {@link GrameObjectLayer}s. */ public void addGrameObjectLayer(GrameObjectLayer gol, int place) { @@ -203,7 +202,7 @@ public void addGrameObjectLayer(GrameObjectLayer gol, int place) this.layers.add(place, gol); if (place <= this.goLayer) this.goLayer++; - GrameUtils.print("Added layer " + gol.toString() + " to Base ID:" + ID, MessageLevel.DEBUG); + GrameUtils.print("Added layer " + gol.toString() + " to Grid ID:" + ID, MessageLevel.DEBUG); } else { @@ -213,7 +212,7 @@ public void addGrameObjectLayer(GrameObjectLayer gol, int place) } /** - * Sets the floor color for all the squares in this Base. + * Sets the floor color for all the squares in this Grid. * * @param c * The color to use. @@ -224,7 +223,7 @@ public void setFloorColor(Color c) } /** - * Sets the floor color of a square in this Base. + * Sets the floor color of a square in this Grid. * * @param pos * {@link Coordinates} of square to switch. @@ -237,7 +236,7 @@ public void setFloorColor(Coordinates pos, Color c) } /** - * Gets the floor color of a square in this Base. + * Gets the floor color of a square in this Grid. * * @param pos * {@link Coordinates} of square to get. @@ -249,7 +248,7 @@ public Color getFloorColor(Coordinates pos) } /** - * Adds a {@link GrameObject} to this Base. + * Adds a {@link GrameObject} to this Grid. * * @param go * {@link GrameObject} to add. @@ -257,7 +256,7 @@ public Color getFloorColor(Coordinates pos) * {@link Coordinates} to add the object to. * @param layer * The layer number to add the object to. - * @see Base#addGrameObject(GrameObject, Coordinates) + * @see Grid#addGrameObject(GrameObject, Coordinates) */ public void addGrameObject(GrameObject go, Coordinates pos, int layer) { @@ -276,13 +275,13 @@ public void addGrameObject(GrameObject go, Coordinates pos, int layer) } /** - * Adds a {@link GrameObject} to the default layer of this Base. + * Adds a {@link GrameObject} to the default layer of this Grid. * * @param go * {@link GrameObject} to add. * @param pos * {@link Coordinates} to add the object to. - * @see Base#addGrameObject(GrameObject, Coordinates, int) + * @see Grid#addGrameObject(GrameObject, Coordinates, int) */ public void addGrameObject(GrameObject go, Coordinates pos) { @@ -290,11 +289,11 @@ public void addGrameObject(GrameObject go, Coordinates pos) } /** - * Checks whether this Base contains a certain {@link GrameObject}. + * Checks whether this Grid contains a certain {@link GrameObject}. * * @param goID * ID of {@link GrameObject} to look for. - * @return True if this Base contains the {@link GrameObject}, else false. + * @return True if this Grid contains the {@link GrameObject}, else false. */ public boolean containsGrameObject(int goID) { @@ -319,7 +318,7 @@ public GrameObject getGrameObject(Coordinates pos, int layer) } /** - * Returns the position of a {@link GrameObject} that is in this Base. + * Returns the position of a {@link GrameObject} that is in this Grid. * * @param goID * {@link GrameObject#ID} of the {@link GrameObject}. @@ -334,9 +333,9 @@ public Coordinates getGrameObjectPos(int goID) } /** - * Return a list of the {@link GrameObjectLayer}s of this Base. + * Return a list of the {@link GrameObjectLayer}s of this Grid. * - * @return A list of the {@link GrameObjectLayer}s of this Base. + * @return A list of the {@link GrameObjectLayer}s of this Grid. */ public ArrayList getGrameObjectLayers() { @@ -344,9 +343,9 @@ public ArrayList getGrameObjectLayers() } /** - * Returns the default {@link GrameObjectLayer} of this Base. + * Returns the default {@link GrameObjectLayer} of this Grid. * - * @return The default {@link GrameObjectLayer} of this Base. + * @return The default {@link GrameObjectLayer} of this Grid. */ public GrameObjectLayer getGrameObjectLayer() { @@ -386,7 +385,7 @@ public void moveGrameObject(int goID, Coordinates pos) * @param pos * {@link Coordinates} to check. * @return True if the {@link Coordinates} are occupied on the default layer, else false. - * @see Base#isOccupied(Coordinates, int) + * @see Grid#isOccupied(Coordinates, int) */ public boolean isOccupied(Coordinates pos) { @@ -410,9 +409,9 @@ public boolean isOccupied(Coordinates pos, int layer) } /** - * Sets the "wraparound" aspect of this Base. + * Sets the "wraparound" aspect of this Grid. *

- * "Wraparound" means that if a {@link GrameObject} tries to go off one side of this Base it will be placed on the other side.
+ * "Wraparound" means that if a {@link GrameObject} tries to go off one side of this Grid it will be placed on the other side.
* Think of Snake and Pac-Man. * * @param f @@ -424,12 +423,12 @@ public void setWraparound(boolean f) } /** - * Gets the "wraparound" aspect of this Base. + * Gets the "wraparound" aspect of this Grid. *

- * "Wraparound" means that if a {@link GrameObject} tries to go off one side of this Base it will be placed on the other side.
+ * "Wraparound" means that if a {@link GrameObject} tries to go off one side of this Grid it will be placed on the other side.
* Think of Snake and Pac-Man. * - * @return True if this Base is a wraparound Base, else false. + * @return True if this Grid is a wraparound Grid, else false. */ public boolean getWraparound() { @@ -437,9 +436,9 @@ public boolean getWraparound() } /** - * Returns the length of the diagonal of this Base. + * Returns the length of the diagonal of this Grid. * - * @return The length of the diagonal of this Base. + * @return The length of the diagonal of this Grid. */ public int getDiagonal() { @@ -447,7 +446,7 @@ public int getDiagonal() } /** - * Sets the title of this Base. + * Sets the title of this Grid. * * @param title * The title to use. @@ -458,9 +457,9 @@ public void setTitle(String title) } /** - * Returns the title of this Base. + * Returns the title of this Grid. * - * @return The title of this Base. + * @return The title of this Grid. */ public String getTitle() { @@ -468,9 +467,9 @@ public String getTitle() } /** - * Gets the amount of layers in this Base. + * Gets the amount of layers in this Grid. * - * @return The amount of layers in this Base. + * @return The amount of layers in this Grid. */ public int getLayerCount() { @@ -478,11 +477,11 @@ public int getLayerCount() } /** - * Prints useful information about this Base. + * Prints useful information about this Grid. */ public String toString() { - String st = "Base ID:" + ID + "\n"; + String st = "Grid ID:" + ID + "\n"; st += "Contains: " + this.layers.size() + " Grame Object layers.\n"; st += "Contains "; int count = 0; diff --git a/src/com/moomoohk/Grame/Essentials/InputHandler.java b/src/com/moomoohk/Grame/Core/InputHandler.java similarity index 93% rename from src/com/moomoohk/Grame/Essentials/InputHandler.java rename to src/com/moomoohk/Grame/Core/InputHandler.java index 252e2c8..2247eb2 100644 --- a/src/com/moomoohk/Grame/Essentials/InputHandler.java +++ b/src/com/moomoohk/Grame/Core/InputHandler.java @@ -1,10 +1,10 @@ -package com.moomoohk.Grame.Essentials; +package com.moomoohk.Grame.Core; import java.awt.KeyEventDispatcher; import java.awt.KeyboardFocusManager; import java.awt.event.KeyEvent; -import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; +import com.moomoohk.Grame.Core.GrameUtils.MessageLevel; /** * Handles keyboard input. diff --git a/src/com/moomoohk/Grame/Interfaces/MainGrameClass.java b/src/com/moomoohk/Grame/Core/MainGrameClass.java similarity index 70% rename from src/com/moomoohk/Grame/Interfaces/MainGrameClass.java rename to src/com/moomoohk/Grame/Core/MainGrameClass.java index d9ca2bf..6a05e6c 100644 --- a/src/com/moomoohk/Grame/Interfaces/MainGrameClass.java +++ b/src/com/moomoohk/Grame/Core/MainGrameClass.java @@ -1,4 +1,4 @@ -package com.moomoohk.Grame.Interfaces; +package com.moomoohk.Grame.Core; public interface MainGrameClass { diff --git a/src/com/moomoohk/Grame/Interfaces/Render.java b/src/com/moomoohk/Grame/Core/Render.java similarity index 68% rename from src/com/moomoohk/Grame/Interfaces/Render.java rename to src/com/moomoohk/Grame/Core/Render.java index 0801678..4af8f41 100644 --- a/src/com/moomoohk/Grame/Interfaces/Render.java +++ b/src/com/moomoohk/Grame/Core/Render.java @@ -1,10 +1,9 @@ -package com.moomoohk.Grame.Interfaces; +package com.moomoohk.Grame.Core; -import com.moomoohk.Grame.Essentials.Base; /** - * Objects to render {@link Base}s. + * Objects to render {@link Grid}s. * * @author Meshulam Silk * @version 1.0 @@ -15,12 +14,12 @@ public interface Render /** * Method to calculate the pixels. * @param pixels An int array of pixels. - * @param b The {@link Base} to render. + * @param g The {@link Grid} to render. * @param width The width of the main canvas. * @param height The height of the main canvas. * @return The pixel array, edited with the new render pixels. */ - public int[] getPixels(int[] pixels, Base b, int width, int height); + public int[] getPixels(int[] pixels, Grid g, int width, int height); /** * The name of this render. * @return The name of this render. diff --git a/src/com/moomoohk/Grame/Core/package-info.java b/src/com/moomoohk/Grame/Core/package-info.java new file mode 100644 index 0000000..416702f --- /dev/null +++ b/src/com/moomoohk/Grame/Core/package-info.java @@ -0,0 +1,7 @@ +/** + * Contains the core classes of the engine. + * + * @author Meshulam Silk (moomoohk@ymail.com) + * @since Feb 6, 2014 + */ +package com.moomoohk.Grame.Core; \ No newline at end of file diff --git a/src/com/moomoohk/Grame/Essentials/EngineState.java b/src/com/moomoohk/Grame/Essentials/EngineState.java deleted file mode 100644 index 8b45af5..0000000 --- a/src/com/moomoohk/Grame/Essentials/EngineState.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.moomoohk.Grame.Essentials; - -import java.io.Serializable; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; - -import com.moomoohk.Grame.Interfaces.GrameObject; -import com.moomoohk.Grame.Interfaces.Render; - -public class EngineState implements Serializable -{ - private static final long serialVersionUID = 374960940802675271L; - - private ArrayList bases; - private ArrayList grameObjects; - private Calendar dateCreated; - private Date dateSaved; - private int mainBase; - private Render mainRender; - - public EngineState() - { - this.bases = new ArrayList(); - this.grameObjects = new ArrayList(); - this.dateCreated = new GregorianCalendar(); - this.mainBase = -1; - this.mainRender = null; - } - - public void addGrameObject(GrameObject go) - { - this.grameObjects.add(go); - } - - public void addBase(Base b) - { - this.bases.add(b); - } - - public void setMainBase(int bID) - { - this.mainBase = bID; - } - - public void setMainRender(Render r) - { - this.mainRender = r; - } - - public void setSaved(Date d) - { - this.dateSaved = d; - } - - public ArrayList getBases() - { - return this.bases; - } - - public ArrayList getGrameObjects() - { - return this.grameObjects; - } - - public Calendar getDateCreated() - { - return dateCreated; - } - - public int getMainBase() - { - return this.mainBase; - } - - public Render getMainRender() - { - return this.mainRender; - } - - public Date getSaved() - { - return this.dateSaved; - } - - public String details() - { - return "Bases: " + this.bases.size() + ", GrameObjects: " + this.grameObjects.size() + ", Date Created: " + new SimpleDateFormat("hh:mm:ss dd/MM/yyyy").format(dateCreated.getTime()) + ", Main Base: " + this.mainBase + ", Main Render: " + this.mainRender; - } -} diff --git a/src/com/moomoohk/Grame/Graphics/PlainGridRender.java b/src/com/moomoohk/Grame/Graphics/PlainGridRender.java deleted file mode 100644 index 4144f0a..0000000 --- a/src/com/moomoohk/Grame/Graphics/PlainGridRender.java +++ /dev/null @@ -1,50 +0,0 @@ - -package com.moomoohk.Grame.Graphics; - -import java.io.Serializable; - -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Interfaces.Render; - -/** - * Renders {@link Base}s in a grid without grouting lines. - * - * @author Meshulam Silk - * @version 1.0 - * @since 2013-04-05 - */ -public class PlainGridRender implements Render, Serializable -{ - private static final long serialVersionUID = 1269305794830678142L; - - public int[] getPixels(int[] pixels, Base b, int width, int height) - { - for (int x = 0; x < width; x++) - for (int y = 0; y < height; y++) - { - Coordinates currSquare = new Coordinates((x ) / ((width) /( b.getColumns())), (y ) / (height / b.getRows())); - if(currSquare.getX()>=b.getColumns()) - currSquare.setX(b.getColumns()-1); - if( currSquare.getY()>=b.getRows()) - currSquare.setY(b.getRows()-1); - if (b.isInBase(currSquare)) - try - { - pixels[x + y * width] = b.getColor(currSquare).getRGB(); - } - catch(Exception e) - { - System.out.println(x+" "+width); - } - } - return pixels; - } - - public String getName() - { - return "Plain_grid_render"; - } - -} - diff --git a/src/com/moomoohk/Grame/GrassMuncher/Chaser.java b/src/com/moomoohk/Grame/GrassMuncher/Chaser.java index 0623213..41b022a 100644 --- a/src/com/moomoohk/Grame/GrassMuncher/Chaser.java +++ b/src/com/moomoohk/Grame/GrassMuncher/Chaser.java @@ -1,17 +1,17 @@ - package com.moomoohk.Grame.GrassMuncher; import java.awt.Color; import com.moomoohk.Grame.Basics.Dir; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Interfaces.GrameObject; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.GrameObject; public class Chaser extends GrameObject { private static final long serialVersionUID = -3075457796713552182L; private GrameObject target; + public Chaser() { super("Chaser", 4, Color.red, false); @@ -24,31 +24,32 @@ public boolean isCollidable() } @Override - public void tick(int bID) + public void tick(int gID) { - if(getPos(bID).distance(target.getPos(bID))==1) + if (getPos(gID).distance(target.getPos(gID)) == 1) MainScript.lose(); - GrameManager.findBase(bID).moveGrameObject(ID, getNext(bID)); + GrameManager.findGrid(gID).moveGrameObject(ID, getNext(gID)); } @Override public void consume(GrameObject go) { - } - private Coordinates getNext(int bID) + } + + private Coordinates getNext(int gID) { - Dir d = new Dir(getPos(bID), this.target.getPos(bID)); - if (!GrameManager.findBase(bID).isOccupied(getPos(bID).addDir(d), 1)) - return getPos(bID).addDir(d); - if(!GrameManager.findBase(bID).isOccupied(getPos(bID).addDir(d.split()[0]), 1)) - return getPos(bID).addDir(d.split()[0]); - if(!GrameManager.findBase(bID).isOccupied(getPos(bID).addDir(d.split()[1]), 1)) - return getPos(bID).addDir(d.split()[1]); - return getPos(bID); + Dir d = new Dir(getPos(gID), this.target.getPos(gID)); + if (!GrameManager.findGrid(gID).isOccupied(getPos(gID).addDir(d), 1)) + return getPos(gID).addDir(d); + if (!GrameManager.findGrid(gID).isOccupied(getPos(gID).addDir(d.split()[0]), 1)) + return getPos(gID).addDir(d.split()[0]); + if (!GrameManager.findGrid(gID).isOccupied(getPos(gID).addDir(d.split()[1]), 1)) + return getPos(gID).addDir(d.split()[1]); + return getPos(gID); } + public void setTarget(GrameObject go) { - this.target=go; + this.target = go; } } - diff --git a/src/com/moomoohk/Grame/GrassMuncher/Coin.java b/src/com/moomoohk/Grame/GrassMuncher/Coin.java index 466009a..b6ab44b 100644 --- a/src/com/moomoohk/Grame/GrassMuncher/Coin.java +++ b/src/com/moomoohk/Grame/GrassMuncher/Coin.java @@ -1,23 +1,24 @@ - package com.moomoohk.Grame.GrassMuncher; import java.awt.Color; -import com.moomoohk.Grame.Interfaces.GrameObject; +import com.moomoohk.Grame.Core.GrameObject; public class Coin extends GrameObject { private static final long serialVersionUID = 3955843569288863271L; private int worth; + public Coin() { super("Coin", 0, Color.green, false); - this.worth=1; + this.worth = 1; } + public Coin(int worth) { super("Coin", 0, Color.green, false); - this.worth=worth; + this.worth = worth; } @Override @@ -27,17 +28,18 @@ public boolean isCollidable() } @Override - public void tick(int bID) + public void tick(int gID) { - + } + public int getWorth() { return this.worth; } + @Override public void consume(GrameObject go) { } } - diff --git a/src/com/moomoohk/Grame/GrassMuncher/MainScript.java b/src/com/moomoohk/Grame/GrassMuncher/MainScript.java index 4cec59b..8e9a704 100644 --- a/src/com/moomoohk/Grame/GrassMuncher/MainScript.java +++ b/src/com/moomoohk/Grame/GrassMuncher/MainScript.java @@ -7,18 +7,18 @@ import javax.swing.SwingUtilities; import com.moomoohk.Grame.Basics.Wall; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Essentials.GrameObjectLayer; -import com.moomoohk.Grame.Essentials.GrameUtils; -import com.moomoohk.Grame.Graphics.RenderManager; -import com.moomoohk.Grame.Interfaces.MainGrameClass; +import com.moomoohk.Grame.Core.Grid; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.GrameObjectLayer; +import com.moomoohk.Grame.Core.GrameUtils; +import com.moomoohk.Grame.Core.MainGrameClass; +import com.moomoohk.Grame.Core.Graphics.RenderManager; import com.moomoohk.Grame.test.SpriteRender; public class MainScript implements MainGrameClass { - public static Base b; + public static Grid g; public static Player p; public static Chaser c; public static int maxCoins = 0; @@ -57,36 +57,36 @@ public void run() @Override public void newGame() { - b = new Base(20, 20); + g = new Grid(20, 20); p = new Player(); c = new Chaser(); GrameManager.pauseAllGrameObjects(true); c.setTarget(p); c.setSpeed(20); p.setSpeed(5); - b.addGrameObjectLayer(new GrameObjectLayer(b.getColumns(), b.getRows()), 1); - b.addGrameObject(p, new Coordinates(0, 0), 0); - b.addGrameObject(c, new Coordinates(b.getColumns() - 1, b.getRows() - 1), 1); - b.setFloorColor(new Color(139, 69, 19)); + g.addGrameObjectLayer(new GrameObjectLayer(g.getColumns(), g.getRows()), 1); + g.addGrameObject(p, new Coordinates(0, 0), 0); + g.addGrameObject(c, new Coordinates(g.getColumns() - 1, g.getRows() - 1), 1); + g.setFloorColor(new Color(139, 69, 19)); for (int i = 1; i <= 339; i++) { - Coordinates temp = GrameUtils.randomCoordinates(b); - while (b.isOccupied(temp) || temp.equals(new Coordinates(0, 0)) || temp.equals(new Coordinates(b.getColumns() - 1, b.getRows() - 1))) - temp = GrameUtils.randomCoordinates(b); - b.addGrameObject(new Coin(), temp, 0); + Coordinates temp = GrameUtils.randomCoordinates(g); + while (g.isOccupied(temp) || temp.equals(new Coordinates(0, 0)) || temp.equals(new Coordinates(g.getColumns() - 1, g.getRows() - 1))) + temp = GrameUtils.randomCoordinates(g); + g.addGrameObject(new Coin(), temp, 0); maxCoins++; } for (int i = 1; i <= 60; i++) { - Coordinates temp = GrameUtils.randomCoordinates(b); - while (b.isOccupied(temp)) - temp = GrameUtils.randomCoordinates(b); - b.addGrameObject(new Wall(), temp, 0); - b.addGrameObject(new Wall(), temp, 1); + Coordinates temp = GrameUtils.randomCoordinates(g); + while (g.isOccupied(temp)) + temp = GrameUtils.randomCoordinates(g); + g.addGrameObject(new Wall(), temp, 0); + g.addGrameObject(new Wall(), temp, 1); } SpriteRender.objects.put(p.ID, "player"); SpriteRender.objects.put(c.ID, "monster"); - RenderManager.render(b.ID, new SpriteRender()); + RenderManager.render(g.ID, new SpriteRender()); RenderManager.setVisible(true); JOptionPane.showMessageDialog(new JFrame(), "Ready to begin?", "Grass Muncher!", JOptionPane.PLAIN_MESSAGE); GrameManager.pauseAllGrameObjects(false); diff --git a/src/com/moomoohk/Grame/GrassMuncher/Player.java b/src/com/moomoohk/Grame/GrassMuncher/Player.java index c75851f..bf03f2d 100644 --- a/src/com/moomoohk/Grame/GrassMuncher/Player.java +++ b/src/com/moomoohk/Grame/GrassMuncher/Player.java @@ -1,22 +1,22 @@ - package com.moomoohk.Grame.GrassMuncher; import java.awt.Color; import com.moomoohk.Grame.Basics.Dir; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Interfaces.GrameObject; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.GrameObject; +import com.moomoohk.Grame.Core.Grid; public class Player extends GrameObject { private static final long serialVersionUID = 1615372944054959042L; private int points; + public Player() { super("Player", 2, Color.DARK_GRAY, false); - this.points=-1; + this.points = -1; } @Override @@ -26,45 +26,44 @@ public boolean isCollidable() } @Override - public void tick(int bID) + public void tick(int gID) { - setPos(bID, getNext(bID)); - if(this.points+1==MainScript.maxCoins) + setPos(gID, getNext(gID)); + if (this.points + 1 == MainScript.maxCoins) MainScript.win(); - if(getPos(bID).distance(MainScript.c.getPos(bID))==1) + if (getPos(gID).distance(MainScript.c.getPos(gID)) == 1) MainScript.lose(); } @Override public void consume(GrameObject go) { - if(!(go instanceof Coin)) + if (!(go instanceof Coin)) return; - Coin coin=(Coin)go; - points+=coin.getWorth(); + Coin coin = (Coin) go; + points += coin.getWorth(); } - private Coordinates getNext(int bID) + private Coordinates getNext(int gID) { - Dir d=GrameManager.dir1; + Dir d = GrameManager.dir1; if (d == null) - return getPos(bID); - Base b=GrameManager.findBase(bID); - if(!b.isInBase(getPos(bID).addDir(d))) - return getPos(bID); - if(b.isOccupied(getPos(bID).addDir(d))) + return getPos(gID); + Grid b = GrameManager.findGrid(gID); + if (!b.isInGrid(getPos(gID).addDir(d))) + return getPos(gID); + if (b.isOccupied(getPos(gID).addDir(d))) { - if(!b.isOccupied(getPos(bID).addDir(d.split()[0]))) - return getPos(bID).addDir(d.split()[0]); - if(!b.isOccupied(getPos(bID).addDir(d.split()[1]))) - return getPos(bID).addDir(d.split()[1]); + if (!b.isOccupied(getPos(gID).addDir(d.split()[0]))) + return getPos(gID).addDir(d.split()[0]); + if (!b.isOccupied(getPos(gID).addDir(d.split()[1]))) + return getPos(gID).addDir(d.split()[1]); } - return getPos(bID).addDir(d); + return getPos(gID).addDir(d); } public int getPoints() { - return this.points+1; + return this.points + 1; } } - diff --git a/src/com/moomoohk/Grame/GrassMuncher/package-info.java b/src/com/moomoohk/Grame/GrassMuncher/package-info.java new file mode 100644 index 0000000..9eb3b7f --- /dev/null +++ b/src/com/moomoohk/Grame/GrassMuncher/package-info.java @@ -0,0 +1,7 @@ +/** + * A demo game I made with Grame. + * + * @author Meshulam Silk (moomoohk@ymail.com) + * @since Feb 6, 2014 + */ +package com.moomoohk.Grame.GrassMuncher; \ No newline at end of file diff --git a/src/com/moomoohk/Grame/test/AISystemTest.java b/src/com/moomoohk/Grame/test/AISystemTest.java index 4a6a4d3..9dc140b 100644 --- a/src/com/moomoohk/Grame/test/AISystemTest.java +++ b/src/com/moomoohk/Grame/test/AISystemTest.java @@ -2,17 +2,17 @@ import java.awt.Color; -import com.moomoohk.Grame.AI.PlayerSimAI; -import com.moomoohk.Grame.AI.SimpleChaseAI; -import com.moomoohk.Grame.AI.SimpleStrollAI; import com.moomoohk.Grame.Basics.Entity; import com.moomoohk.Grame.Basics.Wall; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Essentials.GrameUtils; -import com.moomoohk.Grame.Graphics.RenderManager; -import com.moomoohk.Grame.Interfaces.MainGrameClass; +import com.moomoohk.Grame.Basics.AI.PlayerSimAI; +import com.moomoohk.Grame.Basics.AI.SimpleChaseAI; +import com.moomoohk.Grame.Basics.AI.SimpleStrollAI; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.GrameUtils; +import com.moomoohk.Grame.Core.Grid; +import com.moomoohk.Grame.Core.MainGrameClass; +import com.moomoohk.Grame.Core.Graphics.RenderManager; public class AISystemTest implements MainGrameClass { @@ -21,39 +21,39 @@ public static void main(String[] args) GrameManager.initialize(new AISystemTest()); } - public static void generateStrollers(int amount, Base b) + public static void generateStrollers(int amount, Grid g) { for (int i = 0; i < amount; i++) { Entity ent = new Entity(); - ent.addAI(new SimpleStrollAI(), b.ID); + ent.addAI(new SimpleStrollAI(), g.ID); ent.setSpeed(5); ent.setColor(Color.blue); - Coordinates temp = GrameUtils.randomCoordinates(b); - while (b.isOccupied(temp)) - temp = GrameUtils.randomCoordinates(b); - b.addGrameObject(ent, temp); + Coordinates temp = GrameUtils.randomCoordinates(g); + while (g.isOccupied(temp)) + temp = GrameUtils.randomCoordinates(g); + g.addGrameObject(ent, temp); } } - public static void generateChasers(Base b, int amount, Entity target) + public static void generateChasers(Grid g, int amount, Entity target) { for (int i = 1; i <= amount; i++) { Entity ent = new Entity(Color.red); - ent.addAI(new SimpleChaseAI(), b.ID); - ent.setRange(b.getDiagonal()); + ent.addAI(new SimpleChaseAI(), g.ID); + ent.setRange(g.getDiagonal()); ent.setTarget(target.ID); ent.setColor(Color.red); ent.setSpeed(2); - Coordinates temp = GrameUtils.randomCoordinates(b); - while (b.isOccupied(temp)) - temp = GrameUtils.randomCoordinates(b); - b.addGrameObject(ent, temp); + Coordinates temp = GrameUtils.randomCoordinates(g); + while (g.isOccupied(temp)) + temp = GrameUtils.randomCoordinates(g); + g.addGrameObject(ent, temp); } } - public static void generatePlayers(int number, int amount, Base b) + public static void generatePlayers(int number, int amount, Grid b) { for (int i = 1; i <= amount; i++) { @@ -68,29 +68,29 @@ public static void generatePlayers(int number, int amount, Base b) } } - public static void generatePlayerSims(int amount, Base b) + public static void generatePlayerSims(int amount, Grid g) { for (int i = 1; i <= amount; i++) { Entity ent = new Entity(); ent.setColor(Color.yellow); - ent.setOverrideAI(new PlayerSimAI(), b.ID); + ent.setOverrideAI(new PlayerSimAI(), g.ID); ent.setSpeed(1); - Coordinates temp = GrameUtils.randomCoordinates(b); - while (b.isOccupied(temp)) - temp = GrameUtils.randomCoordinates(b); - b.addGrameObject(ent, temp); + Coordinates temp = GrameUtils.randomCoordinates(g); + while (g.isOccupied(temp)) + temp = GrameUtils.randomCoordinates(g); + g.addGrameObject(ent, temp); } } - public static void generateWalls(int amount, Base b) + public static void generateWalls(int amount, Grid g) { for (int i = 1; i <= amount; i++) { - Coordinates temp = GrameUtils.randomCoordinates(b); - while (b.isOccupied(temp)) - temp = GrameUtils.randomCoordinates(b); - b.addGrameObject(new Wall(), temp); + Coordinates temp = GrameUtils.randomCoordinates(g); + while (g.isOccupied(temp)) + temp = GrameUtils.randomCoordinates(g); + g.addGrameObject(new Wall(), temp); } } @@ -99,18 +99,18 @@ public void newGame() { GrameManager.setDebug(true); GrameManager.setSpam(false); - Base b = new Base(20, 20); - b.setWraparound(true); - generatePlayers(1, 1, b); - generatePlayerSims(1, b); - generateStrollers(5, b); - generateChasers(b, 3, (Entity) GrameManager.findGrameObject(1)); - generateChasers(b, 3, (Entity) GrameManager.findGrameObject(0)); - RenderManager.render(b.ID); + Grid g = new Grid(20, 20); + g.setWraparound(true); + generatePlayers(1, 1, g); + generatePlayerSims(1, g); + generateStrollers(5, g); + generateChasers(g, 3, (Entity) GrameManager.findGrameObject(1)); + generateChasers(g, 3, (Entity) GrameManager.findGrameObject(0)); + RenderManager.render(g.ID); RenderManager.setVisible(true); - RenderManager.setText(b.ID, new Coordinates(6, 6), "test", Color.red); - RenderManager.setText(b.ID, new Coordinates(19, 19), "penis", Color.yellow); - RenderManager.setText(b.ID, new Coordinates(5, 5), "hohohohoh", Color.green); + RenderManager.setText(g.ID, new Coordinates(6, 6), "test", Color.red); + RenderManager.setText(g.ID, new Coordinates(19, 19), "phallus", Color.yellow); + RenderManager.setText(g.ID, new Coordinates(5, 5), "hohohohoh", Color.green); } @Override diff --git a/src/com/moomoohk/Grame/test/ConsumeTest.java b/src/com/moomoohk/Grame/test/ConsumeTest.java index 16efb97..ca128e0 100644 --- a/src/com/moomoohk/Grame/test/ConsumeTest.java +++ b/src/com/moomoohk/Grame/test/ConsumeTest.java @@ -1,13 +1,13 @@ package com.moomoohk.Grame.test; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Graphics.RenderManager; +import com.moomoohk.Grame.Core.Grid; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.GrameObject; +import com.moomoohk.Grame.Core.MainGrameClass; +import com.moomoohk.Grame.Core.Graphics.RenderManager; import com.moomoohk.Grame.GrassMuncher.Coin; -import com.moomoohk.Grame.Interfaces.GrameObject; -import com.moomoohk.Grame.Interfaces.MainGrameClass; public class ConsumeTest implements MainGrameClass { @@ -29,15 +29,15 @@ public static void main(String[] args) @Override public void newGame() { - Base b = new Base(20, 20); + Grid g = new Grid(20, 20); Player p = new Player(); - b.addGrameObject(p, new Coordinates(0, 0)); - for (int i = 0; i < b.getRows(); i++) - for (int j = 0; j < b.getColumns(); j++) - if (!b.isOccupied(new Coordinates(i, j))) - b.addGrameObject(new Coin(), new Coordinates(i, j)); - p.makePlayer(1, true, b.ID); - RenderManager.render(b.ID); + g.addGrameObject(p, new Coordinates(0, 0)); + for (int i = 0; i < g.getRows(); i++) + for (int j = 0; j < g.getColumns(); j++) + if (!g.isOccupied(new Coordinates(i, j))) + g.addGrameObject(new Coin(), new Coordinates(i, j)); + p.makePlayer(1, true, g.ID); + RenderManager.render(g.ID); RenderManager.setVisible(true); } diff --git a/src/com/moomoohk/Grame/test/Dialog.java b/src/com/moomoohk/Grame/test/Dialog.java index 4ef6173..21b4314 100644 --- a/src/com/moomoohk/Grame/test/Dialog.java +++ b/src/com/moomoohk/Grame/test/Dialog.java @@ -3,11 +3,11 @@ import java.awt.Color; import java.util.ArrayList; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Graphics.RenderManager; -import com.moomoohk.Grame.Graphics.PostProcessing.Label; -import com.moomoohk.Grame.Interfaces.GrameObject; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.GrameObject; +import com.moomoohk.Grame.Core.Graphics.RenderManager; +import com.moomoohk.Grame.Core.Graphics.PostProcessing.Label; public class Dialog implements Runnable { @@ -37,10 +37,10 @@ public void start() public void run() { GrameManager.pauseAllGrameObjects(true); - int squareWidth = RenderManager.getMainCanvas().getWidth() / GrameManager.findBase(RenderManager.getMainBase()).getColumns(), squareHeight = RenderManager.getMainCanvas().getHeight() / GrameManager.findBase(RenderManager.getMainBase()).getRows(); - Coordinates goPos = this.go.getPos(RenderManager.getMainBase()); - this.label.setCenterX(Math.max(50, goPos.getX() * squareWidth + squareWidth / 2)); - this.label.setCenterY(Math.max(50, goPos.getY() * squareHeight)); + int squareWidth = RenderManager.getMainCanvas().getWidth() / GrameManager.findGrid(RenderManager.getMainGrid()).getColumns(), squareHeight = RenderManager.getMainCanvas().getHeight() / GrameManager.findGrid(RenderManager.getMainGrid()).getRows(); + Coordinates goPos = this.go.getPos(RenderManager.getMainGrid()); + this.label.setCenterX(goPos.getX() * squareWidth + squareWidth / 2); + this.label.setCenterY(goPos.getY() * squareHeight); for (String line : this.lines) { for (int i = 0; i <= line.length(); i++) diff --git a/src/com/moomoohk/Grame/test/GrameLogo.java b/src/com/moomoohk/Grame/test/GrameLogo.java index 4e61d2f..ffed9e9 100644 --- a/src/com/moomoohk/Grame/test/GrameLogo.java +++ b/src/com/moomoohk/Grame/test/GrameLogo.java @@ -1,36 +1,34 @@ - package com.moomoohk.Grame.test; import java.awt.Color; import com.moomoohk.Grame.Basics.Wall; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Graphics.PlainGridRender; -import com.moomoohk.Grame.Graphics.RenderManager; +import com.moomoohk.Grame.Core.Grid; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.Graphics.CleanGridRender; +import com.moomoohk.Grame.Core.Graphics.RenderManager; public class GrameLogo { public static void main(String[] args) { - Base b=new Base(6, 6); - TestGrameObject player=new TestGrameObject("player", 1, Color.gray, false); - TestGrameObject monster=new TestGrameObject("monster", 1, Color.red, false); - b.addGrameObject(player, new Coordinates(0, 0)); - b.addGrameObject(new Wall(), new Coordinates(1, 1)); - b.addGrameObject(new Wall(), new Coordinates(1, 2)); - b.addGrameObject(new Wall(), new Coordinates(1, 3)); - b.addGrameObject(new Wall(), new Coordinates(1, 4)); - b.addGrameObject(new Wall(), new Coordinates(2, 1)); - b.addGrameObject(new Wall(), new Coordinates(3, 1)); - b.addGrameObject(new Wall(), new Coordinates(4, 1)); - b.addGrameObject(new Wall(), new Coordinates(2, 4)); - b.addGrameObject(new Wall(), new Coordinates(3, 4)); - b.addGrameObject(new Wall(), new Coordinates(4, 4)); - b.addGrameObject(new Wall(), new Coordinates(4, 3)); - b.addGrameObject(monster, new Coordinates(5, 5)); - RenderManager.render(b.ID, new PlainGridRender()); + Grid g = new Grid(6, 6); + TestGrameObject player = new TestGrameObject("player", 1, Color.gray, false); + TestGrameObject monster = new TestGrameObject("monster", 1, Color.red, false); + g.addGrameObject(player, new Coordinates(0, 0)); + g.addGrameObject(new Wall(), new Coordinates(1, 1)); + g.addGrameObject(new Wall(), new Coordinates(1, 2)); + g.addGrameObject(new Wall(), new Coordinates(1, 3)); + g.addGrameObject(new Wall(), new Coordinates(1, 4)); + g.addGrameObject(new Wall(), new Coordinates(2, 1)); + g.addGrameObject(new Wall(), new Coordinates(3, 1)); + g.addGrameObject(new Wall(), new Coordinates(4, 1)); + g.addGrameObject(new Wall(), new Coordinates(2, 4)); + g.addGrameObject(new Wall(), new Coordinates(3, 4)); + g.addGrameObject(new Wall(), new Coordinates(4, 4)); + g.addGrameObject(new Wall(), new Coordinates(4, 3)); + g.addGrameObject(monster, new Coordinates(5, 5)); + RenderManager.render(g.ID, new CleanGridRender()); RenderManager.setVisible(true); } } - diff --git a/src/com/moomoohk/Grame/test/GrameObjectsTest.java b/src/com/moomoohk/Grame/test/GrameObjectsTest.java index 53cdcdf..d6f1724 100644 --- a/src/com/moomoohk/Grame/test/GrameObjectsTest.java +++ b/src/com/moomoohk/Grame/test/GrameObjectsTest.java @@ -3,12 +3,12 @@ import java.awt.Color; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Graphics.PlainGridRender; -import com.moomoohk.Grame.Graphics.RenderManager; -import com.moomoohk.Grame.Interfaces.MainGrameClass; +import com.moomoohk.Grame.Core.Grid; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.MainGrameClass; +import com.moomoohk.Grame.Core.Graphics.CleanGridRender; +import com.moomoohk.Grame.Core.Graphics.RenderManager; public class GrameObjectsTest implements MainGrameClass { @@ -24,13 +24,13 @@ public static void main(String[] args) @Override public void newGame() { - Base b = new Base(20, 20); + Grid g = new Grid(20, 20); Entity ent = new Entity(); - b.addGrameObject(ent, new Coordinates(10, 10)); - b.setWraparound(true); - ent.makePlayer(1, true, b.ID); + g.addGrameObject(ent, new Coordinates(10, 10)); + g.setWraparound(true); + ent.makePlayer(1, true, g.ID); ent.setSpeed(1); - RenderManager.render(b.ID, new PlainGridRender()); + RenderManager.render(g.ID, new CleanGridRender()); RenderManager.setVisible(true); } diff --git a/src/com/moomoohk/Grame/test/NewSpriteRender.java b/src/com/moomoohk/Grame/test/NewSpriteRender.java index b29f74e..87a66f1 100644 --- a/src/com/moomoohk/Grame/test/NewSpriteRender.java +++ b/src/com/moomoohk/Grame/test/NewSpriteRender.java @@ -3,29 +3,29 @@ import java.awt.Color; import java.awt.image.BufferedImage; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Interfaces.Render; +import com.moomoohk.Grame.Core.Grid; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.Render; public class NewSpriteRender implements Render { public static String floorPath; @Override - public int[] getPixels(int[] pixels, Base b, int width, int height) + public int[] getPixels(int[] pixels, Grid g, int width, int height) { - for (int xSquare = 0; xSquare < b.getColumns(); xSquare++) - for (int ySquare = 0; ySquare < b.getRows(); ySquare++) + for (int xSquare = 0; xSquare < g.getColumns(); xSquare++) + for (int ySquare = 0; ySquare < g.getRows(); ySquare++) { try { - drawSprite(xSquare, ySquare, width, height, pixels, b, sprites.get("grass")); - for (int layer = 0; layer < b.getLayerCount(); layer++) - if (b.getGrameObject(new Coordinates(xSquare, ySquare), layer) != null && objects.containsKey(b.getGrameObject(new Coordinates(xSquare, ySquare), layer).ID)) - drawSprite(xSquare, ySquare, width, height, pixels, b, sprites.get(objects.get(b.getGrameObject(new Coordinates(xSquare, ySquare), layer).ID))); + drawSprite(xSquare, ySquare, width, height, pixels, g, sprites.get("grass")); + for (int layer = 0; layer < g.getLayerCount(); layer++) + if (g.getGrameObject(new Coordinates(xSquare, ySquare), layer) != null && objects.containsKey(g.getGrameObject(new Coordinates(xSquare, ySquare), layer).ID)) + drawSprite(xSquare, ySquare, width, height, pixels, g, sprites.get(objects.get(g.getGrameObject(new Coordinates(xSquare, ySquare), layer).ID))); else - if (b.getGrameObject(new Coordinates(xSquare, ySquare), layer) != null) - drawSquare(xSquare, ySquare, width, height, pixels, b, b.getGrameObject(new Coordinates(xSquare, ySquare), layer).getColor()); + if (g.getGrameObject(new Coordinates(xSquare, ySquare), layer) != null) + drawSquare(xSquare, ySquare, width, height, pixels, g, g.getGrameObject(new Coordinates(xSquare, ySquare), layer).getColor()); } catch (Exception e) { @@ -35,7 +35,7 @@ public int[] getPixels(int[] pixels, Base b, int width, int height) return pixels; } - private void drawSprite(int xSquare, int ySquare, int width, int height, int[] pixels, Base b, BufferedImage sprite) + private void drawSprite(int xSquare, int ySquare, int width, int height, int[] pixels, Grid g, BufferedImage sprite) { for (int y = 0; y < sprite.getHeight(); y++) { @@ -54,7 +54,7 @@ private void drawSprite(int xSquare, int ySquare, int width, int height, int[] p } } - private void drawSquare(int xSquare, int ySquare, int width, int height, int[] pixels, Base b, Color c) + private void drawSquare(int xSquare, int ySquare, int width, int height, int[] pixels, Grid g, Color c) { for (int y = 0; y < 30; y++) { diff --git a/src/com/moomoohk/Grame/test/SaveTest.java b/src/com/moomoohk/Grame/test/SaveTest.java index e8209ef..eeebe93 100644 --- a/src/com/moomoohk/Grame/test/SaveTest.java +++ b/src/com/moomoohk/Grame/test/SaveTest.java @@ -1,32 +1,29 @@ package com.moomoohk.Grame.test; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Essentials.GrameUtils; -import com.moomoohk.Grame.Graphics.RenderManager; -import com.moomoohk.Grame.Interfaces.MainGrameClass; +import com.moomoohk.Grame.Core.Grid; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.GrameUtils; +import com.moomoohk.Grame.Core.MainGrameClass; +import com.moomoohk.Grame.Core.Graphics.RenderManager; public class SaveTest implements MainGrameClass { public static void main(String[] args) { - MenuConfiguration menuConfig = new MenuConfiguration(); - GrameManager.initialize(new SaveTest(), menuConfig); + GrameManager.initialize(new SaveTest()); } - @Override public void newGame() { - Base b = new Base(20, 20); + Grid g = new Grid(20, 20); Entity e = new Entity(); - e.makePlayer(1, true, b.ID); - b.addGrameObject(e, GrameUtils.randomCoordinates(b)); - RenderManager.render(b.ID); + e.makePlayer(1, true, g.ID); + g.addGrameObject(e, GrameUtils.randomCoordinates(g)); + RenderManager.render(g.ID); RenderManager.setVisible(true); } - @Override public String getGameName() { return "Save Test"; diff --git a/src/com/moomoohk/Grame/test/SpriteRender.java b/src/com/moomoohk/Grame/test/SpriteRender.java index c03e6dd..2babf2b 100644 --- a/src/com/moomoohk/Grame/test/SpriteRender.java +++ b/src/com/moomoohk/Grame/test/SpriteRender.java @@ -8,11 +8,11 @@ import javax.imageio.ImageIO; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameUtils; -import com.moomoohk.Grame.Essentials.GrameUtils.MessageLevel; -import com.moomoohk.Grame.Interfaces.Render; +import com.moomoohk.Grame.Core.Grid; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameUtils; +import com.moomoohk.Grame.Core.Render; +import com.moomoohk.Grame.Core.GrameUtils.MessageLevel; public class SpriteRender implements Render { @@ -28,20 +28,20 @@ public class SpriteRender implements Render } @Override - public int[] getPixels(int[] pixels, Base b, int width, int height) + public int[] getPixels(int[] pixels, Grid g, int width, int height) { - for (int xSquare = 0; xSquare < b.getColumns(); xSquare++) - for (int ySquare = 0; ySquare < b.getRows(); ySquare++) + for (int xSquare = 0; xSquare < g.getColumns(); xSquare++) + for (int ySquare = 0; ySquare < g.getRows(); ySquare++) { try { - drawSprite(xSquare, ySquare, width, height, pixels, b, sprites.get("grass")); - for (int layer = 0; layer < b.getLayerCount(); layer++) - if (b.getGrameObject(new Coordinates(xSquare, ySquare), layer) != null && objects.containsKey(b.getGrameObject(new Coordinates(xSquare, ySquare), layer).ID)) - drawSprite(xSquare, ySquare, width, height, pixels, b, sprites.get(objects.get(b.getGrameObject(new Coordinates(xSquare, ySquare), layer).ID))); + drawSprite(xSquare, ySquare, width, height, pixels, g, sprites.get("grass")); + for (int layer = 0; layer < g.getLayerCount(); layer++) + if (g.getGrameObject(new Coordinates(xSquare, ySquare), layer) != null && objects.containsKey(g.getGrameObject(new Coordinates(xSquare, ySquare), layer).ID)) + drawSprite(xSquare, ySquare, width, height, pixels, g, sprites.get(objects.get(g.getGrameObject(new Coordinates(xSquare, ySquare), layer).ID))); else - if (b.getGrameObject(new Coordinates(xSquare, ySquare), layer) != null) - drawSquare(xSquare, ySquare, width, height, pixels, b, b.getGrameObject(new Coordinates(xSquare, ySquare), layer).getColor()); + if (g.getGrameObject(new Coordinates(xSquare, ySquare), layer) != null) + drawSquare(xSquare, ySquare, width, height, pixels, g, g.getGrameObject(new Coordinates(xSquare, ySquare), layer).getColor()); } catch (Exception e) { @@ -51,7 +51,7 @@ public int[] getPixels(int[] pixels, Base b, int width, int height) return pixels; } - private void drawSprite(int xSquare, int ySquare, int width, int height, int[] pixels, Base b, BufferedImage sprite) + private void drawSprite(int xSquare, int ySquare, int width, int height, int[] pixels, Grid g, BufferedImage sprite) { for (int y = 0; y < sprite.getHeight(); y++) { @@ -70,7 +70,7 @@ private void drawSprite(int xSquare, int ySquare, int width, int height, int[] p } } - private void drawSquare(int xSquare, int ySquare, int width, int height, int[] pixels, Base b, Color c) + private void drawSquare(int xSquare, int ySquare, int width, int height, int[] pixels, Grid g, Color c) { for (int y = 0; y < 30; y++) { diff --git a/src/com/moomoohk/Grame/test/TestGrameObject.java b/src/com/moomoohk/Grame/test/TestGrameObject.java index ecc9c11..12e3967 100644 --- a/src/com/moomoohk/Grame/test/TestGrameObject.java +++ b/src/com/moomoohk/Grame/test/TestGrameObject.java @@ -1,14 +1,14 @@ - package com.moomoohk.Grame.test; import java.awt.Color; -import com.moomoohk.Grame.Interfaces.GrameObject; +import com.moomoohk.Grame.Core.GrameObject; public class TestGrameObject extends GrameObject { private static final long serialVersionUID = -480851231518169067L; - private int time=0; + private int time = 0; + public TestGrameObject(String name, int speed, Color color, boolean paused) { super(name, speed, color, paused); @@ -21,7 +21,7 @@ public boolean isCollidable() } @Override - public void tick(int bID) + public void tick(int gID) { //this.color=GrameUtils.randomColor(); time++; @@ -33,4 +33,3 @@ public void consume(GrameObject go) { } } - diff --git a/src/com/moomoohk/Grame/test/TestScript.java b/src/com/moomoohk/Grame/test/TestScript.java index 9f9b8b2..2a96d78 100644 --- a/src/com/moomoohk/Grame/test/TestScript.java +++ b/src/com/moomoohk/Grame/test/TestScript.java @@ -2,16 +2,16 @@ import java.awt.Color; -import com.moomoohk.Grame.AI.SimpleChaseAI; -import com.moomoohk.Grame.AI.SimpleStrollAI; import com.moomoohk.Grame.Basics.Entity; -import com.moomoohk.Grame.Essentials.Base; -import com.moomoohk.Grame.Essentials.Coordinates; -import com.moomoohk.Grame.Essentials.GrameManager; -import com.moomoohk.Grame.Essentials.GrameUtils; -import com.moomoohk.Grame.Graphics.RenderManager; -import com.moomoohk.Grame.Interfaces.GrameObject; -import com.moomoohk.Grame.Interfaces.MainGrameClass; +import com.moomoohk.Grame.Basics.AI.SimpleChaseAI; +import com.moomoohk.Grame.Basics.AI.SimpleStrollAI; +import com.moomoohk.Grame.Core.Grid; +import com.moomoohk.Grame.Core.Coordinates; +import com.moomoohk.Grame.Core.GrameManager; +import com.moomoohk.Grame.Core.GrameObject; +import com.moomoohk.Grame.Core.GrameUtils; +import com.moomoohk.Grame.Core.MainGrameClass; +import com.moomoohk.Grame.Core.Graphics.RenderManager; public class TestScript implements MainGrameClass { @@ -23,23 +23,23 @@ public static void main(String[] args) @Override public void newGame() { - Base b = new Base(20, 20); - b.setWraparound(true); + Grid g = new Grid(20, 20); + g.setWraparound(true); Entity ent = new Entity(Color.blue); ent.setSpeed(1); Entity ent2 = new Entity(); ent2.setTarget(ent.ID); ent2.setSpeed(7); - ent2.setRange(b.getDiagonal()); - ent2.addAI(new SimpleChaseAI(), b.ID); - ent2.addAI(new SimpleStrollAI(), b.ID); - ent.makePlayer(1, true, b.ID); + ent2.setRange(g.getDiagonal()); + ent2.addAI(new SimpleChaseAI(), g.ID); + ent2.addAI(new SimpleStrollAI(), g.ID); + ent.makePlayer(1, true, g.ID); GrameObject go = new GrameObject("test", 1, Color.black, false) { private static final long serialVersionUID = -7904811686747660223L; @Override - public void tick(int bID) + public void tick(int gID) { this.color = GrameUtils.randomColor(); } @@ -57,10 +57,10 @@ public void consume(GrameObject go) }; SpriteRender.objects.put(ent.ID, "player"); SpriteRender.objects.put(ent2.ID, "monster"); - b.addGrameObject(ent2, GrameUtils.randomCoordinates(b)); - b.addGrameObject(ent, new Coordinates(10, 10)); - b.addGrameObject(go, GrameUtils.randomCoordinates(b)); - RenderManager.render(b.ID, new SpriteRender()); + g.addGrameObject(ent2, GrameUtils.randomCoordinates(g)); + g.addGrameObject(ent, new Coordinates(10, 10)); + g.addGrameObject(go, GrameUtils.randomCoordinates(g)); + RenderManager.render(g.ID, new SpriteRender()); RenderManager.setVisible(true); } diff --git a/src/com/moomoohk/Grame/test/package-info.java b/src/com/moomoohk/Grame/test/package-info.java new file mode 100644 index 0000000..1d9605a --- /dev/null +++ b/src/com/moomoohk/Grame/test/package-info.java @@ -0,0 +1,7 @@ +/** + * Contains some test classes which shouldn't be touched or interacted with. + * + * @author Meshulam Silk (moomoohk@ymail.com) + * @since Feb 6, 2014 + */ +package com.moomoohk.Grame.test; \ No newline at end of file