چند سوال در مورد ساخت باران (قسمت 13-4)
سلام دوستان 2 تا سوال داشتم در مورد آموزش ساخت باران،ممنون میشم راهنمایی کنید :
1-استاد در اواخر آموزش گفتند کاری کنیم که با action move هر 100 ms یک دایره رسم بشه ،به نظر شما روشی که من رفتم درسته ؟ و آیا کسی روش اصولی تری سراغ داره؟
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
currentTime = System.currentTimeMillis();
Circle circle = new Circle();
circle.x = event.getX();
circle.y = event.getY();
circle.spawnTime = System.currentTimeMillis();
circles.add(circle);
invalidate();
break;
}
case MotionEvent.ACTION_MOVE: {
if (System.currentTimeMillis() - currentTime > 1000) {
Circle circle = new Circle();
circle.x = event.getX();
circle.y = event.getY();
circle.spawnTime = System.currentTimeMillis();
circles.add(circle);
invalidate();
currentTime = System.currentTimeMillis();
}
break;
}
که البته currentTime یک فیلده.
2-همونطور که میدونید و خود استاد هم در پایان آموزش گفتند ،بعد از هر سری نمایش دایره ها حتی بعد از محو شدنشان هنوز در آرایه موجود اند و با دایره های جدید به ادامه آرایه اضافه میشود.
درصورتی که برای بهینه شدن کد باید دایره های محو شده از آرایه حذف شوند ،از بین چند تا راه حلی که به ذهنم رسید دیدن روش پایین بهترینه اما می خوام بدونم کسی روش بهینه تری سراغ نداره ؟
private void releaseMomory() {
if (circles.size() != 0) {
for (int i = 0; i < circles.size(); i++) {
try {
if (System.currentTimeMillis() - circles.get(i).spawnTime > 2000)
circles.remove(i);
}
catch (NullPointerException e) {
e.printStackTrace();
}
}
}
}
در اصل ما از تابع بالا استفاده میکنیم و به thread در متد initialize میگیم :
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true)
try {
Thread.sleep(33);
releaseMomory();
postInvalidate();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
البته حتما باید در متد onDraw به جای استفاده از حلقه foreach از for معمولی استفاده کنیم :
for (int i = 0; i < circles.size(); i++){
}
وگرنه با ارور ConcurrentModificationException میرسیم





در واقع پاک کردن دایره ها نیاز به یک MainLoop مناسب داره که قبل از هر کاری ابتدا عناصر زائد از آرایه خارج می شن و بعد عناصر قابل رسم، ترسیم می شن. به این ترتیب مشکلی پیش نمیاد اما پیاده سازی همین موضوع کار ساده ای نیست و بیشتر به مبحث طراحی بازی بر می گرده. هدف من از طراحی آموزش «باران» آموزش نوشتن چنین افکتی نبود چرا که راه های دیگری برای خلق آن وجود دارد که بهینه است. هدف من این بود که به نوعی منطق فکر کردن، الگوریتمیک و استفاده از امکانات کنترل های سفارشی، برای خلق ایده های بدیع برسیم.

سلام. استاد بهتره یه دوره آموزشی برای بازی سازی و اینا رو هم بزارید خیلی عالی میشه. خیلی ها مشتاقن یاد بگیرن منجمله خودم.

من از روش این دوستمون استفاده کردم ویکم کد رو تعمیم دادم.به این صورت که یه tread جدید واسه حذف کردن آرایه (دایره های ناپدید شده) نوشتم و با استفاده از handle صداش کردم.که این روش اصلا کرشی نداشته.
این کد در CustomRainActivity اضافه کردم:
public static Handler handler = new Handler();
و در CustomRain در متد initialize یک tread جدید ساختم:
Thread xthread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(33);
CustomRainActivity.handler.post(new Runnable() {
@Override
public void run() {
releaseMemory();
}
});
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
xthread.start();
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .