prime31 / nez Goto Github PK
View Code? Open in Web Editor NEWNez is a free 2D focused framework that works with MonoGame and FNA
License: MIT License
Nez is a free 2D focused framework that works with MonoGame and FNA
License: MIT License
So I've noticed that when I start a scene that contains an ArcadeRigidBody as the game's default scene sometimes the Entity spawns in convoluted and awkward positions.
IF I give the game a wait period before entering the scene, or we enter the scene from another scene, everything works as intended.
Some example code hopefully to illustrate my issue:
` public class Character : Entity
{
private string avatarTexture;
public Character (string textureName, int health = 10, int mana = 10, int walkspeed = 1) :base()
{
avatarTexture = textureName;
}
public override void onAddedToScene ()
{
var texture = scene.contentManager.Load<Texture2D> ("bin/MacOSX/" + avatarTexture);
addComponent (new Sprite (texture));
addComponent (new FollowCamera (this));
addComponent (new CharacterController2D ( ));
colliders.add (new BoxCollider ());
base.onAddedToScene ();
}
}
public class TiledMapScene : Scene
{
Entity _player;
public TiledMapScene (string mapName)
{
addRenderer( new DefaultRenderer() );
var map = contentManager.Load<Nez.Tiled.TiledMap> ("bin/MacOSX/" + mapName);
var objects = map.getObjectGroup ("Objects");
var spawn = objects.objectWithName( "spawn" );
var wall = createEntity ("tiled-map");
wall.addComponent (new TiledMapComponent (map, "Collision"));
wall.getComponent<TiledMapComponent> ().tiledmap.getLayer ("Collision").visible = false;
_player = new Character ("mage001");
_player.transform.position = new Vector2 (spawn.x, spawn.y);
addEntity (_player);
}
}
public class Game1 : Core
{
Scene.SceneResolutionPolicy policy;
public Game1 () : base (640, 360, false, true)
{
policy = Scene.SceneResolutionPolicy.NoBorderPixelPerfect;
Scene.setDefaultDesignResolution (320, 180, policy);
}
protected override void Initialize ()
{
// TODO: Add your initialization logic here
base.Initialize ();
//This spawns our ArcadeRigidBody player at a really odd position
//Note, this doesnt happen if we focus on the game after it starts paused
Core.scene = new TiledMapScene ("mainMap");
//This works as intended, player spawns where we tell it to
//Core.schedule (0.5f, timer => Core.scene = new TiledMapScene("mainMap"));
}
}
`
"The type initialiser for 'Nez.Input' threw an exception" when running on the latest commit.
System.DllNotFoundException: user32.dll at (wrapper managed-to-native) Microsoft.Xna.Framework.Input.Touch.TouchPanelCapabilities:GetSystemMetrics (int).
// set some values in the Input class to translate mouse position to our scaled resolution
var scaleX = renderTargetWidth / (float)_finalRenderDestinationRect.Width;
var scaleY = renderTargetHeight / (float)_finalRenderDestinationRect.Height;
Input._resolutionScale = new Vector2( scaleX, scaleY );
Input._resolutionOffset = _finalRenderDestinationRect.Location;
This area in scene seems to cause the problem.
I noticed a couple of things in BehaviorTree.cs that could cause issues.
First, if you set the updatePeriod to 0, you get an infinite loop.
Second, if you happen to hit a really long frame, one that doubles the updatePeriod, it will cause _root.tick(_context); to be run twice because it's in the while loop.
Fixes below:
if (updatePeriod > 0) { _elapsedTime -= Time.deltaTime; if (_elapsedTime <= 0) { while (_elapsedTime <= 0) { _elapsedTime += updatePeriod; } _root.tick(_context); } } else { _root.tick(_context); }
Component initialisation logic is placed in onAddedToEntity()
However, there doesn't seem to be a way to find out if a component has actually been added to the entity yet - meaning there's no way to find out if custom component initialisation code has been run yet.
getComponent
methods within ComponentList
return components which are within the components
list as well as componentsToAdd
.
I currently have the following code in a system. The system is being added to the scene the same frame the PlayerInputComponent
is being added to the entity.
var input = player.getComponent<PlayerInputComponent>();
if (input.xAxisInput.value < 0)
moveLeft();
The xAxisInput
property isn't initialised until the component is added to the entity, so this falls down.
I could place checks everywhere in my code to make sure I don't reference things which haven't been initiated, but I feel like this would be better solved by:
getComponent
which allow you to only return components which have been initialised. (Preferred - no additional checks required)At the moment I've just removed the checks to the componentsToAdd
in the getComponent
method, but this is specific to my needs and I'd love the core library to support this out of the box.
More than happy to write the code, would just like your input on possible solutions first.
I have a TextureAtlas containing 8 frames, but only 7 are added to the animation created through getSpriteAnimation().
Changing the for loop from this
for( var i = point.X; i < point.Y; i++ ) animation.addFrame( subtextures[i] );
to this
for( var i = point.X; i <= point.Y; i++ ) animation.addFrame( subtextures[i] );
Seemed to have fixed the issue for me.
Is there any plan to support ellipse shapes for colliders? Using ellipses for (N)PCs is fairly common, as circles don't always fit sprites very well and rectangles don't conform to natural curves of sprites as well.
I have certain animations that require the collider on an entity to change with each frame. There doesn't seem to be any obvious way to modify an existing collider, as all of my experiments have yielded... odd results. This mostly seems to be due to the way colliders are queued up to be added, rather than being registered immediately. Is there an easy way to modify a collider that I'm simply overlooking, or is that behavior simply not intended in the current state of the framework?
Ive been having an issue using the TrailRibbon component when its attached to a pooled entity. When obtaining an entity from the pool that had been previously used you would see the trail quickly move from its last position that was used.
I fixed the issue be overriding onEnabled() in the TrailRibbon component like below.
I was going to submit a pull request, but decided I'd ask to see if you have a better solution?
TrailRibbon.cs
public override void onEnabled()
{
base.onEnabled();
_segments.Clear();
initializeVertices();
}
So now in my PlayerBulletEntity.cs
public class PlayerBulletEntity : Entity, IPoolable
{
TrailRibbon _trailRibbon;
public PlayerBulletEntity() : base()
{
addComponent(new PlayerBulletComponent());
_trailRibbon = addComponent(new TrailRibbon(10));
_trailRibbon.setRenderLayer(4);
_trailRibbon.ribbonRadius = 8;
_trailRibbon.startColor = Color.AliceBlue;
_trailRibbon.endColor = Color.Yellow;
reset();
}
public void reset()
{
setEnabled(false);
}
public void start(Vector2 pos)
{
transform.setPosition(pos);
_trailRibbon.transform.position = pos;
setEnabled(true);
}
}
Started a new project and started following your Getting Started video on your YouTube channel. At the point where you remove all the default stuff in Monogame such as the LoadContent and such. I run the project and I get a Null error in line 79 of EffectResources.cs Just wondering what the fix was. Here is where the error is.
internal static byte[] getMonoGameEmbeddedResourceBytes( string name )
{
#if FNA
name = name.Replace( ".ogl.mgfxo", ".fxb" );
#endif
var assembly = ReflectionUtils.getAssembly( typeof( MathHelper ) );
using( var stream = assembly.GetManifestResourceStream( name ) )
{
using( var ms = new MemoryStream() )
{
///here
stream.CopyTo( ms );
return ms.ToArray();
}
}
}
This is kind of a discussion for opinions, but personally I think addComponent should return the component being added.
My reason for this at least, is say for entity definitions, we can simply
_spriteAnimations = addComponent(new Sprite<AnimationEnums>(_____));
vs
_spriteAnimations = new Sprite<AnimationEnums>(____);
addComponent(_spriteAnimations);
The chaining seems handy for quick prototyping (such as in the example scenes), but this feels like a more natural way to do it. Any thoughts on this? I'm open to differing opinions, if there's a real benefit to chaining that I just don't know about, I'd be interested!
If each folder will be an animation, then it'd be nice to automatically handle the naming of images within, to avoid conflicts (and having to rename files). Perhaps append the parent folders names (separated by underscores) to the dictionary key, since the folder path will be unique? (i.e Fighter_Down_001)
For example:
Characters/Fighter/Down/001.png ... 003.png
Characters/Fighter/Up/001.png ... 003.png
Throws:
Build started 2016-02-14 9:27:27 PM
/Content/FighterMaleAtlas.xml
----- adding animation: Down, frames: [0 - 2]
----- adding animation: Left, frames: [3 - 5]
----- adding animation: Right, frames: [6 - 8]
----- adding animation: Up, frames: [9 - 11]
Adding texture: 001
Adding texture: 002
Adding texture: 003
/Content/FighterMaleAtlas.xml: error: Processor 'TextureAtlasProcessor' had unexpected failure!
System.ArgumentException: An item with the same key has already been added.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary2.Insert(TKey key, TValue value, Boolean add) at Nez.TextureAtlasGenerator.TextureAtlasProcessor.Process(String[] input, ContentProcessorContext context) in \PipelineImporter\TextureAtlasGenerator\TextureAtlasProcessor.cs:line 75 at Microsoft.Xna.Framework.Content.Pipeline.ContentProcessor
2.Microsoft.Xna.Framework.Content.Pipeline.IContentProcessor.Process(Object input, ContentProcessorContext context)
at MonoGame.Framework.Content.Pipeline.Builder.PipelineManager.ProcessContent(PipelineBuildEvent pipelineEvent)
When importing a texture packer atlas, the only way to get it to work is to have the json file named something like "texturepacker.json" and have the png with the sprites "texturepacker_atlas.png" and in the file "TexturePackerAtlasReader.cs" Line 13 needs to be var texture = reader.ContentManager.Load<Texture2D>( assetName + "_atlas");
If you do not add the _atlas, calling myScene.contentManager.Load<TexturePackerAtlas>("texturepacker")
will return a texture2D
So I'd usually just fix this kind of thing myself, but I'm struggling to understand how exactly the matcher is storing/comparing types.
I'm adding an entity processor like so:
addEntityProcessor(new CombatSystem(new Matcher().all(typeof(CharacterComponent))));
However, this matcher is returning 'true' when an entity with a DialogueComponent
Sprite<T>
attached is getting passed through for comparison. This entity does not have a CharacterComponent
attached.
When debugging I take a look within the Matcher class.
public bool isInterested( BitSet componentBits )
From what I can see, when looking in to the componentBits that are passed in, both DialogComponent
and CharacterComponent
are being represented as {0}, causing the matcher to register my entity for a system it shouldn't do.
Edit: All of that is wrong. This seems related to the Sprite<T>
component instead.
TmxTerrain -> TileId (is a string, should be int)
TmxTile -> Id (is a string, should be int)
Structural thoughts:
TmxData contains all the map data, so TmxDataTile is the tile in that data. Therefore, I think TmxTile should be called 'TmxTilesetTile', as TmxTile is actually the Tile that the tileset contains.
Tiled has animations per tile which should be supported.
TmxTile ->
[XmlArray("animation")] [XmlArrayItem("frame")] public List<TmxTilesetTileAnimationFrame> AnimationFrames;
TmxTilesetTileAnimationFrame ->
[XmlRoot( ElementName = "frame" )]
public class TmxTilesetTileAnimationFrame
{
public TmxTilesetTileAnimationFrame()
{
}[XmlAttribute( AttributeName = "id" )] public int Id; [XmlAttribute( AttributeName = "duration" )] public int duration;
}
Along with an IUpdatable that adjusts the source rectangle/elapsed time.
For reference, in an old project I had, this is what I had done to throw in some support for it:
//(Tileset Constructor)
internal Tileset(IMap parentMap, ContentManager contentManager, TmxTileset tmxTileset)
{
ParentMap = parentMap;
_tmxTileset = tmxTileset;
Texture = contentManager.Load<Texture2D>(_tmxTileset.image.source.Remove(_tmxTileset.image.source.Length - 4, 4).Replace('\\', '/').Replace("Content/", "")); //Trim end of filename
GenerateTiles();
if (_tmxTileset.tiles.Any())
{
var convList = (List<ITilesetTile>)Tiles;
foreach (var tile in _tmxTileset.tiles)
{
if (tile.AnimationFrames.Any())
{
var newTile = new TilesetAnimatedTile(this, tile);
convList.RemoveAll(t => t.Id == newTile.Id);
Tiles.Add(newTile);
}
else
{
var newTile = new TilesetTile(this, tile);
convList.RemoveAll(t => t.Id == newTile.Id);
Tiles.Add(newTile);
}
}
}
SetSourceRectangles();
}
public class TilesetAnimatedTileFrame : ITilesetAnimatedTileFrame
{
public int Id { get; }
public float Duration { get; }
public TilesetAnimatedTileFrame(TmxTilesetTileAnimationFrame tmxAnimationFrame)
{
Id = tmxAnimationFrame.Id + 1; //+1 to fix offsetting
Duration = (float)tmxAnimationFrame.duration / 1000; //To match XNA timing
}
}
public class TilesetAnimatedTile : ITilesetAnimatedTile
{
//public int UpdateOrder { get; } = (int)UpdateOrders.Update;
public ITileset ParentTileset { get; }
public int Id { get; }
public Rectangle SourceRectangle { get; set; }
public IList<ITilesetAnimatedTileFrame> TileFrames { get; } = new List<ITilesetAnimatedTileFrame>();
private int _frameCounter;
private ITilesetAnimatedTileFrame _currentFrame => TileFrames[_frameCounter];
private float _elapsed;
public TilesetAnimatedTile(ITileset parentTileset, TmxTilesetTile tmxTilesetTile)
{
ParentTileset = parentTileset;
Id = tmxTilesetTile.Id + 1; //+1 to fix offsetting
foreach (var aTile in tmxTilesetTile.AnimationFrames)
TileFrames.Add(new TilesetAnimatedTileFrame(aTile));
}
public bool enabled { get; set; } = true;
public int updateOrder { get; set; } = 0;
public void update()
{
_elapsed += Time.deltaTime;
if (_elapsed > _currentFrame.Duration)
{
if (_frameCounter == TileFrames.Count - 1)
_frameCounter = 0;
else
_frameCounter++;
SourceRectangle = ParentTileset.GetSourceRectangle(_currentFrame.Id); //Update SourceRectangle
_elapsed = 0f;
}
}
}
Hi Mike,
I just followed your video on youtube and when I tried to build the Nez project I got the following error;
warning MSB3274: The primary reference "MonoGame.Framework" could not be resolved because it was built against the ".NETPortable,Version=v4.5,Profile=Profile111" framework.
This is a higher version than the currently targeted framework ".NETPortable,Version=v4.0,Profile=Profile5".
I tried changing target but then it spewed a lot of errors in different parts of the Nez projects (mainly reflection parts that have changed in the newer version).
I fixed it by replacing the dll in the Nez\Nez-PCL\MonoGamePCL folder with the DLL from the monogame site. Don't know if the error is on my side or I did something wrong. It works but I just thought I'd let you know!
*Edit: * Visual Studio 2015, Monogame 3.5 installer and Monogame windows openGl project template is what I'm using.
There's actually a number of new map changes since the 0.11, such as
Per the documentation @ http://doc.mapeditor.org/reference/tmx-map-format/ (the relevant lines will say '(since 0.13)' or '(since 0.15), changelog for TMX format is here: http://doc.mapeditor.org/reference/tmx-changelog/
Currently using the following system to change the layer depth of objects based on their position on the screen:
public class RenderOrderSystem : PassiveSystem
{
protected override void begin()
{
var sprites = scene.renderableComponents.componentsWithRenderLayer((int)Layers.Object);
if (sprites.Count == 0)
return;
var max = 1.0f / sprites.Count;
var index = 0;
foreach (var sprite in sprites.OrderByDescending(s => s.entity.transform.position.Y))
{
index++;
var depth = max * index;
sprite.setLayerDepth(depth);
}
}
}
and the following code to set up the lighting renderer:
var lightingRenderer = new DeferredLightingRenderer(0, (int)Layers.Light);
lightingRenderer.renderLayers = new int[] { (int)Layers.Ground, (int)Layers.Object, (int)Layers.Fringe };
But breaks when a DeferredLightingRenderer
is added:
Am I missing any steps required to get this to work properly?
Step one in the wiki has you passing in textures & entities to the wrong scene. You should be passing them into the myScene Scene you create rather than the Scene you get from Core.scene. I was unable to compile the code in the wiki using the latest commit or the release version, until making this change.
Here is a image of the changes needed:
(My apologies if I did not submit this correctly. I have no clue how to submit a pull request to a GitHub wiki.)
Entity using ArcadeRigidbody for movement with no other entities on scene.
Have two PC monitors.
On 144 hz monitor, I get 144 fps and it takes slightly less than 4 seconds to move from one end of window to the other.
On 60 hz monitor, I get about 48 fps, and it takes nearly 7 seconds to move from one end of the window to the other.
There is clearly not framerate independency here, even though ArcadeRigidbody appears to rely on deltatime.
After updating to new version of Nez, I have experienced an issue with BitmapFontReader. I get a Method Not Supported exception on this line:
textures[i] = reader.ReadObject<Texture2D>();
Changing this line by not calling ReadBoolean() seems to fix the issue (but obviously skirts the entire purpose of this check):
var hasTextures = reader.ReadBoolean();
I'm not sure if this error is related to my implementation or not, but there you go.
I'm curious what the preferred approach to changing layer depth is when importing with Tiled (IE some layers in foreground, some in background, etc). The approach I'm trying now is to have tile layers with a custom Depth property, and then setting the value to a TiledLayer object. Then, when the TiledLayer is to be drawn, I pass in the depth value of the current layer being drawn instead of the map's layerDepth value.
This isn't working, though I'm not sure why.
The only other approach I can think of is to have separate map components for each depth I want to use, but that seems unwieldy.
Any way to do this elegantly?
The gid is currently only set when data encoding is csv or base64, so TmxDataTile needs
[XmlAttribute(AttributeName = "gid")]
To make it load the gid in unencoded tmx files
For my project I need sprites that rotate independently of the parent entity. This is fairly easy to implement in a custom renderable component, but should the default RenderableComponent have this functionality built in?
DefaultCommands.cs line 91
I'd open a PR but I'm just kicking the tires on this and don't know if I screwed something else up in my project that's the ultimate root cause of this :)
I get this error when I try and build the Pipeline Importer. I have all the references.
Error CS0433 The type 'FileMode' exists in both 'MonoGame.Framework, Version=3.5.1.1679, Culture=neutral, PublicKeyToken=null' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Nez.PipelineImporter D:\Users\Documents\Visual Studio 2015\Projects\Nez\Nez-master\Nez.PipelineImporter\Tiled\TiledMapImporter.cs
Edit: Fixed it by changing the dll that I referenced
I wouldn't really consider this an issue just something I noticed using Monocle that seems the correct way. So at the minute using a Texture Packer atlas my layout is this:
I can access that texture I need in Nez by typing:
getSubtexture("Wall_Top")
The idea was I could have the same names under different "area" folders and be accessed like
getSubtexture"(Enviroment/Forest/Wall_Top)"
Instead of naming each of my actual files ForestWall_Top, OtherAreaWall_Top etc. Just a suggestion!
I'm using the TiledMapComponent
to setup my collision layer. What I wanted is to add a collider to the entity that moves on the tile map and get collision data.
Looking through the source code for Mover
, specifically notifyTriggerListeners
it seems that any ITriggerListener
component attached to the colliding entity should fire the events on collision, but it doesn't happen.
I've written a couple of behavior trees to test how the aborts work and it seems like there might be a bug or two. It's entirely possible this is working as it should and I'm just not understanding how aborts work.
Here's the code:
`
bool test = true;
TaskStatus ToggleTest()
{
test = !test;
return TaskStatus.Success;
}
public BehaviorTree<BehaviorTreeMiner> buildSelfAbortBugTree()
{
var builder = BehaviorTreeBuilder<BehaviorTreeMiner>.begin( this );
builder.selector( AbortTypes.Self );
{
builder.conditionalDecorator(m => m.test, false);
builder.sequence()
.logAction("1-1")
.action( m => m.ToggleTest() )
.logAction("1-2")
.endComposite();
builder.conditionalDecorator(m => !m.test, false);
builder.sequence()
.logAction("2-1")
.action( m => m.ToggleTest() )
.logAction("2-2")
.endComposite();
}
builder.endComposite();
return builder.build();
}
public BehaviorTree<BehaviorTreeMiner> buildLowerPriorityAbortBugTree()
{
var builder = BehaviorTreeBuilder<BehaviorTreeMiner>.begin( this );
builder.selector();
{
builder.sequence(AbortTypes.LowerPriority)
.conditional( m => m.test )
.logAction("1-1")
.action( m => m.ToggleTest() )
.logAction("1-2")
.endComposite();
builder.sequence(AbortTypes.LowerPriority)
.conditional( m => !m.test )
.logAction("2-1")
.action( m => m.ToggleTest() )
.logAction("2-2")
.endComposite();
}
builder.endComposite();
return builder.build();
}
`
I'm trying to create some HUD elements by adding Sprites and Text under a certain HUD component to the entity.
I'd like to decrease the size of the font, but it looks like the only way to do that is to scale the entity. Is this correct?
What is the recommended way to achieve this? Should I have the text under a different entity or should I use the UI classes instead?
The JSON reference for Nez is broken upon pull. Easy fix, but it seems the NuGet package is out-of-date. This is for the Pipeline Importer project only.
Hopefully I'm not going about this the wrong way, but I have a simple platformer game. The player uses raycasting to figure out where solid ground is.
if (hit.collider != null)
{
velocity.Y = (hit.distance) * directionY;
rayLength = hit.distance;
collisions.below = directionY == 1;
collisions.above = directionY == -1;
}
Basically, the player will move to contact the block by setting the velocity to the remaining space.
However, when I inspect hit.distance
, it doesn't seem to be the distance of the ray starting at the origin, but the distance from the top-left of the screen.
Hopefully I'm not just using this wrong/misunderstanding.
Please add this awesome pixel art upscaling shader for resolutions that aren't scalable by integer.
https://www.allegro.cc/forums/thread/612318
When trying to move at relatively high velocities, the Mover.move() method fails. I realize that at a certain point extra code needs to be written (with, say, extra linecast checks) to compensate for extremely high velocities, but while starting on a platformer with gravity, I was surprised to find that it failed fairly quickly, thought I'd bring it to your attention.
Steps to reproduce:
(The values above are, of course, not the only ones that will trigger this bug, but those happen to be the ones in the code samples)
Here is a minimal code sample I whipped up real quick. I would include a zip of the project, but I know that you develop primarily on OSX and I'm on a PC right now, so I figured this might be easier.
// Game.cs
using Microsoft.Xna.Framework;
using Nez;
namespace Game2Test {
public class Game1 : Core {
public Game1() : base(width: 640, height: 480, isFullScreen: false, enableEntitySystems: false) {
}
protected override void Initialize() {
base.Initialize();
Core.debugRenderEnabled = true;
var myScene = Scene.createWithDefaultRenderer(Color.Black);
var player = myScene.addEntity(new Entity("player"));
player.transform.position = new Vector2(50, 150);
player.colliders.add<BoxCollider>(new BoxCollider(25, 25));
player.addComponent<Mover>(new Mover());
player.addComponent<PlayerMove>(new PlayerMove());
var ground = myScene.addEntity(new Entity("ground"));
ground.transform.position = new Vector2(0, 300);
ground.colliders.add<BoxCollider>(new BoxCollider(640, 10));
scene = myScene;
}
}
}
// PlayerMove.cs
using Nez;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace Game2Test {
class PlayerMove : Component, IUpdatable {
float speed = 100f;
Vector2 velocity;
public void update() {
if (Input.isKeyDown(Keys.Left)) {
velocity.X = -1 * speed;
} else if (Input.isKeyDown(Keys.Right)) {
velocity.X = speed;
} else {
velocity.X = 0f;
}
// apply gravity
velocity.Y += Physics.gravity.Y * Time.deltaTime;
Vector2 deltaMovement = velocity * Time.deltaTime;
Debug.log("deltaMovement.Y = {0} and position.y = {1}", deltaMovement.Y, entity.transform.position.Y);
CollisionResult collisionResult;
entity.getComponent<Mover>().move(deltaMovement, out collisionResult);
}
}
}
When using Input.gamePads[0]isButtonDown(Buttons.LeftTrigger) the return value is always false. Initially I was using the VirtualButton setup and found that my triggers were never returning true. Then I tested just the basic isButtonDown and found that to also never return true. I then went to a pure monogame project and tried isButtonDown and it worked fine.
I tried setting a breakpoint right after the call to Monogame's isButtonDown and checking the value and it is returning false. I did the same in my own project and it returned true.
Also the same problem exists for the other checks (isButtonPressed, etc).
I just came around looking to get started with Nez and was surprised there isn't a nuget package available.
Additional information: Collection was modified; enumeration operation may not execute.
For some reason every once in a while this happens to me while I move around with the character.
My movement component called Mover.move at the end of it's IUpdatable.update loop.
Advice?
Edit: I assume it has something to do with another thread doing
unregisterAllCollidersWithPhysicsSystem
player.transform.position = new Vector2(x,y);
registerAllCollidersWithPhysicsSystem
..to correct the players location if it differs from the server.
What would be the best way to achieve this without making the "physics" go crazy?
Just set the position without unregistering the colliders?
When I clone Nez to one of my computers and attempt to open the solution it fails. The Nez project says load failed and gives me the following message:
"The project is targeting frameworks that are either not installed or are included as part of future updates to Visual Studio."
I've cloned the Nez project previously onto my desktop computer and the project loaded just fine, only on this other PC is it giving me this error.
Two things to note:
I have a 16x16 grid on tiled, but I sometimes include tilesets of 32x32 tiles etc.
When placing those tiles in tiled they are drawn differently (anchor bottom left on Tiled).
What is the best way to sync the results without changing something about Nez that would not be pulled in later?
Is there anything built-in to adjust this currently?
I could theoretically place them as images on the object layer, but it would greatly reduce the dev speed.
I have a basic character controller set up, and I'm importing some non-rectangular collision polygons from a tiled map.
When the player character moves, I have a boxcast set up to correct any intersections (like in the platformer example in Nez.Samples).
Here's a sample of the code I'm working with -
......
entity.colliders.unregisterAllCollidersWithPhysicsSystem();
....
foreach (var neighbor in neighbors)
{
if (neighbor.isTrigger)
continue;
if (collider.collidesWith(neighbor, velocity, out collisionResult))
{
velocity -= collisionResult.minimumTranslationVector;
}
Debug.log($"translationvector: {collisionResult.minimumTranslationVector.X}, {collisionResult.minimumTranslationVector.Y}");
}
}
...
On certain areas, this works correctly. On flat ground, I might get a log
output of 0, -0.4
, which makes sense as the player's gravity is pushing down at 0.4
.
However, on slopes, I'm getting some erratic readings - the character jumps all around and I get output such as
Log: translationvector: 0, -31.58746
Log: translationvector: 0, 0.4125366
Log: translationvector: 0, -32.00002
Log: translationvector: 0, 32.4158
Log: translationvector: 0, -31.58228
Log: translationvector: 0, 0.4177246
Log: translationvector: 0, 32.41754
It's worth noting that my player character has a size of 32px, so there may be a relation between the jumps in Y
being ~32
I've stripped everything off of my character besides the boxcast to make sure it was the issue, and it still remains unfortunately.
Hello,
I'm quite new to monogame and Nez, and thanks for the hard work your doing with this framework;
I'm might be doing something wrong :p but when i'm starting my prototype to load a tiledMap I get this issue.
line 35: var texture = reader.ContentManager.Load<Texture2D>( textureAssetName );
textureAssetName is correct (I get the filename for the png "GameData/Maps/AbandonedMine"), the png file is in the same directory as the tmx file.
Here's the code i'm using in my Game.Initialize():
var MapEntity = scene.createEntity("map");
var TiledMap = scene.contentManager.Load<TiledMap>("GameData/Maps/AbandonedMine");
MapEntity.addComponent(new TiledMapComponent(TiledMap));
I've been using Nez. Love it. But I ran my build on my laptop and it came up all red, like GB were missing and R is all that was left. Same on each of the 3 other machines I could find at the time - all laptops with nvidia cards, all coming up red. Then I tried building the samples on my laptop and the same thing happened even there.
Searching for those symptoms reveals MonoGame/MonoGame#1495 this really old issue which shouldn't really apply to DesktopGL but I can't help but shake the feeling that some issue in the precompiled shaders provided with Nez is causing this, considering that the last fix on that page involves tweaking a shader. Silly question: have you actually tested Nez on nvidia?
For example, it's fairly intuitive to do
var xx = new Sprite<AnimationEnums>();
<get all animations from some loader>
<loop through and add them to the sprite>
rather than
<get all animations from some loader>
var xx = new Sprite<AnimationEnums>(AnimationEnums.WalkLeft, AnimationLoader.Load<xxWalkLeft>();
<loop through the rest of the animations and add them to the sprite>
Parameter-less constructors open up some simpler-style possibilities with reflection and dynamically creating entities/components (At least, I think!) -> I don't really see a reason to force the texture on creation, as if it throws an error, we'll know we didn't set a texture.
For Sprite we can check if any animations exist, and if it's the first one being added, then set the subtexture to animation.frames[0].subtexture.
Any thoughts on this?
In the MacTest sample, as well as my own simple sample, the mouse coords are never correct.
In the attached image, the mouse is clicking on the D of debug, but a button is highlighted. However it's not always like that, sometimes the mouse can be in the middle of the blue area, and be highlighting a button. The offset can vary quite a bit.
Activated Event Time Duration Thread
Log: mouse pos: {X:1165 Y:176}, scaled mouse pos: {X:1165 Y:176}, screen to world point: {X:1165 Y:176}, world to screen point: {X:1165 Y:176} 58.04s
Edit: And for example, with a screen of 1280x720, if I click the bottom right of the screen, the Y coord is over 800
I am pretty new to Nez (and Monogame in general), and am trying to add the project inside Nez.PipelineImporter to my solution, which already references the Nez-PCL project.
I can add the Nez-PipelineImporter project correctly, but on compile time my IDE says that it is missing a reference for "Microsoft.Xna.Framework.Content.Pipeline;". There is unfortunately no documentation on how to add the PipelineImporter project.
Any help is greatly appreciated !
Hi,
I've found what appears to be a bug in how raycasts collide with non-rectangular shapes. I have prepared a gist of my example here.
I'm drawing a raycast at the bottom of a box as an example. As the picture illustrates, the distance between this raycast and the rectangular collider is 31 pixels, which looks correct.
If we move our raycast to a non-rectangular shape, the distance is once again correct. However, this only works when the raycast origin begins outside of the bounding box for the non-rectangular collider.
Once we get inside of the bounding box, the distance no longer updates because the raycast is not sensing any collisions. This final picture shows our raycast distance that should be no longer than a few pixels stuck at 39.5.
The same effect is true for the circle collider.
I am using the version as of commit c559d76
trying to start using the Nez.UI stuff.
made a simple component to display some basic labels.
`
public class TileStats : Component , IUpdatable
{
private UICanvas Canvas;
private Table Layout;
private Label XLabel;
private Label YLabel;
private Label BaseTypeLabel;
private Label DetailTypeLabel;
private Label Walkable;
public override void onAddedToEntity()
{
Canvas =(UICanvas) entity.addComponent<UICanvas>();
Canvas.renderLayer = 999;
Layout = new Table();
XLabel = new Label("X: ");
YLabel = new Label("Y: ");
BaseTypeLabel= new Label("Base Type: ");
DetailTypeLabel = new Label("Detail Type: ");
Walkable = new Label("Walkable: ");
Canvas.stage.addElement(Layout);
Layout.addElement(XLabel);
Layout.row();
Layout.addElement(YLabel);
Layout.row();
Layout.addElement(BaseTypeLabel);
Layout.row();
Layout.addElement(DetailTypeLabel);
Layout.row();
Layout.addElement(Walkable);
Layout.row();
}
public void update()
{
TileData Data = ChunkManager.MouseTile;
if (Data != null)
{
XLabel.setText("X: " + Data.TileX); //int
YLabel.setText("Y: " + Data.TileY); //int
BaseTypeLabel.setText("Base Type: " + Data.TileBaseType); //int
DetailTypeLabel.setText("Detail Type: " + Data.TileDetailType); //int
Walkable.setText("Walkable: " + Data.IsTileWalkable); //bool
}
}
}`
throws a null reference exception in Label.cs in the update layout method.
on this line:
if( isWrapped || _wrappedString.IndexOf( '\n' ) != -1 )
_wrappedString is always null :/
this is the only component in the project using Nez.UI.
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.