JAVA小项目之摇奖机
功能:
- 点击”摇杆“开始;
- 两种结束滚动方式,A:点击”摇杆“ B:分别点击 对应结果框的按钮;
- 实现最后减速停下来效果,模拟真实摇奖机。
知识点: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小项目之摇奖机的更多相关文章
- Java小项目--坦克大战(version1.0)
Java小项目--坦克大战<TankWar1.0> 这个小项目主要是练习j2se的基础内容和面向对象的思想.项目实现了基本的简单功能,我方一辆坦克,用上下左右键控制移动方向,按F键为发射炮 ...
- Java学习笔记三十:Java小项目之租车系统
Java小项目之租车系统 一:项目背景介绍: 根据所学知识,编写一个控制台版的“呱呱租车系统” 功能: 1.展示所有可租车辆: 2.选择车型.租车量: 3.展示租车清单,包含:总金额.总载货量以及其车 ...
- Java小项目之:五子棋,你下棋下得过电脑吗?
Java小项目之:五子棋,你下棋下得过电脑吗? Java五子棋功能要求: 1.创建窗口和设计一个棋盘界面 2.实现鼠标点击,棋子出现,黑白棋轮流下 3.能够判断五子相连输赢 4.添加重新开始,悔棋,退 ...
- java小项目之:植物大战僵尸,这个僵尸有点冷!内附素材源码
Java小项目之:植物大战僵尸! <植物大战僵尸>是由PopCap Games开发的一款益智策略类单机游戏,于2009年5月5日发售,这款游戏可谓是无人不知无人不晓. 在我身边,上到40岁 ...
- Java小项目之:教你做个聊天系统!
Java小项目之:聊天系统 今天给大家带来的java练手小项目是一个简单的聊天室,界面简单,操作不难. 分为注册系统,登录系统和聊天系统三部分,很适合java小白练手. 完整的源码和素材请关注并私信我 ...
- java小项目之:扫雷,这游戏没有你想的那么简单!
扫雷 我之前分享的小项目和小游戏,电影购票.坦克大战.捕鱼达人.贪吃蛇等,虽然已经是耳熟能详人尽皆知的项目和游戏,但是保不齐真的有人没接触过. 今天分享的这个项目,我不相信没人接触过(仅限80后-00 ...
- java小项目之:抽奖系统!java初学者必备(内附源码)
[Java]Java摇奖源码,Java抽奖源码,Java随机抽奖源码 任务描述 本次任务要求为某商场开发一套幸运抽奖系统,客户必须首先注册成为该商场会员,会员登录成功后,就可以参加抽奖活动了.注册 用 ...
- java小项目——抽奖系统
来了来了!这不又到考试周了吗!愁人,又得复习,复习,复习!这段时间每天都在复习线代和高数!(说是复习,说实话其实是在预习,啊哈哈哈哈哈),得有一段时间都没有学到新的知识了,代码感觉都生疏了,惆怅.博客 ...
- java小项目之:象棋,羡慕你们有对象的!
象棋,是我国传统棋类益智游戏,在中国有着悠久的历史,属于二人对抗性游戏的一种,由于用具简单,趣味性强,成为流行极为广泛的棋艺活动.中国象棋是中国棋文化也是中华民族的文化瑰宝. 象棋还有很多口诀,这是最 ...
随机推荐
- 10_RHEL安装搜狗输入法
首先需要安装相关源 1.加入EPEL源 EPEL7几乎是必备的源: $ sudo yum install epel-release 2.添加mosquito-myrepo源 mosquito-myre ...
- 小议window.event || ev
以前做项目时就遇到这个问题,但是太懒没有总结,今天来总结一下 onclick="alert(arguments.callee)"这句随便放在某个元素中,试试不同的浏览器会有弹出什么 ...
- js学习笔记之:键盘应用
为了方便用户操作,可以为用户设置(或者屏蔽)功能键,代替使用频率比较高的操作.本次,将学习一下基本的功能键使用方法.键盘和焦点使用.屏蔽按键等知识点,以及一些相关示例: 1 设置按键功能: 功能键主要 ...
- [Git]Git安装
1.什么是Git Git是一个分布式版本控制/软件配置管理软件, git是用于Linux内核开发的版本控制工具, 与CVS.Subversion一类的集中式版本控制工具不同,它采用了分布式版本库的作法 ...
- 0627 CMD运行php代码
打开cmd: 如何在这里面运行php代码 1.调整环境变量:右击电脑->属性->高级系统设置->环境变量 2.新建环境变量: 上部分的用户变量----- 变量名:PHP_HOME ...
- Win7 64位 php-5.5.13+Apache 2.4.9+mysql-5.6.19 配置
一 :准备阶段 1:php php-5.5.13下载链接:http://windows.php.net/downloads/releases/php-5.5.13-Win32-VC11-x64.zip ...
- php防止SQL注入详解及防范
SQL 注入是PHP应用中最常见的漏洞之一.事实上令人惊奇的是,开发者要同时犯两个错误才会引发一个SQL注入漏洞一个是没有对输入的数据进行过滤(过滤输入),还有一个是没有对发送到数据库的数据进行转义( ...
- js监控键盘大小写事件
JavaScript键盘事件侦听 在使用JavaScript做WEB键盘事件侦听捕获时,主要采用onkeypress.onkeydown.onkeyup三个事件进行出来.该三个事 件的执行顺序如 ...
- python序列化之pickle
来自引用: 1.什么东西能用pickle模块存储? 所有Python支持的 原生类型 : 布尔, 整数, 浮点数, 复数, 字符串, bytes(字节串)对象, 字节数组, 以及 None. 由任何原 ...
- 之前C#代码的重新设计
/* 我用python重构了一把这个代码 大家的反应似乎是过度设计了 好吧,我决定不那么激进,采用更中庸一些的重构 我也有些疑惑: 是否如果重构后的代码比重构前要多,就算过度了呢? */ void m ...