Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/siemens/mp/color_game/Sprite.java


1   /*
2    *  Siemens API for MicroEmulator
3    *  Copyright (C) 2003 Markus Heberling <markus@heberling.net>
4    *
5    *  This library is free software; you can redistribute it and/or
6    *  modify it under the terms of the GNU Lesser General Public
7    *  License as published by the Free Software Foundation; either
8    *  version 2.1 of the License, or (at your option) any later version.
9    *
10   *  This library is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   *  Lesser General Public License for more details.
14   *
15   *  You should have received a copy of the GNU Lesser General Public
16   *  License along with this library; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  package com.siemens.mp.color_game;
20  
21  import javax.microedition.lcdui.Image;
22  import javax.microedition.lcdui.Graphics;
23  
24  public class Sprite extends Layer {
25      
26      public static final int TRANS_NONE = 0;
27      public static final int TRANS_ROT90 = 5;
28      public static final int TRANS_ROT180 = 3;
29      public static final int TRANS_ROT270 = 6;
30      public static final int TRANS_MIRROR = 2;
31      public static final int TRANS_MIRROR_ROT90 = 7;
32      public static final int TRANS_MIRROR_ROT180 = 1;
33      public static final int TRANS_MIRROR_ROT270 = 4;
34      
35      public Sprite(Image image) {
36          super(image.getWidth(), image.getHeight());
37          
38          initializeFrames(image, image.getWidth(), image.getHeight(), false);
39          
40          // initialize collision rectangle
41          initCollisionRectBounds();
42      }
43      
44      public Sprite(Image image, int frameWidth, int frameHeight) {
45          
46          super(frameWidth, frameHeight);
47          // if img is null img.getWidth() will throw NullPointerException
48          if ((frameWidth < 1 || frameHeight < 1) ||
49          ((image.getWidth() % frameWidth) != 0) ||
50          ((image.getHeight() % frameHeight) != 0)) {
51              throw new IllegalArgumentException();
52          }
53          
54          // construct the array of images that
55          // we use as "frames" for the sprite.
56          // use default frame , sequence index = 0
57          initializeFrames(image, frameWidth, frameHeight, false);
58          
59          // initialize collision rectangle
60          initCollisionRectBounds();
61          
62      }
63      
64      public Sprite(Sprite s) {
65          
66          super(s != null ? s.getWidth() : 0,
67          s != null ? s.getHeight() : 0);
68          
69          if (s == null) {
70              throw new NullPointerException();
71          }
72          
73          this.sourceImage = Image.createImage(s.sourceImage);
74          
75          this.numberFrames = s.numberFrames;
76          
77          this.frameCoordsX = new int[this.numberFrames];
78          this.frameCoordsY = new int[this.numberFrames];
79          
80          System.arraycopy(s.frameCoordsX, 0,
81          this.frameCoordsX, 0,
82          s.getRawFrameCount());
83          
84          System.arraycopy(s.frameCoordsY, 0,
85          this.frameCoordsY, 0,
86          s.getRawFrameCount());
87          
88          this.x = s.getX();
89          this.y = s.getY();
90          
91          // these fields are set by defining a reference point
92          this.dRefX = s.dRefX;
93          this.dRefY = s.dRefY;
94          
95          // these fields are set when defining a collision rectangle
96          this.collisionRectX = s.collisionRectX;
97          this.collisionRectY = s.collisionRectY;
98          this.collisionRectWidth = s.collisionRectWidth;
99          this.collisionRectHeight = s.collisionRectHeight;
100         
101         // these fields are set when creating a Sprite from an Image
102         this.srcFrameWidth = s.srcFrameWidth;
103         this.srcFrameHeight = s.srcFrameHeight;
104         
105        
106         this.setVisible(s.isVisible());
107         
108         this.frameSequence = new int[s.getFrameSequenceLength()];
109         this.setFrameSequence(s.frameSequence);
110         this.setFrame(s.getFrame());
111         
112         this.setRefPixelPosition(s.getRefPixelX(), s.getRefPixelY());
113         
114     }
115     
116     public void defineReferencePixel(int x, int y) {
117         dRefX = x;
118         dRefY = y;
119     }
120     
121     
122     public void setRefPixelPosition(int x, int y) {
123         
124         // update this.x and this.y
125         this.x = x - dRefX;
126         this.y = y - dRefY;
127         
128     }
129     
130     
131     public int getRefPixelX() {
132         return this.x + dRefX;
133     }
134     
135     
136     public int getRefPixelY() {
137         return this.y + dRefY;
138     }
139     
140     public void setFrame(int sequenceIndex) {
141         if (sequenceIndex < 0 || sequenceIndex >= frameSequence.length) {
142             throw new IndexOutOfBoundsException();
143         }
144         this.sequenceIndex = sequenceIndex;
145     }
146     
147     
148     public final int getFrame() {
149         return sequenceIndex;
150     }
151     
152     
153     public int getRawFrameCount() {
154         return numberFrames;
155     }
156     
157     
158     public int getFrameSequenceLength() {
159         return frameSequence.length;
160     }
161     
162     
163     public void nextFrame() {
164         sequenceIndex = (sequenceIndex + 1) % frameSequence.length;
165     }
166     
167     
168     public void prevFrame() {
169         if (sequenceIndex == 0) {
170             sequenceIndex = frameSequence.length - 1;
171         } else {
172             sequenceIndex--;
173         }
174     }
175     
176     
177     public final void paint(Graphics g) {
178         if (g == null) {
179             throw new NullPointerException();
180         }
181         
182         if (visible) {
183             
184             int clipX = g.getClipX();
185             int clipY = g.getClipY();
186             int clipW = g.getClipWidth();
187             int clipH =  g.getClipHeight();
188             
189             g.setClip(this.x, this.y, this.srcFrameWidth, this.srcFrameHeight);
190             
191             g.drawImage(sourceImage, this.x-frameCoordsX[frameSequence[sequenceIndex]],
192             this.y-frameCoordsY[frameSequence[sequenceIndex]],Graphics.TOP | Graphics.LEFT);
193             
194             g.setClip(clipX, clipY, clipW, clipH);
195         }
196         
197     }
198     
199     
200     public void setFrameSequence(int sequence[]) {
201         
202         if (sequence == null) {
203             // revert to the default sequence
204             sequenceIndex = 0;
205             customSequenceDefined = false;
206             frameSequence = new int[numberFrames];
207             // copy frames indices into frameSequence
208             for (int i = 0; i < numberFrames; i++) {
209                 frameSequence[i] = i;
210             }
211             return;
212         }
213         
214         if (sequence.length < 1) {
215             throw new IllegalArgumentException();
216         }
217         
218         for (int i = 0; i < sequence.length; i++) {
219             if (sequence[i] < 0 || sequence[i] >= numberFrames) {
220                 throw new ArrayIndexOutOfBoundsException();
221             }
222         }
223         customSequenceDefined = true;
224         frameSequence = new int[sequence.length];
225         System.arraycopy(sequence, 0, frameSequence, 0, sequence.length);
226         sequenceIndex = 0;
227     }
228     
229     
230     public void setImage(Image img, int frameWidth, int frameHeight) {
231         
232         // if image is null image.getWidth() will throw NullPointerException
233         if ((frameWidth < 1 || frameHeight < 1) ||
234         ((img.getWidth() % frameWidth) != 0) ||
235         ((img.getHeight() % frameHeight) != 0)) {
236             throw new IllegalArgumentException();
237         }
238         
239         int noOfFrames =
240         (img.getWidth() / frameWidth)*(img.getHeight() / frameHeight);
241         
242         boolean maintainCurFrame = true;
243         if (noOfFrames < numberFrames) {
244             // use default frame , sequence index = 0
245             maintainCurFrame = false;
246             customSequenceDefined = false;
247         }
248         
249         if (! ((srcFrameWidth == frameWidth) &&
250         (srcFrameHeight == frameHeight))) {
251             
252             // computing is the location
253             // of the reference pixel in the painter's coordinate system.
254             // and then use this to find x and y position of the Sprite
255             int oldX = this.x + dRefX;
256             
257             int oldY = this.y + dRefY;
258             
259             
260             setWidthImpl(frameWidth);
261             setHeightImpl(frameHeight);
262             
263             initializeFrames(img, frameWidth, frameHeight, maintainCurFrame);
264             
265             // initialize collision rectangle
266             initCollisionRectBounds();
267             
268             // set the new x and y position of the Sprite
269             this.x = oldX - dRefX;
270             
271             this.y = oldY - dRefY;
272 
273         } else {
274             // just reinitialize the animation frames.
275             initializeFrames(img, frameWidth, frameHeight, maintainCurFrame);
276         }
277         
278     }
279     
280     
281     public void defineCollisionRectangle(int x, int y, int width, int height) {
282         
283         if (width < 0 || height < 0) {
284             throw new IllegalArgumentException();
285         }
286         
287         collisionRectX = x;
288         collisionRectY = y;
289         collisionRectWidth = width;
290         collisionRectHeight = height;
291     }
292     
293     //transfrom is ignored
294     public void setTransform(int transform) {
295     }
296     
297     //pixellevel nor supported
298     public final boolean collidesWith(Sprite s, boolean pixelLevel) {
299         
300         // check if either of the Sprite's are not visible
301         if (!(s.visible && this.visible)) {
302             return false;
303         }
304         
305         // these are package private
306         // and can be accessed directly
307         int otherLeft    = s.x + s.collisionRectX;
308         int otherTop     = s.y + s.collisionRectY;
309         int otherRight   = otherLeft + s.collisionRectWidth;
310         int otherBottom  = otherTop  + s.collisionRectHeight;
311         
312         int left   = this.x + this.collisionRectX;
313         int top    = this.y + this.collisionRectY;
314         int right  = left + this.collisionRectWidth;
315         int bottom = top  + this.collisionRectHeight;
316         
317         // check if the collision rectangles of the two sprites intersect
318         if (intersectRect(otherLeft, otherTop, otherRight, otherBottom,
319         left, top, right, bottom)) {
320             
321             
322             return true;
323         }
324         return false;
325         
326     }
327     
328     //pixellevel not supported
329     public final boolean collidesWith(TiledLayer t, boolean pixelLevel) {
330         
331         // check if either this Sprite or the TiledLayer is not visible
332         if (!(t.visible && this.visible)) {
333             return false;
334         }
335         
336         // dimensions of tiledLayer, cell, and
337         // this Sprite's collision rectangle
338         
339         // these are package private
340         // and can be accessed directly
341         int tLx1 = t.x;
342         int tLy1 = t.y;
343         int tLx2 = tLx1 + t.width;
344         int tLy2 = tLy1 + t.height;
345         
346         int tW = t.cellWidth;
347         int tH = t.cellHeight;
348         
349         int sx1 = this.x + this.collisionRectX;
350         int sy1 = this.y + this.collisionRectY;
351         int sx2 = sx1 + this.collisionRectWidth;
352         int sy2 = sy1 + this.collisionRectHeight;
353         
354         // number of cells
355         int tNumCols = t.columns;
356         int tNumRows = t.rows;
357         
358         // temporary loop variables.
359         int startCol; // = 0;
360         int endCol;   // = 0;
361         int startRow; // = 0;
362         int endRow;   // = 0;
363         
364         if (!intersectRect(tLx1, tLy1, tLx2, tLy2, sx1, sy1, sx2, sy2)) {
365             // if the collision rectangle of the sprite
366             // does not intersect with the dimensions of the entire
367             // tiled layer
368             return false;
369         }
370         
371         // so there is an intersection
372         
373         // note sx1 < sx2, tLx1 < tLx2, sx2 > tLx1  from intersectRect()
374         // use <= for comparison as this saves us some
375         // computation - the result will be 0
376         startCol = (sx1 <= tLx1) ? 0 : (sx1 - tLx1)/tW;
377         startRow = (sy1 <= tLy1) ? 0 : (sy1 - tLy1)/tH;
378         // since tLx1 < sx2 < tLx2, the computation will yield
379         // a result between 0 and tNumCols - 1
380         // subtract by 1 because sx2,sy2 represent
381         // the enclosing bounds of the sprite, not the
382         // locations in the coordinate system.
383         endCol = (sx2 < tLx2) ? ((sx2 - 1 - tLx1)/tW) : tNumCols - 1;
384         endRow = (sy2 < tLy2) ? ((sy2 - 1 - tLy1)/tH) : tNumRows - 1;
385         
386         //if (!pixelLevel) {
387         // check for intersection with a non-empty cell,
388         for (int row = startRow; row <= endRow; row++) {
389             for (int col = startCol; col <= endCol; col++) {
390                 if (t.cellMatrix[row][col] != 0) {
391                     return true;
392                 }
393             }
394         }
395         // worst case! we scanned through entire
396         // overlapping region and
397         // all the cells are empty!
398         return false;
399         
400         
401     }
402     
403     //pixellevel not supported
404     public final boolean collidesWith(Image image,
405     int x, int y, boolean pixelLevel) {
406         
407         // check if this Sprite is not visible
408         if (!(this.visible)) {
409             return false;
410         }
411         
412         // if image is null
413         // image.getWidth() will throw NullPointerException
414         int otherLeft    = x;
415         int otherTop     = y;
416         int otherRight   = x + image.getWidth();
417         int otherBottom  = y + image.getHeight();
418         
419         int left   = this.x + this.collisionRectX;
420         int top    = this.y + this.collisionRectY;
421         int right  = left + this.collisionRectWidth;
422         int bottom = top  + this.collisionRectHeight;
423         
424         // first check if the collision rectangles of the two sprites intersect
425         if (intersectRect(otherLeft, otherTop, otherRight, otherBottom,
426         left, top, right, bottom)) {
427             
428             
429             return true;
430         }
431         return false;
432         
433     }
434     
435     
436     //  ----- private -----
437     
438     private void initializeFrames(Image image, int fWidth,
439     int fHeight, boolean maintainCurFrame) {
440         
441         int imageW = image.getWidth();
442         int imageH = image.getHeight();
443         
444         int numHorizontalFrames = imageW / fWidth;
445         int numVerticalFrames   = imageH / fHeight;
446         
447         sourceImage = image;
448         
449         srcFrameWidth = fWidth;
450         srcFrameHeight = fHeight;
451         
452         numberFrames = numHorizontalFrames*numVerticalFrames;
453         
454         frameCoordsX = new int[numberFrames];
455         frameCoordsY = new int[numberFrames];
456         
457         if (!maintainCurFrame) {
458             sequenceIndex = 0;
459         }
460         
461         if (!customSequenceDefined) {
462             frameSequence = new int[numberFrames];
463         }
464         
465         int currentFrame = 0;
466         
467         for (int yy = 0; yy < imageH; yy += fHeight) {
468             for (int xx = 0; xx < imageW; xx += fWidth) {
469                 
470                 frameCoordsX[currentFrame] = xx;
471                 frameCoordsY[currentFrame] = yy;
472                 
473                 if (!customSequenceDefined) {
474                     frameSequence[currentFrame] = currentFrame;
475                 }
476                 currentFrame++;
477                 
478             }
479         }
480     }
481     
482     /**
483      * initialize the collision rectangle
484      */
485     private void initCollisionRectBounds() {
486         
487         // reset x and y of collision rectangle
488         collisionRectX = 0;
489         collisionRectY = 0;
490         
491         // intialize the collision rectangle bounds to that of the sprite
492         collisionRectWidth = this.width;
493         collisionRectHeight = this.height;
494         
495     }
496     
497     
498     private boolean intersectRect(int r1x1, int r1y1, int r1x2, int r1y2,
499     int r2x1, int r2y1, int r2x2, int r2y2) {
500         return !(r2x1 >= r1x2 || r2y1 >= r1y2 || r2x2 <= r1x1 || r2y2 <= r1y1);
501     }
502     
503     
504    
505     private static final int INVERTED_AXES = 0x4;
506     private static final int X_FLIP = 0x2;
507     private static final int Y_FLIP = 0x1;
508     private static final int ALPHA_BITMASK = 0xff000000;
509     
510     Image sourceImage;
511     
512     int numberFrames; // = 0;
513     
514     int[] frameCoordsX;
515     int[] frameCoordsY;
516     int srcFrameWidth;
517     int srcFrameHeight;
518     int[] frameSequence;
519     private int sequenceIndex; // = 0
520     private boolean customSequenceDefined; // = false;
521     
522     
523     int dRefX; // =0
524     
525     int dRefY; // =0
526     
527     int collisionRectX; // =0
528     
529     int collisionRectY; // =0
530     
531     int collisionRectWidth;
532     
533     int collisionRectHeight;
534     
535     int t_currentTransformation;
536     
537  
538     
539 }