diff --git a/src/fr/klemek/minimario/Launch.java b/src/fr/klemek/minimario/Launch.java index 36a8bbf..eb5a4bc 100644 --- a/src/fr/klemek/minimario/Launch.java +++ b/src/fr/klemek/minimario/Launch.java @@ -17,10 +17,9 @@ import javax.swing.SwingUtilities; public abstract class Launch { - private static final String VERSION = "1.7.1"; - - private static List windows; + private static final String VERSION = "1.7.2"; + private static TrayIcon trayIcon; private static PopupMenu popup; private static Menu sizeMenu; private static MenuItem add, split, kill, exit; @@ -28,15 +27,13 @@ public abstract class Launch { private static int currentFactor = 2; public static void main(String[] args) { - - windows = new ArrayList<>(); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { - windows.add(new MarioWindow(null, currentFactor, null)); - addTrayIcon(windows.get(0)); + new MarioWindow(null, currentFactor, null); + addTrayIcon(MarioWindow.getAll().get(0)); } catch (IOException e) { e.printStackTrace(); } @@ -50,7 +47,7 @@ public abstract class Launch { System.exit(0); } - TrayIcon trayIcon = new TrayIcon(Utils.createImage("/icon_"+mwRef.getTilesetName()+".png", "icon")); + trayIcon = new TrayIcon(Utils.createImage("/icon_"+mwRef.getTilesetName()+".png", "icon")); trayIcon.setImageAutoSize(true); popup = new PopupMenu(); @@ -63,10 +60,10 @@ public abstract class Launch { size.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { - for(MarioWindow mw:windows) + for(MarioWindow mw:MarioWindow.getAll()) mw.setFactor(f); currentFactor = f; - refreshPopupMenu(); + refreshTray(); } }); sizeMenu.add(size); @@ -77,8 +74,8 @@ public abstract class Launch { @Override public void actionPerformed(ActionEvent e) { try { - windows.add(new MarioWindow(null, currentFactor, null)); - refreshPopupMenu(); + new MarioWindow(null, currentFactor, null); + refreshTray(); } catch (IOException e1) { e1.printStackTrace(); } @@ -90,17 +87,17 @@ public abstract class Launch { @Override public void actionPerformed(ActionEvent e) { List save = new ArrayList<>(); - save.addAll(windows); - windows.clear(); + save.addAll(MarioWindow.getAll()); + MarioWindow.getAll().clear(); currentFactor /= 2; for(MarioWindow mw:save){ try { MarioWindow child1 = new MarioWindow(mw.getCenter(), currentFactor, mw.getTilesetName()); MarioWindow child2 = new MarioWindow(mw.getCenter(), currentFactor, mw.getTilesetName()); - child1.getAi().run(false); - child2.getAi().run(true); - windows.add(child1); - windows.add(child2); + child1.getAi().setInvicible(true); + child2.getAi().setInvicible(true); + child1.getAi().jump(false); + child2.getAi().jump(true); } catch (IOException e1) { e1.printStackTrace(); } @@ -108,7 +105,7 @@ public abstract class Launch { } save = null; System.gc(); - refreshPopupMenu(); + refreshTray(); } }); @@ -117,11 +114,11 @@ public abstract class Launch { @Override public void actionPerformed(ActionEvent e) { Random r = new Random(); - int index = r.nextInt(windows.size()); - windows.get(index).kill(); - windows.remove(index); + int index = r.nextInt(MarioWindow.getAll().size()); + MarioWindow.getAll().get(index).kill(); + MarioWindow.getAll().remove(index); System.gc(); - refreshPopupMenu(); + refreshTray(); } }); @@ -133,11 +130,8 @@ public abstract class Launch { } }); - - - refreshPopupMenu(); + refreshTray(); trayIcon.setPopupMenu(popup); - trayIcon.setToolTip("MiniMario ! (version "+VERSION+")\nBy Klemek"); final SystemTray tray = SystemTray.getSystemTray(); try { @@ -148,18 +142,20 @@ public abstract class Launch { } } - private static void refreshPopupMenu(){ + private static void refreshTray(){ popup.removeAll(); popup.add(sizeMenu); popup.add(add); if(currentFactor > 1){ popup.add(split); } - if(windows.size()>1){ + if(MarioWindow.getAll().size()>1){ exit.setLabel("Kill them all !"); popup.add(kill); + trayIcon.setToolTip(MarioWindow.getAll().size()+" MiniMarios ! (version "+VERSION+")\nBy Klemek"); }else{ exit.setLabel("Kill it !"); + trayIcon.setToolTip("MiniMario ! (version "+VERSION+")\nBy Klemek"); } popup.add(exit); } diff --git a/src/fr/klemek/minimario/MarioAI.java b/src/fr/klemek/minimario/MarioAI.java index 64e3f18..fcc657d 100644 --- a/src/fr/klemek/minimario/MarioAI.java +++ b/src/fr/klemek/minimario/MarioAI.java @@ -3,7 +3,8 @@ package fr.klemek.minimario; import java.awt.Point; import java.awt.Rectangle; import java.awt.geom.Point2D; -import java.util.Random; +import java.util.ArrayList; +import java.util.List; public class MarioAI { @@ -47,8 +48,7 @@ public class MarioAI { private Point2D.Float pos; - private boolean left, wait, turn; - private static Random rand = new Random(); + private boolean left, wait, turn, kicked, invicible; private final int minx,maxx; private int sizex, sizey, speedf; @@ -56,7 +56,7 @@ public class MarioAI { //constructor public MarioAI(int sizex, int sizey, int speedf){ - this.id = rand.nextInt(); + this.id = Utils.nextInt(); this.minx = Utils.getMinX(); this.maxx = Utils.getMaxX(); this.sizex = sizex; @@ -86,7 +86,10 @@ public class MarioAI { this.spdy += GRAVITY*speedf; speed.y = spdy; if(this.spdy>=this.maxspdy){ - int randi = rand.nextInt(100); + this.kicked = false; + this.invicible = false; + this.spdy = 0; + int randi = Utils.nextInt(100); if(randi<40){ //0-39 - 40% this.state = State.STILL; }else if(randi<70){ //40-69 - 30% @@ -104,23 +107,23 @@ public class MarioAI { if(this.time2100){ - int randi = rand.nextInt(100); + int randi = Utils.nextInt(100); if(randi<80){ //0-79 - 80% - this.time2 = this.time+rand.nextInt(MAX_STILL_TIME)+MIN_STATE_TIME; + this.time2 = this.time+Utils.nextInt(MAX_STILL_TIME)+MIN_STATE_TIME; this.wait = true; this.state = State.STILL_DUCK; }else{ //80-99 - 20% @@ -208,32 +211,55 @@ public class MarioAI { this.left = !this.left; } - int[] ybounds = Utils.getYBounds((int) pos.x); - - if(pos.yybounds[1]){ - this.spdy = -rand.nextFloat()*speedf*MAX_JUMP_SPEED_Y-speedf*MIN_JUMP_SPEED_Y; - this.maxspdy = -Math.abs(this.spdy); - this.state = State.JUMPING; + if(this.state != State.JUMPING){ + int[] ybounds = Utils.getYBounds((int) pos.x); + if(pos.y<=ybounds[0]){ + this.spdy = 0; + this.maxspdy = Utils.nextFloat()*speedf*MAX_JUMP_SPEED_Y+speedf*MIN_JUMP_SPEED_Y; + this.state = State.JUMPING; + }else if(pos.y+sizey>ybounds[1]){ + this.spdy = -Utils.nextFloat()*speedf*MAX_JUMP_SPEED_Y-speedf*MIN_JUMP_SPEED_Y; + this.maxspdy = -Math.abs(this.spdy); + this.state = State.JUMPING; + } } + + if(this.spdy<=0){ + Rectangle bounds = this.getBounds(); + for(MarioAI ma:getOthers(this.id)){ + if(ma.spdy<=0 && !ma.isInvicible() && bounds.intersects(ma.getBounds())){ + ma.fall(); + ma.setKicked(true); + } + } + } + } - + return new Point((int)this.pos.x, (int)this.pos.y); } - public void run(boolean left){ + public void jump(boolean left){ this.turn = false; this.left = left; - this.time2 = this.time+rand.nextInt(MAX_WALKING_TIME); + this.time2 = this.time+Utils.nextInt(MAX_WALKING_TIME); this.wait = false; - this.spdy = -rand.nextFloat()*speedf*MAX_JUMP_SPEED_Y-speedf*MIN_JUMP_SPEED_Y; - this.maxspdy = rand.nextFloat()*speedf*MAX_JUMP_SPEED_Y+speedf*MIN_JUMP_SPEED_Y; + this.spdy = -Utils.nextFloat()*speedf*MAX_JUMP_SPEED_Y-speedf*MIN_JUMP_SPEED_Y; + this.maxspdy = Utils.nextFloat()*speedf*MAX_JUMP_SPEED_Y+speedf*MIN_JUMP_SPEED_Y; this.state = State.JUMPING; } + public void fall(){ + int[] ybounds = Utils.getYBounds((int)this.pos.x); + if(this.pos.y-this.sizey getOthers(int id){ + List list = new ArrayList(); + for(MarioWindow mw:MarioWindow.getAll()) + if(mw.getAi().getId() != id) + list.add(mw.getAi()); + return list; + } + } diff --git a/src/fr/klemek/minimario/MarioWindow.java b/src/fr/klemek/minimario/MarioWindow.java index 924389a..7a4e4d5 100644 --- a/src/fr/klemek/minimario/MarioWindow.java +++ b/src/fr/klemek/minimario/MarioWindow.java @@ -9,6 +9,8 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.image.BufferedImage; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.Random; import javax.imageio.ImageIO; @@ -17,7 +19,9 @@ import javax.swing.Timer; public class MarioWindow extends JWindow implements ActionListener { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 797825180779341089L; + + private static List windows = new ArrayList<>(); private static final int REFRESH_MS = 20; private static final int TILE_W = 20; @@ -38,10 +42,13 @@ public class MarioWindow extends JWindow implements ActionListener { public MarioWindow(Point start, int factor, String tilesetName) throws IOException { + windows.add(this); + this.setBackground(new Color(0, 0, 0, 0)); + //this.setLocationRelativeTo(null); if(start == null) - this.setLocationRelativeTo(null); + this.setLocation(Utils.randomScreenLocation(TILE_W*factor, TILE_H*factor)); else this.setLocation((int)(start.x + TILE_W*factor/2f), (int)( start.y + TILE_H*factor/2f)); @@ -63,7 +70,6 @@ public class MarioWindow extends JWindow implements ActionListener { this.tilesetName = tilesetName; - BufferedImage tileset = ImageIO.read(this.getClass().getResource("/"+tilesetName+".png")); this.p = new TilePanel(this, tileset, TILE_W, TILE_H, factor); @@ -114,6 +120,7 @@ public class MarioWindow extends JWindow implements ActionListener { this.setVisible(false); } + //events @Override @@ -162,4 +169,10 @@ public class MarioWindow extends JWindow implements ActionListener { this.setVisible(true); } + + //static functions + + public static List getAll(){ + return windows; + } } diff --git a/src/fr/klemek/minimario/Utils.java b/src/fr/klemek/minimario/Utils.java index 189b7c1..e1b9aae 100644 --- a/src/fr/klemek/minimario/Utils.java +++ b/src/fr/klemek/minimario/Utils.java @@ -3,9 +3,11 @@ package fr.klemek.minimario; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Image; +import java.awt.Point; import java.awt.Rectangle; import java.awt.geom.Point2D; import java.net.URL; +import java.util.Random; import javax.swing.ImageIcon; @@ -13,6 +15,8 @@ public abstract class Utils { private static Rectangle[] bounds = new Rectangle[0]; + protected static Random rand = new Random(); + public static Point2D.Float add(Point2D.Float p1, Point2D.Float p2) { return new Point2D.Float(p1.x + p2.x, p1.y + p2.y); } @@ -90,4 +94,33 @@ public abstract class Utils { return (new ImageIcon(imageURL, description)).getImage(); } } + + + //random + public static int nextInt(int min, int max){ + return rand.nextInt(max-min)+min; + } + + public static int nextInt(int max){ + return rand.nextInt(max); + } + + public static int nextInt(){ + return rand.nextInt(); + } + + public static boolean nextBoolean(){ + return rand.nextBoolean(); + } + + public static float nextFloat(){ + return rand.nextFloat(); + } + + public static Point randomScreenLocation(int sizex, int sizey){ + int x = nextInt(getMinX(),getMaxX()-sizex); + int[] yb = getYBounds(x); + int y = nextInt(yb[0],yb[1]-sizey); + return new Point(x,y); + } } \ No newline at end of file