java 图形与动画_如何优化java动画编程中的显示效果

2023-11-10

展开全部

Java动画编62616964757a686964616fe4b893e5b19e31333264623234程有多种实现方法,但它们实现的基本原理是一样的,即在屏幕上画出一系列的帧来造成运动的感觉。Java多线程技术是Java动画编程中普遍运用的技术,它在控制动画程序的流程和动画的显示效果方面起着重要的作用。Java动画编程中的动画闪烁和图像残缺不全等现象,是Java程序员经常遇到的问题。本文以作者应用实例程序为基础,阐述如何运用多线程、重载Update、双缓冲和图像跟踪等技巧来解决这类问题,以达到动画显示的最佳效果。

Java多线程技术

Java多线程技术简介

目前,线程(Thread)已经为许多操作系统和应用开发系统所采用。线程是程序的单个控制流,具有顺序程序的特点。但是,线程不是一个程序,它仅仅是程序的一个执行序列。线程具有很强的并发功能,在同一时刻可以有多个线程同时处于执行状态。线程是动态的,具有一定的生命周期,分别经历从创建、执行、阻塞、直到消亡的过程。Java语言对多线程编程的支持有两种实现方法:一种是直接继承Thread类,另一种是实现Runnable接口。Thread类提供了对线程的控制方法,如start(),stop(),run()、suspend()、resume()和sleep()等方法,它们可以对线程的状态进行控制。

动画线程的设计与实现

为了每秒中多次更新屏幕,必须创建一个线程来实现动画的循环,这个循环要跟踪当前帧并响应周期性的屏幕更新要求。许多Java初学者容易犯的一个错误是将动画循环放在paint()中,这样占据了主AWT线程,而主线程将负责所有的绘图和事件处理。因此,应该生成一个独立的动画线程来完成图像的显示和更新。例如,在一个Applet框架下,当Applet启动(Start)时,生成一个动画线程;在Applet停止(stop)时,终止该动画线程以释放它所占用的CPU资源。下列程序代码(简称“C1”代码)是该动画线程的具体实现:

public void start() {

if(animatorThread==null) {

animatorThread=new Thread(this);

//开始动画线程

animatorThread.start();

}

}

public void stop(){

//停止动画线程

animatorThread=null;

}

上面终止动画线程的时候,并不是调用该动画线程的stop()方法,而是设置该动画线程为null。因为如果直接调用线程的stop()方法会强制线程终止所有的执行工作,有时会带来不好的结果。设置该动画线程为null,则在run()方法中,由于不满足循环条件,线程会自然退出。这样,也进一步优化了该动画程序。

重载update()和双缓冲技术消除闪烁

在Java中,动画发生闪烁有两个原因:一个是由于在显示下一帧画面的时候,调用了repaint()方法;而repaint()方法被调用时,要清除整个背景,然后才调用paint()方法显示画面。这样,在清除背景和绘制图像的短暂时间间隔内被用户看见的就是闪烁。另一个是由于paint()方法要进行复杂的计算,绘制每一帧花费的时间太长,图像中的各个像素值不能同时得到,使得动画的生成频率低于显示器的刷新频率,从而造成闪烁。

下面两种方法可以明显地消除或减弱闪烁。

重载update()方法

当AWT接收到一个Applet的重绘请求时,它就调用Applet的update()方法。缺省情况下,update()方法清除Applet的背景,然后调用paint()方法。重载update()方法就可以将以前在paint()方法中的绘图代码包含在update()方法中,从而避免每次重绘时将整个区域清除。既然背景不再自动清除,Java程序员需要自己在update()中完成。

双缓冲技术

另一种消除帧之间闪烁的方法是使用双缓冲技术,它在许多动画Applet中被使用。主要原理是创建一幅后台图像,将每一帧画入图像,然后调用drawImage()方法将整个后台图像一次画到屏幕上去。这种方法的优点在于大部分绘制是离屏的。将离屏图像一次绘至屏幕上,比直接在屏幕上绘制要有效得多。在创建后台图像前,首先要通过调用createImage()方法生成合适的后台缓冲区,然后获得在缓冲区做图的环境(即Graphics类对象)。

下列实例程序代码(简称“C2”代码)就是这两种方法的结合使用,双缓冲技术在重载update()方法中实现。其中,offImage是Image类的对象,offGraphics是Graphics类的对象,这两个类对象是实现双缓冲技术的关键。相关代码如下:

public void paint(Graphics g){

update(g);

}

public void update(Graphics g){

Dimension d=getSize();

//如果后台图像不存在,就创建一个后台图像

if((offGraphics==null)||(d.width!=offDimension.width)

||(d.height!=offDimension.height)) {

offDimension=d;

offImage=createImage(d.width,d.height);

offGraphics=offImage.getGraphics();

}

//擦除上一帧

offGraphics.setColor(getBackground());

offGraphics.fillRect(0,0,d.width,d.height);

offGraphics.setColor(Color.black);

//将当前的帧输出到指定的image中

for(int i=0 ; i<10 ; i++){

offGraphics.drawImage(images[i],frameNumber*5%(d.width/2)

,i*d.height/10,this);

}

//输出指定的后台图像

g.drawImage(offImage,frameNumber*5%(d.width/2),0,this);

}

双缓冲技术可以使动画平滑,但有一个缺点,要分配一个后台图像的缓冲,如果图像相当大,这将占用很大一块内存。

图像跟踪与程序的逐步完善

图像跟踪

当动画线程刚刚启动的时候,由于没有全部载入图像,屏幕上显示的画面经常是残缺不全的。这时可以使用MediaTracker或ImageOberver类对象进行图像跟踪,待图像全部载入后,再调用drawImage()方法将图像输出到屏幕上去。DrawImage()方法的第四个参数正是ImageObserver类对象,所以可以用ImageObserver类对象进行图像跟踪。在实际应用Applet程序的init()方法中实现图像跟踪,相当于在动画线程的DrawImage()方法调用以前就画了一次图像,因为动画线程的初始化过程,即init()方法是先被调用的。下列代码(简称“C3”代码)展示了init()方法使用MediaTracker类对象来实现跟踪图像的载入,代码如下:

public void init(){

tracker=new MidiaTracker(this);

for(int i=1;i<=10;i++){

image[i-1]=getImage(getCodeBase(),"image"+i+".gif");

//用MediaTracker类对象的addImage()方法跟踪图像的载入

tracker.addImage(images[i-1],0);

}

......

}

程序的进一步完善

在“C2”代码的重载update()方法中加入下列if语句,从而对MediaTracker类对象的图像跟踪方法做出判断,if语句如下:

if(!tracker.checkAll()){

//如果图像还没有装载完毕,则仅清除背景,同时输出一个状态

g.clearRect(0,0,d.width,d.height);

g.drawString("Please wait...",0,d.height/2);

return;

}

在“C1”代码的stop()方法中加入两行代码,用以释放由双缓冲技术所占用的内存资源,这时stop()方法改为:

public void stop(){

//停止动画线程

animatorThread=null;

//释放用于双缓冲的内存资源

offGraphics=null;

offImage=null;

}

程序修改到此,还有一个小问题,就是动画线程启动后,第一幅图像有时仍有残留痕迹,而不是随着图像的更新而完全擦除掉。如果想解决此问题,只要将“C2”代码中最后的for()循环和g.drawImage()方法改为如下代码就可以了。

for(int i=0;i<10;i++){

offGraphics.drawImage(images[frameNumber%10],

,frameNumber*5%(d.width),i*d.height/10,this);

}

g.drawImage(offImage,0,0,this);

保持恒定的帧速度

为了使用户观看动画时没有闪烁感,至少需要达到每秒12帧的速度。更高的帧速度会产生更平滑的动画。通常,在动画显示的每两帧之间,调用线程的sleep()方法休眠一个固定的

本回答由电脑网络分类达人 崔良飞推荐

2Q==

已赞过

已踩过<

你对这个回答的评价是?

评论

收起

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java 图形与动画_如何优化java动画编程中的显示效果 的相关文章

  • 2024届暑期实习实录(阿里云大数据研发平台)

    1 项目介绍 介绍一下你觉得有挑战的项目 1 项目的痛点需求 配置变更的痛点 你做的目的是什么 思考方向 业务背景 用户需求 产品发展 产品现有局限问题 2 项目 技术 的难点设计 思考方向 业务抽象 技术调研 架构梳理 3 有无涉及多线程
  • 使用IDEA创建SpringBoot项目

    参考 慕课网 廖师兄 两小时学会Springboot http www imooc com learn 767 1 打开IDEA 创建新项目 选择Spring Initializr 2 输入Artifact 3 勾选Web 4 点击fini
  • SpringFramework事件与监听机制(事件)

    SpringBoot版本 2 0 2 RELEASE SpringFramework版本 RELEASE 文章目录 SpringFramework事件与监听机制 SpringFramework的事件 SpringFramework与Spri
  • 爬取地铁站数据,计算两点距离

    爬取地铁站数据 计算两点距离 爬取地铁站数据代码 计算两点距离 效果图 爬取地铁站数据代码 import json import requests from bs4 import BeautifulSoup headers user age
  • [网络安全自学篇] 八十三.WHUCTF之CSS注入、越权、csrf-token窃取及XSS总结

    这是作者网络安全自学教程系列 主要是关于安全工具和实践操作的在线笔记 特分享出来与博友们学习 希望您喜欢 一起进步 前文分享了WHUCTF隐写和逆向题目 包括文字解密 图片解密 佛语解码 冰蝎流量分析 逆向分析 这篇文章将详细讲解一道CSS
  • D3D9Texture::_loadNormTex

    D3D9Texture loadNormTex D3D9Texture loadImpl
  • 消息中间件---RabbitMQ

    目录 1 消息队列 1 1 MQ相关概念 1 1 1 什么是MQ 1 1 2 MQ的功能 1 2 RabbitMQ 1 2 1 概念 1 2 2 四大核心概念 1 2 3 RabbitMQ核心部分 1 2 4 名词介绍 2 Work Que
  • B. Permutation

    Problem B Codeforces include
  • pandas中对列进行上下平移(shift)

    在利用Python进行数据操作时 有时需要对数据某列数据进行上下平移 比如对某一列进行错位加减 pandas里的groupby和shift两个函数就能轻松实现上述操作 df pd DataFrame name a a a b b c val
  • 新系统如何确定性能测试目标

    前提 新系统上线没有明确数字对比 性能需求非可度量 完成目标 1 服务器的某些资源已耗尽 如CPU 内存 句柄 数据库存在大量slow query 2 需求证明系统是可水平扩展的 即增加服务器配置系统TPS 吞吐量 能上去
  • 回忆,这一年(华师918血泪贴)

    回忆 这一年 华师918血泪贴 考研前夕 回想一年前 当时这个时候我应该刚通过了部门的实习答辩 拿了不错的评分 不出意外就等着签三方了 打算骑牛找马看看秋招的机会 但是双非出身的我 一直希望摆脱那种囚笼困境 需要付出比常人更多才能得到人家脱
  • 【五一创作】跑alpaca-lora语言模型的常见问题(心得)

    训练部署alpaca lora语言模型常见问题 Alpaca Lora是一个开源的自然语言处理框架 使用深度学习技术构建了一个端到端的语言模型 在训练和部署alpaca lora语言模型时 可能会遇到一些常见问题 本文将介绍一些这些问题及其
  • 计算机应用基础绩点3.0,学分绩点和期末考说明(华师).doc

    学分绩点和期末考说明 华师 doc 由会员分享 提供在线免费全文阅读可下载 此文档格式为doc 更多相关 学分绩点和期末考说明 华师 doc 文档请在天天文库搜索 1 关于学分绩点的一些说明首先 我们先来了解下几个概念吧1 学分 是用于计算
  • 【CANN训练营】Ascend目标检测与识别-定制自己的AI应用

    参考 https gitee com ascend samples tree master cplusplus level3 application 1 cv detect and classify 1 准备工作 cd samples cp
  • python画易烊千玺_Python02

    class A object def init self 私有 在变量名称前加上 私有 不可继承 不可在外部调用 但是可以在内部调用 self a 1000 约定使用 来表示私有 self def B self print self a A
  • python(数据分析)第4天:绘制网格

    plt grid import matplotlib pyplot as plt import random import matplotlib from matplotlib import cycler from matplotlib f
  • 解决ssh_exchange_identification: read: Connection reset by peer

    解决ssh exchange identification read Connection reset by peer linux远程免密登陆出现上述报错 1 先在远程机器上 vi etc hosts allow 在里面写入 允许所有ip连
  • Pyspark的dataframe写入hive表

    文章最前 我是Octopus 这个名字来源于我的中文名 章鱼 我热爱编程 热爱算法 热爱开源 所有源码在我的个人github 这博客是记录我学习的点点滴滴 如果您对 Python Java AI 算法有兴趣 可以关注我的动态 一起学习 共同
  • 第八章,索引的创建与设计原则

    第八章 索引的创建与设计原则 1 索引的声明与使用 1 1 索引的分类 SQL的索引包括普通索引 唯一性索引 全文索引 单列索引 多列索引和空间索引等 功能逻辑上说 索引主要有 4 种 分别是普通索引 唯一索引 主键索引 全文索引 按物理实

随机推荐

  • 面试题-Java集合、IO

    一 Java集合 HashMap的内部结构 扩容 为什么是2的幂次方 https www cnblogs com chengxiao p 6059914 html HashMap的实现原理 http www importnew com 27
  • 三个空饮料瓶可以换一瓶饮料,给你1箱(50瓶)饮料,你能喝多少瓶饮料?

    突然想起来了一道小学生的数学题 三个空饮料瓶可以换一瓶饮料 给你1箱 50瓶 饮料 你能喝多少瓶饮料 哈哈 于是写了一段代码 不知道还有没有高人了指点下 本人小菜鸟一只 function demo num kong test num2 nu
  • 第三章部分作业重新调试结果(第五周)

    求 百钱百鸡 问题 鸡翁一值钱五 鸡母 一值钱三 鸡雏三值钱一 百钱买百鸡 问鸡翁 鸡母 鸡雏各几何 设买了x只鸡翁 y只鸡目 z只鸡雏 则有 x y z 100 5 x 3 y 1 3 z 100 15 x 9 y z 300 inclu
  • 变分贝叶斯

    Variational Bayesian inference 参考文献 徐亦达老师变分推断课件 A tutorial on variational Bayesian inference 白板推导指数族分布 白板推导变分推断 Log like
  • 实测最像ChatGPT的中文产品:能解释三体、懂弱智吧的梗,内测开启人人都能试!...

    明敏 发自 凹非寺量子位 公众号 QbitAI 最像ChatGPT的中文产品 出现了 昨晚 一个名叫Inspo的生成式对话AI 刚刚在 民间 开启内测 马上引发不小反响 体验过的博主表示 1分钟搞定3份策划 工作5年没它能写 有人自己上手试
  • IP数据报检验和计算

    在进行计算之前先补充一下基础知识 一 原码 反码和补码 原码 原码是计算机机器数中最简单的一种形式 数值位就是真值的绝对值 符号位位 0 时表示正数 符号位为 1 时表示负数 原码又称带符号的绝对值 为了方便整数和小数区别 整数的符号位与数
  • Android 实现按钮 跳转到某网页

    这个是我在刚开始学习Android的时候 我同学要做一个手机端的控制 他说我的东西都用 java web写好了 你只要给我写一个跳转按钮即可 其实很简单只是简单地按钮点击事件和Intent跳转 但是毕竟是第一次帮别人做东西还觉得挺有意义的
  • YouTube深度学习视频推荐系统

    YouTube推荐系统架构 YouTube推荐系统架构是经典的两级模型 召回 精排模型 第一级用候选集生成模型完成候选视频的快速筛选 在这一步 候选视频集合由百万量级降至几百量级 这相当于经典推荐系统架构中的召回层 第二级用排序模型 Ran
  • 【mac】iTerm2中ssh保持连接不断开

    1 概述 转载 http bluebiu com blog iterm2 ssh session idle html 一 一个iTerm2蛋疼的问题 最近基友搞了台mbp 在装一些常用app时 跟我交流到一个情况 用iTerm2进行ssh时
  • 树莓派串口调试助手minicom的简单使用

    安装 minicom sudo apt get install minicom 启动minicom minicom D dev ttyAMA0 minicom 默认波特率为115200 D 代表端口 b 设置波特率参数 例如 b 9600
  • 网络调试工具TCP/UDP socket的使用

    TCP UDP socket调试工具的使用 可以在想服务器发送命令 或者查看服务器返回的数据 打开界面后选择左边客户端还是服务端 使用TCP还是udp 点击创建相应的模拟环境
  • docker 容器满了常用处理方法

    docker 容器满了常用处理方法 1 运行 df h 查看剩余磁盘占用情况 2 进入到docker目录 cd var lib docker 3 运行du h max depth 1 检索文件的最大深度1 即只检索汇总计算当前目录下的文件
  • Oracle用function生成UUID方法

    CREATE OR REPLACE FUNCTION get uuidRETURN VARCHARISguid VARCHAR 50 BEGINguid lower RAWTOHEX sys guid RETURNsubstr guid 1
  • 移动端/帆软移动报表调用拨打电话

    HTML a标签的href 属性 tel 点击可以直接拨打电话 移动端 a href 13622178579 a 把某个单元格 形态赋值为 公式形态 a href style color 508ef9 a ps F1列存储电话号码
  • 自动化运维脚本语言shell练习(2)

    1 编写脚本for1 sh 使用for循环创建20账户 账户名前缀由用户从键盘输入 账户初始密码由用户输入 例如 test1 test2 test3 test10 2 编写脚本for2 sh 使用for循环 通过ping命令测试网段的主机连
  • 程序员,你今年读了几本书?

    调查显示 国人去年平均阅读 4 本书 程序员不应该只有 代码大全 4 23 世界读书日 GitChat 码农读书日 活动最后 1 天 用抄底的价格 抢你要的技术书 GitChat 特意筛选畅销度最高的品种 给予超大力度的优惠 深度学习入门
  • 如何关闭FileZilla Server开机自启

    FileZilla Server开机自启 有些软件开机自启 个人感觉是比较反感的 像流氓一样 如何关闭 选中此电脑 gt 右键单击 gt 点击管理 找到之后FileZilla Server FTP server之后右键点击属性 改成手动启动
  • 重t2加权是什么意思_王者荣耀中说的T0、T1,到底是啥意思?这下总算清楚了

    王者荣耀这款游戏可以说是相当火了 玩这款游戏的人应该有3亿左右了吧 而在这么庞大的人群中 也孕育出一种独特的语言 甚至有些老玩家也是没有听说过得 就比如今天我们要聊的 在王者荣耀中说的TO T1到底是什么意思呢 今天就给大家科普一下 TO英
  • testflight测试的直播软件,怎么使用 TestFlight 测试 App,注意些什么?

    原标题 怎么使用 TestFlight 测试 App 注意些什么 TF签名是什么 TF签名全称为TestFlight 实际为一个苹果官方研发的一款提供给ios开发者内测的一个工具类App 这款app可以在苹果商店搜索到 用户直接搜索打开Te
  • java 图形与动画_如何优化java动画编程中的显示效果

    展开全部 Java动画编62616964757a686964616fe4b893e5b19e31333264623234程有多种实现方法 但它们实现的基本原理是一样的 即在屏幕上画出一系列的帧来造成运动的感觉 Java多线程技术是Java动