السبت، 31 يوليو 2010

التحريك

مقدمة
في هذا الدرس سوف نتعرف على أسس التحريك وهي نفس الأسس التي تعتمد عليها جميع الألعاب حتى ألعاب الحاسوب تعتمد على طرق مشابهة للمبادئ المطروحة في هذا الدرس.
ملاحظة قبل المتابعة
هذا الدرس يعتمد بشكل كلي على ال Multi-Threading في جافا لذلك يجب عليك الاحاطه في هذا الموضوع. يمكنك الاطلاع على هذا الدرس الممتاز في منتيدات الفريق العربي.


public class AnimationCanvas extends Canvas implements Runnable {

    protected void showNotify() {
        Random r = new Random( System.currentTimeMillis() );
        x = r.nextInt( getWidth() );
        y = r.nextInt( getHeight() );
        dirX = 4;
        dirY = 4;

    }

    protected void paint(Graphics g) {
        g.setColor( 0x0 );
        g.fillRect( 0, 0, getWidth(), getHeight() );

        g.setColor( 0xFFFFFF );
        g.fillRect( x, y, WIDTH, HEIGHT );

    }

    public void run() {
        while( !quit ) {
            x += dirX;
            y += dirY;

            if( x <= 0 || x + WIDTH >= getWidth() ) {
                dirX *= -1;

            }

            if( y <= 0 || y + HEIGHT >= getHeight() ) {
                dirY *= -1;
                
            }
            repaint();
            serviceRepaints();

            try {
                Thread.sleep( 50 );

            } catch( Exception ex ) {
                ex.printStackTrace();

            }

        }

    }

    public void start() {
        Thread t = new Thread( this );
        t.start();

    }

    public void stop() {
        quit = true;

    }
    private boolean quit = false;
    private int x;
    private int y;

    private int dirX;
    private int dirY;
    private final int WIDTH = 10;
    private final int HEIGHT = 10;
}

في السطور ما بين 3 و 9 قمنا بأخذ قيمه عشوائيه لكل من الاحداثيات السينية والصادية. الاحداثايات السينية محصورة ما بين 0 و عرض شاشه الهاتف أما الاحداثيات الصادية فهي محصورة ما بين 0 و ارتفاع الشاشة. ثم قمنا بتجهيز متجهات الحركة على المحورين بقيم ابتدائية تساوي 4 لكل منهما.


لاحظ أن الفئة تقوم بعمل implements لل Runnable أي أنها يمكن أن تكون قيمه مرسلة لخيط معين لتنفيذها في ذلك الخيط وهو ما تم عمله فعلا في ال start method ما بين السطور 50 و 54.

في ال run method نقوم بالتحرك خطوه على كل من المحاور ثم نقوم بفحص القيم الجديدة للاحداثايت فاذا تجاوزت أحدها الشاشه نقوم بعكس اتجاه الحركه. هذه ال method عالقه في حلقه تكراريه لا نهائيه لن تنتهي الا بتغيير قيمه المتغير quit الى false.

في كل حلقه نقوم باعاده رسم المربع في المكان الجديد ثم نجبر الخيط على الانتظار لمده 50 milliseconds.

الان نقوم بعرض هذه الشاشة على شاشه الهاتف كالتالي:
public class AnimationMidlet extends MIDlet implements CommandListener {
    AnimationCanvas animator;
    
    public void startApp() {
        animator = new AnimationCanvas();
        animator.start();
        Display.getDisplay(this).setCurrent( animator );
        animator.addCommand( new Command( "Exit", Command.EXIT, 0 ) );
        animator.setCommandListener( this );

    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }

    public void commandAction(Command c, Displayable d) {
        animator.stop();
        destroyApp(true);
        notifyDestroyed();
    }
}

ليست هناك تعليقات:

إرسال تعليق