gornova / marteengine Goto Github PK
View Code? Open in Web Editor NEWMarteEngine is a Java Engine for videogames
Home Page: http://randomtower.blogspot.com
License: Other
MarteEngine is a Java Engine for videogames
Home Page: http://randomtower.blogspot.com
License: Other
closed by error
Integrate tiled and tilemaps into MarteEngine
Comments
thaaks about 13 hours ago | link | edit | delete
What are your ideas for this? What about the Slick builtin classes for Tiled maps?
Comment
What are your ideas for this? What about the Slick builtin classes for Tiled maps?
or cancel
Gornova 23 minutes ago | link | edit | delete
Big point here. In my vision developer just need to Tiled maps and use them in ME. Maybe build a utility method for World class to load entities into world? But if we do this way, we need to specify some kind of generic layers (entity for example) and attributes?
Maybe we can also support Ogmo Editor? http://ogmoeditor.com/
Title says it all, I have the camera working in my game, but it completely freaks out if I use a scalable game. I'm assuming that this is because it checks the display mode of the AppGameContainer. I just need to find out if I can check for a scalable game, and set the display boundaries appropriately.
Is this the right approach? I really have to use a scalableGame.
from arielsan:
bin and target folders must be created in order to build, what do you think about adding an internal ant target to create both folders if they don't exist? It is only a detail, but I was starting to test it and I believe it is easy for the user if you add this to the ant script.
Add hitbox rotation
During my game dev I realised that it's tricky to implement a Hud that stays on top of the camera. An entity that reads the camera offset and realigns itself isn't properly working and always a "bit behind" and tends to jump around the screen if the camera moves too much or often.
So for now I added an Entity instance var named "Hud" to the World that is updated on its own in World.update() and rendered after the camera GC translation is done but of course I'm looking for a more generic solution.
I can imagine that there are requirements to have entities below the camera (say for a static screen sized background) and entities in front of the camera (Hud, screen frame GUI, effects, shaders). They would be rendered before and after the camera GC translations occur.
That would imply that we could have two more lists of entities that need to be updated and rendered before and after the camera and the other "normal" entities.
What do you think about it? Do you have a better solution maybe?
Add tommy as author :D
Play around with camera and create some scrolling game. I might start with a platformer shooter - just for the fun of it
I'm trying to set up my camera to be like Fuzzy's, and I'm having a lot of trouble. I'm using a scalablegame, and when I load a map, the camera's not centered on the map, nor the player, and I get no vertical scroll whatsoever, so that the player can fall off camera, while still being within the map.
I think I'd be able to reason my way through how the system works, except that I have no idea how you did the camera box debug display in fuzzy alpha 2. I looked for the render code, but I couldn't find that.
Any help on this would be great. And if someone could explain to me how the camera works, I will make the tutorial myself, I just need a little guidance.
I think it makes sense to add a version number like MarteEngine_0.2.zip to the files. So it's clear which version you download.
currently when we want to change state in a slick StateBasedGame, we do:
game.enterState(GameWorld.ID, new FadeOutTransition(Color.black),
new FadeInTransition(Color.black));
But.. if GameWorld and current world would pass some entities (for example Editor/GameWorld), World.enter update ME.world current world for quick reference.. for some strange reason you need to set it in onEnter method of both worlds.. strange but we need to investigate
from arielsan
why do you have the .htaccess for the webstart? I mean, I understand for what it is, it only surprises me to see it in a build script, it should be something configured in an apache web server, or am I missing something?
need to remove it!
Integrate tiled and tilemaps into MarteEngine
Maybe we should put the newest lwjgl into our distribution as it fixes a lot of issues (for example with applets).
For Slick we should also try to get newer builds I think, especially since Kev seems to be on a bug run right now :-)
Add to build.xml a target to deploy an applet (and html page with), maybe using this approach: http://blog.gemserk.com/2010/12/30/game-as-applets/
Although I love the simple way of public instance vars in class Entity (x, y, speed and so on) some parts would be easier when we would use getter/setter methods.
So we have to decide if we either bite the bullet and lose some performance in our update calls that assign variables every time. Or we change the Entity API by switching from public instance vars to usage of getters and setters.
What's your opinion?
See http://slick.javaunlimited.net/viewtopic.php?p=18182 put into MarteEngine as optional Method for collision checks?
We must add version reference of MarteEngine on each page of wiki: my idea is to write documentation for only latest version of MarteEngine and forget about old versions
As I said in my other issue, I'm doing some refactoring, and I'm wondering if there's a reason why we're not using Rectangle to describe the Entity's hitbox.
If there isn't, would you be interested in me changing it to a Rectangle, and then refactoring the methods that use it?
The template project that is currently referenced in the "Setup" tutorial contains a bug:
The Eclipse project still has the src tree in the build path. That needs to be removed.
It's a minor issue, I know. But could cause trouble for newbies ;-)
But great stuff, Gornova, just works like a charm (after fixing it) ;-)
First off, I really appreciate you guys building and sharing this awesome engine. I am fully aware that the suggestions I'm going to make could all be bad, and could be going in a direction you don't want to go. I'm by no means implying that either of you aren't good programmers or that you've written bad code.
I'm merely relating some of my thoughts about the engine. If you're not interested in making any of these changes to the engine (or letting me do so), that's fine.
Anyways, this issue thread is where I'm going to keep making suggestions or describing how I'm refactoring the engine for my purposes. If you want to use any of it, or have any input on any of these subjects, please let me know!
I don't see why TextEntity and Background are entities. The only thing they have in common with any other Entity is that they need to be rendered.
For things like text messages and background or other static images, I suggest that we make a separate subclass, or perhaps just create an interface for updating and rendering.
I saw the movers used for Tweens, and I think that we should make it possible to extend these movers and use them for all entity motion.
That way you could abstract motion from Entities, and make our Entity classes smaller and easier to read.
If we implement physics as an interface, we can get rid of one level of inheritence. I feel that using an interface is more proper because PhysicsEntity is only different from Entity by behavior (methods), and that is the definition of an interface.
That's it for now, I'm going to get to work.
scale also hitbox
Particle emitter entities. Some simple entities to add Slick's particle stuff into the game ;-)
closed by error :D
thaaks about 14 hours ago | link | edit | delete
This implies that the hitbox is no longer just a set of coordinates and width/height but it should instead be converted into a Rectangle or a Shape that can be rotated and scaled.
This would also allow for other Shapes as collision zones for a later version.
Comment
This implies that the hitbox is no longer just a set of coordinates and width/height but it should instead be converted into a Rectangle or a Shape that can be rotated and scaled. This would also allow for other Shapes as collision zones for a later version.
or cancel
Gornova 4 minutes ago | link | edit | delete
Yes we can :D But I don't want to change method signature, for developer point of view, all must remain the same :D
see here for description of this problem/maybe feature:
I also like the Tweener stuff from Flashpunk (Entity is subclass of Tweener which is a container for Tweens that can modify it's parents variables). Should allow for more eye candy with Tweens for wobbling entities or strings that rotate, shrink and grow or change their alpha automatically...
Maybe we can refactor Platformers example a bit just to offer a generic PlatformerEntity that developers can extends
After looking at the Alarms wiki, I can't help but think there's a better way to identify alarms while still relying on primitives (instead of instantiating an Alarm class, for example). What do you guys think of this sort of approach?
public class AlarmEntity extends Entity {
private static final int MOVE_RIGHT = ME.newAlarm();
public AlarmEntity(float x, float y, Image image) {
super(x, y, image);
// now add an Alarm: we define an alarm to be triggered every 2 seconds
setAlarm(MOVE_RIGHT, 2, false, true);
}
@Override
public void alarmTriggered(int alarmId) {
// this method is called for every triggered method we can define on this entity
switch(alarmId){
case MOVE_RIGHT:
// in this case we just move right
x = x + 2;
}
}
}
ME.newAlarm() would be defined something like this:
class ME {
private static int alarmCounter = 0;
public static int newAlarm(){
return alarmCounter++;
}
...
}
See for example here: http://flashpunk.net/forums/index.php?topic=1706.0
Camera needs to render only visible stuff (as already implemented). But implementation needs to be improved.
Border of camera (what to render beyond the camera size) needs to be a variable for x and y and not a hardcoded 10.
What about Camera and Tiled map? I think that's also an issue...
Not 100% sure about this one and sorry for bringing this issue back. But the last days I thought it would be better to remove the public instance variables and make them private or protected and provide standard getter and setter methods.
Though I do see the advantage of simply saying "myEntity.x = 50;" it is still bad coding style.
What is your opinion here?
Some simple entity that displays a given text with a given font (constructor parameters) at it's position. Hitbox should completely surround the text. This way we could create nice text effects and simple buttons.
add alpha/transparency to entities. I will approach this next. Good for effects ;-)
add some basic function to entity to use it as text
we need a logo for our engine!
What about Game Maker features like some kind of globals for score, health and so on?
I was wondering if it would make sense to have just one place where you decide if your update routines (and other stuff like alarms) are frame rate based or delta time based.
Something like ME.useDeltatiming = true or false.
This way we could remove some parameters in some methods and simplify checking of this behavior.
So your complete game is either frame based or delta time based and you have to decide once on startup.
Your opinion?
from arielsan:
It seems to be something with proguard, btw, why is proguard required for the applet and webstart distributions? maybe could be an optional feature.
I are right: is better if it's optional!
Hi!! this patch is for convert the Entity Hitbox to a Polygon.
with minor changes in World (the hitBox rendering for tests)
From db598388c208f306ed4ed7321b986fb758827e09 Mon Sep 17 00:00:00 2001
From: unknown <Sabathorn@.(none)>
Date: Tue, 19 Apr 2011 06:25:42 -0430
Subject: [PATCH] Created a Polygon hitBox
---
src/it/randomtower/engine/World.java | 8 ++-
src/it/randomtower/engine/entity/Entity.java | 89 +++++++++++++------------
2 files changed, 51 insertions(+), 46 deletions(-)
diff --git a/src/it/randomtower/engine/World.java b/src/it/randomtower/engine/World.java
index a0f7bbe..b640848 100644
--- a/src/it/randomtower/engine/World.java
+++ b/src/it/randomtower/engine/World.java
@@ -74,9 +74,11 @@ public class World extends BasicGameState {
for (Entity e : entities) {
if (ME.debugEnabled) {
g.setColor(ME.borderColor);
- Rectangle hitBox = new Rectangle(e.x + e.hitboxOffsetX, e.y
- + e.hitboxOffsetY, e.width, e.height);
- g.draw(hitBox);
+ if(null != e.hitBox){
+ g.draw(new Rectangle(e.x + e.hitBox.getX(), e.y
+ + e.hitBox.getY(), e.width, e.height
+ ));
+ }
g.setColor(Color.white);
}
if (camera != null) {
diff --git a/src/it/randomtower/engine/entity/Entity.java b/src/it/randomtower/engine/entity/Entity.java
index 0ddd6c5..5f5d72f 100644
--- a/src/it/randomtower/engine/entity/Entity.java
+++ b/src/it/randomtower/engine/entity/Entity.java
@@ -19,6 +19,7 @@ import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;
+import org.newdawn.slick.geom.Polygon;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Vector2f;
@@ -112,14 +113,16 @@ public abstract class Entity implements Comparable<Entity> {
public boolean visible = true;
/** x offset for collision box */
- public float hitboxOffsetX;
+ //public float hitboxOffsetX;
/** y offset for collision box */
- public float hitboxOffsetY;
+ //public float hitboxOffsetY;
/** hitbox width of entity **/
- public int hitboxWidth;
+ //public int hitboxWidth;
/** hitbox height of entity **/
- public int hitboxHeight;
+ //public int hitboxHeight;
+ public Rectangle hitBox;
+
/** stateManager for entity **/
public StateManager stateManager;
@@ -166,14 +169,14 @@ public abstract class Entity implements Comparable<Entity> {
}
if (on) {
// modify hitbox position accordingly - move it a bit up and left
- this.hitboxOffsetX -= whalf;
- this.hitboxOffsetY -= hhalf;
+ this.hitBox.setX(this.hitBox.getX() - whalf);
+ this.hitBox.setY(this.hitBox.getY() - hhalf);
this.centered = true;
} else {
if (centered == true) {
// reset hitbox position to top left origin
- this.hitboxOffsetX += whalf;
- this.hitboxOffsetY += hhalf;
+ this.hitBox.setX(this.hitBox.getX() + whalf);
+ this.hitBox.setY(this.hitBox.getY() + hhalf);
}
this.centered = false;
}
@@ -267,9 +270,7 @@ public abstract class Entity implements Comparable<Entity> {
}
if (ME.debugEnabled) {
g.setColor(ME.borderColor);
- Rectangle hitBox = new Rectangle(x + hitboxOffsetX, y
- + hitboxOffsetY, hitboxWidth, hitboxHeight);
- g.draw(hitBox);
+ if(null !=hitBox){g.draw(hitBox);}
g.setColor(Color.white);
g.drawRect(x, y, 1, 1);
// draw entity center
@@ -422,11 +423,12 @@ public abstract class Entity implements Comparable<Entity> {
*/
public void setHitBox(float xOffset, float yOffset, int width, int height,
boolean collidable) {
- this.hitboxOffsetX = xOffset;
- this.hitboxOffsetY = yOffset;
- this.hitboxWidth = width;
- this.hitboxHeight = height;
+ //this.hitboxOffsetX = xOffset;
+ //this.hitboxOffsetY = yOffset;
+ //this.hitboxWidth = width;
+ //this.hitboxHeight = height;
this.collidable = true;
+ hitBox = new Rectangle(xOffset,yOffset,width,height);
}
/**
@@ -439,6 +441,8 @@ public abstract class Entity implements Comparable<Entity> {
return type.addAll(Arrays.asList(types));
}
+
+
/**
* check collision with another entity of given type
*
@@ -453,15 +457,14 @@ public abstract class Entity implements Comparable<Entity> {
// offset
for (Entity entity : world.getEntities()) {
if (entity.collidable && entity.type.contains(type)) {
- if (!entity.equals(this)
- && x + hitboxOffsetX + hitboxWidth > entity.x
- + entity.hitboxOffsetX
- && y + hitboxOffsetY + hitboxHeight > entity.y
- + entity.hitboxOffsetY
- && x + hitboxOffsetX < entity.x + entity.hitboxOffsetX
- + entity.hitboxWidth
- && y + hitboxOffsetY < entity.y + entity.hitboxOffsetY
- + entity.hitboxHeight) {
+ if ( !entity.equals(this) && x + hitBox.getX() + hitBox.getWidth() > entity.x
+ + entity.hitBox.getX()
+ && y + hitBox.getY() + hitBox.getHeight() > entity.y
+ + entity.hitBox.getY()
+ && x + hitBox.getX() < entity.x + entity.hitBox.getX()
+ + entity.hitBox.getWidth()
+ && y + hitBox.getY() < entity.y + entity.hitBox.getY()
+ + entity.hitBox.getHeight()) {
this.collisionResponse(entity);
entity.collisionResponse(this);
return entity;
@@ -483,14 +486,14 @@ public abstract class Entity implements Comparable<Entity> {
public Entity collideWith(Entity other, float x, float y) {
if (other.collidable) {
if (!other.equals(this)
- && x + hitboxOffsetX + hitboxWidth > other.x
- + other.hitboxOffsetX
- && y + hitboxOffsetY + hitboxHeight > other.y
- + other.hitboxOffsetY
- && x + hitboxOffsetX < other.x + other.hitboxOffsetX
- + other.hitboxWidth
- && y + hitboxOffsetY < other.y + other.hitboxOffsetY
- + other.hitboxHeight) {
+ && x + hitBox.getX() + hitBox.getWidth() > other.x
+ + other.hitBox.getY()
+ && y + hitBox.getY() + hitBox.getHeight() > other.y
+ + other.hitBox.getY()
+ && x + hitBox.getX() < other.x + other.hitBox.getX()
+ + other.hitBox.getWidth()
+ && y + hitBox.getY() < other.y + other.hitBox.getY()
+ + other.hitBox.getHeight()) {
this.collisionResponse(other);
other.collisionResponse(this);
return other;
@@ -507,14 +510,14 @@ public abstract class Entity implements Comparable<Entity> {
for (Entity entity : world.getEntities()) {
if (entity.collidable && entity.type.contains(type)) {
if (!entity.equals(this)
- && x + hitboxOffsetX + hitboxWidth > entity.x
- + entity.hitboxOffsetX
- && y + hitboxOffsetY + hitboxHeight > entity.y
- + entity.hitboxOffsetY
- && x + hitboxOffsetX < entity.x + entity.hitboxOffsetX
- + entity.hitboxWidth
- && y + hitboxOffsetY < entity.y + entity.hitboxOffsetY
- + entity.hitboxHeight) {
+ && x + hitBox.getX() + hitBox.getWidth() > entity.x
+ + entity.hitBox.getX()
+ && y + hitBox.getY() + hitBox.getHeight() > entity.y
+ + entity.hitBox.getY()
+ && x + hitBox.getX() < entity.x + entity.hitBox.getX()
+ + entity.hitBox.getWidth()
+ && y + hitBox.getY() < entity.y + entity.hitBox.getY()
+ + entity.hitBox.getHeight()) {
this.collisionResponse(entity);
entity.collisionResponse(this);
if (collidingEntities == null)
@@ -535,9 +538,9 @@ public abstract class Entity implements Comparable<Entity> {
* The y-position of the point.
*/
public boolean collidePoint(float x, float y) {
- if (x >= this.x - hitboxOffsetX && y >= this.y - hitboxOffsetY
- && x < this.x - hitboxOffsetX + width
- && y < this.y - hitboxOffsetY + height) {
+ if (x >= this.x - hitBox.getX() && y >= this.y - hitBox.getY()
+ && x < this.x - hitBox.getX() + width
+ && y < this.y - hitBox.getY() + height) {
this.collisionResponse(null);
return true;
}
--
1.7.3.1.msysgit.0
Use github wiki to write basic documentation:
0) write feature list for MarteEngine with webstart (or applets?)
Work on ant build.xml and let developer deploy on webstart, exe, applet or so on
Work on some stress test, like a cannon that fire 1000 bullets or so on
I'm doing a bunch of refactoring and optimizing of ME, because we've got some bloat (for instance, Entity has 1200 lines of code!). I know that's because you guys wanted to get the engine out there in a hurry, and make it simple to use, but I've got time, and I want to clean it up a bit.
I installed the eUML2 plugin, and used it to take a look at the full ME dependency graph. When I did, I figured out that the Solid class is never used.
Is there a reason why we can't get rid of it?
I wonder if is possible to add on MarteEngine, Fizzy: http://slick.javaunlimited.net/viewtopic.php?p=16141 a Jbox2d wrapper :D
My idea is to have all the physics stuff addable on each Entity and World take care of the rest. There are many issues on this approach:
I think that integration is possible but first step must be extend our object, not change it directly and see if it's working :D
Tween and Tweener and involved classes like Ease and *Motion need code cleanup.
Tween and Tweener should not need to know about Entity and should not require an entity as a method parameter. Instead they need to have a proper startingPosition set. That's it.
Method apply() should be renamed to update() and also get the delta value as parameter.
Tweens should be modified to allow usage of delta instead of tick based counting. Also duration should be a value in ticks OR in milliseconds, similar to the solution in my Alarm class. Pretty simple.
I'm wondering if start() and pause() and so on should only affect the current Tween or simply all of them. If they affect only one tween I want to pass the Tween as parameter maybe. And not just rely on the internal variable current...
I've got an enemy which needs to know if the player is on the same platform, and then speed towards them. I looked into the collide methods, and decided that I'd rather simply create a large rectangle, and get the nearest entity contained in that box.
Here's the code I have, which is ... well, it seems to work sometimes, but not the way that I was hoping for. If there's a simpler solution, or if you can see my error, let me know!
...
public boolean canSee(String name, float xExpansion, float yExpansion)
{
if (name == null)
return false;
Rectangle requestBox, theirHitbox;
int nearestIndex = 0, currentIndex = 0;
if (xExpansion <= 0)
{
requestBox = new Rectangle(
this.x + this.hitboxOffsetX + xExpansion, this.y
+ hitboxOffsetY, this.hitboxWidth - xExpansion,
this.hitboxHeight - 1);
} else
{
requestBox = new Rectangle(this.x + this.hitboxOffsetX, this.y
+ hitboxOffsetY, this.hitboxWidth + xExpansion,
this.hitboxHeight - 1);
}
//setHitBox(requestBox.getMinX(), requestBox.getMinY(), (int)requestBox.getWidth(), (int)requestBox.getHeight() );
Vector2f nearestValues = new Vector2f();
if (xExpansion <= 0)
{
}
for (Entity entity : world.getEntities())
{
if (entity.collidable)
{
theirHitbox = new Rectangle(entity.x + entity.hitboxOffsetX,
entity.y + entity.hitboxOffsetY, entity.hitboxWidth,
entity.hitboxHeight);
if (!entity.equals(this)
&& (requestBox.contains(theirHitbox.getMinX(),theirHitbox.getMinY()) ||
requestBox.contains(theirHitbox.getMaxX(), theirHitbox.getMinY()) ||
requestBox.contains(theirHitbox.getMaxX(), theirHitbox.getMaxY()) ||
requestBox.contains(theirHitbox.getMinX(), theirHitbox.getMaxY()) ))
{
// we're casting to the left or up, check for the highest
// values
if (xExpansion < 0)
{
if (currentIndex == 0)
{
nearestIndex = currentIndex;
nearestValues.x = theirHitbox.getMaxX();
nearestValues.y = theirHitbox.getMaxY();
}
// is the new one closer?
else if (theirHitbox.getMaxX() > nearestValues.x
&& theirHitbox.getMaxY() > nearestValues.y)
{
nearestIndex = currentIndex;
nearestValues.x = theirHitbox.getMaxX();
nearestValues.y = theirHitbox.getMaxY();
}
}
else
{
if (currentIndex == 0)
{
nearestIndex = currentIndex;
nearestValues.x = theirHitbox.getMaxX();
nearestValues.y = theirHitbox.getMaxY();
}
// is the new one closer?
else if (theirHitbox.getMinX() < nearestValues.x
&& theirHitbox.getMinY() < nearestValues.y)
{
nearestIndex = currentIndex;
nearestValues.x = theirHitbox.getMaxX();
nearestValues.y = theirHitbox.getMaxY();
}
}
}
}
currentIndex++;
}
String nearestName = world.getEntities().get(nearestIndex).name;
//Log.debug(nearestName);
if (nearestName == name)
{
return true;
}
return false;
}
...
I think that we need to explain better:
Fast tip from Sabathorn:
Hi!! i'm using your engine to make a test game before begin with a project. I noticed that i can't flip animations (or at least i didn't found how) so i did this little CopyPaste enhancement:
/**
* Add animation to entity, first animation added is current animation.
* Can Flip the frames horizontally o vertically
* @param name
* @param loop
* @param fliphorizontal
* @param flipvertical
* @param row
* @param frames
*/
public void addFlippedAnimation(String name, boolean loop,boolean fliphorizontal,boolean flipvertical, int row, int... frames) {
Animation anim = new Animation(false);
anim.setLooping(loop);
for (int i = 0; i < frames.length; i++) {
anim.addFrame(sheet.getSprite(frames[i], row).getFlippedCopy(fliphorizontal, flipvertical), duration);
}
if (animations.size() == 0) {
currentAnim = name;
}
animations.put(name, anim);
}
i hope this pm not being an annoyance.
Thanks for the really cool engine!
add a task on build.xml to distribuite only MarteEngine.jar, without tests and resources :D
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.