我想做一只眼睛,因為為什么不呢,所以我想做一個眨眼影片。
我沒有關閉 "眼皮 "圓圈,而是選擇沿Y軸收縮鞏膜(白色部分),這樣看起來就像眼睛正在閉合。
現在我在中心位置添加了彩色的角膜,但是當我試圖在鞏膜和角膜的y值相遇時收縮角膜時,角膜看起來很奇怪,好像被壓扁了。
是否有任何方法可以使我在收縮鞏膜圈時,當外圈的邊界小于內圈時,角膜圈會消失?
基本來說,就像你調整 JPanel 的大小使其小于組件時發生的情況一樣。他們只是在框架的邊界下消失,而不是出現在框架之外。
代碼。 面板的類:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.Jpanel;
import javax.swing.Timer;
public class EyePanel extends JPanel implements ActionListener{
private int width;
private int height;
private int timeStep = 10;
private Timer定時器。
private 隨機隨機。
眼球。
EyePanel(int width, int height){
this.width = width;
this.height = height。
eye = new Eye(width, height, timeStep)。
JFrame frame = new JFrame() 。
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)。
this.setPreferredSize(new Dimension(width, height))。
frame.add(this)。
frame.pack();
frame.setResizable(false)。
frame.setLocationRelativeTo(null)。
frame.setVisible(true)。
timer = new Timer(timeStep, this)。
random = new Random();
Timer.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g)。
this. setBackground(new Color(255,255,255) )。)
draw(g);
}
public void draw(Graphics g) {
eye.draw(g)。
}
@Override
public void actionPerformed(ActionEvent e) {
repaint()。
}
}
眼睛的類:
import java.awt.Color。
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.*;
import javax.swing.*;
public class Eye {
private int width;
private int height;
private int timeStep;
private int lidDiameter;
private int sclDiameter;
private int corDiameter;
/lid coordinates
private int lidX;
private int lidY;
//sclera coordinates
private int sclX;
private int sclY;
private int sclU; //嶠
private int sclB; //底層
private int sclC; //y-level at which eyes are closed[/span
//cornea coordinates; //y-level at which eyes closed; //cornea coordinates
private int corX;
private int corY;
private int corU; //嶠
private int corB; //底層
private int corC; //y-level at which eyes are closed
private int blinkDelay = 3; /delay in seconds preset
private int blinkTime; //距離下次眨眼的時間。
private int rate = 20; //眼球閉合&打開的速率。
private boolean closed = false;
Eye(int width, int height, int timeStep){
this.width = width;
this.height = height;
this.timeStep = timeStep;
blinkTime = blinkDelay*(1000/timeStep)。
//設定眼睛變數。
if(width>height) lidDiameter = height - (height/10)。
else if(height>width) lidDiameter = width - (width/10) 。
else lidDiameter = 寬度-(高度/10)。
sclDiameter = lidDiameter-(lidDiameter/10)。
corDiameter = sclDiameter/3;
//lid location; lidX = ()
lidX = (int)((width-lidDiameter)/2) 。
lidY = (int)((height-lidDiameter)/2) 。
/lid location
//鞏膜位置; //鞏膜位置?
sclX = (int)(lidX (lidDiameter-sclDiameter)/2) 。
sclY = (int)(lidY (lidDiameter-sclDiameter)/2) 。
sclU = sclY;
sclB = sclDiameter;
sclC = (int)(sclY sclDiameter/2) 。
///sclera location; //sclera location.
//角膜的位置; //角膜的位置。
corX = (int)(sclX (sclDiameter-corDiameter)/10) 。
corY = (int)(sclY (sclDiameter-corDiameter)/10) 。
corU = corY;
corB = corDiameter;
corC = (int)(corY corDiameter/2)。
//cornea location; //cornea location。
//設定眼睛變數。
}
public void close() {
if(sclU != sclC)
sclU =速率。
if(sclB != sclC)
sclB-=速率*2; //底限必須上升(所需金額 上限下降的速率)。
if(sclU >=sclC && sclB <=sclC)
closed = true;
}
public void open {
if(sclU != sclY)
sclU = -rate。
if(sclB != sclDiameter)
sclB-= -rate*2; //bottom limit must rise by (required amt rate of upper limit fall)/span>.
if(sclU == sclY & & sclB == sclDiameter) {
closed = false;
blinkTime = blinkDelay*(1000/timeStep)。
}
}
public void blink() {
if(blinkTime == 0) {
if(! closed)
close()。
if(closed)
open()。
}
else[/span
blinkTime--。
}
public void draw (圖形g) {
Graphics2D g2d = (Graphics2D)g;
//span>眼瞼。
g2d.setColor(Color.pink)。
g2d.fillOval(lidX, lidY, lidDiameter, lidDiameter)。
/sclera
g2d.setColor(Color.white)。
g2d.fillOval(sclX, sclU, sclDiameter, sclB)。
g2d.setColor(Color.black);
g2d.drawLine(sclX, sclC, sclX sclDiameter, sclC)。
/cornea
g2d.setColor(Color.cyan)。
g2d.fillOval(corX, corU, corDiameter, corB)。
g2d.setColor(Color.red);
g2d.drawLine(corX, corC, corX corDiameter, corC)。
//觸發閃爍。
blink()。
}
啟動一切的主類:
public class Main {
public static void main(String[] args){
new EyePanel(600, 600)。
}
uj5u.com熱心網友回復:
在任何情況下,繪畫方法都不應該呼叫任何形式的邏輯來改變物件的狀態。 繪畫是由系統事件觸發的,你對其時間的控制非常有限。 (此類事件的例子包括用戶移動視窗、降低或升高視窗、取消視窗、解鎖螢屏,甚至是將滑鼠移到視窗上。
因此,你要做的第一件事就是從 Eye 類中洗掉這個事件:
//trigger blink
blink()。
...然后把它添加到你的actionPerformed方法中:
@Override。
public void actionPerformed(ActionEvent e) {
eye.blink()。
repaint()。
}
幾乎所有的Swing方法和建構式都必須在AWT事件調度執行緒上運行,所以要改變你的main方法來做到:
public static void main(String[] args) {
EventQueue.invokeLater(() -> new EyePanel(600, 600) )。)
你的代碼并沒有完全做到你所說的那樣(角膜/虹膜不在中心),但我認為你的問題是可以回答的。 Area類可以用來檢查形狀是否相交:
public void draw (圖形g) {
Graphics2D g2d = (Graphics2D)g;
//span>眼瞼。
g2d.setColor(Color.pink)。
g2d.fillOval(lidX, lidY, lidDiameter, lidDiameter)。
/sclera
Area sclera = new Area (
new Ellipse2D.Float(sclX, sclU, sclDiameter, sclB))。)
g2d.setColor(Color.white);
g2d.fill(sclera)。
g2d.setColor(Color.black);
g2d.drawLine(sclX, sclC, sclX sclDiameter, sclC)。
/cornea
Area cornea = new Area(
new Ellipse2D.Float(corX, corU, corDiameter, corB))。
Area hiddenCornea = (Area) cornea.clone();
hiddenCornea.subtract(sclera)。
if (hiddenCornea.isEmpty() ) {
g2d.setColor(Color.cyan)。
g2d.fill(cornerea);
g2d.setColor(Color.red);
g2d.drawLine(corX, corC, corX corDiameter, corC)。
}
}
如果角膜的任何部分被隱藏(不與鞏膜相交),這將跳過繪制角膜。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/310264.html
標籤:
