ترسیم تصویر donut در board ( بازی سازی با جاوا)
با قسمت دوم از سری آموزشهای بازیسازی با جاوا در خدمتتونم.
انشاالله که از این قسمت از آموزش، استفاده ی کافی رو ببرید.
اگر خاطرتون باشه،در قسمت قبل ، کار رو تا ساخت یک board (محیطی که بازی مون در اون به نمایش در میاد) پیش بردیم و در مرحله ی بعد دیدیم که چطور یک تصویر رو در board مون به نمایش دربیاریم.
برای رسم اشکال مختلف، جاوا توابع وکلاسهای بسیاری شامل ابزار نقاشی، کار با رنگها و تصاویرو... را در اختیار ما قرار داده .
در این قسمت قصد داریم به کمک این متد ها(که به JAVA 2D API معروفند) ،تصویر یک donut رو در board مون رسم کنیم.
خب، یک پروژه ی جدید ایجاد کنید ، یک پکیج در پروژتون قرار بدید و در اون، کلاسی بنام Board (از فرم JPanel )
ایجاد کنید.
رسم donut رو طبق توضیحات جلسه قبل، درون این کلاس باید پیاده سازی میکنیم.
public void paintComponent(Graphics g) {
super.paintComponent(g);
drawDonut(g);
}
عملیات رسم از متد paintComponent() آغاز میشود. برای تنها ورودی این متد، (g) ،
تابع drowDonat() را که عملا رسم را در آن پیاده سازی میکنیم ، فراخوانی میکنیم:
private void drawDonut(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
}
کلاس Graphics2D که از کلاس Graphics مشتق شده است، یک کنترل را در سطح بالا برای رسم ایجاد می کند .
قبل از اینکه به رسم شکلمون بپردازیم، از RenderingHints ، برای روانسازی خطوط رسممون استفاده میکنیم. برای انجام اینکار ،کد زیر را به تابع drawDonut() اضافه کنید.
RenderingHints rh
= new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
rh.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY)
g2d.setRenderingHints(rh);
حالا نویت به رسم خود donut میرسه. قبل از هر چیزی ،یک بیضی باید رسم کنیم.(که به کمک کلاس Ellipse2Dرسمش میکنیم.) مختصات مرکز بیضی و هم چنین اندازه ی طول و عرض بیضی را به عنوان ورودی ، وارد میکنیم:
Ellipse2D e = new Ellipse2D.Double(0, 0, 80, 130);
با دستور setStroke() مقدار ضخامت خطوط رسم رو مشخص میکنیم.(ما ضخامت 1 را در نظر گرفتیم. با افزایش این مقدار، خطوط رسم ضخیم تر میشوند.)
g2d.setStroke(new BasicStroke(1));
با دستور setColor() هم ،رنگ مورد نظر رو بهش میدیم.
g2d.setColor(Color.blue);
حالا برای اینکه مشخص کنیم که بیضی دقیقا کجای پنجره ی خروجی قرار بگیره باید از AffineTransform استفاده کنیم .
بهتر هست که برای اینکه خروجی مون شکل بهتری داشته باشد، رسم از مرکز پنجره آغاز شده باشد.
باااین حساب به طول و عرض پنجره نیاز داریم ، که با دستورات زیر، آنها را دریافت میکنیم:
Dimension size = getSize();
double w = size.getWidth();
double h = size.getHeight();
خب، مرکز پنجره با تعریف متغییر های فوق، میشود . (w/2, h/2) پس مختصات نقطه ی شروع رسم را به کمک AffineTransform، برابر این مقدار قرار میدیم. (در واقع با اینکار، نقطه ی سمت چپ بیضی در مرکز پنجره قرار میگیرد(.
AffineTransform at
= AffineTransform.getTranslateInstance(w/2, h/2);
برای رسم هم از دستور draw() استفاده میکنیم:
g2d.draw(at.createTransformedShape(e));
قبل از اینکه کدمون را کامل کنیم، بهتر هست که نتیجه ی کار رو تا به اینجا، ببینینم.
پس کلاس main رو هم،همونطور که در جلسه قبل اشاره کردیم،ایجاد کنید:
package basic_2dgame;
public class skeleton extends javax.swing.JFrame {
public skeleton() {
add(new Board());
setTitle("Donut");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(300,340);
setLocationRelativeTo(null);
}
@SuppressWarnings("unchecked")
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new skeleton().setVisible(true);
}
});
}
}
اگر پروژمون رو اجرا کنیم ،خروجی زیر رو میبینیم:
- حالا برای اینکه از این بیضی برسیم به شکل donut که هدف اصلیمون ،کافیه که بیضی ای که رسمش کردیم رو 72 مرتبه در یک حلقه دوران بدیم و رسمش کنیم.
اینکار رومیشه خیلی راحت به کمک حلقه ی for انجام داد . یعنی دستورات مربوط به AffineTransform و draw رو به داخل حلقه انتقال میدیم .
for (double deg = 0; deg < 360; deg += 5) {
AffineTransform at
= AffineTransform.getTranslateInstance(w/2, h/2);
at.rotate(Math.toRadians(deg));
g2d.draw(at.createTransformedShape(e));
خب،کار تمومه ...
فقط من یکبار دیگه قطعه کدهایی که در کلاس Board نوشتیم رو بطور کامل اینجا میارم براتون که شکل نهایی کلاس رو ببینید :
package basic_2dgame;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
public class Board extends javax.swing.JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
drawDonut(g);
}
@SuppressWarnings("unchecked")
private void drawDonut(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
RenderingHints rh
= new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
rh.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY)
g2d.setRenderingHints(rh);
Dimension size = getSize();
double w = size.getWidth();
double h = size.getHeight();
Ellipse2D e = new Ellipse2D.Double(0, 0, 80, 130);
g2d.setStroke(new BasicStroke(1));
g2d.setColor(Color.blue);
for (double deg = 0; deg < 360; deg += 5) {
AffineTransform at
= AffineTransform.getTranslateInstance(w/2, h/2);
at.rotate(Math.toRadians(deg));
g2d.draw(at.createTransformedShape(e));
}
}
حالا اگه پروژه رو اجرا کنیم، خروجی زیر رو مشاهده میکنیم:
کافیه برای این جلسه .عذر خواهی میکنم اگر کمی سنگین شد بحث امروزمون ...
به امید اینکه مورد استفاده ی همه ی عزیزان قرار گرفته باشه....
انشالله جلسه ی آینده وارد مبحث انیمیشن ، که از مهم ترین مباحث در بازیسازی است ، خواهیم شد.
نظرات کاربران