day4 自制地图
可以根据自己的想法通过可视化界面去制作地图,但是这里只写了一张即一次只能保存一张,保存完就可以玩自己设计的游戏,但属于玩家diy成绩不保存在排行榜中。
package diyMap;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
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.event.WindowEvent;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
public class CreateMap extends JFrame implements ActionListener{
String PATH="F:\\PushBoxGame\\map";
/*素材宽度*/
static int SOUREC_WIDTH = 30;
/*素材高度*/
static int SOUREC_HEIGHT =30;
/*地图宽度*/
static int MAP_WIDTH =720;
/*地图高度*/
static int MAP_HEIGHT=720;
static int[][] map1 = new int[MAP_WIDTH / SOUREC_WIDTH][MAP_HEIGHT / SOUREC_HEIGHT];
static ImageIcon[][] icons = new ImageIcon[MAP_WIDTH / SOUREC_WIDTH][MAP_HEIGHT / SOUREC_HEIGHT];
JPanel mp;
JPanel tool=new JPanel();
JToggleButton wall=new JToggleButton("墙块");
JToggleButton player=new JToggleButton("玩家");
JToggleButton box1=new JToggleButton("箱子");
JToggleButton destination=new JToggleButton("目的地");
JButton clear=new JButton("清空");
JButton save=new JButton("保存");
JButton back=new JButton("返回");
ButtonGroup gp=new ButtonGroup();
ImageIcon[] im;
public CreateMap() {
im=new ImageIcon[6];
im[0] = null;
im[1] = new ImageIcon("picture/box1.png");
im[2] = new ImageIcon("picture/wall.png");
im[4] = new ImageIcon("picture/destination.png");
im[5] = new ImageIcon("picture/player.png");
this.setTitle("地图编辑器(鼠标左键绘图,鼠标右键擦除)");
this.setVisible(true);
this.setResizable(false);
this.setSize(720, 720);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.setLocationRelativeTo(null);
mp=new MySetPanel();
mp.setPreferredSize(new Dimension(800, 800));
mp.setBackground(Color.white);
mp.addMouseMotionListener(new PanelListenner());
mp.addMouseListener(new oneclick());
wall.setActionCommand("墙块");
player.setActionCommand("玩家");
box1.setActionCommand("箱子");
destination.setActionCommand("目的地");
clear.addActionListener(this);
save.addActionListener(this);
back.addActionListener(this);
gp.add(wall);
gp.add(player);
gp.add(box1);
gp.add(destination);
tool.add(wall);
tool.add(player);
tool.add(box1);
tool.add(destination);
tool.add(clear);
tool.add(save);
tool.add(back);
this.add(mp, BorderLayout.CENTER);
this.add(tool, BorderLayout.SOUTH);
}
class oneclick extends MouseAdapter{
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
int op = 0;
if(gp.getSelection()==null) JOptionPane.showMessageDialog(null,"还未选中需要绘制的类型");
else if(e.getButton()==MouseEvent.BUTTON3)op=0;
else if(gp.getSelection().getActionCommand()=="箱子")op=1;
else if(gp.getSelection().getActionCommand()=="目的地")op=4;
else if(gp.getSelection().getActionCommand()=="玩家")op=5;
int num=0;
//得到该位置对应的数组下标
int j=e.getX()/SOUREC_WIDTH;
int i=e.getY()/SOUREC_HEIGHT;
map1[i][j]=op;
icons[i][j]=im[op];
mp.repaint();
}
}
class PanelListenner extends MouseMotionAdapter{
@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
int op = 0;
if(gp.getSelection().getActionCommand()=="墙块")op=2;
int num=0;
//得到该位置对应的数组下标
int j=e.getX()/SOUREC_WIDTH;
int i=e.getY()/SOUREC_HEIGHT;
map1[i][j]=op;
icons[i][j]=im[op];
mp.repaint();
}
}
class MySetPanel extends JPanel {
@Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
//super.paint(g);
for (int i = 0; i < MAP_HEIGHT / SOUREC_HEIGHT; i++) {
for (int j = 0; j < MAP_WIDTH / SOUREC_WIDTH; j++) {
//System.out.println(1);
if (icons[i][j] != null) {
g.drawImage(icons[i][j].getImage(), getDrawX(j), getDrawY(i),SOUREC_WIDTH,SOUREC_HEIGHT,
null);
}
else g.clearRect(getDrawX(j),getDrawY(i),SOUREC_WIDTH,SOUREC_HEIGHT);
}
}
}
}
// 将数组下标转化成对应的图片左上角坐标
public int getDrawX(int j) {
int x = j * 30;
return x;
}
// 将数组下标转化成对应的图片左上角坐标
public int getDrawY(int i) {
int y = i * 30;
return y;
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource()==save) {//保存
//这里要注意空地图是不能保存的
if(gp.getSelection()==null) JOptionPane.showMessageDialog(null,"还未选中需要绘制的类型");
//不完整的地图也是不能保存的
if(gp.getSelection().getActionCommand()!="箱子"||gp.getSelection().getActionCommand()!="墙块"||gp.getSelection().getActionCommand()!="目的地")
{JOptionPane.showMessageDialog(null,"地图不完整");};
int k = JOptionPane.showConfirmDialog(this,
"您确定保存地图吗?", "保存", JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (k == JOptionPane.YES_OPTION) {
CreatMapTxt();
for (int i = 0; i < MAP_HEIGHT / SOUREC_HEIGHT; i++) {
for (int j = 0; j < MAP_WIDTH / SOUREC_WIDTH; j++) {
icons[i][j] = null;
map1[i][j]=0;
}
}
this.dispose();
new DiyMap();
}
}
else if(e.getSource()==clear) {//清空
int k = JOptionPane.showConfirmDialog(this,
"您确定清空地图吗?", "清空", JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (k == JOptionPane.YES_OPTION) {
for (int i = 0; i < MAP_HEIGHT / SOUREC_HEIGHT; i++) {
for (int j = 0; j < MAP_WIDTH / SOUREC_WIDTH; j++) {
icons[i][j] = null;
map1[i][j]=0;
}
}
mp.repaint();
JOptionPane.showMessageDialog(this,"LALALA 清空成功");
}
}
else if(e.getSource()==back) {//返回,返回时也需要将数组清空,防止下次进来地图编辑时,还是最后退出时的样子,因为开的是静态数组
for (int i = 0; i < MAP_HEIGHT / SOUREC_HEIGHT; i++) {
for (int j = 0; j < MAP_WIDTH / SOUREC_WIDTH; j++) {
icons[i][j] = null;
map1[i][j]=0;
}
}
this.dispose();
}
}
void CreatMapTxt() {
try {
// 得到文件输出流
FileOutputStream fos = new FileOutputStream(PATH + "\\diy"+".map");
// 将文件输出流包装成基本数据输出流
DataOutputStream dos = new DataOutputStream(fos);
// 从配置的接口中得到二维数组的大小(由于本类已经实现了上面的Mapconfig接口,所以可以直接用里面的数据)
int i = MAP_HEIGHT / SOUREC_HEIGHT;
int j = MAP_WIDTH / SOUREC_WIDTH;
// 先数组的大小写入文件
dos.writeInt(i);
dos.writeInt(j);
// 按顺序将二维数组写入文件,后面游戏读取地图的时候也要按这种顺序读回来
for (int ii = 0; ii < i; ii++) {
for (int jj = 0; jj < j; jj++) {
dos.writeInt(map1[ii][jj]);
}
}
// 强制流中的数据完全输出完
dos.flush();
// 关闭输出流
dos.close();
} catch (Exception ef) {
ef.printStackTrace();
}
JOptionPane.showMessageDialog(this,"保存成功");
}
protected void processWindowEvent(WindowEvent e) {
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
for (int i = 0; i < MAP_HEIGHT / SOUREC_HEIGHT; i++) {
for (int j = 0; j < MAP_WIDTH / SOUREC_WIDTH; j++) {
icons[i][j] = null;
map1[i][j]=0;
}
}
super.processWindowEvent(e);
}
}
}
号外
两条判断语句是为了增加游戏的合理性,当然没有也是可以的。。。