بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]
پرسش و پاسخ

چند سوال در مورد ساخت باران (قسمت 13-4)

مدیریت گفتگو
Morteza 12 سال پیش
آخرین تغییر: 10 سال پیش

سلام دوستان 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 میرسیم

نظرات

sadeghbarout 12 سال پیش
من خودمم این دو مشکل رو که استاد گفته بود نوشتم ولی الان خیلی اون پروژه رو به خاطر ندارم ولی به نظر میاد راه های خوبی انتخاب کردی و بهینه هم هستن. البته تا اونجایی که یادمه من برای حذفشون همون موقع که دایره ها رو رسم میکرد دایره هایی که باید حذف بشن رو میریختم توی یه آرایه دیگه و در انتهای رسم کردن ها ، اون آرایه رو از آرایه اصلی حذف می کردم. ولی دیگه نمیدونم کدوم بهینه تره ;)
Morteza 12 سال پیش
منظورتون از انتهای رسم کردن ها چیه؟یعنی وقتی که ACTION UP اتفاق می افته؟
sadeghbarout 12 سال پیش
اگه درست خاطرم باشه دایره ها توی یه حلقه رسم میشدن. همون جا که شعاع و alpha ش، خونده ، تنظیم و رسم میشد. من توی همون حلقه این دایره های اضافه رو ریختم تو یه آرایه و بعد حلقه ، دایره اضافی ها رو پاک کردم. حالا اگه خواستی وقتی رفتم خونه برات میذارمش.
Morteza 12 سال پیش
این طور که من فهمیدم یعنی اگر مدت زمان حضور دایره ای 2 ثانیه بیشتر باشه قبل از دستور continue شما اون داره رو توی آرایه ات add می کنی وبعد از حلقه ،آرایه را clean میکنی!.....اما اینطوری که دایره ما از آرایه اصلی پاک نمیشه؟

پاسخ‌ها 3

uncocoder 12 سال پیش

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

نظرات

tux-world 12 سال پیش

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

نظرات

سیامک 10 سال پیش

من از روش این دوستمون استفاده کردم ویکم کد رو تعمیم دادم.به این صورت که یه 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();

نظرات


پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .