功能:

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

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

效果图:

   

  • 窗口类
 package com.gxlee.lhj;

 import java.awt.Color;
 import java.awt.Container;
 import java.awt.Graphics;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.awt.image.BufferedImage;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Random;

 import javax.swing.JFrame;
 import javax.swing.JPanel;

 @SuppressWarnings("serial")
 public class MainFrame extends JFrame {

     private List<Fruit> fruits;
     private boolean running = false;
     private Random r = new Random();
     private String backimg = "bg.png";
     private int fruitOver = 0;

     public MainFrame() {
         // 构造函数
         this.setTitle("摇奖机  v1.0");
         this.setSize(Utils.WIDTH, Utils.HEIGHT);
         this.setDefaultCloseOperation(EXIT_ON_CLOSE);
         this.setLocationRelativeTo(null);
         this.setResizable(false);

         Container c = getContentPane();
         MyPanel zb = new MyPanel();
         c.add(zb);
         fruits = new ArrayList<Fruit>();
         // 添加3个
         for (int i = 0; i < 3; i++) {
             Fruit fruit = new Fruit();
             fruit.setIndex(r.nextInt(6));
             fruits.add(fruit);
         }
         this.addMouseListener(new MousClick());
         this.setVisible(true);

     }

     public class MyPanel extends JPanel {

         protected void paintComponent(Graphics g) {
             g.fillRect(0, 0, Utils.WIDTH, Utils.HEIGHT);
             g.drawImage(Utils.images.get(backimg), 0, 0, Utils.WIDTH,
                     Utils.HEIGHT, this);
             BufferedImage image = Utils.images.get("fruit.jpg");
             BufferedImage subImg = null;

             // 画水果
             if (!running && fruitOver == 3) {
                 int i = 0;
                 for (Fruit f : fruits) {
                     subImg = image.getSubimage(f.getIndex() * 94, 0, 94, 102);
                     g.drawImage(subImg, 84 + (i++ * (67 + 9)), 313, 67, 100,
                             this);
                 }
             } else {
                 int i = 0;
                 for (Fruit f : fruits) {
                     int index = f.getIndex();
                     int offset = f.getOffset();
                     int nextIndex = 0;
                     // 如果offset == 0 的话 或者已经移动到 就只需要一张
                     if (!f.isAlive() || offset == 0) {
                         subImg = image.getSubimage(f.getIndex() * 94, 0, 94,
                                 102);
                         g.drawImage(subImg, 84 + ((i) * (67 + 9)), 313, 67, 100,
                                 this);
                         i+=1;
                         continue;
                     }
                     // 得到下一张图的index
                     nextIndex = (index == 5) ? 0 : index + 1;
                     // 画第一张
                     subImg = image.getSubimage(index * 94, 0, 94, 102 - offset);
                     g.drawImage(subImg, 84 + (i * (67 + 9)), 313 + offset, 67,
                             100 - offset, this);
                     // 画第二张
                     subImg = image.getSubimage(nextIndex * 94, 102 - offset,
                             94, offset);// 取得子图标
                     g.drawImage(subImg, 84 + (i * (67 + 9)), 313, 67, offset,
                             this);
                     i+=1;
                 }
             }
             g.setColor(new Color(181, 36, 43));
             g.fillRect(84, 358, 220, 6);
         }
     }

     public class MousClick extends MouseAdapter {

         @Override
         public void mouseClicked(MouseEvent e) {
             int x = e.getX();
             int y = e.getY();
             //如果按的是开始摇杆
             if(x<=415 && x>=371){
                 if(y<=200 && y>=160){
                     running = true ^ running;
                     new ShowBackGroud().start();
                     if(running){
                         fruitOver = 0;
                         fruits.clear();
                         for (int i = 0; i < 3; i++) {
                             Fruit f = new Fruit();
                             f.setIndex(r.nextInt(6));
                             f.setRunning(true);
                             fruits.add(f);
                             new MyThread(f, 70 + i * 10).start();
                             f.setAlive(true);
                         }
                     }else{
                         for (Fruit f : fruits) {
                             f.setRunning(false);
                         }
                     }
                 }
                 return;
             }
             int index = -1;
             if(y<=495 && y>=480){
                 if(x>=60 && x<=90){
                     //第一个按钮
                      index = 0;
                 }else if(x>=106 && x<=140){
                     //第二个按钮
                      index = 1;
                 }else if(x>=153 && x<=182){
                     //第三个按钮
                     index = 2;
                 }
                 if(running && index >-1)
                     fruits.get(index).setRunning(false);
             }
         }
     }

     public static void main(String[] args) {
         new MainFrame();
     }

     public class MyThread extends Thread {
         public Fruit f;
         public int speed;//最后慢下来时候的初始速度
         public int sleep = 40;//休眠时长
         public int offset;//当传递一个速度是  要完成N张图片的正好播放完产生一个偏移位置
         public MyThread(Fruit f, int delay) {
             this.f = f;
             this.speed = delay;
             offset = getOffset(delay);

         }
         public int getOffset(int delay){
             int sum = 0;
             for(int i = 1;i<=delay;i++){
                 sum +=i;
             }
             return sum % 102;
         }
         @Override
         public void run() {
             while (f.isRunning()) {
                 f.setSpeed(90);// r.nextInt(70)+10 区别不大
                 try {
                     Thread.sleep(40);
                 } catch (InterruptedException e) {
                 }
                 repaint();
             }
             // 停止的时候
             //修正距离  从速度N开始减 速度每减1
             //70开始的话 能走 2485:2485%102 = 37
             // 80的话 3240%102= 78  90%4095%102=15
             f.setDistance(offset, true);//留一个像素
             int sum = 0;
             while (f.isAlive()) {
                 //缓慢下来的效果
                 f.setSpeed(speed);
                 sum += speed;
                 speed-- ;
                 try {
                     Thread.sleep(sleep+=3);
                 } catch (InterruptedException e) {
                 }
                 repaint();
             }
             synchronized (new Object()) {
                 fruitOver++;
             }
         }

     }

     public class ShowBackGroud extends Thread {

         @Override
         public void run() {
             backimg = "bg2.png";
             try {
                 Thread.sleep(500);
             } catch (InterruptedException e) {
             }
             backimg = "bg.png";
         }

     }

 }
  • 水果类
 package com.gxlee.lhj;

 public class Fruit {
     private int index = 0;
     private int nextIndex = 0;
     private int maxIndex = 5;
     private int width=94 ;//单个图片的宽度 并
     private int height = 102;//图片的高度  后面并没有用到 全部写死
     private int distance;
     private boolean alive = true;
     private boolean running ;
     private int speed;
     private int offset;
     public void setSpeed(int speed){
         if (speed<=0){
             speed = 0;
             alive = false;
         }
         this.speed = speed;
         setDisttance(distance+= speed);
     }

     public boolean isRunning() {
         return running;
     }

     public void setRunning(boolean running) {
         this.running = running;
     }

     public int getNextIndex() {
         return nextIndex;
     }
     public void setNextIndex(int nextIndex) {
         this.nextIndex = nextIndex;
     }
     public int getOffset() {
         return offset;
     }
     public void setOffset(int offset) {
         this.offset = offset;
     }

     public int getSpeed() {
         return speed;
     }
     public boolean isAlive() {
         return alive;
     }

     public void setAlive(boolean alive) {
         this.alive = alive;
     }

     public int getDistance() {
         return distance;
     }
     public void setDistance(int offset, boolean flag ) {
         int nextIndex = index==5?0:index+1;
         int dis = nextIndex*102+102-(offset);
         setDisttance(dis);
     }
     public void setDisttance(int distance){
         if(distance>=6*102){distance = distance % 102;}
         this.distance = distance;
         index = distance / 102;
         offset = distance % 102;
         nextIndex = (index == 5) ? 0 : index + 1;
     }

     public void setIndex(int index){
         this.index = index;
         distance = index*height;
     }

     public int getHeight(){
         return height;
     }
     public int getIndex() {
         return index;
     }

     public int getMaxIndex() {
         return maxIndex;
     }
     public void setMaxIndex(int maxIndex) {
         this.maxIndex = maxIndex;
     }
     public int getWidth() {
         return width;
     }

 }
  • 工具类
 package com.gxlee.lhj;

 import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;

 import javax.imageio.ImageIO;

 public class Utils {
     public static Map<String, BufferedImage> images = new HashMap<String,BufferedImage>();
     public static final int WIDTH = 440;
     public static final int HEIGHT =600;

     public static final int FRUIT_WIDTH = 94;
     public static final int FRUIT_HEIGHT = 102;

     static{
       File dir = new File("img");
       File[] files = dir.listFiles();
       for (File file:files) {
         try {
             BufferedImage image = ImageIO.read(file);
             images.put(file.getName(), image);
         } catch (IOException e) {
             //e.printStackTrace();
         }
     }
     }
 }

