Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (491)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (556)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Drawing sprites and animation  (Read 3411 times)
0 Members and 1 Guest are viewing this topic.
Offline DavidW

Junior Member


Medals: 3
Exp: 7 years



« Posted 2011-10-18 00:10:11 »

Hey all, it's me again asking for more object oriented help.  Roll Eyes

I have an abstract sprite class (used to be called "Entity" but I changed it to sprite for some reason) and I wasn't sure how each type of sprite would draw itself, so I made a DrawStrategy interface and each Sprite holds one of these.  So for instance, some sprites have 8 different images depending on what direction they are heading, some always use the same.  Some have an animation cycle, some do not.  I created different DrawStrategy classes for each type of drawing needed, and just add this to the Sprite when I create it.

The thing is, some strategies need more info than others.  So I add methods like setDirection(Direction d) to a DirectionAnimationStrategy class (Direction is an Enum, BTW).  But if a certain sprite child class (like Enemy) needs to call this, then I am forced to cast the DrawStrategy to DirectionAnimationStrategy.  Here is what I am talking about:

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  
package towerdefence.sprite;

import java.awt.geom.Point2D;
import towerdefence.GameWorld;
import towerdefence.graphics.DirectionAnimationStrategy;
import towerdefence.graphics.DrawStrategy;
import towerdefence.path.Path;


public class Enemy extends Sprite {
   
   private Path path;
   private double dist = 0;
   private double speed = 3;

   public Enemy(Point2D.Double l, double w, double h, GameWorld wo, DrawStrategy d) {
      super(l, w, h, wo, d);
      path = wo.getLevel().getPath();
   }

   public  void updateMe() {
     
      Point2D.Double lastLoc = location;
     
      setBounds();
     
      dist += speed;
     
      if(dist > path.length())
         dist = 0;
     
      location = path.getPointFromDistance(dist);
     
      double angle = Math.atan2(location.y - lastLoc.y, location.x - lastLoc.x);
     
      ((DirectionAnimationStrategy)drawStrat).setDirection(Direction.directionFromAngle(angle));
      ((DirectionAnimationStrategy)drawStrat).update();
   }

}


This seems a little messy to me.  Is there a better way to do this?

By the way, Path is a class which tells the Enemy how it is to walk around the game world.  I am making a tower defense game, just in case you missed my earlier thread, so enemies just walk along a predetermined path.  I figured the best way to do this is to store the path as a spline.

EDIT:

For reference, here is my Sprite class:

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  
package towerdefence.sprite;

import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import towerdefence.GameWorld;
import towerdefence.graphics.DrawStrategy;

public abstract class Sprite {

   protected Point2D.Double location;
   protected GameWorld world;
   protected DrawStrategy drawStrat;
   private Rectangle2D.Double bounds;
   private double width, height;
   
   private boolean drawingBounds;
   
   public Sprite(Point2D.Double l, double w, double h, GameWorld wo, DrawStrategy d) {
      location = l;
      world = wo;
      drawStrat = d;
     
      width = w;
      height = h;
     
      bounds = new Rectangle2D.Double();
      setBounds();
   }
   
   public void setDrawStrategy(DrawStrategy d) {
      drawStrat = d;
   }
   
   public void drawMe(Graphics2D g) {
      g.translate(location.x - width/2, location.y - height/2);
      drawStrat.draw(g);
     
      g.translate(-location.x + width/2, -location.y + height/2);
     
      if(drawingBounds)
         g.draw(bounds);
   }
   
   public abstract void updateMe();
   
   protected void setBounds() {
      bounds.setRect(location.x - width/2.0, location.y - height/2.0, width, height);
   }
   
   // Methods for collision detection:
 
   public Rectangle2D getBounds() {
      return bounds;
   }
   
   public boolean collidesWith(Rectangle2D r) {
      return bounds.intersects(r);
   }
   
   public boolean collidesWith(Sprite s) {  
      return collidesWith(s.getBounds());
   }

   public boolean isDrawingBounds() {
      return drawingBounds;
   }

   public void setDrawingBounds(boolean drawingBounds) {
      this.drawingBounds = drawingBounds;
   }
   
}

Hello!
Offline sproingie

JGO Kernel


Medals: 202



« Reply #1 - Posted 2011-10-18 00:24:16 »

There is no way that the code in enemy.updateMe can work unless the DrawStrategy it is given in the constructor is a DirectionAnimationStrategy.  So the constructor should take a DirectionAnimationStrategy, and not a plain DrawStrategy.  You can still treat it as a DrawStrategy (without any casting) for other methods that only need a DrawStrategy and don't otherwise need to be aware of the direction.

Offline DavidW

Junior Member


Medals: 3
Exp: 7 years



« Reply #2 - Posted 2011-10-18 00:44:36 »

Oh so I should just edit the constructor in Enemy?  I didn't think of that...   Clueless

Hello!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline DavidW

Junior Member


Medals: 3
Exp: 7 years



« Reply #3 - Posted 2011-10-18 00:52:48 »

Would you say the way I have set all this business up is a good way to do it?

Hello!
Offline sproingie

JGO Kernel


Medals: 202



« Reply #4 - Posted 2011-10-18 02:43:37 »

I tend to think of a Sprite as the mechanism for drawing in the first place, so a drawing strategy like how to animate is simply a property of the sprite. If I had a class that selected a different sprite based on its facing or position or whatever state, I might call it a Model, similar to a 3D model with rigging that can put into different poses.  This is just my particular design taste, and I don't write action games (my experience is with MUDs) so take my design notes with a grain of salt...
Offline h3ckboy

JGO Coder


Medals: 5



« Reply #5 - Posted 2011-10-18 05:59:40 »

I can't right now, but if you want later on I can post some simple animation code I wrote?
Offline DavidW

Junior Member


Medals: 3
Exp: 7 years



« Reply #6 - Posted 2011-10-18 15:38:45 »

Sure, I would appreciate it if you have the time.  Grin

Hello!
Offline h3ckboy

JGO Coder


Medals: 5



« Reply #7 - Posted 2011-10-18 19:15:20 »

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  
/**
 * This class is the class that is used for animtions.
 * @author Pearce Keesling aka h3ckboy
 *
 */

import java.awt.*;

import java.awt.image.BufferedImage;
import java.awt.Container;
public class Animation implements Cloneable {
   //the frames for the animation
  public BufferedImage[] images;
   //the time between each frame
  int time;
   //time that has passed since last frame
  int elapsedTime = 0;
   int currentFrame;
   public Animation(BufferedImage[] images,int time)
   {
      this.images = images;
      this.time = time;
      currentFrame = 0;
   }
   //advance animation each frame
  public void advance(int time)
   {
      elapsedTime+=time;
      if(elapsedTime>=this.time)
      {
         elapsedTime -=this.time;
         currentFrame++;
         if(currentFrame>=images.length)
         {
            currentFrame = 0;
         }
      }
   }
   //render the animation's current frame
  public void render(Graphics g,int x, int y,Container container)
   {
      g.drawImage(images[currentFrame],x,y,container);
   }
   public void render(Graphics g,int x, int y,int direction,Container container)
   {
      BufferedImage[] images = setDirection(direction,container);
      g.drawImage(images[currentFrame],x,y,container);
   }
   public BufferedImage getCurrentFrame()
   {
      return images[currentFrame];
   }
   public int getCurrentFrameInt()
   {
      return currentFrame;
   }
}


This is the animation class that I use, I tried to cut out some extra stuff I had in that wasn't exactly relevant to animation. feel free to use any or all of it, it was designed to be stand-alone from my programs.

If you have any questions about implementations just ask.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Nickropheliac (15 views)
2014-08-31 22:59:12

TehJavaDev (23 views)
2014-08-28 18:26:30

CopyableCougar4 (33 views)
2014-08-22 19:31:30

atombrot (41 views)
2014-08-19 09:29:53

Tekkerue (40 views)
2014-08-16 06:45:27

Tekkerue (35 views)
2014-08-16 06:22:17

Tekkerue (25 views)
2014-08-16 06:20:21

Tekkerue (37 views)
2014-08-16 06:12:11

Rayexar (72 views)
2014-08-11 02:49:23

BurntPizza (49 views)
2014-08-09 21:09:32
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!