Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Программирование Android

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 34, средняя оценка - 4.82
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 314
#1

onTouchEvent в потоке - Программирование Android

21.02.2012, 12:02. Просмотров 4365. Ответов 22
Метки нет (Все метки)

Здравствуйте. Задача изменить с помощью onTouchEvent(MotionEvent event) переменную public int b и отрисовать графику с новым параметром в цикле – без invalidate();.
Переменная public int b наверняка меняется но метод
Java
1
2
3
4
5
 public void onDraw(Canvas canvas) 
       {
           x=x+b;
        canvas.drawBitmap(bmp, x, y, null);
       }
не видит этого изменения.
Вот основные классы
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.view.MotionEvent;
 
 public class Sprite {
   
     private GameView gameView;
    
    private Bitmap bmp;
   public int x = 0;
    private int y = -155;
     public int b=1;
  
    /**Ширина*/
    private int width;
    
    /**Высота*/
    private int height;
    public boolean onTouchEvent(MotionEvent event)
    {
        Float X=(Float)event.getX();
        Float Y=(Float)event.getY();
        int Action=event.getAction();
        
        if (event.getAction() == MotionEvent.ACTION_DOWN)
        {
           b=5; 
                }
        if (event.getAction() == MotionEvent.ACTION_UP)
        {
             b=55;
                }
                if (event.getAction() == MotionEvent.ACTION_MOVE)
                {
                     
                        }
        return true;
    }      
       /**Конструктор*/
    public Sprite(GameView gameView, Bitmap bmp) 
    {
          this.gameView = gameView;
          this.bmp = bmp;
          this.width = bmp.getWidth(); 
          this.height = bmp.getHeight(); 
    }
 
       public void onDraw(Canvas canvas) 
       {
           x=x+b;
        canvas.drawBitmap(bmp, x, y, null);
       }
}
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
 public class GameView extends SurfaceView {
   
   
    /**Загружаем спрайт*/
    private Bitmap bmp;
        
    /**Поле рисования*/
    private SurfaceHolder holder;
    
    /**объект класса GameView*/
    private GameManager gameLoopThread;
    
    /**Объект класса Sprite*/
    private Sprite sprite;
    
   
    /**Конструктор*/
    public GameView(Context context) 
    {
          super(context);
          gameLoopThread = new GameManager(this);
          holder = getHolder();
          
          /*Рисуем все наши объекты и все все все*/
          holder.addCallback(new SurfaceHolder.Callback() 
          {
                        /*** Уничтожение области рисования */
                 public void surfaceDestroyed(SurfaceHolder holder) 
                 {
                        boolean retry = true;
                        gameLoopThread.setRunning(false);
                        while (retry) 
                        {
                               try 
                               {
                                     gameLoopThread.join();
                                     retry = false;
                               } catch (InterruptedException e) 
                               {
                               }
                        }
                 }
 
                 /** Создание области рисования */
                 public void surfaceCreated(SurfaceHolder holder) 
                 {
                        gameLoopThread.setRunning(true);
                        gameLoopThread.start();
                 }
 
                 /** Изменение области рисования */
                 public void surfaceChanged(SurfaceHolder holder, int format,
                               int width, int height) 
                 {
                 }
          });
          bmp = BitmapFactory.decodeResource(getResources(), R.drawable.bad1);
          sprite = new Sprite(this,bmp);
          
    }
 
    /**Функция рисующая все спрайты и фон*/
    protected void onDraw(Canvas canvas) 
    {
          canvas.drawColor(Color.BLACK);
          sprite.onDraw(canvas);
         
    }
   
          }
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import android.graphics.Canvas;
 
public class GameManager extends Thread
{
       /**Наша скорость в мс = 10*/
       static final long FPS = 500;
      
       /**Объект класса GameView*/
       private GameView view; 
 
       /**Задаем состояние потока*/
       private boolean running = false;
      
       /**Конструктор класса*/
       public GameManager(GameView view) 
       {
             this.view = view;
       }
 
        /**Задание состояния потока*/
       public void setRunning(boolean run) 
       {
             running = run;
       }
 
       /** Действия, выполняемые в потоке */
 
       @Override
       public void run() 
       {
             long ticksPS = 1000 / FPS;
             long startTime;
             long sleepTime;
             while (running) {
                    Canvas c = null;
                    startTime = System.currentTimeMillis();
                    try {
                           c = view.getHolder().lockCanvas();
                           synchronized (view.getHolder()) {
                                  view.onDraw(c);
                           }
                    } finally {
                           if (c != null) {
                                  view.getHolder().unlockCanvasAndPost(c);
                           }
                    }
                    sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
                    try {
                           if (sleepTime > 0)
                                  sleep(sleepTime);
                           else
                                  sleep(5);
                    } catch (Exception e) {}
             }
       }
}
Подскажите пожалуйста в чем тут причина?
0
Вложения
Тип файла: zip Tectnzapasn5.zip (3.12 Мб, 14 просмотров)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.02.2012, 12:02
Здравствуйте! Я подобрал для вас темы с ответами на вопрос onTouchEvent в потоке (Программирование Android):

Разгрузка onTouchEvent - Программирование Android
Пишу игру. В методе onTouchEvent у меня проходят практически все емкие операции - создание уровней игры (а это инициализация многих...

Не срабатывает onTouchEvent - Программирование Android
Всем доброго Вечера, недавно занимаюсь программирование под Android. Каким образом реализовать корректную обработку onTouchEvent в ниже...

Обработка onTouchEvent в Activity - Программирование Android
Хочу в активити обрабатывать все прикосновения, независимого от того, были ли они на кнопке или на свободном пространстве. Однако после...

OnTouchEvent - нарисовать точку - Программирование Android
Здравствуйте! Уже который час мучаюсь с программой. В том месте где пользователь прикасается к экрану нужно нарисовать точку (Circle)....

Warning: Custom view overrides onTouchEvent but not performClick - Программирование Android
У меня есть кастомный view который перегружает onTouchEvent следующим образом. На котором и висит варнинг. @Override public boolean...

ServerSocket в новом потоке - Программирование Android
По нажатию на кнопку запускаю новый поток. в Потоке открывается порт и ждет подключения: public void onClick(View view) { // TODO...

22
Bes-s
30 / 30 / 2
Регистрация: 05.11.2011
Сообщений: 178
21.02.2012, 12:22 #2
почему именно без invalidate() ?
0
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 314
21.02.2012, 13:41  [ТС] #3
Цитата Сообщение от Bes-s Посмотреть сообщение
почему именно без invalidate() ?
Потому что как тут написано при invalidate() "изображение будет обновляться только по нашему требованию", а здесь onDraw постоянно обновляется в цикле и его не надо вызывать, надо только с помощью onTouchEvent изменить в нем значение переменной b, (да и примеры проектов есть, где без invalidate() обходятся), причем public int b=1; имеет модификатор доступа public - значит его везде должно быть видно, и когда выделяешь b - он так же выделяется как в методе
Java
1
2
3
4
5
public void onDraw(Canvas canvas) 
       {
           x=x+b;
        canvas.drawBitmap(bmp, x, y, null);
       }
так и в
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 public boolean onTouchEvent(MotionEvent event)
    {
        Float X=(Float)event.getX();
        Float Y=(Float)event.getY();
        int Action=event.getAction();
        
        if (event.getAction() == MotionEvent.ACTION_DOWN)
        {
           b=5; 
                }
        if (event.getAction() == MotionEvent.ACTION_UP)
        {
                 b=55;
                }
                if (event.getAction() == MotionEvent.ACTION_MOVE)
                {
                         
                        }
        return true;
    }
но не чего не меняется при прикосновение к экрану.
0
Bes-s
30 / 30 / 2
Регистрация: 05.11.2011
Сообщений: 178
21.02.2012, 14:09 #4
не знаю в тему ли... но я onDraw() при вызове перегружаю, и указываю super.onDraw().
а вообще совет: выводить все в logcat. тогда будет видно, что выполнилось, сколько раз и через какое время. тогда будет проще отловить участок, где код не работает, или работает не так как надо. +можно будет увидеть реальный FPS на который способно устройство.

PS: если вы используете переменную только в одном классе, ее не следует делать public. модификатор public нужен только в том случае, если переменную вы будете использовать вне класса(метода, функции) где переменная объявлена.
0
NiRamz
211 / 211 / 16
Регистрация: 26.12.2010
Сообщений: 691
22.02.2012, 11:23 #5
Java
1
2
3
4
5
 /**Функция рисующая все спрайты и фон*/
    protected void onDraw(Canvas canvas){         
        canvas.drawColor(Color.BLACK); // отрисовываем фон
        sprite.onDraw(canvas);vas.drawBitmap(ball, x - (bmp.getWidth()/2), y-(bmp.getHeight()/2), null);
    }
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        switch(event.getAction()){
        case MotionEvent.ACTION_DOWN:
            x = me.getX();
            y = me.getY();
            break;
        case MotionEvent.ACTION_UP:
            break;
        case MotionEvent.ACTION_MOVE:
            break;
        }
        return true;
    }
куски кода из работающего тестового проекта.
так же советую почитать про видимость и доступность переменных и время их жизни. public необходим для того, что бы видеть переменную из других классов. так же:

выделяешь b - он так же выделяется как в методе
это он вам показывает одинаковые значения в коде, то есть что бы было легко найти одинаковые переменные/методы/объекты, а никак не доступность.

p.s. прежде чем пробывать написать игру, надо хотя бы про самые самые основы почитать ..
и еще, тестировал на своем слабеньком аппарате два обсолютно одинаковых примера, так вот тот что был написан с помощью SurfaceView помер при наличии порядка 700 объектов, тот что на openGL выдержал гораздо большую нагрузку.
0
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 314
24.02.2012, 14:05  [ТС] #6
Цитата Сообщение от NiRamz Посмотреть сообщение
куски кода из работающего тестового проекта.
Ошибки выдает -
Java
1
2
3
x = me.getX();
                        y = me.getY();
sprite.onDraw(canvas);vas.drawBitmap(ball, x - (bmp.getWidth()/2), y-(bmp.getHeight()/2), null);
Если я не ошибаюсь - me. - это event., в вашем примере приведены переменные (ball) и объект (если не ошибаюсь это vas.) которых нет в первоначальном проекте. А во вторых единственное отличие которое я вижу - в том , что в onTouchEvent вы присваиваете переменным x,y координаты прикосновения, но если попытаться устранить ошибки (и догадаться - что вы имели ввиду), то не чего не меняется при прикосновение к экрану.
Java
1
2
3
4
5
6
7
8
9
10
 protected void onDraw(Canvas canvas) 
    {
         
         canvas.drawColor(Color.BLACK); // отрисовываем фон
         sprite.onDraw(canvas);
         canvas.drawBitmap(bmp, x-(bmp.getWidth()/2), y-(bmp.getHeight()/2), null); // зачем писать 
         //этот метод, если он уже есть в sprite.onDraw(canvas);? - среда
        // фиксирует ошибку
        
    }
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 public boolean onTouchEvent(MotionEvent event)
    {
      
        
        switch(event.getAction()){
        case MotionEvent.ACTION_DOWN:
             x=event.getX();
             y=event.getY();
                break;
        case MotionEvent.ACTION_UP:
                break;
        case MotionEvent.ACTION_MOVE:
                break;
        }
        return true;
    }
Не могли бы вы сбросить проект или какой ни будь более понятный пример?
0
NiRamz
211 / 211 / 16
Регистрация: 26.12.2010
Сообщений: 691
24.02.2012, 14:40 #7
да на здоровье
0
Вложения
Тип файла: rar SurfaceView.rar (1.28 Мб, 65 просмотров)
NiRamz
211 / 211 / 16
Регистрация: 26.12.2010
Сообщений: 691
24.02.2012, 14:42 #8
sprite.onDraw - отрисовываются одни объекты (в цикле)
canvas.drawBitmap(bmp, x-(bmp.getWidth()/2), y-(bmp.getHeight()/2), null); - отрисовывается другой объект.
1
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 314
27.02.2012, 14:16  [ТС] #9
Спасибо. Почти разобрался как менять скорость движения мяча нажимая на нарисованные (не стандартные) кнопки, а можно ли так же менять скорость движения человечков ( sprite.onDraw), или их надо втыкать в класс где мяч находится?
0
NiRamz
211 / 211 / 16
Регистрация: 26.12.2010
Сообщений: 691
27.02.2012, 15:09 #10
а можно ли так же менять скорость движения человечков
скорость передвижения или скорость анимации?
0
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 314
27.02.2012, 16:38  [ТС] #11
Скорость передвижения, хотя для каждого человечка (чтоб им можно было управлять а у других был какой то интеллект) мне кажется правильнее свой класс создавать, и в каждом классе свой спрайт.
0
NiRamz
211 / 211 / 16
Регистрация: 26.12.2010
Сообщений: 691
27.02.2012, 16:59 #12
раз на то пошло, то делаешь базовый класс, с общим набором свойств/методов для всех (к примеру скорость, здоровье), так же можно сюда внести основную работу со спрайтами, что бы каждый раз не переписывать. Потом же просто наследовать от него уже нужное количество дочерних классов, описать конкретные сущности для этого "персонажа", его поведение в том числе. Все это для удобства работы с большим количеством объектов.

Для главного же персонажа можно создать отдельный класс с сущностями. или унаследовать от родительского.

p.s. все же я советовал бы использовать готовую openGl библиотеку для написания игр ..
0
dajver
409 / 273 / 18
Регистрация: 18.09.2010
Сообщений: 1,112
27.02.2012, 20:38 #13
Мои уроки используются))) Эт очень приятно) А если по теме то тебе нужно создать второй метод рисования который будет рисовать во втором потоке после нажатия на экран. Делаем так:

Создаем интерфейс для дальнейшего использования в потоке:
Java
1
2
3
4
private interface DrawHelper
{
    void draw(Canvas canvas);
}
Дальше нам нужно создать метод который будет повторять работу метода run но немного усовершенствованый:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void draw(DrawHelper helper)
{
    Canvas canvas = null;
    try
    {
        // подготовка Canvas-а
        canvas = mSurfaceHolder.lockCanvas();
        synchronized (mSurfaceHolder)
        {
                helper.draw(canvas);
        }
    }
    catch (Exception e) { }
    finally
    {
        if (canvas != null)
        {
            mSurfaceHolder.unlockCanvasAndPost(canvas);
        }
    }
}
Дальше нужно создать переменные которые будут юзать наш интерфейс в конструкторе или в методе онТач:
Java
1
2
3
4
5
/** Хелпер для перерисовки экрана */
private DrawHelper mDrawScreen;
 
/** Хелпер для рисования результата игры*/
private DrawHelper mDrawGameover;
И прописать нужные нам действия при нажатия на экран:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// функция для рисования экрана
    mDrawScreen = new DrawHelper()
    {
        public void draw(Canvas canvas)
        {
            onDraw(canvas);
        }
    };
 
    // функция для рисования результатов игры
    mDrawGameover = new DrawHelper()
    {
        public void draw(Canvas canvas)
        {
            // Вывели последнее состояние игры
            onDraw(canvas);
 
         //рисуем шо хотим       
        }
    };
Немного видоизменяем на run для того что бы не повторять работу метода draw():
Java
1
2
3
4
5
6
7
8
9
/** Действия, выполняемые в потоке */
public void run()
{
    while (running)
    {
            draw(mDrawScreen);
    }
    draw(mDrawGameover);
}
Метод draw() должен находится в классе потоке, потому что если разместить его в не класса потока будут проблемы с рисованием и возможно потрепает очень нервы.
1
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 314
28.02.2012, 09:32  [ТС] #14
Что то я запутался. Это все надо писать в одном классе или в разных? По идее если почти все у вас private то в одном, но кучу ошибок выдает
import android.graphics.Canvas;

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
public class GameManager extends Thread
{
       /**Наша скорость в мс = 10*/
       static final long FPS = 500;
      
       /**Объект класса GameView*/
       private GameView view; 
 
       /**Задаем состояние потока*/
       private boolean running = false;
       
      
       //СОЗДАЕМ ИНТЕРФЕЙС ДЛЯ ДАЛЬНЕЙШЕГО ИСПОЛЬЗОВАНИЯ В ПОТОКЕ:
       private interface DrawHelper  
       {
           void draw(Canvas canvas);
       }
       
       
      // ДАЛЬШЕ НАМ НУЖНО СОЗДАТЬ МЕТОД КОТОРЫЙ БУДЕТ ПОВТОРЯТЬ РАБОТУ МЕТОДА RUN НО НЕМНОГО УСОВЕРШЕНСТВОВАНЫЙ
       private void draw(DrawHelper helper)
       {
           Canvas canvas = null;
           try
           {
               // подготовка Canvas-а
               canvas = mSurfaceHolder.lockCanvas();   //ОШИБКА
               synchronized (mSurfaceHolder)    //ОШИБКА
               {
                       helper.draw(canvas);
               }
           }
           catch (Exception e) { }
           finally
           {
               if (canvas != null)
               {
                   mSurfaceHolder.unlockCanvasAndPost(canvas);   //ОШИБКА
               }
           }
       } //ОШИБКА
       
       
       //ДАЛЬШЕ НУЖНО СОЗДАТЬ ПЕРЕМЕННЫЕ КОТОРЫЕ БУДУТ ЮЗАТЬ НАШ ИНТЕРФЕЙС В КОНСТРУКТОРЕ ИЛИ В МЕТОДЕ ОНТАЧ:
       