素材:

  • 主界面:

  • 水果:

JAVA小项目之摇奖机的更多相关文章

  1. Java小项目--坦克大战(version1.0)

    Java小项目--坦克大战<TankWar1.0> 这个小项目主要是练习j2se的基础内容和面向对象的思想.项目实现了基本的简单功能,我方一辆坦克,用上下左右键控制移动方向,按F键为发射炮 ...

  2. Java学习笔记三十:Java小项目之租车系统

    Java小项目之租车系统 一:项目背景介绍: 根据所学知识,编写一个控制台版的“呱呱租车系统” 功能: 1.展示所有可租车辆: 2.选择车型.租车量: 3.展示租车清单,包含:总金额.总载货量以及其车 ...

  3. Java小项目之:五子棋,你下棋下得过电脑吗?

    Java小项目之:五子棋,你下棋下得过电脑吗? Java五子棋功能要求: 1.创建窗口和设计一个棋盘界面 2.实现鼠标点击,棋子出现,黑白棋轮流下 3.能够判断五子相连输赢 4.添加重新开始,悔棋,退 ...

  4. java小项目之:植物大战僵尸,这个僵尸有点冷!内附素材源码

    Java小项目之:植物大战僵尸! <植物大战僵尸>是由PopCap Games开发的一款益智策略类单机游戏,于2009年5月5日发售,这款游戏可谓是无人不知无人不晓. 在我身边,上到40岁 ...

  5. Java小项目之:教你做个聊天系统!

    Java小项目之:聊天系统 今天给大家带来的java练手小项目是一个简单的聊天室,界面简单,操作不难. 分为注册系统,登录系统和聊天系统三部分,很适合java小白练手. 完整的源码和素材请关注并私信我 ...

  6. java小项目之:扫雷,这游戏没有你想的那么简单!

    扫雷 我之前分享的小项目和小游戏,电影购票.坦克大战.捕鱼达人.贪吃蛇等,虽然已经是耳熟能详人尽皆知的项目和游戏,但是保不齐真的有人没接触过. 今天分享的这个项目,我不相信没人接触过(仅限80后-00 ...

  7. java小项目之:抽奖系统!java初学者必备(内附源码)

    [Java]Java摇奖源码,Java抽奖源码,Java随机抽奖源码 任务描述 本次任务要求为某商场开发一套幸运抽奖系统,客户必须首先注册成为该商场会员,会员登录成功后,就可以参加抽奖活动了.注册 用 ...

  8. java小项目——抽奖系统

    来了来了!这不又到考试周了吗!愁人,又得复习,复习,复习!这段时间每天都在复习线代和高数!(说是复习,说实话其实是在预习,啊哈哈哈哈哈),得有一段时间都没有学到新的知识了,代码感觉都生疏了,惆怅.博客 ...

  9. java小项目之:象棋,羡慕你们有对象的!

    象棋,是我国传统棋类益智游戏,在中国有着悠久的历史,属于二人对抗性游戏的一种,由于用具简单,趣味性强,成为流行极为广泛的棋艺活动.中国象棋是中国棋文化也是中华民族的文化瑰宝. 象棋还有很多口诀,这是最 ...

随机推荐

  1. Eclipse中使用Maven创建Servlet3.0 Web 项目

    摘要 Apache Maven是一个优秀的项目构建和管理工具,许多开源项目都使用Maven进行构建.由于最近工作中要用到Maven,于是这里记录下在Eclipse中使用Maven插件创建一个基于Ser ...

  2. Linq介绍

    什么是LINQ? LINQ全称Language Integrated Query,中文翻译"语言集成查询".在.NET框架中,大致使用三大组件实现这个封装,分别 LINQ to O ...

  3. javascript权威指南学习笔记1

    打开这本书,进入到javascript的世界.以前都是看各种视频,感觉什么收获也没有,反而弄得脑袋混乱,希望能够按照这本书的节奏掌握javascript这门语言,为我的前端学习打下基础. 学习前准备: ...

  4. [标签] action的使用

    1.描述 This tag enables developers to call actions directly from a JSP page by specifying the action n ...

  5. 30 个 php 操作 redis 常用方法代码例子

    这篇文章主要介绍了 30 个 php 操作 redis 常用方法代码例子 , 本文其实不止 30 个方法 , 可以操作 string 类型. list 类型和 set 类型的数据 , 需要的朋友可以参 ...

  6. bzoj2066: [Poi2004]Gra

    Description 让我们考虑一个在m x 1 的板子上玩的游戏,板子被从1 到 m编号. 现在板子上有n 个棋子, 每个都严格占据板子上的一个格子. 没有一个棋子占据格子m. 每个单独的移动遵循 ...

  7. HTML CSS简介与图片映射

    1. CSS 入门 内联样式:在 HTML 元素中使用 “style” 属性,需要将表现与内容混在一起: 内部样式表:在 HTML 文档头部 <head> 区域使用 <style&g ...

  8. 《FPGA零基础入门到精通视频教程》-第001b讲软件的破解

    高清视频和配套讲义这里下载 http://www.fpgaw.com/thread-68128-1-1.html 优酷视频地址,不是很清楚

  9. JMS集群部署问题 java.net.ConnectException: Connection refused; No available router to destination

    1:本地spring配置如下 <!-- JndiTemplate --> <bean id="jndiTpl" class="org.springfra ...

  10. 【HDOJ】5057 Argestes and Sequence

    树状数组,其实很简单.只是MLE. #include <iostream> #include <cstdio> #include <cstring> using n ...