Initial commit
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="src" path="res"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||||
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
</classpath>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
/bin/
|
||||||
|
/resources/*
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>MiniMario</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.8
|
||||||
|
After Width: | Height: | Size: 315 B |
|
After Width: | Height: | Size: 309 B |
|
After Width: | Height: | Size: 300 B |
|
After Width: | Height: | Size: 307 B |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,23 @@
|
|||||||
|
package fr.klemek.minimario;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
|
public class Launch {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
new MarioWindow();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,258 @@
|
|||||||
|
package fr.klemek.minimario;
|
||||||
|
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.geom.Point2D;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class MarioAI {
|
||||||
|
|
||||||
|
//times
|
||||||
|
private static final int MIN_STATE_TIME = 500;
|
||||||
|
private static final int MAX_STILL_TIME = 10000-MIN_STATE_TIME;
|
||||||
|
private static final int MAX_WALKING_TIME = 5000-MIN_STATE_TIME;
|
||||||
|
private static final int MAX_RUNNING_TIME = 3000-MIN_STATE_TIME;
|
||||||
|
|
||||||
|
//speeds
|
||||||
|
private static final float WALK_SPEED = 0.5f;
|
||||||
|
private static final float RUN_SPEED = 1.5f;
|
||||||
|
private static final float JUMP_SPEED_X = 0.25f;
|
||||||
|
private static final float GRAVITY = 0.25f;
|
||||||
|
private static final float MAX_JUMP_SPEED_Y = 5f;
|
||||||
|
|
||||||
|
//tiles
|
||||||
|
private static final int MARIO_STILL = 0;
|
||||||
|
private static final int MARIO_WALKING_2 = 1;
|
||||||
|
private static final int MARIO_JUMPING = 2;
|
||||||
|
private static final int MARIO_FALLING = 3;
|
||||||
|
private static final int MARIO_TURNING = 4;
|
||||||
|
private static final int MARIO_BACK = 5;
|
||||||
|
private static final int MARIO_DUCK = 6;
|
||||||
|
private static final int MARIO_WIN = 7;
|
||||||
|
private static final int MARIO_RUNNING_1 = 8;
|
||||||
|
private static final int MARIO_RUNNING_2 = 9;
|
||||||
|
private static final int MARIO_LOOK_UP = 10;
|
||||||
|
private static final int MARIO_LOOSING = 11;
|
||||||
|
|
||||||
|
private enum State{
|
||||||
|
STILL, STILL_BACK, STILL_WIN, STILL_DUCK, STILL_LOOK_UP, WALKING, RUNNING, JUMPING, LOOSING
|
||||||
|
}
|
||||||
|
|
||||||
|
private State state;
|
||||||
|
private int time, time2;
|
||||||
|
private float spdy, maxspdy;
|
||||||
|
|
||||||
|
private Point2D.Float pos;
|
||||||
|
|
||||||
|
private boolean left, wait, turn;
|
||||||
|
private Random rand;
|
||||||
|
|
||||||
|
private final int minx,maxx;
|
||||||
|
private int sizex, sizey, speedf;
|
||||||
|
|
||||||
|
public MarioAI(int sizex, int sizey, int speedf){
|
||||||
|
this.minx = Utils.getMinX();
|
||||||
|
this.maxx = Utils.getMaxX();
|
||||||
|
this.sizex = sizex;
|
||||||
|
this.sizey = sizey;
|
||||||
|
this.speedf = speedf;
|
||||||
|
this.state = State.STILL;
|
||||||
|
this.time = 0;
|
||||||
|
this.pos = new Point2D.Float();
|
||||||
|
this.rand = new Random();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize(int sizex, int sizey, int speedf){
|
||||||
|
this.sizex = sizex;
|
||||||
|
this.sizey = sizey;
|
||||||
|
this.speedf = speedf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPos(Point newpos){
|
||||||
|
this.pos = new Point2D.Float(newpos.x, newpos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void moved(Point newpos){
|
||||||
|
this.pos = new Point2D.Float(newpos.x, newpos.y);
|
||||||
|
this.state = State.LOOSING;
|
||||||
|
this.time2 = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point refresh(int refresh){
|
||||||
|
time += refresh;
|
||||||
|
|
||||||
|
Point2D.Float speed = new Point2D.Float();
|
||||||
|
|
||||||
|
switch(this.state){
|
||||||
|
case JUMPING:
|
||||||
|
speed.x = (this.left?-1f:1f)*speedf*JUMP_SPEED_X;;
|
||||||
|
this.spdy += GRAVITY*speedf;
|
||||||
|
speed.y = spdy;
|
||||||
|
if(this.spdy>=this.maxspdy){
|
||||||
|
int randi = rand.nextInt(100);
|
||||||
|
if(randi<40){ //0-39 - 40%
|
||||||
|
this.state = State.STILL;
|
||||||
|
}else if(randi<70){ //40-69 - 30%
|
||||||
|
this.state = State.WALKING;
|
||||||
|
}else{ //70-99 - 30%
|
||||||
|
this.state = State.RUNNING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STILL_BACK:
|
||||||
|
case STILL_LOOK_UP:
|
||||||
|
case STILL_WIN:
|
||||||
|
case STILL_DUCK:
|
||||||
|
case STILL:
|
||||||
|
if(this.time2<this.time){
|
||||||
|
if(this.wait){
|
||||||
|
this.wait = false;
|
||||||
|
int randi = rand.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;
|
||||||
|
this.maxspdy = rand.nextFloat()*speedf*MAX_JUMP_SPEED_Y;
|
||||||
|
this.state = State.JUMPING;
|
||||||
|
}else{ //90-99 - 10%
|
||||||
|
boolean nextSide = rand.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.wait = true;
|
||||||
|
int randi = rand.nextInt(100);
|
||||||
|
if(randi<75){ //0-74 - 75%
|
||||||
|
this.state = State.STILL;
|
||||||
|
}else if(randi<85){ //75-84 - 10 %
|
||||||
|
this.state = State.STILL_LOOK_UP;
|
||||||
|
}else if(randi<95){ //85-94 - 10%
|
||||||
|
this.state = State.STILL_DUCK;
|
||||||
|
}else if(randi<99){ //95-99 - 4%
|
||||||
|
this.state = State.STILL_BACK;
|
||||||
|
}else{ //99 - 1%
|
||||||
|
this.state = State.STILL_WIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WALKING:
|
||||||
|
speed.x = (this.left?-1f:1f)*speedf*WALK_SPEED;
|
||||||
|
if(this.time2<this.time){
|
||||||
|
if(this.wait){
|
||||||
|
this.wait = false;
|
||||||
|
int randi = rand.nextInt(100);
|
||||||
|
if(randi<60){ //0-59 - 60%
|
||||||
|
boolean nextSide = rand.nextBoolean();
|
||||||
|
this.left = nextSide;
|
||||||
|
this.state = State.STILL;
|
||||||
|
}else if(randi<90){ //60-89 - 30%
|
||||||
|
boolean nextSide = rand.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;
|
||||||
|
this.maxspdy = rand.nextFloat()*speedf*MAX_JUMP_SPEED_Y;
|
||||||
|
this.state = State.JUMPING;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
this.time2 = this.time+rand.nextInt(MAX_WALKING_TIME)+MIN_STATE_TIME;
|
||||||
|
this.wait = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RUNNING:
|
||||||
|
speed.x = (this.left?-1f:1f)*speedf*RUN_SPEED;;
|
||||||
|
if(this.time2<this.time){
|
||||||
|
if(this.wait){
|
||||||
|
this.wait = false;
|
||||||
|
int randi = rand.nextInt(100);
|
||||||
|
if(randi<50){ //0-49 - 50%
|
||||||
|
boolean nextSide = rand.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;
|
||||||
|
this.maxspdy = rand.nextFloat()*speedf*MAX_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.wait = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LOOSING:
|
||||||
|
if(this.time-this.time2>100){
|
||||||
|
this.time2 = this.time+rand.nextInt(MAX_STILL_TIME)+MIN_STATE_TIME;
|
||||||
|
this.wait = true;
|
||||||
|
this.state = State.STILL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pos = Utils.add(this.pos, speed);
|
||||||
|
|
||||||
|
if(pos.x<=minx && this.left || pos.x+sizex>=maxx && !this.left){
|
||||||
|
this.turn = true;
|
||||||
|
this.left = !this.left;
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] ybounds = Utils.getYBounds((int) pos.x);
|
||||||
|
|
||||||
|
if(this.state != State.JUMPING){
|
||||||
|
if(pos.y<ybounds[0]){
|
||||||
|
this.spdy = 0f;
|
||||||
|
this.maxspdy = rand.nextFloat()*speedf*MAX_JUMP_SPEED_Y;
|
||||||
|
this.state = State.JUMPING;
|
||||||
|
}else if(pos.y+sizey>ybounds[1]){
|
||||||
|
this.spdy = -rand.nextFloat()*speedf*MAX_JUMP_SPEED_Y;
|
||||||
|
this.maxspdy = 0f;
|
||||||
|
this.state = State.JUMPING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Point((int)this.pos.x, (int)this.pos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTile(){
|
||||||
|
if(this.turn){
|
||||||
|
if(this.time%200>=100){
|
||||||
|
this.turn = false;
|
||||||
|
}
|
||||||
|
return MARIO_TURNING;
|
||||||
|
}else{
|
||||||
|
switch(this.state){
|
||||||
|
case LOOSING:
|
||||||
|
return MARIO_LOOSING;
|
||||||
|
case WALKING:
|
||||||
|
return this.time%400<200?MARIO_STILL:MARIO_WALKING_2;
|
||||||
|
case RUNNING:
|
||||||
|
return this.time%150<75?MARIO_RUNNING_1:MARIO_RUNNING_2;
|
||||||
|
case JUMPING:
|
||||||
|
return this.spdy<=1f?MARIO_JUMPING:MARIO_FALLING;
|
||||||
|
case STILL_LOOK_UP:
|
||||||
|
return MARIO_LOOK_UP;
|
||||||
|
case STILL_WIN:
|
||||||
|
return MARIO_WIN;
|
||||||
|
case STILL_BACK:
|
||||||
|
return MARIO_BACK;
|
||||||
|
case STILL_DUCK:
|
||||||
|
return MARIO_DUCK;
|
||||||
|
case STILL:
|
||||||
|
default:
|
||||||
|
return MARIO_STILL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReversed(){
|
||||||
|
return this.left;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
package fr.klemek.minimario;
|
||||||
|
|
||||||
|
import java.awt.AWTException;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Menu;
|
||||||
|
import java.awt.MenuItem;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.PopupMenu;
|
||||||
|
import java.awt.SystemTray;
|
||||||
|
import java.awt.TrayIcon;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseMotionAdapter;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.JWindow;
|
||||||
|
import javax.swing.Timer;
|
||||||
|
|
||||||
|
public class MarioWindow extends JWindow implements ActionListener {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static final String VERSION = "1.5";
|
||||||
|
|
||||||
|
private static final int REFRESH_MS = 20;
|
||||||
|
private static final int TILE_W = 20;
|
||||||
|
private static final int TILE_H = 24;
|
||||||
|
|
||||||
|
private TilePanel p;
|
||||||
|
private final Timer refresh;
|
||||||
|
|
||||||
|
private int factor = 2;
|
||||||
|
|
||||||
|
private MarioAI ai;
|
||||||
|
|
||||||
|
private Point initialClick;
|
||||||
|
|
||||||
|
public MarioWindow() throws IOException {
|
||||||
|
|
||||||
|
this.setBackground(new Color(0, 0, 0, 0));
|
||||||
|
this.setLocationRelativeTo(null);
|
||||||
|
|
||||||
|
this.ai = new MarioAI(TILE_W*factor,TILE_H*factor, factor);
|
||||||
|
|
||||||
|
Random r = new Random();
|
||||||
|
String tileset_name = "mario";
|
||||||
|
if(r.nextInt(100)>=90){ //90-99 - 10%
|
||||||
|
tileset_name = "luigi";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(r.nextInt(100)>=99){ //99 - 1%
|
||||||
|
tileset_name += "_fire";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BufferedImage tileset = ImageIO.read(this.getClass().getResource("/"+tileset_name+".png"));
|
||||||
|
this.p = new TilePanel(this, tileset, TILE_W, TILE_H, factor);
|
||||||
|
|
||||||
|
this.p.addMouseListener(new MouseAdapter() {
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
initialClick = e.getPoint();
|
||||||
|
getComponentAt(initialClick);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.p.addMouseMotionListener(new MouseMotionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
|
||||||
|
// get location of Window
|
||||||
|
int thisX = getLocation().x;
|
||||||
|
int thisY = getLocation().y;
|
||||||
|
|
||||||
|
// Determine how much the mouse moved since the initial click
|
||||||
|
int xMoved = (thisX + e.getX()) - (thisX + initialClick.x);
|
||||||
|
int yMoved = (thisY + e.getY()) - (thisY + initialClick.y);
|
||||||
|
|
||||||
|
// Move window to this position
|
||||||
|
int X = thisX + xMoved;
|
||||||
|
int Y = thisY + yMoved;
|
||||||
|
setLocation(X, Y);
|
||||||
|
ai.moved(getLocation());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.add(this.p);
|
||||||
|
|
||||||
|
this.refresh = new Timer(REFRESH_MS, this);
|
||||||
|
|
||||||
|
this.pack();
|
||||||
|
this.setAlwaysOnTop(true);
|
||||||
|
|
||||||
|
if (!SystemTray.isSupported()) {
|
||||||
|
System.out.println("SystemTray is not supported");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrayIcon trayIcon = new TrayIcon(Utils.createImage("/icon_"+tileset_name+".png", "icon"));
|
||||||
|
trayIcon.setImageAutoSize(true);
|
||||||
|
|
||||||
|
final PopupMenu popup = new PopupMenu();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Menu sizeMenu = new Menu("Change size");
|
||||||
|
popup.add(sizeMenu);
|
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++){
|
||||||
|
final int f = (int)Math.pow(2, i);
|
||||||
|
MenuItem size = new MenuItem(f+"x");
|
||||||
|
size.addActionListener(new ActionListener(){
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
setFactor(f);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sizeMenu.add(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem exit = new MenuItem("Kill it !");
|
||||||
|
exit.addActionListener(new ActionListener(){
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
popup.add(exit);
|
||||||
|
|
||||||
|
trayIcon.setPopupMenu(popup);
|
||||||
|
trayIcon.setToolTip("MiniMario ! (version "+VERSION+")\nBy Klemek");
|
||||||
|
|
||||||
|
final SystemTray tray = SystemTray.getSystemTray();
|
||||||
|
try {
|
||||||
|
tray.add(trayIcon);
|
||||||
|
} catch (AWTException e) {
|
||||||
|
System.out.println("TrayIcon could not be added.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.setVisible(true);
|
||||||
|
|
||||||
|
this.ai.setPos(this.getLocation());
|
||||||
|
|
||||||
|
this.refresh.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFactor(int factor){
|
||||||
|
this.setVisible(false);
|
||||||
|
this.factor = factor;
|
||||||
|
this.ai.setSize(TILE_W*factor,TILE_H*factor, factor);
|
||||||
|
this.p.setFactor(factor);
|
||||||
|
this.pack();
|
||||||
|
this.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if (e.getSource().equals(this.refresh)) {
|
||||||
|
this.setLocation(this.ai.refresh(REFRESH_MS));
|
||||||
|
this.p.setTile(this.ai.getTile(), this.ai.isReversed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package fr.klemek.minimario;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JWindow;
|
||||||
|
|
||||||
|
public class TilePanel extends JPanel {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final int tileWidth, tileHeight, imageWidth, imageHeight, columns, rows;
|
||||||
|
private int id, factor;
|
||||||
|
private BufferedImage image;
|
||||||
|
private boolean reversed = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public TilePanel(JWindow parent, BufferedImage image, int tileWidth, int tileHeight, int factor) {
|
||||||
|
super();
|
||||||
|
this.tileWidth = tileWidth;
|
||||||
|
this.tileHeight = tileHeight;
|
||||||
|
this.image = image;
|
||||||
|
this.imageWidth = image.getWidth();
|
||||||
|
this.imageHeight = image.getHeight();
|
||||||
|
this.columns = this.imageWidth / this.tileWidth;
|
||||||
|
this.rows = this.imageHeight / this.tileHeight;
|
||||||
|
System.out.println("Tileset : "+this.columns+"x"+this.rows);
|
||||||
|
this.setFactor(factor);
|
||||||
|
this.setBackground(new Color(0, 0, 0, 0));
|
||||||
|
this.setOpaque(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFactor(int factor){
|
||||||
|
this.factor = factor;
|
||||||
|
Dimension size = new Dimension(tileWidth * factor, tileHeight * factor);
|
||||||
|
this.setPreferredSize(size);
|
||||||
|
this.setMinimumSize(size);
|
||||||
|
this.setMaximumSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
g.clearRect(0, 0, tileWidth * factor, tileHeight * factor);
|
||||||
|
if (id >= 0 && id < rows * columns) {
|
||||||
|
if (reversed) {
|
||||||
|
g.drawImage(image, 0, 0, tileWidth * factor, tileHeight * factor, (1 + id % columns) * tileWidth,
|
||||||
|
(id / columns) * tileHeight, (id % columns) * tileWidth, (1 + id / columns) * tileHeight, this);
|
||||||
|
} else {
|
||||||
|
g.drawImage(image, 0, 0, tileWidth * factor, tileHeight * factor, (id % columns) * tileWidth,
|
||||||
|
(id / columns) * tileHeight, (1 + id % columns) * tileWidth, (1 + id / columns) * tileHeight, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTile(int id, boolean reversed) {
|
||||||
|
this.id = id;
|
||||||
|
this.reversed = reversed;
|
||||||
|
this.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package fr.klemek.minimario;
|
||||||
|
|
||||||
|
import java.awt.GraphicsDevice;
|
||||||
|
import java.awt.GraphicsEnvironment;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.geom.Point2D;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
|
||||||
|
public abstract class Utils {
|
||||||
|
|
||||||
|
private static Rectangle[] bounds = new Rectangle[0];
|
||||||
|
|
||||||
|
public static Point2D.Float add(Point2D.Float p1, Point2D.Float p2) {
|
||||||
|
return new Point2D.Float(p1.x + p2.x, p1.y + p2.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getMaxX() {
|
||||||
|
int maxx = 0;
|
||||||
|
|
||||||
|
GraphicsDevice[] gds = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
|
||||||
|
if(bounds.length == 0){
|
||||||
|
bounds = new Rectangle[gds.length];
|
||||||
|
}
|
||||||
|
for (int i = 0; i < gds.length; i++) {
|
||||||
|
GraphicsDevice gd = gds[i];
|
||||||
|
bounds[i] = gd.getDefaultConfiguration().getBounds();
|
||||||
|
if(bounds[i].getMaxX()>maxx){
|
||||||
|
maxx=(int) bounds[i].getMaxX();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getMinX(){
|
||||||
|
int minx = 0;
|
||||||
|
GraphicsDevice[] gds = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
|
||||||
|
if(bounds.length == 0){
|
||||||
|
bounds = new Rectangle[gds.length];
|
||||||
|
}
|
||||||
|
for (int i = 0; i < gds.length; i++) {
|
||||||
|
GraphicsDevice gd = gds[i];
|
||||||
|
bounds[i] = gd.getDefaultConfiguration().getBounds();
|
||||||
|
if(bounds[i].getMinX()<minx){
|
||||||
|
minx=(int) bounds[i].getMinX();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return minx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[] getYBounds(int x){
|
||||||
|
if(bounds.length == 0){
|
||||||
|
GraphicsDevice[] gds = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
|
||||||
|
bounds = new Rectangle[gds.length];
|
||||||
|
for (int i = 0; i < gds.length; i++) {
|
||||||
|
GraphicsDevice gd = gds[i];
|
||||||
|
Utils.bounds[i] = gd.getDefaultConfiguration().getBounds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] out = null;
|
||||||
|
|
||||||
|
for(Rectangle b:bounds){
|
||||||
|
if(x>=b.getMinX()&&x<=b.getMaxX()){
|
||||||
|
if(out == null){
|
||||||
|
out = new int[]{(int)b.getMinY(),(int)b.getMaxY()};
|
||||||
|
}else{
|
||||||
|
if(b.getMinY()<out[0])
|
||||||
|
out[0] = (int) b.getMinY();
|
||||||
|
if(b.getMaxY()>out[1])
|
||||||
|
out[1] = (int) b.getMaxY();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(out == null)
|
||||||
|
out = new int[]{0,0};
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Obtain the image URL
|
||||||
|
public static Image createImage(String path, String description) {
|
||||||
|
URL imageURL = Utils.class.getResource(path);
|
||||||
|
|
||||||
|
if (imageURL == null) {
|
||||||
|
System.err.println("Resource not found: " + path);
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return (new ImageIcon(imageURL, description)).getImage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||