SlideShare a Scribd company logo
2D Graphics and Animations in Java World
Outline
• 2D Graphics in Java
• OOP concepts in Graphics
• Complexity Graphics
• 2D Animations
• Timer APIs
Graphics
• Graphic = สิ่งที่ถูกเขียนขึ้น
• Graphic != Animation != รูปภาพ
• Computer Graphics
– กล่าวถึงการแสดงสิ่งที่ถูกเขียนบนคอมพิวเตอร์
– วิชา 01418482
• Graphical User Interface (GUI)
Graphics
Graphics
Graphics
• ใน Java มี API สาหรับกราฟฟิกโดยเฉพาะ
– ไม่ต้องเขียนสมการยาก ๆ กับการ์ดจอ
• ส่วนใหญ่อยู่ใน package java.awt
• สามารถแสดงผลได้ทั้ง 2D และ 3D
– ในคอร์สนี้จะกล่าวถึง 2D เท่านั้น
– 3D จาเป็นต้องศึกษาด้วยตนเอง
Computer’s 2D Space
• การวาดภาพในคอมพิวเตอร์มีข้อตกลงที่ซับซ้อน
– ผลจากการใช้คณิตศาสตร์
• เมื่อวาดภาพจาเป็นต้องรู้ตาแหน่งที่แน่นอน
– จะให้เริ่มต้นวาดที่ไหนและจบที่ไหน
• การบอกตาแหน่งใช้พิกัดเป็นสื่อกลาง
– x แทนแนวนอน, y แทนแนวตั้ง
• จุดกาเนิดอยู่ที่มุมซ้ายบนสุด
– แตกต่างจากคณิตศาสตร์ที่เคยเรียนมา
Computer’s 2D Space
(0, 0) +𝑥
+𝑦
Java Graphics API
• การวาดรูปควรวาดใน Canvas หรือ JPanel
– JFrame เหมาะสาหรับใส่ component อื่นมากกว่า
– เกิดปัญหาเมื่อทางานกับ component จานวนมาก
• อธิบายขั้นตอนการวาดใน paintComponent(g: Graphics)
– component ไม่มี s
– ใช้วิธีการ override method
• สาหรับคลาส Canvas อธิบายใน paint(g: Graphics)
– ปัจจุบันไม่นิยมใช้
Java Graphics API
JPanel panel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// TODO: Describe draw algorithm here
}
};
Java Graphics API
• Graphics เป็น abstract class
– Provide method ไม่ค่อยเพียงพอต่อการวาดภาพ
• ใน JFrame g จะส่งวัตถุของคลาส sun.java2d.SunGraphics2D
– SunGraphics2D inherited Graphics2D
– Graphics2D inheritedGraphics
• สามารถ cast g เป็น Graphics2D
– อ้างอิง method ใน Graphics2D ได้
– Provide method เพียงพอกับการวาดภาพสองมิติ
Java Graphics API
JPanel panel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// TODO: Describe draw algorithm here
}
};
Drawing Shape by Calling
• Graphics2D สามารถวาดรูปเรขาคณิตผ่าน method
– ใช้เมื่อต้องการวาดรูปอย่างเดียว
– ไม่จาเป็นต้องอ้างถึงรูปนั้นอีก
• Method การวาดส่วนใหญ่ขึ้นต้นด้วย draw
– Ctrl + Space ดูได้ว่ามีอะไรบ้าง
• รูปที่วาดทีหลังจะแสดงอยู่เหนือรูปที่วาดก่อน
– หลักการวาดทับ
– ลาดับของคาสั่ง
Drawing Shape by Calling (1)
Method หน้าที่
drawLine(x1: int, y1: int,
x2: int, y2: int)
วาดเส้นจากจุด 𝑥1, 𝑦1 ไปยัง
𝑥2, 𝑦2
drawOval(x: int, y: int,
width: int, height: int)
วาดวงรีโดยกาหนดให้มุมซ้ายบนอยู่ที่
ตาแหน่ง 𝑥, 𝑦 มีความกว้าง width
และสูง height
drawRect(x: int, y: int,
width: int, height: int)
วาดสี่เหลี่ยมโดยกาหนดให้มุมซ้ายบนอยู่ที่
ตาแหน่ง 𝑥, 𝑦 มีความกว้าง width
และสูง height
Drawing Shape by Calling (2)
Method หน้าที่
drawString(str: String, x:
int, y: int)
วาดตัวอักษร str โดยกาหนดให้ 𝑥, 𝑦
เป็น baseline ของตัวอักษร
drawArc(x: int, y: int,
width: int, height: int,
startAngle: int, arcAngle:
int)
วาดส่วนโค้งโดยกาหนดความกว้าง, สูง,
พิกัดที่อยู่, องศาการเริ่มวาดส่วนโค้งและ
สิ้นสุดส่วนโค้ง
drawPolygon(xPoints: int[],
yPoints: int[], nPoints:
int)
วาดรูปหลายเหลี่ยมโดยกาหนดพิกัดและ
จานวนพิกัด
Drawing Shape
• การวาดรูปให้นึกถึงพิกัดเสมอ
• หากนึกไม่ออกให้ลองวาดบนกระดาษก่อน
– สังเกตว่ามีจุดใดเริ่มต้น, สิ้นสุด และใช้เรขาคณิตแบบใด
• รูปที่ใช้บ่อยสามารถสร้างเป็นคลาสใหม่ได้
– extends JPanel , override paintComponent(g: Graphics)
– override getPreferredSize(): Dimension เพื่อบอกขนาดขั้นต่า
ของรูป
Drawing Shape by Object
• เราสามารถสั่งให้ Graphics2D วาดรูปจาก object ได้
– ส่วนใหญ่สร้างจากคลาสใน package java.awt.geom
– สั่งวาดผ่าน method draw(s: Shape)
• สามารถกาหนดรูปร่างได้หลากหลายมากขึ้น
– เพิ่มความยืดหยุ่น
• สามารถอ้างถึงรูปร่างที่วาดได้
– มีประโยชน์ในการอ้างอิงถึงรูปร่างที่วาด
– ทา animation ได้ง่ายขึ้น
Drawing Shape by Object
Method Object
drawLine(x1: int, y1: int,
x2: int, y2: int)
Line2D.Double
Line2D.Float
drawOval(x: int, y: int,
width: int, height: int)
Ellipse2D.Double
Ellipse2D.Float
drawRect(x: int, y: int,
width: int, height: int)
Rectangle2D.Double
Rectangle2D.Float
drawPolygon(xPoints: int[],
yPoints: int[], nPoints: int)
Polygon
drawArc(x: int, y: int,
width: int, height: int,
startAngle: int, arcAngle:
int)
Arc2D.Double
Arc2D.Float
Fill Shape
• หากเข้าใจการวาด การเทสีจะไม่มีปัญหา
• g2d.fill…(…)
– เปลี่ยนจาก draw… เป็น fill…
– ยกเว้น fillLine, fillString
• สั่งเทสีผ่าน method fill(s: Shape)
g2d.fillRect(0, 0, 100, 100);
g2d.fill(
new Rectangle2D.Double(100, 100, 100, 100)
);
Area
• บางรูปไม่สามารถวาดด้วยวิธีการตรง
– ถึงแม้ polygon อาจจะเป็นไปยาก
• พยายามมองให้เป็นรูปเรขาคณิต
– รูปเรขาคณิตที่ซ้อนทับกัน
• สามารถใช้คลาส Area ช่วยวาดรูปได้
– java.awt.geom
– Area implements Shape
– สามารถวาดเส้นหรือเทสีได้
Area Operation
Area
?
Transformation
• รูปร่างหนึ่งสามารถเปลี่ยนเป็นรูปร่างอื่นได้
• Transform = การแปลง
– Linear Transform ในวิชา 01417322
• ใช้วัตถุของคลาส AffineTransform ในการแปลง
– แปลงได้ทั้ง g2d และ object รูปร่าง
– ช่วยจัดการเรื่องคณิตศาสตร์ที่ซับซ้อน
Transformation
Transformation in g2d
• การแปลงใน g2d ทาให้พิกัดการเริ่มต้นวาดรูปเปลี่ยนไป
– เปลี่ยนแปลงตามการแปลง
• การแปลงมีผลต่อการวาดรูปถัดไป
– ลาดับก่อนหลังของคาสั่ง
– แปลงไปแล้วอย่าลืมแปลงกลับ
• ดูการแปลงด้วย g2d.getTransform(): AffineTransform
Transformation in g2d
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLUE);
g2d.fillRect(0, 0, 100, 100);
g2d.setColor(Color.GREEN);
g2d.translate(100, 100);
g2d.fillRect(0, 0, 100, 100);
AffineTransform t = g2d.getTransform();
System.out.println(t.getTranslateX());
System.out.println(t.getTranslateY());
Transformation in g2d
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLUE);
g2d.fillRect(0, 0, 100, 100);
g2d.setColor(Color.GREEN);
g2d.translate(100, 100);
g2d.fillRect(0, 0, 100, 100);
g2d.setColor(Color.BLACK);
g2d.fillOval(-100, 0, 100, 100);
AffineTransform t = g2d.getTransform();
System.out.println(t.getTranslateX());
System.out.println(t.getTranslateY());
Transformation in Shape
• การแปลงของ Shape object ต้องใช้ Area object ช่วย
– คลาส AffineTransform
– + new(s: Shape)
• area.transform(t: AffineTransform)
– สร้างและกาหนดรูปแบบการแปลงก่อน
Transformation in Shape
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(new Color(0, 150, 200));
Area area = new Area(
new Rectangle2D.Double(0, 0, 100, 100)
);
AffineTransform t = new AffineTransform();
t.translate(150, 150);
t.scale(2, 2);
t.rotate(Math.toRadians(45));
area.transform(t);
g2d.fill(area);
2D Graphics and Animations in Java World
Animation
• Animation = ภาพเคลื่อนไหว
• การเคลื่อนไหวเกิดขึ้นเมื่อมีแรงมากระทาหรือเคลื่อนไหวได้เอง
– คน, สัตว์, สิ่งของ
• การวาดภาพสามารถทาภาพเคลื่อนไหวได้
– แต่ละภาพวัตถุอยู่ตาแหน่งที่ต่างกัน
– Stop motion
– การสร้างภาพเคลื่อนไหวของกล้องวิดีโอ
Animation
http://9gag.com/gag/a44LqEd/car-race-stop-motion
Animation
• ภาพเคลื่อนไหวคอมพิวเตอร์ใช้รูปแบบเดียวกับกล้องวิดีโอ
• เกิดเมื่อมีบางสิ่งเปลี่ยนพิกัด
– เคลื่อนที่
– หมุน
– เปลี่ยนขนาด
– เปลี่ยนสี
– ...
Computer’s Animation
• 1 รูปของภาพเคลื่อนไหว = 1 frame
• คอมพิวเตอร์วาดและลบรูปออกจากหน้าจอ
– เหตุการณ์นี้เกิดขึ้นเร็วมาก
– หากช้าจอจะกระพริบหรือกระตุก
• Frame per second (FPS)
– จานวนรูปภาพที่วาดภายใน 1 วินาที
– มาตรวัดความลื่นของเกมและภาพยนตร์
– 30 ~ 60 FPS
Computer’s Animation
Animation in Java 2D
• ใน Java สามารถสร้างภาพเคลื่อนไหวด้วยวิธีเดียวกัน
• เมื่อพิกัดเปลี่ยนแปลง ลบแล้ววาดรูปใหม่
– เรียก method repaint()
• รูปที่เป็นภาพเคลื่อนไหวต้องอ้างถึงได้
– เปลี่ยนแปลงพิกัดได้
– ปรับเปลี่ยนรูปทรงได้
– แปลงได้
Animation in Java 2D
Graphics2D g2d = (Graphics2D) g;
g2d.fillRect(0, 0, 100, 100);
g2d.fillRect(x, y, 100, 100);
g2d.fillRect(0, 0, width, height);
g2d.fillRect(x, y, width, height);
อ้างถึงไม่ได้
เปลี่ยนตาแหน่งได้เท่านั้น
เปลี่ยนขนาดได้เท่านั้น
อ้างถึงได้ทั้งหมด
Animation in Java 2D
• การลบและวาดภาพใหม่เป็นสิ่งที่ต้องทาตลอดเวลา
• คอมพิวเตอร์ทางานได้เพียง 1 อย่างเท่านั้น
– โปรแกรมต้องทางาน รูปก็ต้องวาด
– เป็นไปไม่ได้ ?
• Multithreading
– สร้าง thread สาหรับจัดการการวาดโดยเฉพาะ
Timer API
• Package javax.swing.Timer
• คลาสสาหรับจัดการสิ่งที่ต้องทาเป็นช่วงกาหนดเวลา
– ทุก ๆ 1 วินาที
• สามารถใช้ Timer ในการสั่งลบและวาดได้
– สิ่งที่ต้องทา: ลบแล้ววาดใหม่
– อาจต้องอัพเดตค่าบางอย่าง
• สิ่งที่จะทา เขียนในคลาสที่ implements ActionListener
– Anonymous class, Inner class, class ปกติ
– ตามความเหมาะสมของสิ่งที่จะทา
Timer API
final int ONE_SECOND = 1000;
Timer t = new Timer(ONE_SECOND, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO: Implement update algorithm and logic here
// TODO: Repaint
}
});
Timer API
• Timer object สามารถสั่งเริ่มและหยุดได้
– t.start()
– t.stop()
– ไม่ต้องกังวลเรื่องการ interrupt ของ thread
• พยายามสั่งหยุด Timer เมื่อจบโปรแกรมทุกครั้ง
– บางครั้ง process ไม่หยุดการทางาน
Timer API
final int ONE_SECOND = 1000;
Timer t = new Timer(ONE_SECOND, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(new java.util.Date());
}
});
t.start();
Translation
• การเปลี่ยนแปลงรูปร่างเพื่อสร้างภาพเคลื่อนไหว
– หาสมการที่สามารถบอกตาแหน่งได้โดยใช้หมายเลข frame
– กาหนดระยะการเปลี่ยนแปลงต่อ frame
• ขึ้นกับความง่ายและเหมาะสม
– หมายเลข frame overflow ได้
– การเคลื่อนที่บางประเภทมองระยะการเปลี่ยนแปลงยาก
Translation
• การเลื่อนขนานแบบเส้นตรง
– การเดินทางเป็นแนวเส้นตรง
– สมการเชิงเส้นตัวแปรเดียว
𝑥 𝑡 = 𝑠 𝑥 𝑡 + 𝑥0
𝑦𝑡 = 𝑠 𝑦 𝑡 + 𝑦0
𝑑𝑥 𝑡
𝑑𝑡
= 𝑑𝑥 = 𝑠 𝑥
𝑑𝑦𝑡
𝑑𝑡
= 𝑑𝑦 = 𝑠 𝑦
Translation
𝑥𝑡 = 2𝑡
𝑦𝑡 = 𝑡
𝑥0 = 0
𝑑𝑥 = 2
𝑦0 = 0
𝑑𝑦 = 1
Rectangle2D.Double rect = new Rectangle2D.Double(0, 0, 2, 2);
// Initial Initial Initial
public void actionPerformed(ActionEvent e) {
rect.x += 2;
rect.y += 1;
screenPanel.repaint();
t++;
}
𝑑𝑥
𝑑𝑦
Translation
• การเลื่อนขนานแบบวงกลม, วงรี
– สามารถใช้เรื่องวงกลม 1 หน่วยในการแก้ปัญหา
𝑥 𝑡
2
+ 𝑦𝑡
2
= 𝑟
𝑥 𝑡 = 𝑟𝑥 cos 𝑠𝑡 + 𝜃 + 𝑥0
𝑦𝑡 = 𝑟𝑦sin 𝑠𝑡 + 𝜃 + 𝑦0
𝑑𝑥 = −𝑟𝑥 𝑠 sin 𝑠𝑡 + 𝜃
𝑑𝑦 = 𝑟𝑦 𝑠cos 𝑠𝑡 + 𝜃
Translation
𝑥𝑡 = 100 cos 𝑡 + 45° + 100
𝑦𝑡 = 100sin 𝑡 + 45° + 100
𝑑𝑥 = −100 sin 𝑡 + 45°
𝑑𝑦 = 100cos 𝑡 + 45°
𝑥0 = 100
𝑦0 = 100
Collision
http://www.doubledogmusic.com/images/2008/collision.jpg
Collision
• การชนของวัตถุสองมิติเกิดขึ้นเมื่อวัตถุซ้อนกัน
• การชนกันขึ้นกับความเป็นจริงของวัตถุ
– ขึ้นกับ policy ว่าเป็นอย่างไร
– อะไรทะลุได้ ทะลุไม่ได้
• บางครั้งเมื่อวัตถุชนกันทาให้ความเร็วเปลี่ยนไป
– 𝑑𝑥, 𝑑𝑦 ต้องเปลี่ยนแปลงค่าได้
Collision
• การตรวจสอบการชนมีได้สองวิธี
– ตรวจสอบพิกัดสองรูปว่าซ้อนทับหรือไม่
– ใช้สมบัติ intersect ของ Area object
• ขึ้นกับลักษณะ
– ชนเฉพาะด้านหรือชนได้รอบทิศ
– รูปซับซ้อนหรือไม่
• FPS มาก ยิ่งทาให้การตรวจสอบเหมือนจริงยิ่งขึ้น
Collision
if (rect.getMinX() < 0) {
dx = speed;
} else if (rect.getMaxX() > screenPanel.getWidth()) {
dx = -speed;
}
if (rect.getMinY() < 0) {
dy = speed;
} else if (rect.getMaxY() > screenPanel.getHeight()) {
dy = -speed;
}
rect.x += dx;
rect.y += dy;
screenPanel.repaint();

More Related Content

PDF
実践!AWSクラウドデザインパターン
PDF
AWS X-Rayによるアプリケーションの分析とデバッグ
PDF
バックアップ勉強会#1 バックアップ基礎
PDF
TIME_WAITに関する話
PPT
rsyncのちょっとイイ話
PDF
パケットが教えてくれた ルートサーバが 13個の理由
PDF
ZFSでストレージ
PDF
MongoDB〜その性質と利用場面〜
実践!AWSクラウドデザインパターン
AWS X-Rayによるアプリケーションの分析とデバッグ
バックアップ勉強会#1 バックアップ基礎
TIME_WAITに関する話
rsyncのちょっとイイ話
パケットが教えてくれた ルートサーバが 13個の理由
ZFSでストレージ
MongoDB〜その性質と利用場面〜

What's hot (13)

PDF
Groovyで楽にSQLを実行してみよう
PDF
Goとテスト
PDF
RDBでのツリー表現入門
PPTX
Choosing the Segment Length for Adaptive Bitrate Streaming
PDF
オンプレを少しずつコンテナ化する
PDF
OSC 2011 Hokkaido 自宅SAN友の会(後半)
PPTX
Machine Learning on Your Hand - Introduction to Tensorflow Lite Preview
PDF
負荷テストを行う際に知っておきたいこと 初心者編
PDF
PowerShellを使用したWindows Serverの管理
PPTX
データ集計基盤のいままでとこれから 〜Hadoopからdataflowまで使い込んだ経験を徹底共有〜
PDF
Amazon Inspector v2で脆弱性管理を始めてみた
PDF
すごく分かるwarden
PDF
OpenStackをコマンドで攻める! 構築・運用とトラブル解決 - OpenStack最新情報セミナー 2014年6月
Groovyで楽にSQLを実行してみよう
Goとテスト
RDBでのツリー表現入門
Choosing the Segment Length for Adaptive Bitrate Streaming
オンプレを少しずつコンテナ化する
OSC 2011 Hokkaido 自宅SAN友の会(後半)
Machine Learning on Your Hand - Introduction to Tensorflow Lite Preview
負荷テストを行う際に知っておきたいこと 初心者編
PowerShellを使用したWindows Serverの管理
データ集計基盤のいままでとこれから 〜Hadoopからdataflowまで使い込んだ経験を徹底共有〜
Amazon Inspector v2で脆弱性管理を始めてみた
すごく分かるwarden
OpenStackをコマンドで攻める! 構築・運用とトラブル解決 - OpenStack最新情報セミナー 2014年6月
Ad

Similar to 2D Graphics and Animations in Java World (20)

PDF
Java-Chapter 14 Creating Graphics with DWindow
PDF
Applet 5 class_inheritance
PDF
Applet 5 class_inheritance
PPT
Mobile Game and Application with J2ME
PPT
J2ME Game Concept
PPT
Java Programming [5/12] : Build Graphical User Interface
PDF
01 intro computergraphic
PPT
พื้นฐานภาษาจาวา
PDF
Java 7&12 6 2
PDF
Applet 6 mouse_keyboard
PPT
บทที่1
PPT
บทที่1
PPT
Chapter1 uml3
PPT
Chapter1 uml3
PDF
Lesson2
PPT
การสอนครั้งที่ 2 intro ความรู้เบื้องต้นเกี่ยวกับคอมพิวเตอร์กราฟิก
PPT
บทที่1
PDF
Flash professional cs5-01-2012-01-12a_2
DOC
Adobe Flash CS3
PDF
Java Programming: การสร้างส่วนต่อประสานกราฟิกกับผู้ใช้ (Java GUI)
Java-Chapter 14 Creating Graphics with DWindow
Applet 5 class_inheritance
Applet 5 class_inheritance
Mobile Game and Application with J2ME
J2ME Game Concept
Java Programming [5/12] : Build Graphical User Interface
01 intro computergraphic
พื้นฐานภาษาจาวา
Java 7&12 6 2
Applet 6 mouse_keyboard
บทที่1
บทที่1
Chapter1 uml3
Chapter1 uml3
Lesson2
การสอนครั้งที่ 2 intro ความรู้เบื้องต้นเกี่ยวกับคอมพิวเตอร์กราฟิก
บทที่1
Flash professional cs5-01-2012-01-12a_2
Adobe Flash CS3
Java Programming: การสร้างส่วนต่อประสานกราฟิกกับผู้ใช้ (Java GUI)
Ad

2D Graphics and Animations in Java World

  • 2. Outline • 2D Graphics in Java • OOP concepts in Graphics • Complexity Graphics • 2D Animations • Timer APIs
  • 3. Graphics • Graphic = สิ่งที่ถูกเขียนขึ้น • Graphic != Animation != รูปภาพ • Computer Graphics – กล่าวถึงการแสดงสิ่งที่ถูกเขียนบนคอมพิวเตอร์ – วิชา 01418482 • Graphical User Interface (GUI)
  • 6. Graphics • ใน Java มี API สาหรับกราฟฟิกโดยเฉพาะ – ไม่ต้องเขียนสมการยาก ๆ กับการ์ดจอ • ส่วนใหญ่อยู่ใน package java.awt • สามารถแสดงผลได้ทั้ง 2D และ 3D – ในคอร์สนี้จะกล่าวถึง 2D เท่านั้น – 3D จาเป็นต้องศึกษาด้วยตนเอง
  • 7. Computer’s 2D Space • การวาดภาพในคอมพิวเตอร์มีข้อตกลงที่ซับซ้อน – ผลจากการใช้คณิตศาสตร์ • เมื่อวาดภาพจาเป็นต้องรู้ตาแหน่งที่แน่นอน – จะให้เริ่มต้นวาดที่ไหนและจบที่ไหน • การบอกตาแหน่งใช้พิกัดเป็นสื่อกลาง – x แทนแนวนอน, y แทนแนวตั้ง • จุดกาเนิดอยู่ที่มุมซ้ายบนสุด – แตกต่างจากคณิตศาสตร์ที่เคยเรียนมา
  • 8. Computer’s 2D Space (0, 0) +𝑥 +𝑦
  • 9. Java Graphics API • การวาดรูปควรวาดใน Canvas หรือ JPanel – JFrame เหมาะสาหรับใส่ component อื่นมากกว่า – เกิดปัญหาเมื่อทางานกับ component จานวนมาก • อธิบายขั้นตอนการวาดใน paintComponent(g: Graphics) – component ไม่มี s – ใช้วิธีการ override method • สาหรับคลาส Canvas อธิบายใน paint(g: Graphics) – ปัจจุบันไม่นิยมใช้
  • 10. Java Graphics API JPanel panel = new JPanel() { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // TODO: Describe draw algorithm here } };
  • 11. Java Graphics API • Graphics เป็น abstract class – Provide method ไม่ค่อยเพียงพอต่อการวาดภาพ • ใน JFrame g จะส่งวัตถุของคลาส sun.java2d.SunGraphics2D – SunGraphics2D inherited Graphics2D – Graphics2D inheritedGraphics • สามารถ cast g เป็น Graphics2D – อ้างอิง method ใน Graphics2D ได้ – Provide method เพียงพอกับการวาดภาพสองมิติ
  • 12. Java Graphics API JPanel panel = new JPanel() { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; // TODO: Describe draw algorithm here } };
  • 13. Drawing Shape by Calling • Graphics2D สามารถวาดรูปเรขาคณิตผ่าน method – ใช้เมื่อต้องการวาดรูปอย่างเดียว – ไม่จาเป็นต้องอ้างถึงรูปนั้นอีก • Method การวาดส่วนใหญ่ขึ้นต้นด้วย draw – Ctrl + Space ดูได้ว่ามีอะไรบ้าง • รูปที่วาดทีหลังจะแสดงอยู่เหนือรูปที่วาดก่อน – หลักการวาดทับ – ลาดับของคาสั่ง
  • 14. Drawing Shape by Calling (1) Method หน้าที่ drawLine(x1: int, y1: int, x2: int, y2: int) วาดเส้นจากจุด 𝑥1, 𝑦1 ไปยัง 𝑥2, 𝑦2 drawOval(x: int, y: int, width: int, height: int) วาดวงรีโดยกาหนดให้มุมซ้ายบนอยู่ที่ ตาแหน่ง 𝑥, 𝑦 มีความกว้าง width และสูง height drawRect(x: int, y: int, width: int, height: int) วาดสี่เหลี่ยมโดยกาหนดให้มุมซ้ายบนอยู่ที่ ตาแหน่ง 𝑥, 𝑦 มีความกว้าง width และสูง height
  • 15. Drawing Shape by Calling (2) Method หน้าที่ drawString(str: String, x: int, y: int) วาดตัวอักษร str โดยกาหนดให้ 𝑥, 𝑦 เป็น baseline ของตัวอักษร drawArc(x: int, y: int, width: int, height: int, startAngle: int, arcAngle: int) วาดส่วนโค้งโดยกาหนดความกว้าง, สูง, พิกัดที่อยู่, องศาการเริ่มวาดส่วนโค้งและ สิ้นสุดส่วนโค้ง drawPolygon(xPoints: int[], yPoints: int[], nPoints: int) วาดรูปหลายเหลี่ยมโดยกาหนดพิกัดและ จานวนพิกัด
  • 16. Drawing Shape • การวาดรูปให้นึกถึงพิกัดเสมอ • หากนึกไม่ออกให้ลองวาดบนกระดาษก่อน – สังเกตว่ามีจุดใดเริ่มต้น, สิ้นสุด และใช้เรขาคณิตแบบใด • รูปที่ใช้บ่อยสามารถสร้างเป็นคลาสใหม่ได้ – extends JPanel , override paintComponent(g: Graphics) – override getPreferredSize(): Dimension เพื่อบอกขนาดขั้นต่า ของรูป
  • 17. Drawing Shape by Object • เราสามารถสั่งให้ Graphics2D วาดรูปจาก object ได้ – ส่วนใหญ่สร้างจากคลาสใน package java.awt.geom – สั่งวาดผ่าน method draw(s: Shape) • สามารถกาหนดรูปร่างได้หลากหลายมากขึ้น – เพิ่มความยืดหยุ่น • สามารถอ้างถึงรูปร่างที่วาดได้ – มีประโยชน์ในการอ้างอิงถึงรูปร่างที่วาด – ทา animation ได้ง่ายขึ้น
  • 18. Drawing Shape by Object Method Object drawLine(x1: int, y1: int, x2: int, y2: int) Line2D.Double Line2D.Float drawOval(x: int, y: int, width: int, height: int) Ellipse2D.Double Ellipse2D.Float drawRect(x: int, y: int, width: int, height: int) Rectangle2D.Double Rectangle2D.Float drawPolygon(xPoints: int[], yPoints: int[], nPoints: int) Polygon drawArc(x: int, y: int, width: int, height: int, startAngle: int, arcAngle: int) Arc2D.Double Arc2D.Float
  • 19. Fill Shape • หากเข้าใจการวาด การเทสีจะไม่มีปัญหา • g2d.fill…(…) – เปลี่ยนจาก draw… เป็น fill… – ยกเว้น fillLine, fillString • สั่งเทสีผ่าน method fill(s: Shape) g2d.fillRect(0, 0, 100, 100); g2d.fill( new Rectangle2D.Double(100, 100, 100, 100) );
  • 20. Area • บางรูปไม่สามารถวาดด้วยวิธีการตรง – ถึงแม้ polygon อาจจะเป็นไปยาก • พยายามมองให้เป็นรูปเรขาคณิต – รูปเรขาคณิตที่ซ้อนทับกัน • สามารถใช้คลาส Area ช่วยวาดรูปได้ – java.awt.geom – Area implements Shape – สามารถวาดเส้นหรือเทสีได้
  • 23. Transformation • รูปร่างหนึ่งสามารถเปลี่ยนเป็นรูปร่างอื่นได้ • Transform = การแปลง – Linear Transform ในวิชา 01417322 • ใช้วัตถุของคลาส AffineTransform ในการแปลง – แปลงได้ทั้ง g2d และ object รูปร่าง – ช่วยจัดการเรื่องคณิตศาสตร์ที่ซับซ้อน
  • 25. Transformation in g2d • การแปลงใน g2d ทาให้พิกัดการเริ่มต้นวาดรูปเปลี่ยนไป – เปลี่ยนแปลงตามการแปลง • การแปลงมีผลต่อการวาดรูปถัดไป – ลาดับก่อนหลังของคาสั่ง – แปลงไปแล้วอย่าลืมแปลงกลับ • ดูการแปลงด้วย g2d.getTransform(): AffineTransform
  • 26. Transformation in g2d Graphics2D g2d = (Graphics2D) g; g2d.setColor(Color.BLUE); g2d.fillRect(0, 0, 100, 100); g2d.setColor(Color.GREEN); g2d.translate(100, 100); g2d.fillRect(0, 0, 100, 100); AffineTransform t = g2d.getTransform(); System.out.println(t.getTranslateX()); System.out.println(t.getTranslateY());
  • 27. Transformation in g2d Graphics2D g2d = (Graphics2D) g; g2d.setColor(Color.BLUE); g2d.fillRect(0, 0, 100, 100); g2d.setColor(Color.GREEN); g2d.translate(100, 100); g2d.fillRect(0, 0, 100, 100); g2d.setColor(Color.BLACK); g2d.fillOval(-100, 0, 100, 100); AffineTransform t = g2d.getTransform(); System.out.println(t.getTranslateX()); System.out.println(t.getTranslateY());
  • 28. Transformation in Shape • การแปลงของ Shape object ต้องใช้ Area object ช่วย – คลาส AffineTransform – + new(s: Shape) • area.transform(t: AffineTransform) – สร้างและกาหนดรูปแบบการแปลงก่อน
  • 29. Transformation in Shape Graphics2D g2d = (Graphics2D) g; g2d.setColor(new Color(0, 150, 200)); Area area = new Area( new Rectangle2D.Double(0, 0, 100, 100) ); AffineTransform t = new AffineTransform(); t.translate(150, 150); t.scale(2, 2); t.rotate(Math.toRadians(45)); area.transform(t); g2d.fill(area);
  • 31. Animation • Animation = ภาพเคลื่อนไหว • การเคลื่อนไหวเกิดขึ้นเมื่อมีแรงมากระทาหรือเคลื่อนไหวได้เอง – คน, สัตว์, สิ่งของ • การวาดภาพสามารถทาภาพเคลื่อนไหวได้ – แต่ละภาพวัตถุอยู่ตาแหน่งที่ต่างกัน – Stop motion – การสร้างภาพเคลื่อนไหวของกล้องวิดีโอ
  • 34. Computer’s Animation • 1 รูปของภาพเคลื่อนไหว = 1 frame • คอมพิวเตอร์วาดและลบรูปออกจากหน้าจอ – เหตุการณ์นี้เกิดขึ้นเร็วมาก – หากช้าจอจะกระพริบหรือกระตุก • Frame per second (FPS) – จานวนรูปภาพที่วาดภายใน 1 วินาที – มาตรวัดความลื่นของเกมและภาพยนตร์ – 30 ~ 60 FPS
  • 36. Animation in Java 2D • ใน Java สามารถสร้างภาพเคลื่อนไหวด้วยวิธีเดียวกัน • เมื่อพิกัดเปลี่ยนแปลง ลบแล้ววาดรูปใหม่ – เรียก method repaint() • รูปที่เป็นภาพเคลื่อนไหวต้องอ้างถึงได้ – เปลี่ยนแปลงพิกัดได้ – ปรับเปลี่ยนรูปทรงได้ – แปลงได้
  • 37. Animation in Java 2D Graphics2D g2d = (Graphics2D) g; g2d.fillRect(0, 0, 100, 100); g2d.fillRect(x, y, 100, 100); g2d.fillRect(0, 0, width, height); g2d.fillRect(x, y, width, height); อ้างถึงไม่ได้ เปลี่ยนตาแหน่งได้เท่านั้น เปลี่ยนขนาดได้เท่านั้น อ้างถึงได้ทั้งหมด
  • 38. Animation in Java 2D • การลบและวาดภาพใหม่เป็นสิ่งที่ต้องทาตลอดเวลา • คอมพิวเตอร์ทางานได้เพียง 1 อย่างเท่านั้น – โปรแกรมต้องทางาน รูปก็ต้องวาด – เป็นไปไม่ได้ ? • Multithreading – สร้าง thread สาหรับจัดการการวาดโดยเฉพาะ
  • 39. Timer API • Package javax.swing.Timer • คลาสสาหรับจัดการสิ่งที่ต้องทาเป็นช่วงกาหนดเวลา – ทุก ๆ 1 วินาที • สามารถใช้ Timer ในการสั่งลบและวาดได้ – สิ่งที่ต้องทา: ลบแล้ววาดใหม่ – อาจต้องอัพเดตค่าบางอย่าง • สิ่งที่จะทา เขียนในคลาสที่ implements ActionListener – Anonymous class, Inner class, class ปกติ – ตามความเหมาะสมของสิ่งที่จะทา
  • 40. Timer API final int ONE_SECOND = 1000; Timer t = new Timer(ONE_SECOND, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO: Implement update algorithm and logic here // TODO: Repaint } });
  • 41. Timer API • Timer object สามารถสั่งเริ่มและหยุดได้ – t.start() – t.stop() – ไม่ต้องกังวลเรื่องการ interrupt ของ thread • พยายามสั่งหยุด Timer เมื่อจบโปรแกรมทุกครั้ง – บางครั้ง process ไม่หยุดการทางาน
  • 42. Timer API final int ONE_SECOND = 1000; Timer t = new Timer(ONE_SECOND, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println(new java.util.Date()); } }); t.start();
  • 43. Translation • การเปลี่ยนแปลงรูปร่างเพื่อสร้างภาพเคลื่อนไหว – หาสมการที่สามารถบอกตาแหน่งได้โดยใช้หมายเลข frame – กาหนดระยะการเปลี่ยนแปลงต่อ frame • ขึ้นกับความง่ายและเหมาะสม – หมายเลข frame overflow ได้ – การเคลื่อนที่บางประเภทมองระยะการเปลี่ยนแปลงยาก
  • 44. Translation • การเลื่อนขนานแบบเส้นตรง – การเดินทางเป็นแนวเส้นตรง – สมการเชิงเส้นตัวแปรเดียว 𝑥 𝑡 = 𝑠 𝑥 𝑡 + 𝑥0 𝑦𝑡 = 𝑠 𝑦 𝑡 + 𝑦0 𝑑𝑥 𝑡 𝑑𝑡 = 𝑑𝑥 = 𝑠 𝑥 𝑑𝑦𝑡 𝑑𝑡 = 𝑑𝑦 = 𝑠 𝑦
  • 45. Translation 𝑥𝑡 = 2𝑡 𝑦𝑡 = 𝑡 𝑥0 = 0 𝑑𝑥 = 2 𝑦0 = 0 𝑑𝑦 = 1 Rectangle2D.Double rect = new Rectangle2D.Double(0, 0, 2, 2); // Initial Initial Initial public void actionPerformed(ActionEvent e) { rect.x += 2; rect.y += 1; screenPanel.repaint(); t++; } 𝑑𝑥 𝑑𝑦
  • 46. Translation • การเลื่อนขนานแบบวงกลม, วงรี – สามารถใช้เรื่องวงกลม 1 หน่วยในการแก้ปัญหา 𝑥 𝑡 2 + 𝑦𝑡 2 = 𝑟 𝑥 𝑡 = 𝑟𝑥 cos 𝑠𝑡 + 𝜃 + 𝑥0 𝑦𝑡 = 𝑟𝑦sin 𝑠𝑡 + 𝜃 + 𝑦0 𝑑𝑥 = −𝑟𝑥 𝑠 sin 𝑠𝑡 + 𝜃 𝑑𝑦 = 𝑟𝑦 𝑠cos 𝑠𝑡 + 𝜃
  • 47. Translation 𝑥𝑡 = 100 cos 𝑡 + 45° + 100 𝑦𝑡 = 100sin 𝑡 + 45° + 100 𝑑𝑥 = −100 sin 𝑡 + 45° 𝑑𝑦 = 100cos 𝑡 + 45° 𝑥0 = 100 𝑦0 = 100
  • 49. Collision • การชนของวัตถุสองมิติเกิดขึ้นเมื่อวัตถุซ้อนกัน • การชนกันขึ้นกับความเป็นจริงของวัตถุ – ขึ้นกับ policy ว่าเป็นอย่างไร – อะไรทะลุได้ ทะลุไม่ได้ • บางครั้งเมื่อวัตถุชนกันทาให้ความเร็วเปลี่ยนไป – 𝑑𝑥, 𝑑𝑦 ต้องเปลี่ยนแปลงค่าได้
  • 50. Collision • การตรวจสอบการชนมีได้สองวิธี – ตรวจสอบพิกัดสองรูปว่าซ้อนทับหรือไม่ – ใช้สมบัติ intersect ของ Area object • ขึ้นกับลักษณะ – ชนเฉพาะด้านหรือชนได้รอบทิศ – รูปซับซ้อนหรือไม่ • FPS มาก ยิ่งทาให้การตรวจสอบเหมือนจริงยิ่งขึ้น
  • 51. Collision if (rect.getMinX() < 0) { dx = speed; } else if (rect.getMaxX() > screenPanel.getWidth()) { dx = -speed; } if (rect.getMinY() < 0) { dy = speed; } else if (rect.getMaxY() > screenPanel.getHeight()) { dy = -speed; } rect.x += dx; rect.y += dy; screenPanel.repaint();