Slick Forums

Discuss the Slick 2D Library
It is currently Sun May 26, 2013 12:56 am

All times are UTC




Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 420 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7, 8, 9 ... 28  Next
Author Message
 Post subject:
PostPosted: Thu Apr 14, 2011 3:39 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
Hi appel, I have some questions:

1) could you share all the scene graph stuff? :D

2) I have some special case I dunno the best way to handle it:

In my current game I have arrows which have a physics component. Once they hit a target I want them to become stuck.

Right now, I am creating a new entity with similar information to the other one but without physics component and remove the old one. One problem with this solution is that I am creating a new entity and destroying another each time the arrows hit. Another problem is the arrows become invisible for one frame (because there is no arrow for one frame), this one could be a problem with the systems ordering (in my code).

I was thinking about only removing the physics component from the first one instead creating a new entity, but I have a problem: I need to handle the component removal to do extra logic (remove the body from the physics engine, etc). Dunno how to achieve that with Artemis, and if it should be in that way or my current solution is better.

Thanks for the answer.

I have already posted about the game in other forum thread, but if you didn't see it, here is the link of the game.

_________________
Image


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 14, 2011 7:26 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
arielsan wrote:
Hi appel, I have some questions:

1) could you share all the scene graph stuff? :D

2) I have some special case I dunno the best way to handle it:

In my current game I have arrows which have a physics component. Once they hit a target I want them to become stuck.

Right now, I am creating a new entity with similar information to the other one but without physics component and remove the old one. One problem with this solution is that I am creating a new entity and destroying another each time the arrows hit. Another problem is the arrows become invisible for one frame (because there is no arrow for one frame), this one could be a problem with the systems ordering (in my code).

I was thinking about only removing the physics component from the first one instead creating a new entity, but I have a problem: I need to handle the component removal to do extra logic (remove the body from the physics engine, etc). Dunno how to achieve that with Artemis, and if it should be in that way or my current solution is better.

Thanks for the answer.

I have already posted about the game in other forum thread, but if you didn't see it, here is the link of the game.


Removing a component is simple: Entity.removeComponent(ComponentType type)

Then invoke Entity.refresh()

Systems will be notified if a Entity it is currently holding no longer is relevant for the system aspect:
EntitySystem.removed(Entity e)
Just override it in your system.


My early scene-graph system:

Code:
package com.gamadu.modulus.systems;

import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.EntitySystem;
import com.artemis.utils.Bag;
import com.artemis.utils.ImmutableBag;
import com.artemis.utils.Utils;
import com.gamadu.modulus.components.LocalTransform;
import com.gamadu.modulus.components.Node;
import com.gamadu.modulus.components.Transform;

public class SceneGraphSystem extends EntitySystem {

   private ComponentMapper<Node> nodeMapper;
   private ComponentMapper<Transform> transformMapper;
   private ComponentMapper<LocalTransform> localTransformMapper;
   
   private Bag<Entity> rootNode;

   public SceneGraphSystem() {
      super(Node.class);
      rootNode = new Bag<Entity>();
   }
   
   @Override
   public void initialize() {
      nodeMapper = new ComponentMapper<Node>(Node.class, world.getEntityManager());
      transformMapper = new ComponentMapper<Transform>(Transform.class, world.getEntityManager());
      localTransformMapper = new ComponentMapper<LocalTransform>(LocalTransform.class, world.getEntityManager());
   }
   
   @Override
   protected void processEntities(ImmutableBag<Entity> entities) {
      for(int i = 0, s = rootNode.size(); s > i; i++) {
         processEntity(rootNode.get(i));
      }
   }
   
   private void processEntity(Entity entity) {
      Node node = nodeMapper.get(entity);
      Bag<Entity> children = node.getChildren();
      
      for(int i = 0, s = children.size(); s > i; i++) {
         Entity e = children.get(i);
         updateWorldTransformation(e);
         processEntity(e);
      }
   }

   private void updateWorldTransformation(Entity e) {
      Node node = nodeMapper.get(e);
      Entity parent = node.getParent();
      Transform parentTransform = transformMapper.get(parent);
      Transform transform = transformMapper.get(e);
      LocalTransform localTransform = localTransformMapper.get(e);
      
      float currentX = parentTransform.getX()+localTransform.getX();
      float currentY = parentTransform.getY()+localTransform.getY();
      
      float x = Utils.getRotatedX(currentX, currentY, parentTransform.getX(), parentTransform.getY(), parentTransform.getRotation());
      float y = Utils.getRotatedY(currentX, currentY, parentTransform.getX(), parentTransform.getY(), parentTransform.getRotation());
      
      transform.setLocation(x, y);
      transform.setRotation(parentTransform.getRotation());
   }

   @Override
   protected boolean checkProcessing() {
      return true;
   }

   @Override
   protected void added(Entity e) {
      Node node = nodeMapper.get(e);
      Entity parent = node.getParent();
      if(parent == null) {
         rootNode.add(e);
      } else {
         Node parentNode = nodeMapper.get(parent);
         parentNode.addChild(e);
      }
   }

   @Override
   protected void removed(Entity e) {
   }

}


Code:
package com.gamadu.modulus.components;

import com.artemis.Component;
import com.artemis.Entity;
import com.artemis.utils.Bag;

public class Node extends Component {
   private Entity parent;
   private Bag<Entity> children;

   public Node() {
      children = new Bag<Entity>();
   }
   
   public Node(Entity parent) {
      this();
      this.parent = parent;
   }
   
   public Entity getParent() {
      return parent;
   }
   
   public Bag<Entity> getChildren() {
      return children;
   }
   
   public void addChild(Entity child) {
      children.add(child);
   }

   public void removeChild(Entity child) {
      children.remove(child);
   }

}


Code:
package com.gamadu.modulus.components;

import com.artemis.Component;
import com.artemis.utils.Utils;

public class LocalTransform extends Component {
   private float x;
   private float y;
   private float rotation;

   public LocalTransform() {
   }

   public LocalTransform(float x, float y) {
      this.x = x;
      this.y = y;
   }

   public LocalTransform(float x, float y, float rotation) {
      this(x, y);
      this.rotation = rotation;
   }

   public void addX(float x) {
      this.x += x;
   }

   public void addY(float y) {
      this.y += y;
   }

   public float getX() {
      return x;
   }

   public void setX(float x) {
      this.x = x;
   }

   public float getY() {
      return y;
   }

   public void setY(float y) {
      this.y = y;
   }

   public void setLocation(float x, float y) {
      this.x = x;
      this.y = y;
   }

   public float getRotation() {
      return rotation;
   }

   public void setRotation(float rotation) {
      this.rotation = rotation;
   }

   public void addRotation(float angle) {
      rotation = (rotation + angle) % 360;
   }

   public float getRotationAsRadians() {
      return (float) Math.toRadians(rotation);
   }
   
   public float getDistanceTo(LocalTransform t) {
      return Utils.distance(t.getX(), t.getY(), x, y);
   }

}


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 14, 2011 9:20 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
Sorry, I didn't explain the problem very well. The thing is, when my system gets notified it is because the component was removed from the entity, but I need than component to get the body to be removed from the physics engine.

Thanks for the scene graph stuff!

_________________
Image


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 14, 2011 9:25 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
arielsan wrote:
Sorry, I didn't explain the problem very well. The thing is, when my system gets notified it is because the component was removed from the entity, but I need than component to get the body to be removed from the physics engine.


You can check what I do in the removed method in this code:

http://gamadu.com/svn/tankz/trunk/src/c ... ystem.java

Or... the PhysicsSystem can have a Map or Bag to contain the physics instance for a entity by entityId, if you don't want to store a reference to it in a component.

btw. LocalTransform could extend Transform, and then be empty. I haven't tested it though. (they are the same)


Top
 Profile  
 
 Post subject:
PostPosted: Sat Apr 23, 2011 4:34 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
what do you think about adding a default void implementation for initialize() method in EntitySystem abstract class?

Code:
   public void initialize() {
      
   }


So ppl doesn't have to implement it on each system.

Maybe same thing could be made for the checkProcessing (like EntityProcessingSystem does).

thanks

_________________
Image


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 27, 2011 10:37 pm 
Offline

Joined: Sat May 23, 2009 8:50 pm
Posts: 24
Location: Uruguay
appel, could you apply the fix to the determined order for entitysystem intialization.

it would mean changing this:

Code:
public void initializeAll() {
   for(EntitySystem es : systems.values()) {
      es.initialize();
   }
}


to this


Code:
public void initializeAll() {
   for (int i = 0; i < bagged.size(); i++) {
      bagged.get(i).initialize();
   }
}


previously you could work around the issue by asking for the systems, and calling initialize yourself, but now "initialize" is protected, so you have to use ugly reflection for that.

_________________
Image
Game Dev Blog


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 28, 2011 12:21 am 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
Updated.


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 01, 2011 2:47 am 
Offline

Joined: Sat May 23, 2009 8:50 pm
Posts: 24
Location: Uruguay
appel could you change the signature for setSystem on the SystemManager from:

Code:
public EntitySystem setSystem(EntitySystem system)


to this:

Code:
public <T extends EntitySystem> T setSystem(T system) {


it implies no change in the logic but allows the following code without casting:

Code:
CleanupSystem cleanupSystem = systemManager.setSystem(new CleanupSystem());


thanks a lot, so far liking artemis a lot.

_________________
Image
Game Dev Blog


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 05, 2011 4:07 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
Appel, what should be the approach when restarting a game. As I see in Tankz you are building again all systems, I am doing the same.

However, after restarting a game four or more times my game never starts again, no errors, only a black screen.

Looking at EntitySystem code:

Code:
   private static int SYSID = 0;
   private long systemBit = (long) Math.pow(2, SYSID++);


I believe the bug could be related with that, because after building a lot of systems that value be outside of the long boundaries (2^64).

I made a quick modification of that value (made it public) before I create all the systems again after a game restart and the bug didn't happen again, but I am not sure that is the problem.

What do you think? if it is that, which could be the solution?

Thanks

ps: btw, I am working on a new game (another one yeah, cant keep working on only one game for too much :S )

_________________
Image


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 05, 2011 4:26 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
What do you think of this solution?

(hate code formatting, it hides what I want to share)

_________________
Image


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 05, 2011 6:07 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
Good catch, thanks. I'll fix it.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 05, 2011 11:29 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
It's fixed, updates in svn.

Btw. long in Java is 128 bit.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 05, 2011 11:44 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
arielsan wrote:
What do you think of this solution?

(hate code formatting, it hides what I want to share)

I did not like that solution because it means you need to somehow inject that system bit. I like to make the framework easy to use with as little effort as possible, that means making the framework take care of it self. If the developer needs to define the system bit, he's taking care of the framework.


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 06, 2011 3:18 am 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
No, you are wrong, the user don't have to inject anything, the SystemManager does, it keeps auto contained int he framework, you could even make it package protected so no one could call that set method from outside.

Also, you have one class less than now.

_________________
Image


Last edited by arielsan on Fri May 06, 2011 3:22 am, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri May 06, 2011 3:21 am 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
appel wrote:
It's fixed, updates in svn.

Btw. long in Java is 128 bit.


My bad.

_________________
Image


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 420 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7, 8, 9 ... 28  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group