Marios kicking each-other and code organization

This commit is contained in:
Kleme
2017-09-14 13:36:42 +02:00
parent c584472bb7
commit 4ee557a0b8
4 changed files with 170 additions and 72 deletions
+25 -29
View File
@@ -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;
@@ -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<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);
}
+96 -40
View File
@@ -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;
}
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;
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.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<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;
}
}
+16 -3
View File
@@ -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;
}
}
+33
View File
@@ -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);
}
}