📄 petepanel.java
字号:
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class PetePanel extends JPanel implements Runnable
{
/**线程runner: 控制企鹅动画
* 线程runner1: 控制枫叶动画
* 线程runner2: 拉开序幕,显示画面
* 线程runner3: 落下序幕
* 线程runner4:用于控制何时落下序幕
* petePics[]数组用于存储构成企鹅动画的各帧图像
* leave: 代表枫叶图像
* current: 企鹅动画当前帧的索引
* x, y :企鹅图像的起始横,纵坐标
* z: 枫叶图像的起始横坐标
* w, v : 左右子序幕的宽度
*/
private Thread runner, runner1, runner2, runner3, runner4;
private Image petePics[], leave;
private int current = 0, x = -10, y = 200, z = 600, w = 300, v = 300;
public PetePanel()
{
super();
setBackground(Color.black);
//加载构成企鹅动画的各帧图像
petePics = new Image[3];
String peteSrc[] = { "source/right1.gif","source/right2.gif","source/right3.gif" };
//实现图像缓冲
MediaTracker track=new MediaTracker(this);
Toolkit kit = Toolkit.getDefaultToolkit();
for (int i=0; i < petePics.length; i++)
{
petePics[i] = kit.getImage(peteSrc[i]);
track.addImage(petePics[i],i);
}
//加载枫叶图像
leave=kit.getImage("source/change.gif");
track.addImage(leave,3);
try
{
track.waitForAll();
} catch(InterruptedException e) {}
//启动线程runner2, 拉开序幕
if(runner2==null)
{
runner2=new Thread(this);
runner2.start();
}
//启动线程runner4,用于监控何时启动线程runner3落下序幕
if(runner4==null)
{
runner4=new Thread(this);
runner4.start();
}
}
//绘制动画
public void paintComponent(Graphics comp)
{
Graphics2D comp2D = (Graphics2D)comp;
//清屏
comp2D.setColor(getBackground());
comp2D.fillRect(0,0,getSize().width,getSize().height);
//绘制枫叶
if(runner1!=null)
{
if(leave!=null)
comp2D.drawImage(leave,10+z,20,this);
}
if(runner!=null)
{
//绘制太阳,太阳运行轨迹为抛物线
comp2D.setColor(Color.red);
double temp=0.001211*(-30+x-300)*(-30+x-300);
int temp1=(int)temp;
comp2D.fillOval(-30+x,temp1,60,60);
//绘制企鹅
if (petePics[current]!= null)
comp2D.drawImage(petePics[current], x, y, this);
//绘制企鹅过河时所用的划板
comp2D.setColor(Color.red);
comp2D.drawLine(x-20,y+30,x+50,y+30);
//绘制左右码头
comp2D.setColor(Color.cyan);
comp2D.fillRect(0,230,130,70);
comp2D.fillRect(470,230,130,70);
//绘制河水波纹
comp2D.setColor(Color.white);
BasicStroke pen = new BasicStroke(2F,
BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
comp2D.setStroke(pen);
for (int ax = 130; ax < 470; ax += 10)
for (int ay = 250; ay < 300 ; ay += 10)
{
Arc2D.Float wave = new Arc2D.Float(ax, ay,
10, 10, 0, -180, Arc2D.OPEN);
comp2D.draw(wave);
}
}
//绘制序幕(拉开)
if(runner2!=null)
{
comp2D.setColor(Color.blue);
comp2D.fillRect(0,0,w,600);
comp2D.setColor(Color.yellow);
comp2D.fillRect(v,0,600-v,600);
}
//绘制序幕(落下)
if(runner3!=null)
{
comp2D.setColor(Color.blue);
comp2D.fillRect(0,0,w,600);
comp2D.setColor(Color.yellow);
comp2D.fillRect(v,0,600-v,600);
}
}
//主控制函数
public void run()
{
//绘制企鹅
while(Thread.currentThread()==runner)
{
walk(-10,150);
jump();
walk(x,640);
}
//绘制枫叶
while(Thread.currentThread()==runner1)
{
z=z-1;
if(z<-150)
z=600;
repaint();
pause(30);
}
//拉开序幕
while(Thread.currentThread()==runner2)
{
if(w>-15)
w--;
if(v<615)
v++;
repaint();
pause(100);
//已经拉开序幕, 动画开始: 企鹅开始从左到右行走,枫叶开始从右到左移动
if((w<-10)&&(v>610)) {
runner=new Thread(this);
runner1=new Thread(this);
runner.start();
runner1.start();
runner2=null;
}
}
//落下序幕
while(Thread.currentThread()==runner3)
{
if(w<300)
w++;
if(v>300)
v--;
repaint();
pause(100);
}
//确定何时应该落下序幕
while(Thread.currentThread()==runner4)
{
pause(100000);
runner=null;
runner1=null;
runner2=null;
runner3=new Thread(this);
runner3.start();
runner4=null;
}
}
//控制企鹅水平行走轨迹
private void walk(int start, int end)
{
int showpic = 0;
for (int i = start; i < end; i += 5)
{
x = i;
// swap images
current = showpic;
repaint();
pause(150);
showpic++;
if (showpic > 2)
showpic = 0;
}
}
//控制企鹅上下移动轨迹
private void jump()
{
int moveY=-3;
int moveX=2;
current=2;
while(true)
{
x+=moveX;
y+=moveY;
if(y<100)
{
moveY*=-1;
continue;
}
if(y>200)
{
moveY*=-1;
continue;
}
if(x>420)
break;
repaint();
pause(150);
}
}
//设置线程休眠时间
private void pause(int time)
{
try
{
Thread.sleep(time);
} catch (InterruptedException e) { }
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -