思维导图
效果图
代码目录
Bg()
package com.sxt; import java.awt.*; public class Bg { // MIner mIner=new MIner(); Image bg = Toolkit.getDefaultToolkit().getImage("images/bg.jpg"); Image bg1 = Toolkit.getDefaultToolkit().getImage("images/bg1.jpg"); Image peo = Toolkit.getDefaultToolkit().getImage("images/peo.png"); Image water = Toolkit.getDefaultToolkit().getImage("images/辣椒水.png"); // Image shoukao = Toolkit.getDefaultToolkit().getImage("images/手铐.png"); //关卡 static int level = 1; //目标得分 int goal = 5 * level; //积分 static int count; //辣椒水数量 static int waterNum = 3; //手铐数量 static int shoukaonum = 3; //辣椒水的状态 默认是false 表示并未使用 static boolean waterflag = false; //手铐的状态 //static boolean shoukaoflag = false; //背景开始时间 long startime; //背景开始时间 long endtime; //药水价格 int price=3; //药水是否购买 boolean shop=false; //绘制 void psintself(Graphics g) { // int x = 310; // if (x >= 200) { // x += 20; // } else if (x <= 568) { // x -= 20; // } g.drawImage(bg, 0, 200, null); g.drawImage(bg1, 0, 0, null); switch (GameWin.state) { case 0: drawword(g, 80, Color.black, "准备开始!", 200, 400); break; case 1: g.drawImage(peo, 310, 50, null); g.drawImage(water, 500, 50, null); //g.drawImage(shoukao, 455, 158, null); drawword(g, 30, Color.black, "积分:" + count, 30, 150); drawword(g, 30, Color.black, "辣椒水*" + waterNum, 530, 100); //drawword(g, 30, Color.black, "手铐*" + shoukaonum, 560, 200); //关卡数 drawword(g, 20, Color.black, "第" + level + "关", 30, 60); //目标积分 drawword(g, 30, Color.black, "目标积分:" + goal, 30, 110); endtime=System.currentTimeMillis(); long tim=20-(endtime-startime)/1000; drawword(g, 30, Color.black, "倒计时:"+(tim>0?tim:0)+"秒", 520, 150); break; case 2: g.drawImage(water, 300, 400, null); drawword(g, 30, Color.black, "辣椒水价格:"+price + waterNum, 300, 500); drawword(g, 30, Color.black, "是否购买?"+"" + waterNum, 400, 600); if (shop){ count=count-price; waterNum++; shop=false; GameWin.state=1; startime=System.currentTimeMillis(); } break; case 3: drawword(g, 80, Color.black, "宇将军逃脱!", 200, 350); drawword(g, 80, Color.black, "积分:" + count, 200, 450); break; case 4: drawword(g, 80, Color.red, "存折起诉成功!", 200, 350); drawword(g, 80, Color.black, "积分:" + count, 200, 450); break; default: } } boolean gametime(){ long tim=(endtime-startime)/1000; if (tim>20){ return true; } return false; } //下一关重新加载页面 void regame(){ //关卡 level = 1; //目标得分 goal = 5 * level; //积分 count=0; //辣椒水数量 waterNum = 3; //手铐数量 shoukaonum = 3; //辣椒水的状态 默认是false 表示并未使用 waterflag = false; } //绘制字符串 public void drawword(Graphics g, int size, Color color, String str, int x, int y) { g.setColor(color); g.setFont(new Font("仿宋", Font.BOLD, size)); g.drawString(str, x, y); } }
Gamewin()
package com.sxt; import javax.swing.*; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; public class GameWin extends JFrame { //游戏状态 // 0:准备状态 1:正在游戏 2:商店 3:失败 4:胜利 static int state; //存放多个金块 ArrayList<Object> goldlist = new ArrayList<>(); Bg bg = new Bg(); Line line = new Line(this); //MIner miner=new MIner(this); Image image; Object ob = new Object(); //生成添加金块石块 { //先判断是否重叠 再添加到集合中 Gold gold = null; boolean isplace = true; for (int i = 0; i < 6; i++) { double r = Math.random(); if (r < 0.5) { //存放陈泽 gold = new Gold(); } else { //存放黑白 gold = new goldmini(); } //判断是否重叠 for (Object object : goldlist) { //gold.getrec()是获取创建好的金块,但这些金块并未添加到集合中 //object.getrec()是获取集合中的金块 if (gold.getrec().intersects(object.getrec())) { //如果重叠 则不能放置 isplace = false; } } if (isplace) { goldlist.add(gold); } else { isplace = true; i--; } } for (int i = 0; i < 3; i++) { Rock rock1 = new Rock(); for (Object object : goldlist) { if (rock1.getrec().intersects(object.getrec())) { isplace = false; } } if (isplace) { goldlist.add(rock1); rock1.type = 2; } else { isplace = true; i--; } } } //初始化窗口 void launch() { this.setVisible(true); this.setLayout(null); this.setSize(768, 1000); this.setTitle("陈泽大战宇将军"); this.setDefaultCloseOperation(1); addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { switch (state) { case 0: if (e.getButton() == 3) { state = 1; //将系统时间赋值给开始时间 bg.startime = System.currentTimeMillis(); } break; case 1: super.mouseClicked(e); if (e.getButton() == 1 && line.state == 0) { //1是左键 line.state = 1; } //抓取返回 点击右键 if (e.getButton() == 3 && line.state == 3) { if (Bg.waterNum > 0) { Bg.waterflag = true; Bg.waterNum--; // for (Object obj : goldlist) { // if (obj.type==1){ // Bg.waterflag=true; // Bg.waterNum--; // System.out.println("金快"); // } else { // Bg.shoukaoflag=true; // Bg.shoukaonum--; // } } else { System.out.println("辣椒水用完了"); } } break; case 2: if (e.getButton() == 1) { bg.shop = true; } if (e.getButton() == 3) { state = 1; bg.startime = System.currentTimeMillis(); } break; case 3: case 4: if (e.getButton() == 1) { state = 0; bg.regame(); line.reline(); } break; default: } } }); //死循环 while (true) { //重复绘制 repaint(); nextlevel(); //延迟效果 线程 try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } //下一关 public void nextlevel() { if (bg.gametime() && state == 1) { if (Bg.count >= bg.goal) { if (Bg.level == 5) { state = 4; } else { state=2; Bg.level++; } } else { state = 3; } dispose(); GameWin gameWin = new GameWin(); gameWin.launch(); } } //加载页面 @Override public void paint(Graphics g) { //双缓存技术解决组件频闪问题 image = this.createImage(768, 1000); Graphics gimage = image.getGraphics(); bg.psintself(gimage); if (state == 1) { //miner.paint(g); for (Object gold : goldlist) { gold.paintself(gimage); } try { line.paintself(gimage); } catch (InterruptedException e) { e.printStackTrace(); } } g.drawImage(image, 0, 0, null); } public static void main(String[] args) { GameWin gw = new GameWin(); gw.launch(); } }
Gold()
Gold()
package com.sxt; import java.awt.*; public class Gold extends Object { Gold(){ this.x=(int)(Math.random()*700) ; this.y=(int) (Math.random()*500+300) ; this.width=100; this.height=138; //默认均为false 不能被移动 this.flag=false; this.m=100; this.count=4; this.type=1; this.img= Toolkit.getDefaultToolkit().getImage("images/陈泽.png"); } }
goldmini()
class goldmini extends Gold { goldmini(){ this.x=(int)(Math.random()*650) ; this.width=78; this.height=90; this.m=70; this.count=2; this.type=1; this.img= Toolkit.getDefaultToolkit().getImage("images/黑白.png"); } }
Line()
package com.sxt; import java.awt.*; public class Line { //起始坐标 int x = 380; int y = 180; //终点坐标 int endx = 500; int endy = 500; //线长 double length = 26; double n = 0; //方向 int dir = 1; //状态 0:摇摆 1:抓取 2:收回 int state; //钩爪 Image hook = Toolkit.getDefaultToolkit().getImage("images/hook.png"); GameWin frame; Line(GameWin frame) { this.frame = frame; } //抓取判定 //碰撞检测 void logic() { for (Object gold : this.frame.goldlist) { if (endx > gold.x && endx < gold.x + gold.width && endy > gold.y && endy < gold.y + gold.height) { //System.out.println("判定成功1"); state = 3; gold.flag = true; } } } void paintself(Graphics g) throws InterruptedException { logic(); //线的四种情况 switch (state) { case 0: if (n < 0.25) { dir = 1; } else if (n > 0.85) { dir = -1; } n = n + 0.005 * dir; extracted(g); break; case 1: if (length < 750) { length = length + 10; extracted(g); } else { state = 2; } break; case 2: if (length > 100) { length = length - 10; extracted(g); } else { state = 0; } break; case 3: int m = 1; //抓取后坐标都要开始改变 if (length > 100) { length = length - 10; extracted(g); for (Object gold : this.frame.goldlist) { //抓取返回 if (gold.flag) { m = gold.m; gold.x = endx - gold.width / 2; gold.y = endy; if (length <= 100) { gold.x = -150; gold.y = -150; //加分 Bg.count += gold.count; gold.flag = false; Bg.waterflag = false; state = 0; } if (Bg.waterflag) { if (gold.type == 1) { //降低金块的质量,其实是更新了刷新的频率 m = 1; } if (gold.type == 2) { gold.x = -150; gold.y = -150; gold.flag = false; Bg.waterflag = false; // Bg.shoukaoflag = false; state = 2; } } } } } Thread.sleep(m); break; } } private void extracted(Graphics g) { //线长度的改变通过终点坐标的改变而改变 /*图片的位置改变是通过图片X,Y坐标的改变而改变的,而图片随着线走则是 因为图片X,Y坐标与线的endX,endY相等,而线的终点坐标是一直在改变的*/ endx = (int) (x + length * Math.cos(n * Math.PI)); endy = (int) (y + length * Math.sin(n * Math.PI)); g.setColor(Color.ORANGE); g.drawLine(x - 1, y, endx - 1, endy); g.drawLine(x, y, endx, endy); g.drawLine(x + 1, y, endx + 1, endy); g.drawImage(hook, endx - 36, endy - 25, null, null); } //重置线的元素 void reline() { n = 0; length = 100; } }
Miner()
package com.sxt; import java.awt.*; public class MIner { int x = 310; int endx=0; Image peo = Toolkit.getDefaultToolkit().getImage("images/peo.png"); // GameWin frame; // MIner(GameWin frame){ // this.frame=frame; // } public void paint(Graphics g) { if (x >= 200) { endx += x; } else if (x <= 568) { endx -= x; } //g.drawImage(peo,x,50,null); } }
Object()
package com.sxt; import java.awt.*; public class Object { //金块,石头的父类 有所需的基本对象 //坐标 int x; int y; //宽高 int width; int height; //能否移动 boolean flag; //质量 int m; //积分 int count; //类型 1是金块 2是石头 int type; //图片 Image img; void paintself(Graphics g){ g.drawImage(img,x,y,null); } public int getWidth() { return width; } //获取矩形 /*在Java中,Rectangle 是一个二维图形,表示一个没有边框的矩形区域, 只包含其四个顶点的坐标信息。Rectangle 类是Javaawt包的一部分, 通常用于图形用户界面(GUI)编程中处理矩形区域,如图像处理、窗口布局等。*/ /*Rectangle 类提供了一系列方法,用于获取和设置矩形的位置和大小(宽度和高度) ,以及用于检测其他矩形是否与之相交或相等。例如,Rectangle 类中的 x 属性 表示矩形的左上角的x坐标,y 属性表示矩形的左上角的y坐标,width 属性表示矩 形的宽度,height 属性表示矩形的高度。*/ public Rectangle getrec(){ return new Rectangle(x,y,width,height); } }
Rock()
package com.sxt; import java.awt.*; public class Rock extends Object{ Rock(){ this.x=(int)(Math.random()*700) ; this.y=(int) (Math.random()*500+300) ; this.width=68; this.height=63; //默认均为false 不能被移动 this.flag=false; this.m=150; this.count=-2; this.type=2; this.img= Toolkit.getDefaultToolkit().getImage("images/将军.png"); } }