Marios kicking each-other and code organization
This commit is contained in:
@@ -17,10 +17,9 @@ import javax.swing.SwingUtilities;
|
||||
|
||||
public abstract class Launch {
|
||||
|
||||
private static final String VERSION = "1.7.1";
|
||||
|
||||
private static List<MarioWindow> 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;
|
||||
@@ -29,14 +28,12 @@ public abstract class Launch {
|
||||
|
||||
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<MarioWindow> 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);
|
||||
}
|
||||
|
||||
@@ -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.time2<this.time){
|
||||
if(this.wait){
|
||||
this.wait = false;
|
||||
int randi = rand.nextInt(100);
|
||||
int randi = Utils.nextInt(100);
|
||||
if(randi<70){ //0-69 - 70%
|
||||
this.state = State.WALKING;
|
||||
}else if(randi<90){ //70-89 - 20%
|
||||
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;
|
||||
}else{ //90-99 - 10%
|
||||
boolean nextSide = rand.nextBoolean();
|
||||
boolean nextSide = Utils.nextBoolean();
|
||||
this.turn = this.left != nextSide;
|
||||
this.left = nextSide;
|
||||
this.state = State.RUNNING;
|
||||
}
|
||||
}else{
|
||||
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;
|
||||
int randi = rand.nextInt(100);
|
||||
int randi = Utils.nextInt(100);
|
||||
if(randi<75){ //0-74 - 75%
|
||||
this.state = State.STILL;
|
||||
}else if(randi<85){ //75-84 - 10 %
|
||||
@@ -140,23 +143,23 @@ public class MarioAI {
|
||||
if(this.time2<this.time){
|
||||
if(this.wait){
|
||||
this.wait = false;
|
||||
int randi = rand.nextInt(100);
|
||||
int randi = Utils.nextInt(100);
|
||||
if(randi<60){ //0-59 - 60%
|
||||
boolean nextSide = rand.nextBoolean();
|
||||
boolean nextSide = Utils.nextBoolean();
|
||||
this.left = nextSide;
|
||||
this.state = State.STILL;
|
||||
}else if(randi<90){ //60-89 - 30%
|
||||
boolean nextSide = rand.nextBoolean();
|
||||
boolean nextSide = Utils.nextBoolean();
|
||||
this.turn = this.left != nextSide;
|
||||
this.left = nextSide;
|
||||
this.state = State.RUNNING;
|
||||
}else{ //90-99 - 10%
|
||||
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;
|
||||
}
|
||||
}else{
|
||||
this.time2 = this.time+rand.nextInt(MAX_WALKING_TIME)+MIN_STATE_TIME;
|
||||
this.time2 = this.time+Utils.nextInt(MAX_WALKING_TIME)+MIN_STATE_TIME;
|
||||
this.wait = true;
|
||||
}
|
||||
}
|
||||
@@ -166,30 +169,30 @@ public class MarioAI {
|
||||
if(this.time2<this.time){
|
||||
if(this.wait){
|
||||
this.wait = false;
|
||||
int randi = rand.nextInt(100);
|
||||
int randi = Utils.nextInt(100);
|
||||
if(randi<50){ //0-49 - 50%
|
||||
boolean nextSide = rand.nextBoolean();
|
||||
boolean nextSide = Utils.nextBoolean();
|
||||
this.turn = this.left != nextSide;
|
||||
this.left = nextSide;
|
||||
this.state = State.WALKING;
|
||||
}else if(randi<90){ //50-89 - 40%
|
||||
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;
|
||||
}else{ //90-99 - 10%
|
||||
this.state = State.STILL;
|
||||
}
|
||||
}else{
|
||||
this.time2 = this.time+rand.nextInt(MAX_RUNNING_TIME)+MIN_STATE_TIME;
|
||||
this.time2 = this.time+Utils.nextInt(MAX_RUNNING_TIME)+MIN_STATE_TIME;
|
||||
this.wait = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LOOSING:
|
||||
if(this.time-this.time2>100){
|
||||
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;
|
||||
}
|
||||
|
||||
if(this.state != State.JUMPING){
|
||||
int[] ybounds = Utils.getYBounds((int) pos.x);
|
||||
|
||||
if(pos.y<ybounds[0]){
|
||||
this.spdy = Math.abs(this.spdy);
|
||||
this.maxspdy = rand.nextFloat()*speedf*MAX_JUMP_SPEED_Y+speedf*MIN_JUMP_SPEED_Y;
|
||||
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 = -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 = -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<ybounds[1]){
|
||||
this.turn = false;
|
||||
this.wait = false;
|
||||
this.maxspdy = Utils.nextFloat()*speedf*MAX_JUMP_SPEED_Y+speedf*MIN_JUMP_SPEED_Y;
|
||||
this.spdy = 0;
|
||||
this.state = State.JUMPING;
|
||||
}
|
||||
}
|
||||
|
||||
//getter/setter
|
||||
|
||||
public void setSize(int sizex, int sizey, int speedf){
|
||||
@@ -261,7 +287,7 @@ public class MarioAI {
|
||||
case RUNNING:
|
||||
return this.time%150<75?MARIO_RUNNING_1:MARIO_RUNNING_2;
|
||||
case JUMPING:
|
||||
return this.spdy<=MAX_JUMP_SPEED_Y/10f?MARIO_JUMPING:MARIO_FALLING;
|
||||
return this.spdy<=MAX_JUMP_SPEED_Y/10f?MARIO_JUMPING:this.kicked?MARIO_LOOSING:MARIO_FALLING;
|
||||
case STILL_LOOK_UP:
|
||||
return MARIO_LOOK_UP;
|
||||
case STILL_WIN:
|
||||
@@ -289,4 +315,34 @@ public class MarioAI {
|
||||
return id;
|
||||
}
|
||||
|
||||
public float getSpdy() {
|
||||
return spdy;
|
||||
}
|
||||
|
||||
public boolean isInvicible() {
|
||||
return invicible;
|
||||
}
|
||||
|
||||
public void setInvicible(boolean invicible) {
|
||||
this.invicible = invicible;
|
||||
}
|
||||
|
||||
public boolean isKicked() {
|
||||
return kicked;
|
||||
}
|
||||
|
||||
public void setKicked(boolean kicked) {
|
||||
this.kicked = kicked;
|
||||
}
|
||||
|
||||
//static functions
|
||||
|
||||
public static List<MarioAI> getOthers(int id){
|
||||
List<MarioAI> list = new ArrayList<MarioAI>();
|
||||
for(MarioWindow mw:MarioWindow.getAll())
|
||||
if(mw.getAi().getId() != id)
|
||||
list.add(mw.getAi());
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<MarioWindow> 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<MarioWindow> getAll(){
|
||||
return windows;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user