Project

General

Profile

Download (11.9 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / overlays / OverlayStars.java @ ec4987d4

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2022 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.overlays;
11

    
12
import android.content.res.Resources;
13
import android.graphics.Bitmap;
14
import android.graphics.BitmapFactory;
15
import android.graphics.Canvas;
16
import android.graphics.Paint;
17

    
18
import org.distorted.library.effect.EffectQuality;
19
import org.distorted.library.effect.FragmentEffectAlpha;
20
import org.distorted.library.effect.MatrixEffectMove;
21
import org.distorted.library.effect.MatrixEffectScale;
22
import org.distorted.library.effect.PostprocessEffectGlow;
23
import org.distorted.library.effect.VertexEffectMove;
24
import org.distorted.library.effect.VertexEffectScale;
25
import org.distorted.library.main.DistortedEffects;
26
import org.distorted.library.main.DistortedNode;
27
import org.distorted.library.main.DistortedScreen;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.main.InternalOutputSurface;
30
import org.distorted.library.mesh.MeshJoined;
31
import org.distorted.library.mesh.MeshQuad;
32
import org.distorted.library.message.EffectListener;
33
import org.distorted.library.type.Dynamic;
34
import org.distorted.library.type.Dynamic1D;
35
import org.distorted.library.type.Dynamic2D;
36
import org.distorted.library.type.Dynamic3D;
37
import org.distorted.library.type.Static1D;
38
import org.distorted.library.type.Static2D;
39
import org.distorted.library.type.Static3D;
40
import org.distorted.library.type.Static4D;
41
import org.distorted.main.R;
42

    
43
import java.util.Random;
44

    
45
///////////////////////////////////////////////////////////////////////////////////////////////////
46

    
47
public class OverlayStars extends OverlayGeneric implements EffectListener
48
{
49
   private static final int DUR_APP =  1500;
50
   private static final int DUR_MOV =  3500;
51
   private static final int DUR_GLO =   600;
52

    
53
   private ListenerOverlay mListener;
54
   private DistortedNode mNodeFalling, mNodeCentral;
55
   private DistortedScreen mScreen;
56
   private DistortedTexture mTexture;
57
   private Bitmap mCountBitmap, mStarBitmap;
58
   private Canvas mCountCanvas;
59
   private Paint mPaint;
60
   private int mBmpW, mBmpH;
61
   private float mWidth, mHeight;
62
   private Random mRandom;
63
   private long mMoveID, mGlow1ID, mGlow2ID, mAlphaID;
64
   private int mTotalStars, mNewStars;
65
   private FragmentEffectAlpha mAlpha;
66
   private Dynamic1D mAlphaStrength;
67
   private boolean mIncrease;
68
   private float mTextHeight;
69

    
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71

    
72
   private Dynamic3D createRandomMove(boolean increase)
73
      {
74
      Dynamic3D move = new Dynamic3D();
75
      move.setMode(Dynamic.MODE_PATH);
76
      move.setDuration(DUR_MOV);
77
      move.setCount(0.5f);
78

    
79
      float widthS = (mRandom.nextFloat()-0.5f)*mWidth*1.10f;
80
      float widthM = widthS + (mRandom.nextFloat()-0.5f)*mWidth*0.2f;
81
      float heighS = mRandom.nextFloat()*mHeight*0.2f;
82
      float heighM = (mRandom.nextFloat()-0.5f)*mHeight*0.2f;
83

    
84
      Static3D pointS = new Static3D(widthS,mHeight*0.55f+heighS,0);
85
      Static3D pointM = new Static3D(widthM,mHeight*0.25f+heighM,0);
86
      Static3D pointE = new Static3D(0,0,0);
87
      Static3D pointF = new Static3D(0,0,-10000);
88

    
89
      if( increase )
90
         {
91
         move.add(pointS);
92
         move.add(pointM);
93
         move.add(pointE);
94
         move.add(pointF);
95
         }
96
      else
97
         {
98
         move.add(pointF);
99
         move.add(pointE);
100
         move.add(pointM);
101
         move.add(pointS);
102
         }
103

    
104
      return move;
105
      }
106

    
107
///////////////////////////////////////////////////////////////////////////////////////////////////
108

    
109
   private void createAlphaEffect(boolean appear)
110
      {
111
      if( mAlpha==null )
112
         {
113
         mAlphaStrength = new Dynamic1D();
114
         mAlphaStrength.setMode(Dynamic.MODE_PATH);
115
         mAlphaStrength.setDuration(DUR_APP);
116
         mAlphaStrength.setCount(0.5f);
117
         equipAlpha(mAlphaStrength,appear);
118
         mAlpha = new FragmentEffectAlpha(mAlphaStrength);
119
         }
120
      else
121
         {
122
         mAlphaStrength.resetToBeginning();
123
         equipAlpha(mAlphaStrength,appear);
124
         }
125
      }
126

    
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128

    
129
   private void equipAlpha(Dynamic1D alpha, boolean appear)
130
      {
131
      Static1D point0 = new Static1D(0.0f);
132
      Static1D point1 = new Static1D(1.0f);
133

    
134
      alpha.removeAll();
135

    
136
      if( appear )
137
        {
138
        alpha.add(point0);
139
        alpha.add(point1);
140
        }
141
      else
142
        {
143
        alpha.add(point1);
144
        alpha.add(point0);
145
        }
146
      }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

    
150
   private float computeQuotientAndTextHeight(int total)
151
      {
152
      if( total>=10000 )
153
         {
154
         mTextHeight = 0.610f;
155
         return 0.16f;
156
         }
157
      if( total>= 1000 )
158
         {
159
         mTextHeight = 0.625f;
160
         return 0.20f;
161
         }
162
      if( total>=  100 )
163
         {
164
         mTextHeight = 0.640f;
165
         return 0.26f;
166
         }
167

    
168
      mTextHeight = 0.655f;
169
      return 0.28f;
170
      }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

    
174
   private void createBitmap(Resources res, int total)
175
      {
176
      mStarBitmap = BitmapFactory.decodeResource(res, R.drawable.star);
177
      mBmpW = mStarBitmap.getWidth();
178
      mBmpH = mStarBitmap.getHeight();
179
      mCountBitmap = Bitmap.createBitmap(mBmpW,mBmpH,Bitmap.Config.ARGB_8888);
180
      mCountCanvas = new Canvas(mCountBitmap);
181

    
182
      float quotient = computeQuotientAndTextHeight(total);
183

    
184
      mPaint = new Paint();
185
      mPaint.setColor(0xff000000);
186
      mPaint.setTextSize(mBmpH*quotient);
187
      mPaint.setAntiAlias(true);
188
      mPaint.setTextAlign(Paint.Align.CENTER);
189
      }
190

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

    
193
   private DistortedNode createNodeFalling(boolean increase)
194
      {
195
      DistortedTexture texture = new DistortedTexture();
196
      texture.setTexture(mStarBitmap);
197

    
198
      MeshQuad[] mesh = new MeshQuad[mNewStars];
199

    
200
      for(int i=0; i<mNewStars; i++)
201
         {
202
         mesh[i] = new MeshQuad();
203
         mesh[i].setEffectAssociation(0,1,i+1);
204
         }
205

    
206
      MeshJoined wholeMesh = new MeshJoined(mesh);
207

    
208
      DistortedEffects effects = new DistortedEffects();
209
      VertexEffectScale scaleE = new VertexEffectScale(mWidth*0.15f);
210
      scaleE.setMeshAssociation(1,-1);
211
      effects.apply(scaleE);
212

    
213
      for(int i=0; i<mNewStars; i++)
214
        {
215
        Dynamic3D moveP = createRandomMove(increase);
216
        VertexEffectMove moveE= new VertexEffectMove(moveP);
217
        moveE.setMeshAssociation(0,i+1);
218
        effects.apply(moveE);
219

    
220
        if( i==0 )
221
           {
222
           mMoveID = moveE.getID();
223
           moveE.notifyWhenFinished(this);
224
           }
225
        }
226

    
227
      return new DistortedNode(texture,effects,wholeMesh);
228
      }
229

    
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231

    
232
   private DistortedNode createNodeCentral(int numStars)
233
      {
234
      mTexture = new DistortedTexture();
235
      renderStars(numStars);
236

    
237
      MeshQuad mesh = new MeshQuad();
238

    
239
      DistortedEffects effects = new DistortedEffects();
240
      float scaleM  = mWidth*0.40f;
241
      Static3D moveM= new Static3D(0,0,1);
242
      MatrixEffectMove move  = new MatrixEffectMove(moveM);
243
      MatrixEffectScale scale= new MatrixEffectScale(scaleM);
244
      effects.apply(move);
245
      effects.apply(scale);
246
      createAlphaEffect(true);
247
      effects.apply(mAlpha);
248

    
249
      return new DistortedNode(mTexture,effects,mesh);
250
      }
251

    
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253

    
254
   private void renderStars(int numStars)
255
      {
256
      String txt = ""+numStars;
257
      mCountBitmap.eraseColor(0x00000000);
258
      mCountCanvas.drawBitmap(mStarBitmap,0,0,null);
259
      mCountCanvas.drawText(txt,mBmpW*0.5f,mBmpH*mTextHeight,mPaint);
260
      mTexture.setTexture(mCountBitmap);
261
      }
262

    
263
///////////////////////////////////////////////////////////////////////////////////////////////////
264

    
265
   public long startOverlay(DistortedScreen screen, ListenerOverlay listener, DataGeneric data)
266
      {
267
      mRandom = new Random();
268
      mScreen = screen;
269
      mListener= listener;
270
      DataStars stars = (DataStars)data;
271
      mTotalStars = 7;//stars.getTotal();
272
      mNewStars   = stars.getNew();
273
      Resources res = stars.getResources();
274
      mWidth = mScreen.getWidth();
275
      mHeight= mScreen.getHeight();
276
      mIncrease = mNewStars>0;
277
      if( !mIncrease ) mNewStars = -mNewStars;
278

    
279
      createBitmap(res, mTotalStars);
280
      mNodeFalling = createNodeFalling(mIncrease);
281
      mNodeFalling.enableDepthStencil(InternalOutputSurface.NO_DEPTH_NO_STENCIL);
282
      mScreen.attach(mNodeFalling);
283
      mNodeCentral = createNodeCentral(mTotalStars);
284
      mNodeCentral.glDepthMask(false);
285
      mScreen.attach(mNodeCentral);
286

    
287
      return 0;
288
      }
289

    
290
///////////////////////////////////////////////////////////////////////////////////////////////////
291

    
292
   private PostprocessEffectGlow constructGlow(boolean firstPhase)
293
      {
294
      Dynamic2D haloRadius = new Dynamic2D(DUR_GLO,0.5f);
295
      Static2D point0 = new Static2D( 0, 0);
296
      Static2D point1 = new Static2D(15,50);
297

    
298
      if( firstPhase )
299
         {
300
         haloRadius.add(point0);
301
         haloRadius.add(point1);
302
         }
303
      else
304
         {
305
         haloRadius.add(point1);
306
         haloRadius.add(point0);
307
         }
308

    
309
      Static4D color = new Static4D(1,1,1,0.5f);
310

    
311
      PostprocessEffectGlow glow = new PostprocessEffectGlow(haloRadius,color);
312
      glow.setQuality(EffectQuality.MEDIUM);
313
      glow.notifyWhenFinished(this);
314

    
315
      return glow;
316
      }
317

    
318
///////////////////////////////////////////////////////////////////////////////////////////////////
319

    
320
   public void effectFinished(long id)
321
      {
322
      if( id==mMoveID )
323
         {
324
         PostprocessEffectGlow glow = constructGlow(true);
325
         mGlow1ID = glow.getID();
326
         DistortedEffects effects = mNodeCentral.getEffects();
327
         effects.apply(glow);
328
         }
329
      if( id==mGlow1ID )
330
         {
331
         renderStars(mTotalStars+(mIncrease ? mNewStars : -mNewStars));
332
         PostprocessEffectGlow glow = constructGlow(false);
333
         mGlow2ID = glow.getID();
334
         DistortedEffects effects = mNodeCentral.getEffects();
335
         effects.abortById(mGlow1ID);
336
         effects.apply(glow);
337
         }
338
      if( id==mGlow2ID )
339
         {
340
         DistortedEffects effects = mNodeCentral.getEffects();
341
         effects.abortById(mGlow2ID);
342
         createAlphaEffect(false);
343
         mAlphaID = mAlpha.getID();
344
         mAlpha.notifyWhenFinished(this);
345
         effects.apply(mAlpha);
346
         }
347
      if( id==mAlphaID )
348
         {
349
         mScreen.detach(mNodeCentral);
350
         mNodeCentral.markForDeletion();
351
         mNodeCentral=null;
352
         mScreen.detach(mNodeFalling);
353
         mNodeFalling.markForDeletion();
354
         mNodeFalling=null;
355
         mListener.overlayFinished(id);
356
         }
357
      }
358

    
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360

    
361
  @SuppressWarnings("unused")
362
  public static void enableEffects()
363
     {
364
     FragmentEffectAlpha.enable();
365
     VertexEffectMove.enable();
366
     VertexEffectScale.enable();
367
     PostprocessEffectGlow.enable();
368
     }
369
}
(5-5/5)