I am trying to move actor on stage from point to point by actions and it is not working, i have tried for hours and it just not working, i will be glad for help..
I have searched by the internet for codes and all i tried didn't worked, i really dont understand what is wrong with this code, it is basically the same as a working one on a tutorial in the internet
the actor class:
public class Player extends Actor {
float x,y;
float screenWidth,screenHeight;
private Sprite sprite;
Texture image;
float width,height;
public Player(Texture image,float x, float y,float width,float height, float screenWidth, float screenHeight)
{
this.width = width;
this.height = height;
this.x = x;
this.y = y;
this.screenWidth = screenWidth;
this.screenHeight = screenHeight;
this.image = image;
sprite = new Sprite(image, 0, 0, image.getWidth(), image.getHeight());
sprite.setPosition(x, y);
}
#Override
public float getX() {
return x;
}
#Override
public void setX(float x) {
this.x = x;
}
#Override
public float getY() {
return y;
}
#Override
public void setY(float y) {
this.y = y;
}
#Override
public float getWidth() {
return width;
}
#Override
public void setWidth(float width) {
this.width = width;
}
#Override
public float getHeight() {
return height;
}
#Override
public void setHeight(float height) {
this.height = height;
}
#Override
public void act(float delta) {
super.act(delta);
}
#Override
public void draw (Batch batch, float parentAlpha) {
batch.draw(sprite,x,y,width,height);
}
}
and the main class:
player = new Player(playerTexture,screenWidth/2,screenHeight-200,playerTexture.getWidth(),playerTexture.getHeight(),screenWidth,screenHeight);
MoveToAction action = new MoveToAction();
action.setPosition(300f,0f);
action.setDuration(10f);
player.addAction(action);
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(orthographicCamera.combined);
batch.begin();
// batch.draw(playerTexture,10,10,10,10);
batch.end();
stage.act(Gdx.graphics.getDeltaTime());
stage.draw(); //this will call the batch to draw the sprite
}
Actor already has x, y, width, and height fields. Since you created your own, you have hidden those parameters.
The source of your problem is that you failed to override setPosition() to use your fields. So the move action calls that and changes the fields that you have hidden and when you draw it, you are using your own fields that have not been changed.
Don't hide fields. It is very error-prone. You should delete the fields I mentioned above, along with all your overrides of getters and setters.
Here's a rule of thumb for OOP in general: if you are overriding any getter or setter without calling the super method, you are probably breaking something.
Unrelated, but you should be using TextureRegion instead of Sprite. A Sprite is a TextureRegion with additional parameters for size and position. Since those features are also in Actor, it is redundant and error-prone to use Sprite.
Related
First, thank you for reading this post, any help is welcome.
My actor is correctly rendered on the stage, but with the Actions.moveTo, it leaves a trail ? I just don't get it. It's like the texture is rendered at a new position on every new frame.
Here is my code for my class :
public class SlidingCap extends Actor {
private Texture capOver;
private float xPosition;
private float yPosition;
public SlidingCap(float x, float y) {
this.xPosition = x;
this.yPosition = y;
this.capOver = new Texture(Gdx.files.internal("images/cappingPlate.png"));
setBounds(x, y, 288, 180);
}
#Override
public void act(float delta) {
super.act(delta);
}
#Override
public void draw(Batch batch, float parentAlpha) {
batch.draw(capOver, getX(), getY(), 288, 180);
this.addAction(Actions.moveTo(xPosition+10, yPosition+10, 5f));
}
}
And the ScreenGame render method:
#Override
public void render(float delta) {
gameStage.act(delta);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
this.capMiniGame = new SlidingCap(100, 100);
this.gameStage.addActor(capMiniGame);
gameStage.draw();
}
You're adding a new SlidingCap every frame with this code
this.capMiniGame = new SlidingCap(100, 100);
this.gameStage.addActor(capMiniGame);
Try adding the SlidingCap once in the Create or show method instead of every frame
Couldn't find a relevant explanation online
I have homework to do I should create a class called Shapes and 2 more classes one for rectangle and the second is for a circle.
I wanted to know what is the best way to arrange constructors, data members and methods because for example for a rectangle I should have height and width and the circle has a radius.
public class Shapes {
//Should I use only common Data members, constructors and functions in the base class?
private int x;
private int y;
private int width;
private int height;
private String color;
private double radius;
also how do I create the relevant constructors using super()?
I think I got it all mixed up:
//Constructors:
public Shapes() {
}
//Common constructor
public Shapes(int x, int y, String color) {
setX(x);
setY(y);
setColor(color);
}
//Circle constructor:
public Shapes(int x, int y, String color, double radius) {
this(x, y, color);
setRadius(radius);
}
//Rectangle constructor:
public Shapes(int x, int y, int width, int height, String color) {
this(x, y, color);
setWidth(width);
setHeight(height);
}
in the rectangle class it looks like this:
public Rectangle() {
super();
}
public Rectangle(int x, int y, int width, int height, String color) {
super(x, y, width, height, color);
}
and in the circle class I did it like that:
public Circle() {
super();
}
public Circle(int x, int y, String color, double radius) {
super(x, y, color, radius);
}
I need a print method to print all info from each class that is relevant to the class is there any way using this print method in the base (shapes) class to avoid multiple print methods?
There are different parameters to show but we've been told to avoid multiplication of the code.
A base class should never have any properties that are not common to all of its subclasses. In fact, it shouldn't even know about its subclasses. For more information, read about the Liskov Substitution Principle and the Open/Closed Principle.
Therefore the base class should probably only have the parameters x, y and color. So the Shapes constructor could be like this:
public Shapes(int x, int y, String color) {
setX(x);
setY(y);
setColor(color);
}
and the Circle constructor like this:
public Circle(int x, int y, String color, double radius) {
super(x, y, color);
this.radius = radius;
}
The way you overloaded the base class constructors for fitting the different derived classes is really a very bad design. Not only does it contradict the aforementioned principles. It will also be very hard to understand for someone who reads the code.
Only put members in a super class if they will make sense for all sub-classes. You should also be using an abstract class to prevent creation of a plain Shape object, and the protected keyword in order to hide members from the outside world, but allow sub-classes to view them.
public abstract class Shape {
protected int x;
protected int y;
protected String color;
protected Shape() { this(0, 0, ""); }
protected Shape(int x, int y, String color) {
this.x = x;
this.y = y;
this.color = color;
}
// setter and getters for x, y, and color
}
public class Rectangle extends Shape {
private int width;
private int height;
public Rectangle() { this(0, 0, "", 0, 0); }
public Rectangle(int x, int y, String color, int width, int height) {
super(x, y, color);
this.width = width;
this.height = height;
}
// setters and getters for width and height
}
public class Circle extends Shape {
private double radius;
public Circle() { this(0, 0, "", 0.0); }
public Circle(int x, int y, String color, double radius) {
super(x, y, color);
this.radius = radius;
}
// setter and getter for radius
}
Let's start with the attributes. You should think if an attribute applies for subclasses of a class, or only for some of them. For example, does it make sense to put a "radius" attribute in the Shapes class? Will all subclasses of Shape need that attribute? Think of Rectangle: does a rectangle (instance) have a radius? If you declare the radius attribute in Shapes, what would be its value for rectangle instances? Avoid having spare attributes in classes, for perfomance but mainly for readability. The same applies to width and height.
Now, what about color? Will each and every shape have a color? So, it is a shared attribute?.
The x and y attributes are some kind of special here: the same attribute can mean two completely different things: for a circle should it be the center, but for rectangles could be the top-left (or whatever) point. Should them be the same attribute, or should be two different pair of attributes? I would go for the second, but it's my opinion.
Finally, regarding the constructors: would you let someone to create a shape instance without being either a circle or a rectangle? Do you need a public constructor in the Shapes class? Does have sense a shape being just a shape and not a circle or a rectangle (or any other subclass of Shape)?
By the way: I think it would be better to rename your Shapes class to just Shape.. a class represents one concept; then you can create instances of that concept, which are shapes...
=== EDIT ===
I forgot the last part of your question about print methods: one you decide where to put each attribute, you will find and answer for yourself.. can a method of a class access attributes in some of their subclasses?
Oh, something else: the toString method is allways present because it is defined in the Object class.. think about the relation of the toString method and the print method you need.
Make the shape class an abstract class with one abstract method which all the other classes will have to define
public abstract class Shape {
protected int x;
protected int y;
protected String color;
public Shape(String color) {
this.color = color;
}
public Shape() {
this("0xfffffff");
}
public Shape(int x, int y, String color) {
this(color);
this.x = x;
this.y = y;
}
public Shape(int x, int y) {
this();
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getY() { return y; }
public String getColor() { return color; }
public void setX(int x) { this.x = x; }
public void setY(int y) { this.y = y; }
public void setColor(String color) { this.color = color; }
#Override
public abstract String toString();
}
public class Rectangle extends Shape {
private int width;
private int height;
public Rectangle(int width, int height){
super();
this.width = width;
this.height = height;
}
public Rectangle(int width, int height, String color){
super(color);
this.width = width;
this.height = height;
}
public int getWidth() { return width; }
public int getHeight() { return height; }
// Also include setters if you don't need immutability
#Override
public String toString() {
return String.format("Rectangle\nWidth: %d\nHeight: %d\nColor: %s", width, height, color);
}
}
This is just my opinion. There are many other ways of structuring these classes, but it all depends on how you want to use them. The way I have provided makes it easy to extend this into 3D, so you can have 3D Shape base class declared like this:
public abstract class Shape3D extends Shape {
protected int z;
public Shape3D() {
super();
}
}
Not saying you will need a 3D object, but it's all about not entrapping yourself with design as the project gets more complex.
In your main class, you can have an array of Shapes and you can easily print them all knowing that they would have all defined the toString method.
public final class Main {
public static void main(String []args) {
List<Shape> shapes = new ArrayList<>();
// fill the list with all kinds of shapes
for (Shape shape: shapes) {
System.out.println(shape); // Will default to System.out.println(shape.toString());
}
}
}
One last to to make note of; When you find yourself having to write long constructors for a class, you might want to ask yourself if you will benefit from making use of the Builder pattern. For example the Rectangle class can be created with a builder like:
public abstract class ShapeBuilder {
int x, y;
String color;
public ShapeBuilder setX(int x) {
this.x = x;
return this;
}
public ShapeBuilder setY(int y) {
this.y = y;
return this;
}
public ShapeBuilder setColor(String color) {
this.color = color;
return this;
}
public abstract <T extends Shape> T build();
}
public class RectangleBuilder extends ShapeBuilder {
int width;
int height;
public RectangleBuilder setWidth(int width) {
this.width = width;
return this;
}
...
#Override
public Rectangle build() {
Rectangle rect = new Rectangle(width, height, color);
rect.setX(x);
rect.setY(y);
return rect;
}
}
So I am creating a sprite and drawing it to the screen using a different class.
I now want to scale it to be the same aspect ratio/size on each screen.
I have tried doing that by using this code:
public Player(Vector2 position, float width, float height, float rotation, float speed)
{
super(speed, rotation, width, height, position);
}
public void update()
{
width = Gdx.graphics.getWidth() / 10;
height = Gdx.graphics.getHeight() / 10;
}
But this doesn't work, it does nothing.
I have also tried setting the width and height to a static value for example 100 by 100. But this does not work either.
Thank you for any help! :)
Edit: adding base and derived classes:
Here's the code for the Entity class:
public abstract class Entity {
public void setPosition(Vector2 position) {
this.position = position;
}
public float getWidth() {
return width;
}
public void setWidth(float width) {
this.width = width;
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
public Rectangle getBounds() {
return bounds;
}
public void setBounds(Rectangle bounds) {
this.bounds = bounds;
}
}
Here's the code for the MoveEntity class:
public MoveEntity(float speed, float rotation,
float width, float height,
Vector2 position) {
super(position, width, height);
this.speed = speed;
this.rotation = rotation;
vel = new Vector2(0, 0);
}
public Vector2 getVel() {
return vel;
}
public void setVel(Vector2 target) {
this.vel = target;
}
public float getRotation() {
return rotation;
}
public void setRotation(float r) {
..............///
maybe it do not speak English, but you talk about a sprite and I do not see him any site, anyway.
assuming this is the sprite to which you refer -> spr_player
You can do this in several ways but basing on this line of code that you publish
Variable class. (for test):
float width = Gdx.graphics.getWidth() / 10;
float height = Gdx.graphics.getHeight() / 10;
Try to use this:
sb.draw(spr_player, p.getPosition().x, p.getPosition().y
width, height);
this is the funtion in the Class SpriteBatch:
public void draw (Texture texture, float x, float y,
float width, float height)
also you could use, setSize in the Sprite class, somewhere before render.
spr_player.setSize(width, height);
this is the funtion in the Class Sprite:
public void setSize (float width, float height)
if the size will not change during the game maybe, you can call the setSize, in method created or show, or in the constructor call this way, if the result you want:
Sprite spr_player = new Sprite (your_texture, width, height);
this is the funtion in the Class Sprite:
public Sprite (Texture texture, int srcWidth, int srcHeight)
I've started using LWJGL recently since I stopped using Java and wanted a quick refresher with something new tied in. Unfortunately, I've encountered a problem while working on a small Java pong game. I sort of sped through it, but I've reviewed my code multiple times and I cannot figure out what is wrong.
Problem: I can't update multiple entities on the screen at the same time. It is weird because I have no problem moving them, and their values update accordingly according to the debugger, but the graphics will not update on the screen. Here is my code for the main program:
package lwjgl2;
import static org.lwjgl.opengl.GL11.*;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
public class Main {
private Box ball = new Box(640>>1, 480>>1, 5, 5);
private Box paddle = new Box(10, 10, 10, 40);
private long lastTime;
private long getTime(){
return (Sys.getTime() * 1000) / Sys.getTimerResolution();
}
private int getDelta(){
long currentTime = getTime();
int delta = (int) (currentTime - lastTime);
lastTime = getTime();
return delta;
}
public Main() {
//display
try{
Display.setDisplayMode(new DisplayMode(640,480));
Display.setTitle("Hello");
Display.create();
} catch(LWJGLException e){
e.printStackTrace();
}
//ogl
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 640, 480, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
lastTime = getTime();
//main loop
while(!Display.isCloseRequested()){
glClear(GL_COLOR_BUFFER_BIT);
if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
Display.destroy();
System.exit(0);
}
paddle.setDX(0.1);
ball.setDX(0.3);
ball.setDY(0.2);
//main game loop goes nyah
ball.update(getDelta());
paddle.update(getDelta());
ball.draw();
paddle.draw();
Display.update();
Display.sync(60);
}
//destroy display
Display.destroy();
}
private class Box extends Entity{
public Box(int x, int y, int height, int width) {
super(x, y, height, width);
// TODO Auto-generated constructor stub
}
public void update(int delta){
super.x += dx * delta;
super.y += dy * delta;
}
public void draw(){
glRecti(x, y, x + height, y + width);
}
}
public static void main(String args[]){
new Main();
}
}
Like I said, the only entity that will actually render properly on the screen is whatever I call the update() method on first, in this case, the ball. If I call the paddle first, then the paddle will move, but the ball will stay still. I know I must have made a stupid mistake somewhere but I can't find it.
Also, the Entity class, possibly the main culprit:
package lwjgl2;
import java.awt.Rectangle;
public abstract class Entity {
protected int x;
protected int y;
protected int height;
protected int width;
protected double dx;
protected double dy;
protected Rectangle bounds = new Rectangle();
public Entity(int x, int y, int height, int width) {
this.x = x;
this.y = y;
this.height = height;
this.width = width;
this.dx = 0;
this.dy = 0;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public double getDX(){
return dx;
}
public double getDY(){
return dy;
}
public void setX(int x){
this.x = x;
}
public void setY(int y){
this.y = y;
}
public void setDX(double dx){
this.dx = dx;
}
public void setDY(double dy){
this.dy = dy;
}
public void update(int delta){
}
public void draw(int delta){
}
}
I've figured it out. It happens that updating multiple entities at varying times through the loop isn't a good idea, so you should create a method for updating every entity at once.
I am beginner in codenameone. I have task assigned that draws anything[not rectangles or any shapes] on screen. Anything means It could be anything with fingers. Like android has gesturelayout where you can draw anything on surface.
I have seen some forums that said I should derive the container and override paint method. That never led me to anything. Even the tutorial guide just goes through steps.I won't some working examples or any link where i can find some suitable material.
Did you read the developer guide: http://www.codenameone.com/developer-guide.html
JavaDocs: https://codenameone.googlecode.com/svn/trunk/CodenameOne/javadoc/index.html
You should derive component and override paint, notice this code is really bad since it doesn't eliminate duplicates or do anything clever:
class Draw extends Component {
private ArrayList<Point> points = new ArrayList<Point>();
public Draw() {
setFocusable(true);
}
public void pointerPressed(int x, int y) {
points.add(new Point(x, y, 0xff0000));
}
public void pointerDragged(int x, int y) {
points.add(new Point(x, y, 0xff0000));
}
public void pointerReleased(int x, int y) {
points.add(new Point(x, y, 0xff0000));
}
public void paint(Graphics g) {
Point lastPoint = null;
for(Point p : points) {
if(lastPoint != null) {
g.setColor(p.color);
g.drawLine(lastPoint.x, lastPoint.y, p.x, p.y);
}
lastPoint = p;
}
}
}
class Point {
int x;
int y;
int color;
public Point(int x, int y, int color) {
this.x = x; this.y = y; this.color = color;
}
}