JAVA小项目之摇奖机

  功能:

  1. 点击”摇杆“开始;
  2. 两种结束滚动方式,A:点击”摇杆“ B:分别点击 对应结果框的按钮;
  3. 实现最后减速停下来效果,模拟真实摇奖机。

  知识点:A.线程的控制,B.图片轮播原理

效果图:

   

  • 窗口类
  1 package com.gxlee.lhj;
  2 
  3 import java.awt.Color;
  4 import java.awt.Container;
  5 import java.awt.Graphics;
  6 import java.awt.event.MouseAdapter;
  7 import java.awt.event.MouseEvent;
  8 import java.awt.image.BufferedImage;
  9 import java.util.ArrayList;
 10 import java.util.List;
 11 import java.util.Random;
 12 
 13 import javax.swing.JFrame;
 14 import javax.swing.JPanel;
 15 
 16 @SuppressWarnings("serial")
 17 public class MainFrame extends JFrame {
 18 
 19     private List<Fruit> fruits;
 20     private boolean running = false;
 21     private Random r = new Random();
 22     private String backimg = "bg.png";
 23     private int fruitOver = 0;
 24 
 25     public MainFrame() {
 26         // 构造函数
 27         this.setTitle("摇奖机  v1.0");
 28         this.setSize(Utils.WIDTH, Utils.HEIGHT);
 29         this.setDefaultCloseOperation(EXIT_ON_CLOSE);
 30         this.setLocationRelativeTo(null);
 31         this.setResizable(false);
 32 
 33         Container c = getContentPane();
 34         MyPanel zb = new MyPanel();
 35         c.add(zb);
 36         fruits = new ArrayList<Fruit>();
 37         // 添加3个
 38         for (int i = 0; i < 3; i++) {
 39             Fruit fruit = new Fruit();
 40             fruit.setIndex(r.nextInt(6));
 41             fruits.add(fruit);
 42         }
 43         this.addMouseListener(new MousClick());
 44         this.setVisible(true);
 45 
 46     }
 47 
 48     public class MyPanel extends JPanel {
 49 
 50         protected void paintComponent(Graphics g) {
 51             g.fillRect(0, 0, Utils.WIDTH, Utils.HEIGHT);
 52             g.drawImage(Utils.images.get(backimg), 0, 0, Utils.WIDTH,
 53                     Utils.HEIGHT, this);
 54             BufferedImage image = Utils.images.get("fruit.jpg");
 55             BufferedImage subImg = null;
 56 
 57             // 画水果
 58             if (!running && fruitOver == 3) {
 59                 int i = 0;
 60                 for (Fruit f : fruits) {
 61                     subImg = image.getSubimage(f.getIndex() * 94, 0, 94, 102);
 62                     g.drawImage(subImg, 84 + (i++ * (67 + 9)), 313, 67, 100,
 63                             this);
 64                 }
 65             } else {
 66                 int i = 0;
 67                 for (Fruit f : fruits) {
 68                     int index = f.getIndex();
 69                     int offset = f.getOffset();
 70                     int nextIndex = 0;
 71                     // 如果offset == 0 的话 或者已经移动到 就只需要一张
 72                     if (!f.isAlive() || offset == 0) {
 73                         subImg = image.getSubimage(f.getIndex() * 94, 0, 94,
 74                                 102);
 75                         g.drawImage(subImg, 84 + ((i) * (67 + 9)), 313, 67, 100,
 76                                 this);
 77                         i+=1;
 78                         continue;
 79                     }
 80                     // 得到下一张图的index
 81                     nextIndex = (index == 5) ? 0 : index + 1;
 82                     // 画第一张
 83                     subImg = image.getSubimage(index * 94, 0, 94, 102 - offset);
 84                     g.drawImage(subImg, 84 + (i * (67 + 9)), 313 + offset, 67,
 85                             100 - offset, this);
 86                     // 画第二张
 87                     subImg = image.getSubimage(nextIndex * 94, 102 - offset,
 88                             94, offset);// 取得子图标
 89                     g.drawImage(subImg, 84 + (i * (67 + 9)), 313, 67, offset,
 90                             this);
 91                     i+=1;
 92                 }
 93             }
 94             g.setColor(new Color(181, 36, 43));
 95             g.fillRect(84, 358, 220, 6);
 96         }
 97     }
 98 
 99     public class MousClick extends MouseAdapter {
100 
101         @Override
102         public void mouseClicked(MouseEvent e) {
103             int x = e.getX();
104             int y = e.getY();
105             //如果按的是开始摇杆
106             if(x<=415 && x>=371){
107                 if(y<=200 && y>=160){
108                     running = true ^ running;
109                     new ShowBackGroud().start();
110                     if(running){
111                         fruitOver = 0;
112                         fruits.clear();
113                         for (int i = 0; i < 3; i++) {
114                             Fruit f = new Fruit();
115                             f.setIndex(r.nextInt(6));
116                             f.setRunning(true);
117                             fruits.add(f);
118                             new MyThread(f, 70 + i * 10).start();
119                             f.setAlive(true);
120                         }
121                     }else{
122                         for (Fruit f : fruits) {
123                             f.setRunning(false);
124                         }
125                     }
126                 }
127                 return;
128             }
129             int index = -1;
130             if(y<=495 && y>=480){
131                 if(x>=60 && x<=90){
132                     //第一个按钮
133                      index = 0;
134                 }else if(x>=106 && x<=140){
135                     //第二个按钮
136                      index = 1;
137                 }else if(x>=153 && x<=182){
138                     //第三个按钮
139                     index = 2;
140                 }
141                 if(running && index >-1)
142                     fruits.get(index).setRunning(false);
143             }
144         }
145     }
146 
147     public static void main(String[] args) {
148         new MainFrame();
149     }
150 
151     public class MyThread extends Thread {
152         public Fruit f;
153         public int speed;//最后慢下来时候的初始速度
154         public int sleep = 40;//休眠时长
155         public int offset;//当传递一个速度是  要完成N张图片的正好播放完产生一个偏移位置
156         public MyThread(Fruit f, int delay) {
157             this.f = f;
158             this.speed = delay;
159             offset = getOffset(delay);
160             
161         }
162         public int getOffset(int delay){
163             int sum = 0;
164             for(int i = 1;i<=delay;i++){
165                 sum +=i;
166             }
167             return sum % 102;
168         }
169         @Override
170         public void run() {
171             while (f.isRunning()) {
172                 f.setSpeed(90);// r.nextInt(70)+10 区别不大
173                 try {
174                     Thread.sleep(40);
175                 } catch (InterruptedException e) {
176                 }
177                 repaint();
178             }
179             // 停止的时候
180             //修正距离  从速度N开始减 速度每减1 
181             //70开始的话 能走 2485:2485%102 = 37
182             // 80的话 3240%102= 78  90%4095%102=15  
183             f.setDistance(offset, true);//留一个像素
184             int sum = 0;
185             while (f.isAlive()) {
186                 //缓慢下来的效果
187                 f.setSpeed(speed);
188                 sum += speed;
189                 speed-- ;
190                 try {
191                     Thread.sleep(sleep+=3);
192                 } catch (InterruptedException e) {
193                 }
194                 repaint();
195             }
196             synchronized (new Object()) {
197                 fruitOver++;
198             }
199         }
200 
201     }
202 
203     public class ShowBackGroud extends Thread {
204 
205         @Override
206         public void run() {
207             backimg = "bg2.png";
208             try {
209                 Thread.sleep(500);
210             } catch (InterruptedException e) {
211             }
212             backimg = "bg.png";
213         }
214 
215     }
216 
217 }
View Code
  • 水果类
 1 package com.gxlee.lhj;
 2 
 3 
 4 public class Fruit {
 5     private int index = 0;
 6     private int nextIndex = 0;
 7     private int maxIndex = 5;
 8     private int width=94 ;//单个图片的宽度 并
 9     private int height = 102;//图片的高度  后面并没有用到 全部写死
10     private int distance;
11     private boolean alive = true;
12     private boolean running ;
13     private int speed;
14     private int offset;
15     public void setSpeed(int speed){
16         if (speed<=0){
17             speed = 0;
18             alive = false;
19         }
20         this.speed = speed;
21         setDisttance(distance+= speed);
22     }
23     
24     public boolean isRunning() {
25         return running;
26     }
27 
28     public void setRunning(boolean running) {
29         this.running = running;
30     }
31 
32     public int getNextIndex() {
33         return nextIndex;
34     }
35     public void setNextIndex(int nextIndex) {
36         this.nextIndex = nextIndex;
37     }
38     public int getOffset() {
39         return offset;
40     }
41     public void setOffset(int offset) {
42         this.offset = offset;
43     }
44  
45     public int getSpeed() {
46         return speed;
47     }
48     public boolean isAlive() {
49         return alive;
50     }
51 
52     public void setAlive(boolean alive) {
53         this.alive = alive;
54     }
55 
56     public int getDistance() {
57         return distance;
58     }
59     public void setDistance(int offset, boolean flag ) {
60         int nextIndex = index==5?0:index+1;
61         int dis = nextIndex*102+102-(offset);
62         setDisttance(dis);
63     }
64     public void setDisttance(int distance){
65         if(distance>=6*102){distance = distance % 102;}
66         this.distance = distance; 
67         index = distance / 102;
68         offset = distance % 102;
69         nextIndex = (index == 5) ? 0 : index + 1;    
70     }
71 
72     public void setIndex(int index){
73         this.index = index;
74         distance = index*height;
75     }
76     
77     public int getHeight(){
78         return height;
79     }
80     public int getIndex() {
81         return index;
82     }
83 
84     public int getMaxIndex() {
85         return maxIndex;
86     }
87     public void setMaxIndex(int maxIndex) {
88         this.maxIndex = maxIndex;
89     }
90     public int getWidth() {
91         return width;
92     }
93     
94     
95     
96 }
View Code
  • 工具类
 1 package com.gxlee.lhj;
 2 
 3 import java.awt.image.BufferedImage;
 4 import java.io.File;
 5 import java.io.IOException;
 6 import java.util.HashMap;
 7 import java.util.Map;
 8 
 9 import javax.imageio.ImageIO;
10 
11 public class Utils {
12     public static Map<String, BufferedImage> images = new HashMap<String,BufferedImage>();
13     public static final int WIDTH = 440;
14     public static final int HEIGHT =600;
15     
16     public static final int FRUIT_WIDTH = 94;
17     public static final int FRUIT_HEIGHT = 102;
18     
19     
20     static{
21       File dir = new File("img");
22       File[] files = dir.listFiles();
23       for (File file:files) {
24         try {
25             BufferedImage image = ImageIO.read(file);
26             images.put(file.getName(), image);
27         } catch (IOException e) {
28             //e.printStackTrace();
29         }
30     }    
31     }
32 }
View Code

素材:

  • 主界面:

  • 水果:

转载于:https://www.cnblogs.com/Hfly/p/4770669.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值