       /** Хелпер для перерисовки экрана */
       private DrawHelper mDrawScreen;               //ОШИБКА
        
       /** Хелпер для рисования результата игры*/
       private DrawHelper mDrawGameover;                //ОШИБКА
       
     //И ПРОПИСАТЬ НУЖНЫЕ НАМ ДЕЙСТВИЯ ПРИ НАЖАТИЯ НА ЭКРАН:
    // функция для рисования экрана
       mDrawScreen = new DrawHelper()
       {
           public void draw(Canvas canvas)
           {
               onDraw(canvas);                  //ОШИБКА
           }
       };                                     
    
       // функция для рисования результатов игры
       mDrawGameover = new DrawHelper()
       {
           public void draw(Canvas canvas)
           {
               // Вывели последнее состояние игры
               onDraw(canvas);                     //ОШИБКА
    
            //рисуем шо хотим       
           }
       };                                //ОШИБКА
 
     //НЕМНОГО ВИДОИЗМЕНЯЕМ НА RUN ДЛЯ ТОГО ЧТО БЫ НЕ ПОВТОРЯТЬ РАБОТУ МЕТОДА DRAW():
       public void run()
       {
           while (running)
           {
                   draw(mDrawScreen);
           }
           draw(mDrawGameover);
       } 
       
       /**Конструктор класса*/
       public GameManager(GameView view) 
       {
           
             this.view = view;
       }
 
        /**Задание состояния потока*/
       public void setRunning(boolean run) 
       {
             running = run;
       }
 
       /** Действия, выполняемые в потоке */
}
Цитата Сообщение от dajver Посмотреть сообщение
Метод draw() должен находится в классе потоке, потому что если разместить его в не класса потока будут проблемы с рисованием и возможно потрепает очень нервы.
имееется ввиду этот метод?
Java
1
2
3
4
5
public void onDraw(Canvas canvas) 
       {
          
        canvas.drawBitmap(bmp, x, y, null);
       }
У вас нет случайно готового проекта?
0
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 314
28.02.2012, 16:12  [ТС] #15
Я вот тут попробовал из меча спрайт сделать, получилось очень "процедурно", идея в том, чтобы в зависимости от расстояния (if) запускать те или иные команды у соперника, а как это согласовать с классами - когда все координаты спрайтов приватные - не очень ясно. Вот основной класс
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
import java.util.ArrayList;
import java.util.List;
 
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
 
 
 
 
public class GameView extends SurfaceView implements SensorEventListener{   
    /**Объект класса GameManager*/
    private GameManager gameLoopThread;
    /**Список спрайтов*/
    private List<mySprite> sprites = new ArrayList<mySprite>();
    /**Переменная запускающая поток рисования*/
    private boolean running = false;
    
private int BMP_ROWS = 2;
    
    /**Колонок в спрайте = 3*/
    private int BMP_COLUMNS = 6;
    
    private float ballSpeed = 0;
    private int currentFrame = 0;
    
    private int nnn = 0;
    
    private int width;
    private int height;
    
    
    
    Bitmap ball;
    
    private int bnSpeed;
    private int currentFrame2 = 0;
    
    private int width2;
    private int height2;
    
    Bitmap bn;
   
    //кнопки
    
    float x=0, y=55,n,b,n2=255,b2=55,btn=43,btn2=280,fn=255, fn2=95;
    Bitmap button;
    private int width3;
    private int height3;
    //фон
    
    
    private SensorManager mSensorManager;
    private Sensor mSensor;
    private float ySensorValue = 0, zSensorValue = 0;
    Bitmap fon;
    
    
    /** Начало gamemanager class*/
    public class GameManager extends Thread{
        private GameView view;   
        public GameManager(GameView view){
              this.view = view;
        }
        public void setRunning(boolean run){
              running = run;
        }
 
        public void run(){
            while (running){
                Canvas canvas = null;
                try{
                    // подготовка Canvas-а
                    canvas = view.getHolder().lockCanvas();
                    synchronized (view.getHolder()){
                        // собственно рисование
                        onDraw(canvas);
                    }
                }
                catch (Exception e) { }
                finally{
                    if (canvas != null){
                        view.getHolder().unlockCanvasAndPost(canvas);
                    }
                }
            }
        }
    }
    
    //-----------------------------------------Конец класса GameManager-------------------------------------
    
    
    int heightWindow, widthWindow;
    Context mContext;
    /**Конструктор класса*/
    public GameView(Context context, int w, int h) {
          super(context);
          gameLoopThread = new GameManager(this);
          this.heightWindow = h;
          this.widthWindow = w;
          this.mContext = context;
          
          mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
          mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
          mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);
          
          
       //this.width = ball.getWidth() / BMP_COLUMNS;
         //  this.height = ball.getHeight() / BMP_ROWS;
          ball = BitmapFactory.decodeResource(getResources(), R.drawable.bn5);
          bn = BitmapFactory.decodeResource(getResources(), R.drawable.bn52);
          button = BitmapFactory.decodeResource(getResources(), R.drawable.button);
         fon = BitmapFactory.decodeResource(getResources(), R.drawable.fon);
          
          /*Рисуем все наши объекты и все все все*/
          getHolder().addCallback(new SurfaceHolder.Callback() {
                 /*** Уничтожение области рисования */
                 public void surfaceDestroyed(SurfaceHolder holder) {
                     boolean retry = true;
                     gameLoopThread.setRunning(false);
                    
                     while (retry){
                        try{
                            // ожидание завершение потока
                            gameLoopThread.join();
                            retry = false;
                        }
                        catch (InterruptedException e) { }
                     }
                 }
 
                 /** Создание области рисования */
                 public void surfaceCreated(SurfaceHolder holder) {
                        createSprites();
                        gameLoopThread.setRunning(true);
                        gameLoopThread.start();
                 }
 
                 /** Изменение области рисования */
                 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                 }
          });
    }
 
    /**Создание всех спрайтов*/
    private void createSprites(){
          sprites.add(createSprite(R.drawable.bad1));
          
    }
 
    /**Создаем спрайт на сцене*/
    private mySprite createSprite(int resouce) {
          Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
          return new mySprite(this, bmp);
    }
    
    
    // Измеряем fps
    int     m_count     = 0;
    long     m_fps         = 0;
    long     m_startTime = System.currentTimeMillis();  
    // заканчиваем
    
    /**Функция рисующая все спрайты и фон*/
    protected void onDraw(Canvas canvas){         
        //canvas.drawColor(Color.BLACK); // отрисовываем фон
        canvas.drawBitmap(fon, fn-fon.getWidth()/2, fn2-fon.getHeight()/2, null);
        seeFPS();
        
        //this.width = bmp.getWidth() / BMP_COLUMNS;
       // this.height = bmp.getHeight() / BMP_ROWS;
       // this.gameView = gameView;
       // this.bmp = bmp;
        //боец игрока
        
        
        
        
        canvas.drawBitmap(button, btn-button.getWidth()/2, btn2-button.getHeight()/2, null);
        
        width = ball.getWidth()/6;
        height = ball.getHeight();
        
        currentFrame = ++currentFrame % BMP_COLUMNS;
        moveBall();
         int srcX = currentFrame * width;
         int srcY = 0;
         
         Rect src = new Rect(srcX, srcY, srcX + width, srcY + height);//кусок снимка
         Rect dst = new Rect((int)x, (int)y, (int)x + width,(int) y + height);//нразмер его на экране
        
        canvas.drawBitmap(ball, src, dst, null);
         
        //боец комп
        
        width2 = bn.getWidth()/6;
        height2 = bn.getHeight();
        
        currentFrame2 = ++currentFrame2 % BMP_COLUMNS;
        
         int srcX2 = currentFrame * width2;
         int srcY2 =0;
         
         Rect src2 = new Rect(srcX2, srcY2, srcX2 + width2, srcY2 + height2);//кусок снимка
         Rect dst2 = new Rect((int)n2, (int)b2, (int)n2 + width2,(int) b2 + height2);//нразмер его на экране
        
        canvas.drawBitmap(bn, src2, dst2, null);
        
        
        Paint p = new Paint(createPaint(0));
        canvas.drawText("FPS: " + String.valueOf(m_fps), 10, p.getTextSize() + 5, p);
        
    }
    
    
    
     /**что то для измерения FPS*/
    public void seeFPS() {
    if (System.currentTimeMillis() - m_startTime > 1000){
            m_fps = (1000 * m_count)/ (System.currentTimeMillis() - m_startTime);
            m_startTime = System.currentTimeMillis();
            m_count = 0;
            Log.v("FPS", Integer.toString((int)m_fps));
        }
       ++m_count;
     }
 
    public void onAccuracyChanged(Sensor sensor, int accuracy) {}
 
    public void onSensorChanged(SensorEvent event) {
        // TODO Auto-generated method stub
        //float [] values = event.values;
        switch(event.sensor.getType()){
        case Sensor.TYPE_ORIENTATION:{
            ySensorValue = event.values[SensorManager.DATA_Y];
            zSensorValue = event.values[SensorManager.DATA_Z];
            break;
        }
        }
    }
    
    // перемещаем мяч, проверяя на пересечение с краями экрана
    private void moveBall(){
        x = x+ballSpeed;
          if (n2 + bnSpeed > 325) {
              bnSpeed = -5;
       }
       if (n2 + bnSpeed< 0) {
              bnSpeed = 5;
       }
       n2 = n2 + bnSpeed;
        
        
    }
 
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        switch(event.getAction()){
        case MotionEvent.ACTION_DOWN:
            //x = me.getX();
            //y = me.getY();
            //sprites.add(createSprite(R.drawable.bad1));
             n=event.getX();
             b=event.getY();
            if(b>265&&b<285&&n<80&&n>55){
                ballSpeed=8;
                bnSpeed=8;
            }
            if(b>265&&b<285&&n<55&&n>1){
                ballSpeed=-8;
                bnSpeed=-8;
            }
            break;
        case MotionEvent.ACTION_UP:
            //x = me.getX();
            //y = me.getY();
            ballSpeed=0;
            break;
        case MotionEvent.ACTION_MOVE:
            //x = me.getX();
            //y = me.getY();
            break;
        }
        return true;
    }
    
    private Paint createPaint(int sw){
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setSubpixelText(true);
        paint.setAntiAlias(true);
        paint.setColor(Color.GREEN);
        paint.setTextSize(10);
        return paint;
    }
}
0
Вложения
Тип файла: zip SurfaceView52.zip (2.95 Мб, 9 просмотров)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.02.2012, 16:12
Привет! Вот еще темы с ответами:

Остановить задачу в потоке - Программирование Android
Как можно остановить задачу в потоке, если использует ExecutorService ? ExecutorService es = Executors.newFixedThreadPool(2);

Handlers в новом потоке - Программирование Android
Почему не могу создать handlers в новом потоке ? Thread streamThread = new Thread(new Runnable() { public void run() { ...

Установить listener в потоке - Программирование Android
Нужно установить listener, но нет возможности его установить на Activity, можно ли как то обойти это. Есть возможность работы с Thread и...

Подскажите - не вызывается метод в потоке - Программирование Android
progress = ProgressDialog.show(getActivity(), &quot;Please wait...&quot;, &quot;Applying changes may take a few minutes.&quot;,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
28.02.2012, 16:12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru