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

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

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

onTouchEvent в потоке - Android

21.02.2012, 12:02. Просмотров 4265. Ответов 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) {}
             }
       }
}
Подскажите пожалуйста в чем тут причина?
Вложения
Тип файла: zip Tectnzapasn5.zip (3.12 Мб, 14 просмотров)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Bes-s
30 / 30 / 2
Регистрация: 05.11.2011
Сообщений: 178
21.02.2012, 12:22     onTouchEvent в потоке #2
почему именно без invalidate() ?
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 293
21.02.2012, 13:41  [ТС]     onTouchEvent в потоке #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;
    }
но не чего не меняется при прикосновение к экрану.
Bes-s
30 / 30 / 2
Регистрация: 05.11.2011
Сообщений: 178
21.02.2012, 14:09     onTouchEvent в потоке #4
не знаю в тему ли... но я onDraw() при вызове перегружаю, и указываю super.onDraw().
а вообще совет: выводить все в logcat. тогда будет видно, что выполнилось, сколько раз и через какое время. тогда будет проще отловить участок, где код не работает, или работает не так как надо. +можно будет увидеть реальный FPS на который способно устройство.

PS: если вы используете переменную только в одном классе, ее не следует делать public. модификатор public нужен только в том случае, если переменную вы будете использовать вне класса(метода, функции) где переменная объявлена.
NiRamz
211 / 211 / 16
Регистрация: 26.12.2010
Сообщений: 691
22.02.2012, 11:23     onTouchEvent в потоке #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 выдержал гораздо большую нагрузку.
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 293
24.02.2012, 14:05  [ТС]     onTouchEvent в потоке #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;
    }
Не могли бы вы сбросить проект или какой ни будь более понятный пример?
NiRamz
211 / 211 / 16
Регистрация: 26.12.2010
Сообщений: 691
24.02.2012, 14:40     onTouchEvent в потоке #7
да на здоровье
Вложения
Тип файла: rar SurfaceView.rar (1.28 Мб, 65 просмотров)
NiRamz
211 / 211 / 16
Регистрация: 26.12.2010
Сообщений: 691
24.02.2012, 14:42     onTouchEvent в потоке #8
sprite.onDraw - отрисовываются одни объекты (в цикле)
canvas.drawBitmap(bmp, x-(bmp.getWidth()/2), y-(bmp.getHeight()/2), null); - отрисовывается другой объект.
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 293
27.02.2012, 14:16  [ТС]     onTouchEvent в потоке #9
Спасибо. Почти разобрался как менять скорость движения мяча нажимая на нарисованные (не стандартные) кнопки, а можно ли так же менять скорость движения человечков ( sprite.onDraw), или их надо втыкать в класс где мяч находится?
NiRamz
211 / 211 / 16
Регистрация: 26.12.2010
Сообщений: 691
27.02.2012, 15:09     onTouchEvent в потоке #10
а можно ли так же менять скорость движения человечков
скорость передвижения или скорость анимации?
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 293
27.02.2012, 16:38  [ТС]     onTouchEvent в потоке #11
Скорость передвижения, хотя для каждого человечка (чтоб им можно было управлять а у других был какой то интеллект) мне кажется правильнее свой класс создавать, и в каждом классе свой спрайт.
NiRamz
211 / 211 / 16
Регистрация: 26.12.2010
Сообщений: 691
27.02.2012, 16:59     onTouchEvent в потоке #12
раз на то пошло, то делаешь базовый класс, с общим набором свойств/методов для всех (к примеру скорость, здоровье), так же можно сюда внести основную работу со спрайтами, что бы каждый раз не переписывать. Потом же просто наследовать от него уже нужное количество дочерних классов, описать конкретные сущности для этого "персонажа", его поведение в том числе. Все это для удобства работы с большим количеством объектов.

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

p.s. все же я советовал бы использовать готовую openGl библиотеку для написания игр ..
dajver
407 / 271 / 18
Регистрация: 18.09.2010
Сообщений: 1,106
27.02.2012, 20:38     onTouchEvent в потоке #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() должен находится в классе потоке, потому что если разместить его в не класса потока будут проблемы с рисованием и возможно потрепает очень нервы.
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 293
28.02.2012, 09:32  [ТС]     onTouchEvent в потоке #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);
       }
У вас нет случайно готового проекта?
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 293
28.02.2012, 16:12  [ТС]     onTouchEvent в потоке #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;
    }
}
Вложения
Тип файла: zip SurfaceView52.zip (2.95 Мб, 9 просмотров)
dajver
407 / 271 / 18
Регистрация: 18.09.2010
Сообщений: 1,106
29.02.2012, 23:08     onTouchEvent в потоке #16
Цитата Сообщение от nnnikotinnn995 Посмотреть сообщение
Что то я запутался. Это все надо писать в одном классе или в разных? По идее если почти все у вас private то в одном, но кучу ошибок выдает
import android.graphics.Canvas;

У вас нет случайно готового проекта?
Как я понял у тебя в проекте класс GameView наследует SurfaceView { а в этом классе класс поток GameManager } правильно? Если да то пиши все кроме метода - интерфейса в класс поток - GameManager.

Java
1
2
3
4
5
6
7
mDrawScreen = new DrawHelper()
       {
           public void draw(Canvas canvas)
           {
               onDraw(canvas);                  //ОШИБКА
           }
       };
пишется в метода онТач или конструкторе, в зависимости от требуемого эффекта, это не отдельный метод, как и его братюня
Java
1
mDrawGameover = new DrawHelper(){}
Проекта готового нет, если нужно то сделаю.
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 293
01.03.2012, 21:23  [ТС]     onTouchEvent в потоке #17
Цитата Сообщение от dajver Посмотреть сообщение
Если да то пиши все кроме метода - интерфейса в класс поток - GameManager
Если я все правильно понял онтач тоже надо писать в GameManager, но тогда координаты х и у будут не доступны для манипуляций в onTouchEvent(MotionEvent event) из класса Sprite , придется переписывать метод onDraw(canvas);, а впрочем у меня и так не работает и без проекта мысль не понятна (буду признателен если вы выложите проект). Если все методы onDraw(canvas); написаны в одном классе (как у меня в предыдущем вложение) то все переменные изменяются в onTouchEvent, но это не удобно - приходится многие свойства объекта (персонажа) писать заново да и все писать на одной странице очень не удобно, можно попробовать как тут вызывать метод из из других классов (Sprite1,Sprite2...) но тогда придется под каждую реакцию противника писать свой класс. Может стоит попробовать вызывать эти переменный как методы (sprite.х, sprite.у...)?
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 293
02.03.2012, 14:13  [ТС]     onTouchEvent в потоке #18
Цитата Сообщение от dajver Посмотреть сообщение
А если по теме то тебе нужно создать второй метод рисования который будет рисовать во втором потоке после нажатия на экран. Делаем так:
Создаем интерфейс для дальнейшего использования в потоке:
В общем я догадался, можно не чего не перерисовывать и не создавать ни каких методов. Можно просто сделать х – public и вызвать его в классе GameView, туда же онтач, и не надо внедрятся в поток, все изменения становятся видны. И весь ИИ можно писать в одном классе. Мне только не понятно в чем преимущество вашего способа по сравнению с этим?
Кстати, как вы думаете, на AndEngine легче будет создать такого типа игру?
Вложения
Тип файла: zip Tectn5.zip (3.76 Мб, 10 просмотров)
Тип файла: zip andenginen52.zip (3.75 Мб, 8 просмотров)
dajver
407 / 271 / 18
Регистрация: 18.09.2010
Сообщений: 1,106
04.03.2012, 02:47     onTouchEvent в потоке #19
Цитата Сообщение от nnnikotinnn995 Посмотреть сообщение
В общем я догадался, можно не чего не перерисовывать и не создавать ни каких методов. Можно просто сделать х – public и вызвать его в классе GameView, туда же онтач, и не надо внедрятся в поток, все изменения становятся видны. И весь ИИ можно писать в одном классе. Мне только не понятно в чем преимущество вашего способа по сравнению с этим?
Кстати, как вы думаете, на AndEngine легче будет создать такого типа игру?
Мой способ делает все немного не так как у Вас, я наверно не так понял задачу, и нафигачил лишнего.

На AndEngine намного легче будет, во первых сократиться код, так как там ручками ничего делать практически не нужно, создали спрайт, вписали куда ему ехать и он едет, а во вторых он быстрее чем канвас, намного быстрее, и в третьих просто удобный, так как множество функций можно не выполнять котоыре нужно прописывать на канве.

А вообще я бы заюзал OpenGL ES вот это хорошая игрушка! Что что, а вот на нем можно собрать любую игру.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.03.2012, 13:29     onTouchEvent в потоке
Еще ссылки по теме:

Android Warning: Custom view overrides onTouchEvent but not performClick
Android OnTouchEvent - нарисовать точку
Android Handlers в новом потоке
Запустить сервис в другом потоке Android
Android Подскажите - не вызывается метод в потоке

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

Или воспользуйтесь поиском по форуму:
nnnikotinnn995
4 / 4 / 0
Регистрация: 07.07.2011
Сообщений: 293
05.03.2012, 13:29  [ТС]     onTouchEvent в потоке #20
Честно говоря я не больше двух месяцев изучаю JAVA и не могу не воспользываться случаем чтобы у Вас спросить одно не понятное место с точки зрения языка (об котором я пака ни чего не нашел в книгах). Вот оно самое страшное место
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
 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.onDraw2(c);
                           }
                    } finally {
                           if (c != null) {
                                  view.getHolder().unlockCanvasAndPost(c);
                           }
                    }
                    sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
                    try {
                           if (sleepTime > 0)
                                  sleep(sleepTime);
                           else
                                  sleep(25);
                    } catch (Exception e) {}
             }
       }
Если в catch (Exception e) {} удалить скобки {}, в которых не чего не происходит, то возникает ошибка. Зачем же нужны эти скобки, если в них не чего не происходит? По внешнему виду catch (Exception e) {} походит на функцию, в теле которой не чего не происходит. Зачем тогда эта функция тут присутствует?
Yandex
Объявления
05.03.2012, 13:29     onTouchEvent в потоке
Ответ Создать тему
Опции темы

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