📄 animatorapplet.java
字号:
import javax.swing.JApplet;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Graphics;
import java.awt.image.PixelGrabber;
import java.awt.image.MemoryImageSource;
import java.awt.Color;
public class AnimatorApplet extends JApplet implements Runnable{
boolean startMoved=false;
final int speedPixels=3; //路边树木及精灵的移动象素速度
final int speedDelay=200; //路边树木及精灵的移动延时
Image treeImage;
Image movedImage;
Image stickImage;
Image roadImage; //道路图片
Image spiritImage1,spiritImage2; //精灵图片
MediaTracker tracker;
Thread bgThread;
int win_w;
int win_h;
int treeImage_w;
int treeImage_h;
int stickImage_w;
int stickImage_h;
int spiritImage_w;
int spiritImage_h;
PixelGrabber pixelGrabber;
PixelGrabber pixelGrabberPatch; //打补丁的象素抓取器
int[] pixels;
boolean isReady=false;
boolean treeWhileStop=false; //将用这个标志终止线程内部的while循环
int x=0; //路边树木的移动横坐标
SpiritThread spiritThread; //精灵线程
PixelGrabber pixelGrabberSpirit; //抓取精灵将移到的位置处的背景象素
boolean meetStatus=false; //精灵碰到达标棒
Image imageTreeBuffer; //路边树木双缓冲区
Image imageSpiritBuffer; //精灵双缓冲区
public void init(){
tracker=new MediaTracker(this);
treeImage=getImage(getCodeBase(),"image/tree.jpg"); //将被移动的路边树木图片
stickImage=getImage(getCodeBase(),"image/stick.gif"); //达标棒图片
roadImage=getImage(getCodeBase(),"image/road.jpg");
spiritImage1=getImage(getCodeBase(),"image/spirit1.gif");
spiritImage2=getImage(getCodeBase(),"image/spirit2.gif");
tracker.addImage(treeImage,1);
tracker.addImage(stickImage,2);
tracker.addImage(roadImage,3);
tracker.addImage(spiritImage1,4);
tracker.addImage(spiritImage2,5);
try{
tracker.waitForAll(); //确保图象已被加载,否则treeImage_h等值仍为-1。
}catch(InterruptedException e){
System.out.println("加载图象文件失败");
}
win_w=getSize().width;
win_h=getSize().height;
treeImage_w=treeImage.getWidth(null);
treeImage_h=treeImage.getHeight(null);
//
stickImage_w=stickImage.getWidth(null);
stickImage_h=stickImage.getHeight(null);
//
spiritImage_w=spiritImage1.getWidth(null);
spiritImage_h=spiritImage1.getHeight(null);
//
pixels = new int[win_w * win_h];
//
imageTreeBuffer=createImage(win_w,treeImage_h); //双缓冲区,注意高度为treeImage_h.
imageSpiritBuffer=createImage(win_w,win_h - treeImage_h); //双缓冲区,高度为applet窗口下半部分.
}
public void start(){
bgThread=new Thread(this); //启动路边树木移动线程
bgThread.start();
spiritThread=new SpiritThread(); //启动精灵线程
spiritThread.start();
}
public void paint(Graphics g){
//动画开始
if(imageTreeBuffer!=null){ //applet初始化后会调用一次paint,此时imageTreeBuffer为空.
g.drawImage(imageTreeBuffer,0,0,null); //显示路边树木缓冲区象素数据
}
if(imageSpiritBuffer!=null){ //绘制移动中的精灵
g.drawImage(imageSpiritBuffer,0,treeImage_h,null);
}
}
public void run(){ //背景图向左移动
Graphics g1=imageTreeBuffer.getGraphics(); //取得缓冲区相应的Graphics对象
while(!treeWhileStop){
if(x >treeImage_w) x=0;
if(treeImage_w -x< win_w){ //从x处开始抓取的图片小于applet窗口宽度
pixelGrabber=new PixelGrabber(treeImage,x,0,treeImage_w -x,treeImage_h,pixels,0,treeImage_w -x);
try{
pixelGrabber.grabPixels();
}catch(InterruptedException e){
System.err.println("interrupted waiting for pixels!");
}
movedImage=createImage(new MemoryImageSource(treeImage_w -x,treeImage_h,pixels,0,treeImage_w -x));
g1.drawImage(movedImage,0,0,null);
//显示补丁
pixelGrabberPatch=new PixelGrabber(treeImage,0,0,win_w -(treeImage_w-x),treeImage_h,pixels,0,win_w -(treeImage_w -x));
try{
pixelGrabberPatch.grabPixels();
}catch(InterruptedException e){
System.err.println("interrupted waiting for pixels!");
}
movedImage=createImage(new MemoryImageSource(win_w -(treeImage_w -x),treeImage_h,pixels,0,win_w -(treeImage_w -x)));
g1.drawImage(movedImage,(treeImage_w -x)-1,0,null);
}
else{
pixelGrabber=new PixelGrabber(treeImage, x, 0, win_w, treeImage_h, pixels, 0, win_w);
try {
pixelGrabber.grabPixels();
} catch (InterruptedException e){
System.err.println("interrupted waiting for pixels!");
}
movedImage=createImage(new MemoryImageSource(win_w,treeImage_h,pixels,0,win_w));
g1.drawImage(movedImage,0,0,null);
}
repaint();
try{
Thread.sleep(speedDelay);
}catch(Exception e){}
isReady=true;
x+=speedPixels; //改变路边树背景取图位移
}
}
public void destroy(){ //当applet被摧毁时才停止线程,调换页面时的stop()不作处理.
if(bgThread!=null){
treeWhileStop=true; //使该线程的内部while循环终止
bgThread=null;
}
if(spiritThread!=null){
meetStatus=true; //使该线程的内部while循环终止
spiritThread=null;
}
}
class SpiritThread extends Thread { //Thread已声明Runnable接口
Graphics g2=imageSpiritBuffer.getGraphics(); //取得缓冲区相应的Graphics对象
Image oldBgImage;
int[] pixels=new int[spiritImage_w * spiritImage_h];
int stick_x=win_w -30; //初始化达标棒的显示位置
int stick_y=(win_h - treeImage_h)/2;
int spirit_x=-10; //精灵的开始起跑位置,负数使精灵从左边框渐现.
int spirit_y=(win_h - treeImage_h)/2;
public void run(){
g2.drawImage(roadImage,0,0,null); //绘制道路背景
g2.drawImage(stickImage,stick_x,stick_y,null); //显示达标棒
while(!meetStatus){ //精灵碰到达标棒
//精灵未碰到达标棒,起跑.
pixelGrabberSpirit=new PixelGrabber(roadImage,spirit_x,spirit_y,spiritImage_w,spiritImage_h,pixels,0,spiritImage_w);
try{
pixelGrabberSpirit.grabPixels();
}catch(InterruptedException e){
System.err.println("interrupted waiting for pixels!");
}
oldBgImage=createImage(new MemoryImageSource(spiritImage_w,spiritImage_h,pixels,0,spiritImage_w));
spirit_x+=speedPixels; //增加精灵的移动位置
if(Math.abs(spirit_x)%2==1){ //奇数,显示spiritImage1图片
g2.drawImage(oldBgImage,spirit_x-speedPixels,spirit_y,null); //先恢复前一精灵位置处的背景
g2.drawImage(spiritImage1,spirit_x,spirit_y,null);
}
else if(Math.abs(spirit_x)%2==0){ //偶数,显示spiritImage2图片
g2.drawImage(oldBgImage,spirit_x-speedPixels,spirit_y,null);
g2.drawImage(spiritImage2,spirit_x,spirit_y,null);
}
if(spirit_x +spiritImage_w > stick_x){ //检测精灵碰到达标棒
meetStatus=true;
g2.drawImage(stickImage,stick_x,stick_y,null);
}
repaint();
try{
Thread.sleep(speedDelay); //延时,决定精灵的步速.
}catch(Exception e){}
}
treeWhileStop=true; //使路边树木移动线程内部的while终止
bgThread=null; //停止路边树木移动线程
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -