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
Why Rust? - Matthias Endler - Codemotion Amsterdam 2016
PDF
暗認本読書会9
PPTX
90分 Scheme to C(勝手に抄訳版)
PDF
네이버 오픈세미나 백엔드_아키텍쳐
PPTX
L2 over l3 ecnaspsulations (english)
PDF
0章 Linuxカーネルを読む前に最低限知っておくべきこと
PDF
PostgreSQL + pgpool構成におけるリカバリ
PDF
ネットワークが切れても大丈夫!リアルタイムWebアプリケーションを簡単開発するフレームワーク Winter Cardinalのご紹介
Why Rust? - Matthias Endler - Codemotion Amsterdam 2016
暗認本読書会9
90分 Scheme to C(勝手に抄訳版)
네이버 오픈세미나 백엔드_아키텍쳐
L2 over l3 ecnaspsulations (english)
0章 Linuxカーネルを読む前に最低限知っておくべきこと
PostgreSQL + pgpool構成におけるリカバリ
ネットワークが切れても大丈夫!リアルタイムWebアプリケーションを簡単開発するフレームワーク Winter Cardinalのご紹介

What's hot (19)

PDF
go generate 完全入門
PDF
Message Redelivery: An Unexpected Journey - Pulsar Summit SF 2022
DOC
Obracenje muslimanke
PDF
AWS와 함께 한 쿠키런 서버 Re-architecting 사례 (Gaming on AWS)
PDF
CNN for sentence classification
PDF
Rustで始める競技プログラミング
PPTX
ARM LinuxのMMUはわかりにくい
PDF
【15-A-1】ドラゴンクエストXを支える失敗事例
PPTX
Adcとは?〜A10 Thunderで可能なこと〜
PDF
TPC-DSから学ぶPostgreSQLの弱点と今後の展望
PDF
Linux女子部 firewalld徹底入門!
PPTX
대용량 분산 아키텍쳐 설계 #1 아키텍쳐 설계 방법론
ODP
Rust Primer
PDF
System Device Tree and Lopper: Concrete Examples - ELC NA 2022
PPTX
Python의 계산성능 향상을 위해 Fortran, C, CUDA-C, OpenCL-C 코드들과 연동하기
PDF
量子アニーリングのこれまでとこれから -- ハード・ソフト・アプリ三方向からの協調的展開 --
PDF
OpenStackをさらに”使う”技術 概要と基礎操作
PDF
zkStudyClub: HyperPlonk (Binyi Chen, Benedikt Bünz)
PPTX
Network Security v1.0 - Module 1.pptx
go generate 完全入門
Message Redelivery: An Unexpected Journey - Pulsar Summit SF 2022
Obracenje muslimanke
AWS와 함께 한 쿠키런 서버 Re-architecting 사례 (Gaming on AWS)
CNN for sentence classification
Rustで始める競技プログラミング
ARM LinuxのMMUはわかりにくい
【15-A-1】ドラゴンクエストXを支える失敗事例
Adcとは?〜A10 Thunderで可能なこと〜
TPC-DSから学ぶPostgreSQLの弱点と今後の展望
Linux女子部 firewalld徹底入門!
대용량 분산 아키텍쳐 설계 #1 아키텍쳐 설계 방법론
Rust Primer
System Device Tree and Lopper: Concrete Examples - ELC NA 2022
Python의 계산성능 향상을 위해 Fortran, C, CUDA-C, OpenCL-C 코드들과 연동하기
量子アニーリングのこれまでとこれから -- ハード・ソフト・アプリ三方向からの協調的展開 --
OpenStackをさらに”使う”技術 概要と基礎操作
zkStudyClub: HyperPlonk (Binyi Chen, Benedikt Bünz)
Network Security v1.0 - Module 1.pptx
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();