Im trying to make a isometric videogame in Libgdx and when Im programming the animations I have a strange error.
I have two 3 tiles in the scene: static body without animation, tile floor and body with animation.
All have the same coordinates and the static body wihout animation and tile floor are in the same position but the body with animation are in wrong position.
Here a image, all in the image are in the same scene at the same time:
Image from scene
Static body is a frame from Spritesheet of the animation.
Here is my relevant code:
TextureAtlas texureAtlasHair;
Animation<TextureRegion> animationHairHeroRunning;
SpriteBatch batch;
texureAtlasHair = new TextureAtlas("hero/ClothesBueno/ClothesB.atlas");
animationHairHeroRunning = new Animation<TextureRegion>(1f/4f,texureAtlasHair.findRegions("Stance"));
heroLoad = new Texture("map/Stance_1.png");
heroLoadSprite = new Sprite(heroLoad);
heroLoadSprite.flip(false,true);
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(dungeonCam.combined);
dungeonCam.update();
batch.begin();
elapsedTime += Gdx.graphics.getDeltaTime();
//FloorTile
Vector2 pointFloor = twoDToIso(new Vector2(25,30));
batch.draw(floor,pointFloor.x,pointFloor.y);
//Hero without animation
Vector2 pointHero = twoDToIso(new Vector2(25,30));
batch.draw(heroLoadSprite,pointHero.x,pointHero.y);
//Hero with animation
TextureRegion currentFrameHair =
animationHairHeroRunning.getKeyFrame(elapsedTime,true);
batch.draw(currentFrameHair,pointHero.x,pointHero.y,128,-128);
batch.end();
}
public Vector2 twoDToIso(Vector2 punto) {
Vector2 tempP = new Vector2(0, 0);
tempP.x = (punto.x - punto.y) * 32;
tempP.y = (punto.x + punto.y) * 16;
return tempP;
}
Edit
AtlasImage
And my .atlas is like this.
.atlas
And my actual code to AtlasRegions:
Array<TextureAtlas.AtlasRegion> arrayRegions;
texureAtlasHair = new TextureAtlas("hero/ClothesBueno/ClothesB.atlas");
arrayRegions = texureAtlasHair.findRegions("Stance");
animationHairHeroRunning = new Animation(1f/4f,arrayRegions);
Related
I am trying to create a continuous animation, eventually the goal would be a bouncing ball that bounces off the edges of the screen, however, one step at a time.
I started with the sample code from Oracle that has an animation of circles that move for 40 seconds.
public void start(Stage primaryStage)
{
Group root = new Group();
Scene scene = new Scene(root, 800, 600);
primaryStage.setScene(scene);
Group circles = new Group();
for (int i = 0; i < 1; i++)
{
MovingCircle circle = new MovingCircle(150, Color.web("white", 0.05));
circle.setStrokeType(StrokeType.OUTSIDE);
circle.setStroke(Color.web("black", 0.16));
circle.setStrokeWidth(4);
circles.getChildren().add(circle);
}
root.getChildren().add(circles);
Timeline timeline = new Timeline();
timeline.setCycleCount(Timeline.INDEFINITE);
for (Node circle: circles.getChildren())
{
if(circle instanceof MovingCircle)
{
MovingCircle c = (MovingCircle)circle;
timeline.getKeyFrames().addAll(
/* new KeyFrame(Duration.ZERO, // set start position at 0
new KeyValue(circle.translateXProperty(), random() * 800),
new KeyValue(circle.translateYProperty(), random() * 600)
),*/
new KeyFrame(new Duration(10), // set end position at 40s
c.getXMovement(), c.getYMovement())
);
c.updateCenter();
}
}
// play 40s of animation
timeline.play();
primaryStage.show();
}
I created a new MovingCircle that extends Circle to try and add other stuff to it later. The two new class methods return exactly what was commented out from the default code given.
I changed the cycle to indefinite so that it would go forever. All the circle does though is bounce between its original starting point and the translated point. I have tried updating its center location in hopes that the next bounce would move it to a different location, however, that doesn't work.
I am at quite a loss as to what to try next to get this working more the way I was hoping.
I am currently trying to rotate a positionVector (0,0,1) around the world's x-axis and then rotate it back to its original position (just trying to get it to work). I read into rotation matrixes and got it working (sorta) but i am pretty stuck now.
As the image and code shows i create a cube at the starting point (0,0,1) and rotate it down in this case 30 degrees. But it seems to rotate more than 30 degrees when rotating clockwise. However when i rotate it back counterclockwise (30 degrees) it does rotate the proper amount. Which results in it not ending up at its starting point as it should (0,0,1).
I was wondering if any of you could shed some light on why this is happening and how to fix it. Thank you guys in advance!
public float RotAngle = 330f;
public GameObject cube;
public GameObject original;
public GameObject relocator;
public GameObject initialTurn;
void Start ()
{
Vector3 pixelPos = new Vector3(0f, 0f, 1f);
original = GameObject.Instantiate(cube,pixelPos,Quaternion.identity) as GameObject;
original.name = "Original";
initialTurn = GameObject.Instantiate(cube, pixelPos, Quaternion.identity) as GameObject;
initialTurn.name = "InitialTurn";
relocator = GameObject.Instantiate(cube, pixelPos, Quaternion.identity) as GameObject;
relocator.name = "Relocator";
}
void Update()
{
initialTurn.transform.position = RotateAroundOrigin(original.transform.position, RotAngle*Mathf.Deg2Rad);
relocator.transform.position = RotateAroundOrigin(initialTurn.transform.position, (RotAngle * -1f) * Mathf.Deg2Rad);
}
Vector3 RotateAroundOrigin(Vector3 startPos,float angle)
{
startPos.Normalize();
startPos.y = (startPos.y * Mathf.Cos(angle)) - (startPos.z * Mathf.Sin(angle));
startPos.z = (startPos.y * Mathf.Sin(angle)) + (startPos.z * Mathf.Cos(angle));
return startPos.normalized;
}
You can rotate a direction vector pretty easily with a Quaternion.
Try this:
Vector3 RotateAroundOrigin(Vector3 startPos,float angle)
{
startPos.Normalize();
Quaternion rot = Quaternion.Euler(angle, 0.0f, 0.0f); // Rotate [angle] degrees about the x axis.
startPos = rot * startPos;
return startPos;
}
I am trying my hand at easeljs and animating a spritesheet. This is the first time I am working with sprites and as such am not knowledgeable about them.
My simple easeljs code to show this specific animation is;
var stage;
function init() {
// create a new stage and point it at our canvas:
stage = new createjs.Stage(document.getElementById("demoCanvas"));
var data = {
images: ["http://i.imgur.com/g5WtL7v.png"],
frames: {width:256, height:256},
animations: {
run:[0,4]
}
};
var spriteSheet = new createjs.SpriteSheet(data);
var animation = new createjs.BitmapAnimation(spriteSheet);
animation.gotoAndPlay("run");
}
But the sprite doesn't shows up on the canvas at all. WHat am I doing wrong?
Additional question;
defining frames in easeljs can be done by
frames: [ // x, y, width, height, imageIndex, regX, regY
While I do understand width and height, what are x, y, imageIndex and regX, regY. The documentaion explains how I can use these parameters but for someone who is working with sprites for the 1st time in my life, I just dont know what these terms mean.
EDIT: I have also tried changing the code as such;
var stage;
function init() {
// create a new stage and point it at our canvas:
stage = new createjs.Stage("demoCanvas");
var data = {
images: ["http://i.imgur.com/g5WtL7v.png"],
frames: {width:256, height:256, count:8},
animations: {
run:[0,4, true]
}
};
var ss = new createjs.SpriteSheet(data);
var animation = new createjs.BitmapAnimation(ss);
animation.x = 100;
animation.y = 100;
stage.addChild(animation);
createjs.Ticker.setFPS(60);
createjs.Ticker.addEventListener("tick", stage);
}
But I am still seeing a blank canvas...
You are missing a frame-count in the frames-object:
frames: {width:...,height:...,count:4} // or whatever number of frames your sprite holds
And just in case: The width and height is the width and height of 1 frame, not the entire image.
See more information and examples here: http://www.createjs.com/Docs/EaselJS/classes/SpriteSheet.html
ok i got things to work by combining both the codes that I have listed above;
var stage;
function init() {
// create a new stage and point it at our canvas:
stage = new createjs.Stage("demoCanvas");
var data = {
images: ["http://i.imgur.com/g5WtL7v.png"],
frames: {width:256, height:256, count:8},
animations: {
run:[0,4, true]
}
};
var ss = new createjs.SpriteSheet(data);
var animation = new createjs.BitmapAnimation(ss);
animation.x = 100;
animation.y = 100;
stage.addChild(animation);
animation.gotoAndPlay("run");
createjs.Ticker.setFPS(10);
createjs.Ticker.addEventListener("tick", stage);
}
Now I have some questions;
If I need animation.gotoAndPlay("run"); to animate the sprite how come the code at https://github.com/CreateJS/EaselJS/blob/master/examples/SpriteSheet_simple.html doesn't needs it?
whats the difference between new createjs.Sprite(ss, "run"); and new createjs.BitmapAnimation(spriteSheet); . I am unable to find any documentation of the former.
I am trying to learn NME with haxe to create a small game. I have setup NME 3.5.5 with Haxe 2.10 in FlashDevelop. To draw the game background, I'm using
// Class level variable
var background : nme.display.Bitmap;
public function initResources() : Void
{
background = new Bitmap(Assets.getBitmapData("img/back.png"));
}
And in the render loop, I'm rendering like this.
g.clear();
g.beginBitmapFill(background.bitmapData, true, true);
g.drawRect(0, 0, 640, 480);
g.endFill();
This is drawing the image across the view and I need to resize it to fit the screen.
EDIT:
Here is the function i'm using to scale the bitmap. It doesn't work and nothing is rendered on the screen.
public static function resize( source:Bitmap, width:Int, height:Int ) : Bitmap
{
var scaleX:Int = Std.int(width / source.bitmapData.width);
var scaleY:Int = Std.int(height / source.bitmapData.height);
var data:BitmapData = new BitmapData(width, height, true);
var matrix:Matrix = new Matrix();
matrix.scale(scaleX, scaleY);
data.draw(source.bitmapData, matrix);
return new Bitmap(data);
}
Thanks.
EDIT 2:
Finally made it. I was unnecessarily casting it to int. Here's the solution.
public static function resize( source:Bitmap, width:Int, height:Int ) : Bitmap
{
var scaleX:Float = width / source.bitmapData.width;
var scaleY:Float = height / source.bitmapData.height;
var data:BitmapData = new BitmapData(width, height, true);
var matrix:Matrix = new Matrix();
matrix.scale(scaleX, scaleY);
data.draw(source.bitmapData, matrix);
return new Bitmap(data);
}
Look this Resizing BitmapData in ActionScript 3
You should use BitmapData.draw and scaled matrix.
I am drawing a traingleStrip using VertexPositionTexture and BasicEffect that extends from the first person perspective of the screen out a certain distance on the Z axis.
In a loop I pass start and end vectors to this code to create my vertices.
public VertexPositionTexture[] vertices = new VertexPositionTexture[4];
private int xPos = 4;
public waypointLineSegment(Vector3 startPoint, Vector3 endPoint)
{
this.texture = texture1;
vertices[0].Position = new Vector3(endPoint.X - xPos, endPoint.Y, endPoint.Z); //Upper Left Point
vertices[0].TextureCoordinate = new Vector2(0, 1);
vertices[1].Position = new Vector3(startPoint.X - xPos, endPoint.Y, startPoint.Z); //Lower Left point
vertices[1].TextureCoordinate = new Vector2(0, 0);
vertices[2].Position = new Vector3(endPoint.X + xPos, endPoint.Y, endPoint.Z); //Upper Right Point
vertices[2].TextureCoordinate = new Vector2(1, 1);
vertices[3].Position = new Vector3(startPoint.X + xPos, endPoint.Y, startPoint.Z); //Lower Right Point
vertices[3].TextureCoordinate = new Vector2(1, 0);
}
I initialize like this:
protected override void Initialize()
{
graphics.GraphicsDevice.RasterizerState = RasterizerState.CullNone;
basicEffect = new BasicEffect(graphics.GraphicsDevice);
base.Initialize();
}
I render the plane in this way:
Vector3 transformedReference = Vector3.Transform(new Vector3(0, 0, 10), aRotationInt);
Vector3 cameraLookat = firstPersonVector + transformedReference;
view = Matrix.CreateLookAt(firstPersonVector, cameraLookat, Vector3.Up);
basicEffect.View = view;
foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
{
pass.Apply();
graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, allVertices, 0, 2);
}
This works great. But, when I apply a rotation to the view, the strip will disappear every once in a while. Then it will reappear with a single degree of more or less rotation applied.
I cannot find a pattern. It might happen at 37 degrees or 315 etc. I have set the GraphicsDevice RasterizerState to CullMode.None. Can anyone help?: