创意画板——(java)小游戏(4)
我们这几天把所有基本的功能,已经全部实现了(图像重绘功能,迭代图像,递归图形等),代码如下:
窗体类:
package xq0729;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class DrawUI extends JFrame {
//定义按钮和颜色的字符串
String[] btnstrs = {"直线","矩形","圆","曲线","三角形","递归图形","迭代分形","撤回","清空","橡皮擦","3D图形","谢尔宾斯基三角形"};
Color[] colors ={
Color.WHITE,Color.YELLOW,Color.BLACK,Color.BLUE,Color.RED,Color.MAGENTA,
Color.GRAY,Color.LIGHT_GRAY,Color.PINK,Color.GREEN,Color.CYAN
};
Shape[] shapes; // 创建图像保存的数组
public void initUI() {
//创建一个窗口
DrawUI jf=new DrawUI();
jf.setTitle("画板");
jf.setSize(800,600);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setBackground(Color.WHITE);
//添加流式布局管理器
FlowLayout fl = new FlowLayout();
jf.setLayout(fl);
//创建画板监听器的对象
DrawListener dl=new DrawListener();
//定义菜单
String[] filestrs={"New","OPen","OPenFiles","Import","Setting"};
JMenuBar bar=new JMenuBar();//菜单容器
JMenu fileMenu=new JMenu("文件");
JMenu shapeMenu=new JMenu("图形");
JMenu colorMenu=new JMenu("颜色");
JMenu helpMenu=new JMenu("Help");
//文件下
for (int i = 0; i < filestrs.length; i++) {
JMenu jm=new JMenu(filestrs[i]);// 菜单
for (int j = 0; j < filestrs.length; j++) {
JMenuItem jmi=new JMenuItem(filestrs[j]);// 菜单
jm.add(jmi);
jmi.addActionListener(dl);
}
fileMenu.add(jm);
}
// 颜色
for (int i = 0; i < colors.length; i++) {
JMenuItem jmi=new JMenuItem();// 菜单
jmi.setBackground(colors[i]);
colorMenu.add(jmi);
jmi.addActionListener(dl);
}
//图形
for (int i = 0; i < btnstrs.length; i++) {
JMenuItem jmi=new JMenuItem(btnstrs[i]);// 菜单
shapeMenu.add(jmi);
jmi.addActionListener(dl);
}
bar.add(fileMenu);
bar.add(shapeMenu);
bar.add(colorMenu);
bar.add(helpMenu);
jf.setJMenuBar(bar);
Dimension dim = new Dimension(100,40); //按钮的尺寸
for (int i = 0; i < btnstrs.length; i++) { // 在循环中调用下面封装的方法
addButton(btnstrs[i],dim,Color.white,dl,jf);
}
Dimension colordim = new Dimension(40,40);//颜色按钮的尺寸
for (int i = 0; i < colors.length; i++) {
addButton("",colordim,colors[i],dl,jf);
}
jf.setVisible(true);
//添加画笔
Graphics g = jf.getGraphics();
dl.g2=g;
jf.addMouseListener(dl);
jf.addMouseMotionListener(dl);
jf.shapes=dl.shapes; //把窗口和监听器之间的数组关联起来
}
//封装起来了
public void addButton(String btnstr,Dimension dim, Color color, ActionListener al,JFrame jf){
JButton btn = new JButton(btnstr);
btn.setBackground(color);
btn.setPreferredSize(dim);
jf.add(btn);
btn.addActionListener(al);
}
public void paint(Graphics g) { //重写paint函数,保证重绘
super.paint(g);
for (int i=0;i<shapes.length;i++) {
if(shapes[i]!=null)
shapes[i].drawShape(g);
}
}
public static void main(String[] args) {
DrawUI d =new DrawUI();
d.initUI();
}
}
监听器类:
package xq0729;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Random;
import javax.swing.JButton;
public class DrawListener implements MouseListener,ActionListener,MouseMotionListener{
int x,y,x1,x2,y1,y2,x3,y3,x4,y4,x5,y5;
int count=0;
Graphics g2; // 定义画笔
//public DrawListener(Graphics g) {
// this.g=g;
//}
int x6 = 400,y6 = 200,d = 400;
String shapeStr="";
Shape[] shapes = new Shape[200];
int index=0;
public void actionPerformed(ActionEvent e){
String btnstr = e.getActionCommand();// 字符串
System.out.println("点击了"+btnstr);
// 区分按钮颜色和按钮字符
if(btnstr.equals("")){
JButton btn = (JButton) e.getSource();
Color btnBgcolor = btn.getBackground();
System.out.println("按钮对象:"+btn.getText());
g2.setColor(btnBgcolor);
}else{
shapeStr=btnstr;
}
}
public void mouseClicked(MouseEvent e){
x = e.getX();
y = e.getY();
if(shapeStr.equals("三角形")) {
if(count==0) {
x3 = e.getX();
y3 = e.getY();
g2.drawOval(x3-2, y3-2, 4, 4);
count++;
}else if(count==1) {
x4=e.getX();
y4=e.getY();
g2.drawLine(x3, y3, x4, y4);
count++;
}else if(count==2) {
x5=e.getX();
y5=e.getY();
g2.drawLine(x5, y5, x4, y4);
g2.drawLine(x5, y5, x3, y3);
count=0;
}
}else if(shapeStr.equals("谢尔宾斯基三角形")) {
a(10,x6,y6,d);
}
System.out.println("点击:x="+x+" y="+y);
}
public void a(int n,int x6,int y6,int d) {
if(n==0) {
return;
}
double x7 = x6-d/2;
double args = Math.sqrt(3)/2;
double y7 = y6+args*d;
double x8 = x6+d/2;
double y8 = y6+args*d;
//因绘制线段的方法需要整型作为参数故进行强制类型转换
int x1f = (int)x7;
int y1f = (int)y7;
int x2f = (int)x8;
int y2f = (int)y8;
//绘制主三角形
g2.drawLine(x6, y6, x2f, y2f);
g2.drawLine(x6, y6, x1f, y1f);
g2.drawLine(x1f,y1f,x2f,y2f);
//三段线段的中点坐标
int n1x = (x6+x1f)/2;
int n1y = (y1f+y6)/2;
int n2x = (x2f+x6)/2;
int n2y = (y2f+y6)/2;
int n3x = (x2f+x1f)/2;
int n3y = y2f;
//绘制下次递归挖去的三角形
g2.drawLine(n1x, n1y, n2x, n2y);
g2.drawLine(n2x, n2y, n3x, n3y);
g2.drawLine(n1x, n1y, n3x, n3y);
//递归调用绘制方法 递归层数减一 边长减半 以两个中点为新顶点
a(n-1,n1x,n1y,d/2);
a(n-1,n2x,n2y,d/2);
a(n-1,x6,y6,d/2);
}
public void mousePressed(MouseEvent e){
x1=e.getX();
y1=e.getY();
System.out.println("按下");
//随机在0-99 选取10 个数
Random random = new Random();
for (int i = 0; i < 10; i++) {
int rannum = random.nextInt(100);
System.out.println(rannum);
}
// int rannum = random.nextInt(10);
}
public void mouseReleased(MouseEvent e){
x2=e.getX();
y2=e.getY();
// 画线
if (shapeStr.equals("直线")){
g2.drawLine(x1,y1,x2,y2);
Shape shape = new Shape();
shape.x1=x1;
shape.y1=y1;
shape.x2=x2;
shape.y2=y2;
shape.name="直线";
shape.color=g2.getColor();
shape.drawShape(g2);
shapes[index++]=shape;
}else if(shapeStr.equals("矩形")){
// 左上角的坐标 宽 高
g2.drawRect(min(x1,x2),min(y1,y2),abs(x2-x1),abs(y2-y1));
Shape shape = new Shape();
shape.x1=x1;
shape.y1=y1;
shape.x2=x2;
shape.y2=y2;
shape.name="矩形";
shape.color=g2.getColor();
shape.drawShape(g2);
shapes[index++]=shape;
}else if(shapeStr.equals("圆")){
// 外切矩形 左上角的坐标 宽 高
g2.drawOval(Math.min(x1,x2),min(y1,y2),abs(x2-x1),abs(y2-y1));
Shape shape = new Shape();
shape.x1=x1;
shape.y1=y1;
shape.x2=x2;
shape.y2=y2;
shape.name="圆";
shape.color=g2.getColor();
shape.drawShape(g2);
shapes[index++]=shape;
}else if (shapeStr.equals("3D图形")) {
for (int i = 0; i < 255; i++) {
Color color = new Color(i,i ,i );
g2.setColor(color);
g2.fillOval(x1+i/3,y1+i/3,255-i,255-i);//坐标移动 尺寸减小
}
}else if(shapeStr.equals("递归图形")) {
drawMyOval(min(x1,x2),min(y1,y2),abs(x2-x1),abs(y2-y1));
} else if(shapeStr.equals("迭代分形")) {
g2.fillRect(0, 0, 800, 800);
//Color color = new Color(0,255,0);
//g2.setColor(color);
double x=0,y=0;
double a=1.40 ,b=1.56,c=1.40,d=-6.56;
for(int i=0;i<100000;i++) {
double tempx =d*Math.sin(a*x)-Math.sin(b*y);
double tempy=c*Math.cos(a*x)+Math.cos(b*y);
//迭代
x=tempx;
y=tempy;
// 放大 再整体转型
int px=(int) (tempx*30)+x1;
int py=(int) (tempy*30)+y1;
Color color=new Color(i%255,i%255,0,60);
g2.setColor(color);
//绘制一个点
g2.drawLine(px, py, px, py);
}
}
System.out.println("松开");
}
public void drawMyOval(int x,int y,int w,int h){
if(w<50) {
return;
}
for (int i = 0; i < w; i++) {
Color color = new Color(i%255,i%255 ,i%255);
g2.setColor(color);
g2.drawRect(x+i/2, y+i/2, w-i, h-i);
}
//递归
g2.drawRect(x, y, w, h);
drawMyOval(x, y, w/3,h/3);
drawMyOval(x+w/3, y, w/3, h/3);
drawMyOval(x+2*(w/3), y, w/3, h/3);
drawMyOval(x, y+h/3, w/3,h/3);
drawMyOval(x+w/3, y+h/3, w/3, h/3);
drawMyOval(x+2*(w/3), y+h/3, w/3, h/3);
drawMyOval(x, y+2*(h/3), w/3, h/3);
drawMyOval(x+w/3, y+2*(h/3), w/3, h/3);
drawMyOval(x+2*(w/3), y+2*(h/3), w/3, h/3);
}
public int min(int a,int b){
return a < b ? a : b;
}
public int abs(int a){
return a < 0 ? -a : a;
}
public void mouseEntered(MouseEvent e){
}
public void mouseExited(MouseEvent e){
}
public void mouseDragged(MouseEvent e) {
int x3=e.getX();
int y3=e.getY();
if (shapeStr.equals("橡皮擦")) {
g2.fillRect(x3, y3, 30, 30);
Color a =new Color(238,238,238);
g2.setColor(a);
}else if (shapeStr.equals("曲线")) {
//g2.fillOval(x3, y3, 10, 10);
g2.drawLine(x1,y1,x3,y3);
x1=x3;
y1=y3;
}
}
public void mouseMoved(MouseEvent e) {
}
}
图像保存类:
package xq0729;
import java.awt.Color;
import java.awt.Graphics;
public class Shape {
int x1,x2,y1,y2;
String name;
Color color;
/**
* 画图形的方法
* @param g 画笔对象
*/
public void drawShape(Graphics g){
g.setColor(color);
if(name.equals("直线")){
g.drawLine(x1,y1,x2,y2);
}else if(name.equals("矩形")){
g.drawRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x2-x1),Math.abs(y2-
y1));
}else if(name.equals("圆")){
g.drawOval(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x2-
x1),Math.abs(y2-y1));
}
}
}