diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..fb50116 --- /dev/null +++ b/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..9d26d4a --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + Sokoban + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/README.md b/README.md index 7edbf5a..520dd0f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ # Box +本项目是一个推箱子的简易游戏 +效果如下: +![screenshot](./屏幕截图%202026-04-01%20125249.png) diff --git a/bin/Start.class b/bin/Start.class new file mode 100644 index 0000000..3b0d80a Binary files /dev/null and b/bin/Start.class differ diff --git a/bin/com/mr/image/background.png b/bin/com/mr/image/background.png new file mode 100644 index 0000000..43c4878 Binary files /dev/null and b/bin/com/mr/image/background.png differ diff --git a/bin/com/mr/image/box1.png b/bin/com/mr/image/box1.png new file mode 100644 index 0000000..bb339c5 Binary files /dev/null and b/bin/com/mr/image/box1.png differ diff --git a/bin/com/mr/image/box2.png b/bin/com/mr/image/box2.png new file mode 100644 index 0000000..5aee0d6 Binary files /dev/null and b/bin/com/mr/image/box2.png differ diff --git a/bin/com/mr/image/destination.png b/bin/com/mr/image/destination.png new file mode 100644 index 0000000..f91e251 Binary files /dev/null and b/bin/com/mr/image/destination.png differ diff --git a/bin/com/mr/image/player.png b/bin/com/mr/image/player.png new file mode 100644 index 0000000..5871016 Binary files /dev/null and b/bin/com/mr/image/player.png differ diff --git a/bin/com/mr/image/wall.png b/bin/com/mr/image/wall.png new file mode 100644 index 0000000..4504cc8 Binary files /dev/null and b/bin/com/mr/image/wall.png differ diff --git a/bin/com/mr/map/1 b/bin/com/mr/map/1 new file mode 100644 index 0000000..ca546b8 --- /dev/null +++ b/bin/com/mr/map/1 @@ -0,0 +1,20 @@ +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000011100000000000 +00000014100000000000 +00000010100000000000 +00000010100000000000 +00000010111111000000 +00011112020041000000 +00014002311111000000 +00011111210000000000 +00000001010000000000 +00000001010000000000 +00000001410000000000 +00000001110000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 diff --git a/bin/com/mr/map/2 b/bin/com/mr/map/2 new file mode 100644 index 0000000..c9a8093 --- /dev/null +++ b/bin/com/mr/map/2 @@ -0,0 +1,20 @@ +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000011111110000000 +00000010344410000000 +00000010001111000000 +00000111200001000000 +00000100012101000000 +00000102010001000000 +00000100011111000000 +00000111110000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 diff --git a/bin/com/mr/map/3 b/bin/com/mr/map/3 new file mode 100644 index 0000000..bd7e514 --- /dev/null +++ b/bin/com/mr/map/3 @@ -0,0 +1,20 @@ +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000011111000000000 +00000013001000000000 +00000010221011100000 +00000010201014100000 +00000011101114100000 +00000001000004100000 +00000001001000100000 +00000001001111100000 +00000001111000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 diff --git a/bin/com/mr/map/4 b/bin/com/mr/map/4 new file mode 100644 index 0000000..1d26b87 --- /dev/null +++ b/bin/com/mr/map/4 @@ -0,0 +1,20 @@ +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000011111000000 +00000001110001000000 +00000011000121000000 +00000010011001000000 +00000010200001000000 +00000013011201000000 +00000011114441000000 +00000000011111000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 diff --git a/bin/com/mr/map/5 b/bin/com/mr/map/5 new file mode 100644 index 0000000..c8fd5c8 --- /dev/null +++ b/bin/com/mr/map/5 @@ -0,0 +1,20 @@ +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000111110000000 +00000000130410000000 +00000000121010000000 +00000000100010000000 +00000011101010000000 +00000010020410000000 +00000010240010000000 +00000011111110000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 diff --git a/bin/com/mr/map/6 b/bin/com/mr/map/6 new file mode 100644 index 0000000..2b303e7 --- /dev/null +++ b/bin/com/mr/map/6 @@ -0,0 +1,20 @@ +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000111100000000 +00000001100110000000 +00000001020010000000 +00000001002010000000 +00000001114010000000 +00000000014010000000 +00000000014110000000 +00000001114010000000 +00000001020310000000 +00000001002010000000 +00000001000110000000 +00000001111100000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 diff --git a/bin/com/mr/map/7 b/bin/com/mr/map/7 new file mode 100644 index 0000000..50434e6 --- /dev/null +++ b/bin/com/mr/map/7 @@ -0,0 +1,20 @@ +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000111100000000 +00000001144100000000 +00000011444100000000 +00000011020100000000 +00000010202100000000 +00000010120110000000 +00000010102010000000 +00000010000010000000 +00000011131110000000 +00000000111000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 diff --git a/bin/com/mr/model/Box.class b/bin/com/mr/model/Box.class new file mode 100644 index 0000000..ad8b752 Binary files /dev/null and b/bin/com/mr/model/Box.class differ diff --git a/bin/com/mr/model/Destination.class b/bin/com/mr/model/Destination.class new file mode 100644 index 0000000..1777603 Binary files /dev/null and b/bin/com/mr/model/Destination.class differ diff --git a/bin/com/mr/model/Map.class b/bin/com/mr/model/Map.class new file mode 100644 index 0000000..8634442 Binary files /dev/null and b/bin/com/mr/model/Map.class differ diff --git a/bin/com/mr/model/Player.class b/bin/com/mr/model/Player.class new file mode 100644 index 0000000..346307b Binary files /dev/null and b/bin/com/mr/model/Player.class differ diff --git a/bin/com/mr/model/RigidBody.class b/bin/com/mr/model/RigidBody.class new file mode 100644 index 0000000..88360e5 Binary files /dev/null and b/bin/com/mr/model/RigidBody.class differ diff --git a/bin/com/mr/model/Wall.class b/bin/com/mr/model/Wall.class new file mode 100644 index 0000000..6fd465a Binary files /dev/null and b/bin/com/mr/model/Wall.class differ diff --git a/bin/com/mr/util/GameImageUtil.class b/bin/com/mr/util/GameImageUtil.class new file mode 100644 index 0000000..7e8f88c Binary files /dev/null and b/bin/com/mr/util/GameImageUtil.class differ diff --git a/bin/com/mr/util/GameMapUtil.class b/bin/com/mr/util/GameMapUtil.class new file mode 100644 index 0000000..d9ce4eb Binary files /dev/null and b/bin/com/mr/util/GameMapUtil.class differ diff --git a/bin/com/mr/view/GamePanel.class b/bin/com/mr/view/GamePanel.class new file mode 100644 index 0000000..2797f10 Binary files /dev/null and b/bin/com/mr/view/GamePanel.class differ diff --git a/bin/com/mr/view/MainFrame$1.class b/bin/com/mr/view/MainFrame$1.class new file mode 100644 index 0000000..c7a6a4f Binary files /dev/null and b/bin/com/mr/view/MainFrame$1.class differ diff --git a/bin/com/mr/view/MainFrame.class b/bin/com/mr/view/MainFrame.class new file mode 100644 index 0000000..675be93 Binary files /dev/null and b/bin/com/mr/view/MainFrame.class differ diff --git a/bin/com/mr/view/MapEditPanel$DrawMapPanel.class b/bin/com/mr/view/MapEditPanel$DrawMapPanel.class new file mode 100644 index 0000000..bb50218 Binary files /dev/null and b/bin/com/mr/view/MapEditPanel$DrawMapPanel.class differ diff --git a/bin/com/mr/view/MapEditPanel.class b/bin/com/mr/view/MapEditPanel.class new file mode 100644 index 0000000..37f719a Binary files /dev/null and b/bin/com/mr/view/MapEditPanel.class differ diff --git a/bin/com/mr/view/StarPanel.class b/bin/com/mr/view/StarPanel.class new file mode 100644 index 0000000..9fff360 Binary files /dev/null and b/bin/com/mr/view/StarPanel.class differ diff --git a/src/Start.java b/src/Start.java new file mode 100644 index 0000000..3a01116 --- /dev/null +++ b/src/Start.java @@ -0,0 +1,7 @@ +import com.mr.view.MainFrame; + +public class Start { + public static void main(String[] args) { + new MainFrame().setVisible(true); + } +} diff --git a/src/com/mr/image/background.png b/src/com/mr/image/background.png new file mode 100644 index 0000000..43c4878 Binary files /dev/null and b/src/com/mr/image/background.png differ diff --git a/src/com/mr/image/box1.png b/src/com/mr/image/box1.png new file mode 100644 index 0000000..bb339c5 Binary files /dev/null and b/src/com/mr/image/box1.png differ diff --git a/src/com/mr/image/box2.png b/src/com/mr/image/box2.png new file mode 100644 index 0000000..5aee0d6 Binary files /dev/null and b/src/com/mr/image/box2.png differ diff --git a/src/com/mr/image/destination.png b/src/com/mr/image/destination.png new file mode 100644 index 0000000..f91e251 Binary files /dev/null and b/src/com/mr/image/destination.png differ diff --git a/src/com/mr/image/player.png b/src/com/mr/image/player.png new file mode 100644 index 0000000..5871016 Binary files /dev/null and b/src/com/mr/image/player.png differ diff --git a/src/com/mr/image/wall.png b/src/com/mr/image/wall.png new file mode 100644 index 0000000..4504cc8 Binary files /dev/null and b/src/com/mr/image/wall.png differ diff --git a/src/com/mr/map/1 b/src/com/mr/map/1 new file mode 100644 index 0000000..ca546b8 --- /dev/null +++ b/src/com/mr/map/1 @@ -0,0 +1,20 @@ +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000011100000000000 +00000014100000000000 +00000010100000000000 +00000010100000000000 +00000010111111000000 +00011112020041000000 +00014002311111000000 +00011111210000000000 +00000001010000000000 +00000001010000000000 +00000001410000000000 +00000001110000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 diff --git a/src/com/mr/map/2 b/src/com/mr/map/2 new file mode 100644 index 0000000..c9a8093 --- /dev/null +++ b/src/com/mr/map/2 @@ -0,0 +1,20 @@ +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000011111110000000 +00000010344410000000 +00000010001111000000 +00000111200001000000 +00000100012101000000 +00000102010001000000 +00000100011111000000 +00000111110000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 diff --git a/src/com/mr/map/3 b/src/com/mr/map/3 new file mode 100644 index 0000000..bd7e514 --- /dev/null +++ b/src/com/mr/map/3 @@ -0,0 +1,20 @@ +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000011111000000000 +00000013001000000000 +00000010221011100000 +00000010201014100000 +00000011101114100000 +00000001000004100000 +00000001001000100000 +00000001001111100000 +00000001111000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 diff --git a/src/com/mr/map/4 b/src/com/mr/map/4 new file mode 100644 index 0000000..1d26b87 --- /dev/null +++ b/src/com/mr/map/4 @@ -0,0 +1,20 @@ +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000011111000000 +00000001110001000000 +00000011000121000000 +00000010011001000000 +00000010200001000000 +00000013011201000000 +00000011114441000000 +00000000011111000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 diff --git a/src/com/mr/map/5 b/src/com/mr/map/5 new file mode 100644 index 0000000..c8fd5c8 --- /dev/null +++ b/src/com/mr/map/5 @@ -0,0 +1,20 @@ +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000111110000000 +00000000130410000000 +00000000121010000000 +00000000100010000000 +00000011101010000000 +00000010020410000000 +00000010240010000000 +00000011111110000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 diff --git a/src/com/mr/map/6 b/src/com/mr/map/6 new file mode 100644 index 0000000..2b303e7 --- /dev/null +++ b/src/com/mr/map/6 @@ -0,0 +1,20 @@ +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000111100000000 +00000001100110000000 +00000001020010000000 +00000001002010000000 +00000001114010000000 +00000000014010000000 +00000000014110000000 +00000001114010000000 +00000001020310000000 +00000001002010000000 +00000001000110000000 +00000001111100000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 diff --git a/src/com/mr/map/7 b/src/com/mr/map/7 new file mode 100644 index 0000000..50434e6 --- /dev/null +++ b/src/com/mr/map/7 @@ -0,0 +1,20 @@ +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000111100000000 +00000001144100000000 +00000011444100000000 +00000011020100000000 +00000010202100000000 +00000010120110000000 +00000010102010000000 +00000010000010000000 +00000011131110000000 +00000000111000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 diff --git a/src/com/mr/model/Box.java b/src/com/mr/model/Box.java new file mode 100644 index 0000000..8a9ed52 --- /dev/null +++ b/src/com/mr/model/Box.java @@ -0,0 +1,36 @@ +package com.mr.model; + +import com.mr.util.GameImageUtil; +/** + * + * @author mingrisoft + * + */ + +public class Box extends RigidBody { + private boolean arrived = false;// Ƿ񵽴Ŀĵ + + public Box() { + super(GameImageUtil.boxImage1); + } + + public Box(int x, int y) { + super(x,y); + setImage(GameImageUtil.boxImage1); + } + + public void arrive() {// + setImage(GameImageUtil.boxImage2); + arrived = true; + } + + public void leave() {// 뿪 + setImage(GameImageUtil.boxImage1); + arrived = false; + } + + public boolean isArrived() { + return arrived; + } + +} diff --git a/src/com/mr/model/Destination.java b/src/com/mr/model/Destination.java new file mode 100644 index 0000000..56ea8b4 --- /dev/null +++ b/src/com/mr/model/Destination.java @@ -0,0 +1,17 @@ +package com.mr.model; + +import com.mr.util.GameImageUtil; +/** + * Ŀĵ + * + * @author mingrisoft + * + */ + +public class Destination extends RigidBody { + + public Destination() { + super(GameImageUtil.destinationImage); + } + +} diff --git a/src/com/mr/model/Map.java b/src/com/mr/model/Map.java new file mode 100644 index 0000000..8e9a559 --- /dev/null +++ b/src/com/mr/model/Map.java @@ -0,0 +1,67 @@ +package com.mr.model; + +import java.util.ArrayList; +/** + * ͼ + * + * @author mingrisoft + * + */ + +public class Map { + private RigidBody matrix[][];// ͼ + private Player player;// ͼеҶ + private ArrayList boxs;// ͼаб + + public Map(RigidBody matrix[][]) { + this.matrix = matrix; + player = new Player(); + boxs = new ArrayList<>(); + init(); + } + /** + * ȡͼ + * + * @return + */ + public RigidBody[][] getMapData() { + return matrix; + } + /** + * ͼݳʼ,ҳͼҺӵλã¼ЩλãͬʱԭҺӵĶ + */ + private void init() { + // ͼ + for (int i = 0, ilength = matrix.length; i < ilength; i++) { + for (int j = 0, jlength = matrix[i].length; j < jlength; j++) { + RigidBody rb = matrix[i][j];// + if (rb instanceof Player) {// + player.x = i;// ¼û + player.y = j;// ¼û + matrix[i][j] = null;// µĸ + } else if (rb instanceof Box) { + Box box = new Box(i, j);// ӦúӶ + boxs.add(box);// б + matrix[i][j] = null;// µĸ + } + } + } + } + /** + * ȡͼеҶ + * + * @return + */ + public Player getPlayer() { + return player; + } + /** + * ȡͼеб + * + * @return + */ + public ArrayList getBoxs() { + return boxs; + } + +} diff --git a/src/com/mr/model/Player.java b/src/com/mr/model/Player.java new file mode 100644 index 0000000..9b5dd35 --- /dev/null +++ b/src/com/mr/model/Player.java @@ -0,0 +1,14 @@ +package com.mr.model; + +import com.mr.util.GameImageUtil; +/** + * + * @author mingrisoft + * + */ +public class Player extends RigidBody{ + + public Player() { + super(GameImageUtil.playerImage); + } +} diff --git a/src/com/mr/model/RigidBody.java b/src/com/mr/model/RigidBody.java new file mode 100644 index 0000000..f60d39c --- /dev/null +++ b/src/com/mr/model/RigidBody.java @@ -0,0 +1,51 @@ +package com.mr.model; + +import java.awt.Image; + +/** + * + * + * @author mingrisoft + * + */ + +public abstract class RigidBody { + public int x;// + public int y;// + private Image image;// ͼƬ + + public RigidBody(int x, int y) { + this.x = x; + this.y = y; + } + + public RigidBody(Image image) { + this.image = image; + } + + public Image getImage() { + return image; + } + + public void setImage(Image image) { + this.image = image; + } + + /** + * дequals()xyȷΨһ + */ + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RigidBody other = (RigidBody) obj; + if (x != other.x) + return false; + if (y != other.y) + return false; + return true; + } +} diff --git a/src/com/mr/model/Wall.java b/src/com/mr/model/Wall.java new file mode 100644 index 0000000..ae95b0b --- /dev/null +++ b/src/com/mr/model/Wall.java @@ -0,0 +1,17 @@ +package com.mr.model; + +import com.mr.util.GameImageUtil; +/** + * ǽ + * + * @author mingrisoft + * + */ + +public class Wall extends RigidBody { + + public Wall() { + super(GameImageUtil.wallImage); + } + +} diff --git a/src/com/mr/util/GameImageUtil.java b/src/com/mr/util/GameImageUtil.java new file mode 100644 index 0000000..a48b8b5 --- /dev/null +++ b/src/com/mr/util/GameImageUtil.java @@ -0,0 +1,37 @@ +package com.mr.util; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.File; +import javax.imageio.ImageIO; + +/** + * ͼࡣ + * + * @author mingrisoft + */ +public class GameImageUtil { + + private static final String IMAGE_PATH = "src/com/mr/image";// ͼƬŵ· + public static BufferedImage playerImage;// ͼƬ + public static BufferedImage boxImage1;// δĿĵͼƬ + public static BufferedImage boxImage2;// ѵĿĵͼƬ + public static BufferedImage wallImage;// ǽͼƬ + public static BufferedImage destinationImage;// ĿĵͼƬ + public static BufferedImage backgroundImage;// ͼƬ + + static {// ͼƬгʼ + try { + playerImage = ImageIO.read(new File(IMAGE_PATH, "player.png")); + boxImage1 = ImageIO.read(new File(IMAGE_PATH, "box1.png")); + boxImage2 = ImageIO.read(new File(IMAGE_PATH, "box2.png")); + wallImage = ImageIO.read(new File(IMAGE_PATH, "wall.png")); + destinationImage = ImageIO + .read(new File(IMAGE_PATH, "destination.png")); + backgroundImage = ImageIO + .read(new File(IMAGE_PATH, "background.png")); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/com/mr/util/GameMapUtil.java b/src/com/mr/util/GameMapUtil.java new file mode 100644 index 0000000..dfa0674 --- /dev/null +++ b/src/com/mr/util/GameMapUtil.java @@ -0,0 +1,170 @@ +package com.mr.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; + +import com.mr.model.Box; +import com.mr.model.Destination; +import com.mr.model.Map; +import com.mr.model.Player; +import com.mr.model.RigidBody; +import com.mr.model.Wall; + +/** + * ͼݹࡣ + * + * @author mingrisoft + */ +public class GameMapUtil { + private static final char NULL_CODE = '0';// հʹõռλ + private static final char WALL_CODE = '1';// ǽʹõռλ + private static final char BOX_CODE = '2';// ʹõռλ + private static final char PLAYER_CODE = '3';// ʹõռλ + private static final char DESTINATION_CODE = '4';// Ŀĵʹõռλ + private static final String MAP_PATH = "src/com/mr/map";// ͼŵ· + public static final String CUSTOM_MAP_NAME = "custom";// Զͼ + + /** + * ͼļ + * + * @param arr + * - ͼ + * @param mapName + * - ͼļ + */ + static public void createMap(RigidBody[][] arr, String mapName) { + StringBuilder data = new StringBuilder();// ͼļҪд + for (int i = 0, ilength = arr.length; i < ilength; i++) { + for (int j = 0, jlength = arr[i].length; j < jlength; j++) { + RigidBody rb = arr[i][j];// ȡͼеĸ + if (rb == null) {// ǿն + data.append(NULL_CODE);// ƴӿհռλ + } else if (rb instanceof Wall) {// ǽ + data.append(WALL_CODE);// ƴǽռλ + } else if (rb instanceof Player) {// + data.append(PLAYER_CODE);// ƴҵռλ + } else if (rb instanceof Box) {// + data.append(BOX_CODE);// ƴӵռλ + } else if (rb instanceof Destination) {// Ŀĵ + data.append(DESTINATION_CODE);// ƴĿĵصռλ + } + } + data.append("\n");// ƴӻ + } + File mapFile = new File(MAP_PATH, mapName);// ͼļ + // ʼļ + try (FileOutputStream fos = new FileOutputStream(mapFile);) { + fos.write(data.toString().getBytes());// ַд뵽ļ + fos.flush();// ˢ + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * ȡԶͼļ + * + * @return Զͼ + */ + public static Map readCustomMap() { + File f = new File(MAP_PATH, CUSTOM_MAP_NAME);// ͼļ + if (!f.exists()) {// ļ + return null; + } + Map map = readMap(CUSTOM_MAP_NAME);// ȡԶļе + return map;// Զͼ + } + /** + * Զͼļ + */ + public static void clearCustomMap() { + File f = new File(MAP_PATH, CUSTOM_MAP_NAME);// ͼļ + if (f.exists()) {// ļ + f.delete();// ɾ + } + } + + /** + * ȡͼļ + * + * @param mapNum + * - ͼļ + * @return ͼļ + */ + public static Map readMap(int mapNum) { + // תΪַط + return readMap(String.valueOf(mapNum)); + } + + /** + * ȡͼļ + * + * @param mapName + * - ͼļ + * @return ͼļ + */ + public static Map readMap(String mapName) { + File f = new File(MAP_PATH, mapName);// ȡͼļ + if (!f.exists()) {// ļ + System.err.println("ͼ:" + mapName); + return null; + } + RigidBody[][] data = new RigidBody[20][20];// ͼ + // + try (FileInputStream fis = new FileInputStream(f); + InputStreamReader isr = new InputStreamReader(fis); + BufferedReader br = new BufferedReader(isr)) { + String tmp = null;// ȡһݵʱַ + int row = 0;// ǰȡ + while ((tmp = br.readLine()) != null) {// ѭһݵַ + char codes[] = tmp.toCharArray();// ֳַַ + // ѭַ飬֤ȡ20 + for (int i = 0; i < codes.length && row < 20; i++) { + RigidBody rb = null;// ׼浽ͼеĸ + switch (codes[i]) {// ж϶ַ + case WALL_CODE :// ǽռλ + rb = new Wall();// ǽʽʵ + break; + case BOX_CODE :// ӵռλ + rb = new Box();// ӵʽʵ + break; + case PLAYER_CODE :// ҵռλ + rb = new Player();// ҵʽʵ + break; + case DESTINATION_CODE :// Ŀĵصռλ + rb = new Destination();// Ŀĵصʽʵ + break; + } + data[row][i] = rb;// 󱣴浽ͼ + } + row++;// ȡ + } + } catch (IOException e) { + e.printStackTrace(); + } + return new Map(data);// ذ˵ͼݵĵͼ + } + + /** + * ȡܹؿ + * + * @return + */ + public static int getLevelCount() { + File dir = new File(MAP_PATH);// ȡͼ· + if (dir.exists()) {// ·ļ + File maps[] = dir.listFiles();// ȡļµļ + for (File f : maps) {// Щļ + if (CUSTOM_MAP_NAME.equals(f.getName())) {// Զͼ + return maps.length - 1;// ܹؿ = ļ -1 + } + } + return maps.length;// ܹؿ = ļ + } + return 0;// ûйؿ + } +} diff --git a/src/com/mr/view/GamePanel.java b/src/com/mr/view/GamePanel.java new file mode 100644 index 0000000..bba48d7 --- /dev/null +++ b/src/com/mr/view/GamePanel.java @@ -0,0 +1,211 @@ +package com.mr.view; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.image.BufferedImage; +import java.util.ArrayList; + +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +import com.mr.model.Box; +import com.mr.model.Destination; +import com.mr.model.Map; +import com.mr.model.Player; +import com.mr.model.RigidBody; +import com.mr.model.Wall; +import com.mr.util.GameMapUtil; +/** + * Ϸ + * + * @author mingrisoft + * + */ +public class GamePanel extends JPanel implements KeyListener { + private MainFrame frame;// + private int level;// ؿ + private RigidBody[][] data = new RigidBody[20][20];// ͼ + private BufferedImage image;// ͼƬ + private Graphics2D g2;// ͼƬĻͼ + private Player player;// + private ArrayList boxs;// б + + /** + * 췽ϷȡؿŶӦĵͼؿС1ȡԶͼ + * + * @param frame + * - + * @param level + * - ؿ + */ + public GamePanel(MainFrame frame, int level) { + this.frame = frame; + this.level = level; + + Map map;// Ϸͼ + if (level < 1) {// ؿС1 + map = GameMapUtil.readCustomMap();// ȡԶͼ + this.level = 0;// ؿΪ0㶨һ + if (map == null) {// ûԶͼļ + this.level = 1;// ؿΪһ + map = GameMapUtil.readMap(1);// ʼһ + } + } else {// ؿ1 + map = GameMapUtil.readMap(level);// ȡӦؿĵͼ + } + + data = map.getMapData();// ȡͼĵͼ + player = map.getPlayer();// ȡͼҶ + boxs = map.getBoxs();// ȡͼб + + // ͼƬΪ600*600IJͼ + image = new BufferedImage(600, 600, BufferedImage.TYPE_INT_RGB); + g2 = image.createGraphics();// ȡͼƬͼ + + this.frame.addKeyListener(this);// Ӽ̼ + this.frame.setFocusable(true);// ȡ + this.frame.setTitle("(esc¿ʼ)");// ޸ + } + /** + * дƷ + */ + @Override + public void paint(Graphics g) { + paintImage();// ͼƬ + g.drawImage(image, 0, 0, this);// ͼƬƵ + + boolean finish = true;// жϷǷı־ + for (Box box : boxs) {// б + finish &= box.isArrived();// ־ӵ״̬ + } + if (finish && boxs.size() > 0) {// ӶĿĵӵĸ0 + gotoAnotherLevel(level + 1);// һ + } + } + + /** + * ͼƬ + */ + private void paintImage() { + g2.setColor(Color.WHITE);// ʹðɫ + g2.fillRect(0, 0, getWidth(), getHeight());// һͼƬ + + for (int i = 0, ilength = data.length; i < ilength; i++) {// ͼ + for (int j = 0, jlength = data[i].length; j < jlength; j++) { + RigidBody rb = data[i][j];// ȡ + if (rb != null) { + Image image = rb.getImage();// ȡͼƬ + g2.drawImage(image, i * 30, j * 30, 30, 30, this);// ڶӦλûƸͼƬ + } + } + } + for (Box box : boxs) {// б + // ڶӦλûͼƬ + g2.drawImage(box.getImage(), box.x * 30, box.y * 30, 30, 30, this); + } + // ͼƬ + g2.drawImage(player.getImage(), player.x * 30, player.y * 30, 30, 30, + this); + } + /** + * ؿ + * + * @param level + * - ؿ + */ + private void gotoAnotherLevel(int level) { + frame.removeKeyListener(this);// ɾʵֵļ¼ + // ̣߳Runnableӿڵ + Thread t = new Thread(() -> { + try { + Thread.sleep(500);// 0.5֮ + } catch (Exception e) { + e.printStackTrace(); + } + if (level > GameMapUtil.getLevelCount()) {// Ĺؿؿ + frame.setPanel(new StarPanel(frame));// 뿪ʼ + JOptionPane.showMessageDialog(frame, "ͨ");// ͨضԻ + } else { + frame.setPanel(new GamePanel(frame, level));// Ӧؿ + } + }); + t.start();// ߳ + } + /** + * ̰ʱ + */ + @Override + public void keyPressed(KeyEvent e) { + int key = e.getKeyCode();// ȡµİֵ + int x = player.x;// ¼Һ + int y = player.y;// ¼ + switch (key) {// жϰֵ + case KeyEvent.VK_UP :// µϼͷ + moveThePlayer(x, y - 1, x, y - 2); + break; + case KeyEvent.VK_DOWN :// µ¼ͷ + moveThePlayer(x, y + 1, x, y + 2); + break; + case KeyEvent.VK_LEFT :// µͷ + moveThePlayer(x - 1, y, x - 2, y); + break; + case KeyEvent.VK_RIGHT :// µҼͷ + moveThePlayer(x + 1, y, x + 2, y); + break; + case KeyEvent.VK_ESCAPE :// Esc + gotoAnotherLevel(level);// ¿ʼϷ + break; + } + repaint();// ػ + } + /** + * ƶҽɫ + * + * @param xNext1 + * - ƶһĿλõĺ + * @param yNext1 + * - ƶһĿλõ + * @param xNext2 + * - ƶĿλõĺжӱƵλ + * @param yNext2 + * - ƶĿλõжӱƵλ + */ + private void moveThePlayer(int xNext1, int yNext1, int xNext2, int yNext2) { + if (data[xNext1][yNext1] instanceof Wall) {// ǰǽ + return;// ʲô + } + Box box = new Box(xNext1, yNext1);// ûǰλôӶ + if (boxs.contains(box)) {// бǴڵ + int index = boxs.indexOf(box);// ȡбе + box = boxs.get(index);// ȡбиӵĶ + if (data[xNext2][yNext2] instanceof Wall) {// ӵǰǽ + return;// ʲô + } + if (boxs.contains(new Box(xNext2, yNext2))) {// ӵǰ + return;// ʲô + } + if (data[xNext2][yNext2] instanceof Destination) {// ӵǰĿĵ + box.arrive();// ӵ + } else if (box.isArrived()) {// ӾĿĵ + box.leave();// 뿪 + } + box.x = xNext2;// ӱƵλ + box.y = yNext2; + } + player.x = xNext1;// ƶλ + player.y = yNext1; + } + + @Override + public void keyReleased(KeyEvent e) { + // ʵִ˷ + } + @Override + public void keyTyped(KeyEvent e) { + // ʵִ˷ + } +} diff --git a/src/com/mr/view/MainFrame.java b/src/com/mr/view/MainFrame.java new file mode 100644 index 0000000..a2bcdd9 --- /dev/null +++ b/src/com/mr/view/MainFrame.java @@ -0,0 +1,68 @@ +package com.mr.view; + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +import com.mr.util.GameMapUtil; +/** + * + * + * @author mingrisoft + * + */ + +public class MainFrame extends JFrame { + private int width = 605;// ɵСʱĿȣɵСѡ616 + private int height = 627;// ɵСʱĸ߶ȣɵС߶ѡ638 + + public MainFrame() { + setTitle("");// ñ + setResizable(false);// ɵС + setSize(width, height);// ÿ + Toolkit tool = Toolkit.getDefaultToolkit(); // ϵͳĬ߰ + Dimension d = tool.getScreenSize(); // ȡĻߴ磬һά + // Ļмʾ + setLocation((d.width - getWidth()) / 2, (d.height - getHeight()) / 2); + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);// رմ岻κβ + addListener();// Ӽ + setPanel(new StarPanel(this));// 뿪ʼ + GameMapUtil.clearCustomMap();// ɾԶͼ + } + /** + * е + * + * @param panel + * - + */ + + public void setPanel(JPanel panel) { + Container c = getContentPane();// ȡ + c.removeAll();// ɾ + c.add(panel, BorderLayout.CENTER);// + c.validate();// ֤ + c.repaint(); + } + + /** + * + */ + private void addListener() { + addWindowListener(new WindowAdapter() {// Ӵ¼ + public void windowClosing(WindowEvent e) {// رʱ + int closeCode = JOptionPane.showConfirmDialog(MainFrame.this, + "Ƿ˳Ϸ", "ʾ", JOptionPane.YES_NO_OPTION);// ѡԻ򣬲¼ûѡ + if (closeCode == JOptionPane.YES_OPTION) {// ûѡȷ + System.exit(0);// رճ + } + } + }); + } + +} diff --git a/src/com/mr/view/MapEditPanel.java b/src/com/mr/view/MapEditPanel.java new file mode 100644 index 0000000..6902e8a --- /dev/null +++ b/src/com/mr/view/MapEditPanel.java @@ -0,0 +1,255 @@ +package com.mr.view; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.image.BufferedImage; + +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JToggleButton; + +import com.mr.model.Box; +import com.mr.model.Destination; +import com.mr.model.Player; +import com.mr.model.RigidBody; +import com.mr.model.Wall; +import com.mr.util.GameMapUtil; +/** + * ͼ༭ + * + * @author mingrisoft + * + */ +public class MapEditPanel extends JPanel { + private MainFrame frame;// ͼ + private BufferedImage image;// ƵͼͼƬ + private Graphics2D g2;// ͼͼƬĻͼ + private DrawMapPanel editPanel;// + private JToggleButton wall;// ǽťʾѡ״̬ + private JToggleButton player;// Ұťʾѡ״̬ + private JToggleButton box;// Ӱťʾѡ״̬ + private JToggleButton destination;// Ŀĵذťʾѡ״̬ + private JButton save, clear, back;// 水ťťذť + private RigidBody data[][];// ͼ + private int offsetX = 100, offsetY = 80;// ͼͼƬڻĺƫ + + /** + * ͼ༭췽 + */ + public MapEditPanel(MainFrame frame) { + this.frame = frame; + this.frame.setTitle("ͼ༭(ͼҼ)"); + init();// ʼ + addListener();// ¼ + } + + /** + * ʼ + */ + private void init() { + // ʹ400*400IJɫͼƬ,ϷΪ600*600˴ΪϷŰ + image = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB); + g2 = image.createGraphics();// ȡͼƬͼ + editPanel = new DrawMapPanel();// ʵ + data = new RigidBody[20][20];// ͼϷһ + setLayout(new BorderLayout());// ʹñ߽粼 + + save = new JButton("");// ʵť + clear = new JButton(""); + back = new JButton(""); + wall = new JToggleButton("ǽ"); + player = new JToggleButton(""); + box = new JToggleButton(""); + destination = new JToggleButton("Ŀĵ"); + wall.setSelected(true);// ǽťĬѡ + + ButtonGroup group = new ButtonGroup();// ť + group.add(wall);// ťǽť + group.add(player);// ťҰť + group.add(box);// ťӰť + group.add(destination);// ťĿĵذť + + FlowLayout flow = new FlowLayout();// + flow.setHgap(20);// ˮƽ20 + JPanel buttonPanel = new JPanel(flow);// ť壬 + + buttonPanel.add(wall);// ťӰť + buttonPanel.add(player); + buttonPanel.add(box); + buttonPanel.add(destination); + buttonPanel.add(clear); + buttonPanel.add(save); + buttonPanel.add(back); + + add(editPanel, BorderLayout.CENTER);// ͼλ + add(buttonPanel, BorderLayout.SOUTH);// ťϲ + } + + /** + * ͼƬ + */ + void paintImage() { + g2.setColor(Color.WHITE);// ʹðɫ + g2.fillRect(0, 0, image.getWidth(), image.getHeight());// һͼƬİɫ + for (int i = 0, ilength = data.length; i < ilength; i++) {// ͼ + for (int j = 0, jlength = data[i].length; j < jlength; j++) { + RigidBody rb = data[i][j];// ȡ + if (rb != null) {// null + Image image = rb.getImage();// ȡ˸ͼƬ + g2.drawImage(image, i * 20, j * 20, 20, 20, this);// ͼƬ + } + } + } + } + + /** + * ¼ + */ + private void addListener() { + frame.addMouseListener(editPanel);// ӻͼе¼ + frame.addMouseMotionListener(editPanel);// ӻͼеҷ¼ + + clear.addActionListener(e -> { // ťʱ + data = new RigidBody[20][20];// ͼ¸ֵ + repaint();// ػ + }); + + save.addActionListener(e -> {// 水ťʱ + String name = GameMapUtil.CUSTOM_MAP_NAME;// ͼΪԶͼ + // while (true) { + // name = JOptionPane.showInputDialog(MapEditPanel.this, + // "ͼ");// Ի򣬲¼ûֵ + // if (name == null) {// ûѡȡ + // return;// + // } else if ("".equals(name.trim())) {// ûδκЧֵ + // continue;// ִѭ + // } else {// ûЧֵ + // break;// ˳ѭ + // } + // } + GameMapUtil.createMap(data, name);// ˵ͼļ + JOptionPane.showMessageDialog(MapEditPanel.this, + "ԶͼɹֱӿʼϷ");// Իʾɹ + back.doClick();// ذťĵ¼ + }); + + back.addActionListener(e -> {// ذťʱ + frame.removeMouseListener(editPanel);// ɾͼе¼ + frame.removeMouseMotionListener(editPanel);// ɾͼеҷ¼ + frame.setPanel(new StarPanel(frame));// 뿪ʼ + }); + } + + /** + * ͼ༭еĻͼ + * + * + */ + class DrawMapPanel extends JPanel + implements + MouseListener, + MouseMotionListener { + boolean paintFlag = false;// ǽ־ + int clickButton;// İ + + /** + * дͼ + */ + @Override + public void paint(Graphics g) { + paintImage();// ͼƬ + g.setColor(Color.gray);// ʹûɫ + g.fillRect(0, 0, getWidth(), getHeight());// һ + g.drawImage(image, offsetX, offsetY, this);// ͼƬƵ + } + + /** + * Ƹ + * + * @param e + * - ¼ + */ + private void drawRigid(MouseEvent e) { + RigidBody rb;// + // ǷڵͼΧڱ־ڴѹ˻ͼ壬ЩֵҪ΢ + boolean inMap = e.getX() > offsetX && e.getX() < 400 + offsetX + && e.getY() > offsetY + 20 && e.getY() < 400 + offsetY + 20; + if (inMap && paintFlag) {// ڵͼڵı־ͻǽ־Ϊtrue + int x = (e.getX() - offsetX) / 20;// ĸĺ + int y = (e.getY() - offsetY - 20) / 20;// ĸ + if (wall.isSelected()) {// ǽťѡ + rb = new Wall();// 尴ǽʵ + } else if (player.isSelected()) {// Ұťѡ + rb = new Player();// 尴ҽʵ + } else if (box.isSelected()) {// ťѡ + rb = new Box();// 尴ӽʵ + } else {// Ŀĵذťѡ + rb = new Destination();// 尴Ŀĵؽʵ + } + if (clickButton == MouseEvent.BUTTON1) {// µ + if (data[x][y] == null) {// ѡеλûκθ + data[x][y] = rb;// ѡаťӦĸ + } + } else if (clickButton == MouseEvent.BUTTON3) {// µҼ + data[x][y] = null;// ѡеλõĶ + } + repaint();// ػ + } + } + + /** + * ҷʱ + */ + @Override + public void mouseDragged(MouseEvent e) { + drawRigid(e);// ǽ + } + + /** + * 갴ʱ + */ + @Override + public void mousePressed(MouseEvent e) { + paintFlag = true;// ǽ־Ϊtrue + clickButton = e.getButton();// ¼ǰµ갴 + drawRigid(e);// ǽ + } + + /** + * 갴̧ʱ + */ + @Override + public void mouseReleased(MouseEvent e) { + paintFlag = false;// ǽ־Ϊfalse + } + + @Override + public void mouseMoved(MouseEvent e) { + // ʵִ˷ + } + + @Override + public void mouseClicked(MouseEvent e) { + // ʵִ˷ + } + + @Override + public void mouseEntered(MouseEvent e) { + // ʵִ˷ + } + + @Override + public void mouseExited(MouseEvent e) { + // ʵִ˷ + } + } +} diff --git a/src/com/mr/view/StarPanel.java b/src/com/mr/view/StarPanel.java new file mode 100644 index 0000000..df62fe1 --- /dev/null +++ b/src/com/mr/view/StarPanel.java @@ -0,0 +1,97 @@ +package com.mr.view; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.image.BufferedImage; + +import javax.swing.JPanel; + +import com.mr.util.GameImageUtil; +/** + * ʼ + * + * @author mingrisoft + * + */ +public class StarPanel extends JPanel implements KeyListener { + BufferedImage image;// ʾͼƬ + Graphics2D g2;// ͼƬͼ + MainFrame frame;// + int x = 160;// ͼĺ + int y;// ͼ + final int y1 = 320;// һѡ + final int y2 = 420;// ڶѡ + + public StarPanel(MainFrame frame) { + this.frame = frame; + this.frame.addKeyListener(this); + this.frame.setFocusable(true); + // ͼƬʹ600*600IJͼ + image = new BufferedImage(600, 600, BufferedImage.TYPE_INT_RGB); + g2 = image.createGraphics(); + this.frame.setTitle(""); + y = y1;// Ĭѡһѡ + } + + @Override + public void paint(Graphics g) { + paintImage();// ͼƬ + g.drawImage(image, 0, 0, this);// ͼƬ + } + /** + * ͼƬ + */ + private void paintImage() { + g2.drawImage(GameImageUtil.backgroundImage, 0, 0, this); + g2.setColor(Color.BLACK);// ʹúɫ + g2.setFont(new Font("", Font.BOLD, 40));// + g2.drawString("ʼϷ", 230, y1 + 30);// Ƶһѡ + g2.drawString("ͼ༭", 230, y2 + 30);// Ƶڶѡ + g2.drawImage(GameImageUtil.playerImage, x, y, this);// ͼƬΪѡͼ + } + + /** + * ̰ʱ + */ + @Override + public void keyPressed(KeyEvent e) { + int key = e.getKeyCode();// ȡı + switch (key) {// жϰ + case KeyEvent.VK_ENTER :// ǻس + switch (y) {// жͼ + case y1 :// ѡеһѡ + frame.removeKeyListener(this);// ɾǰ¼ + frame.setPanel(new GamePanel(frame, 0));// Ϸ + break; + case y2 :// ѡеڶѡ + frame.removeKeyListener(this);// ɾǰ¼ + frame.setPanel(new MapEditPanel(frame));// ͼ༭ + break; + } + break; + case KeyEvent.VK_UP :// ϼͷ¼ͷһ߼ + case KeyEvent.VK_DOWN :// ¼ͷ + if (y == y1) {// ͼѡеһѡ + y = y2;// ѡеڶѡ + } else { + y = y1;// ֵһѡ + } + break; + } + repaint();// ػ + } + + @Override + public void keyReleased(KeyEvent e) { + // ʵִ˷ + } + + @Override + public void keyTyped(KeyEvent e) { + // ʵִ˷ + } +} diff --git a/屏幕截图 2026-04-01 125249.png b/屏幕截图 2026-04-01 125249.png new file mode 100644 index 0000000..dad94cd Binary files /dev/null and b/屏幕截图 2026-04-01 125249.png differ diff --git a/屏幕截图 2026-04-01 125328.png b/屏幕截图 2026-04-01 125328.png new file mode 100644 index 0000000..0e1aa98 Binary files /dev/null and b/屏幕截图 2026-04-01 125328.png differ