I am making Flappy Bird and I am struggling to get the bird to animate. I have tried the following:
This is the class where I create the ImageView of the bird:
public class Bird {
public static Image[] birdFrames = new Image[3];
public static ImageView birdView = new ImageView();
private static int frameCounter = 0;
public static ImageView bird() {
birdFrames[0] = new Image("/Resources/BirdFrame0.png");
birdFrames[1] = new Image("/Resources/BirdFrame1.png");
birdFrames[2] = new Image("/Resources/BirdFrame2.png");
birdView.setImage(birdFrames[0]);
return birdView;
}
public static void birdAnimate() {
birdView.setImage(birdFrames[frameCounter++]);
if (frameCounter == 3) {
frameCounter = 0;
}
}
}
And here is the code I used to add it to the stage:
Bird.bird().relocate(100,200);
Bird.birdAnimate();
root.getChildren().add(Bird.bird());
All I get is a non updating still image of the bird on my screen
If anyone knows why this isn't working and how to fix it, I would really appreciate the help
Related
I'm new to Java and I'm trying to make a Visual Novel type of game.
What I'm trying to do is display text from a text file line by line by pressing a space button, like in a usual novel.
I've overlooked different methods but nothing works out for me. I know there are Scanner and BufferedReader, but are they suitable for what I'm doing?
Right now all that happens is when I press "space" the whole text appears on the screen, and when I let go, it dissapears.
This is my game class:
public class NovelGame extends Game {
public static final int WIDTH = 1366;
public static final int HEIGHT = 768;
public SpriteBatch batch;
public String txtFileString;
public String lines[];
public BitmapFont bitmapFont;
#Override
public void create () {
batch = new SpriteBatch();
bitmapFont = new BitmapFont();
this.setScreen(new MainMenuScreen(this));
txtFileString = Gdx.files.internal("script.txt").readString();
String[] anArray = txtFileString.split("\\r?\\n");}
#Override
public void render () {
super.render();
}}
This is my game screen class:
public class MainGameScreen implements Screen{
private Texture img;
NovelGame game;
public MainGameScreen (NovelGame game) {
this.game = game;
}
#Override
public void show() {
img = new Texture("bck.jpg");
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // This cryptic line clears the screen.
game.batch.begin();
game.batch.draw(img, 0, 0);
if(Gdx.input.isKeyPressed(Input.Keys.SPACE)){
game.bitmapFont.draw(game.batch, game.txtFileString,Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2);
}
game.batch.end();
}
I had an idea to display it using while and if, but can't exactly figure out how to do it.
EDIT: I found a way to display text, but now, once I run my game, it starts piling one on another endlessly after I press space.
Code:
public class MainGameScreen implements Screen{
private Texture img;
NovelGame game;
public MainGameScreen (NovelGame game) {
this.game = game;
}
#Override
public void show() {
img = new Texture("bck.jpg");
}
#Override
public void render(float delta) {
try {
BufferedReader br = new BufferedReader (new FileReader("C:\\Users\\hydra\\Documents\\JAVA_PROJECTS\\gamespace\\core\\assets\\startd.txt"));
while((game.strLine = br.readLine()) != null){
game.list.add(game.strLine);
}
br.close();
} catch (IOException e) {
System.err.println("Unable to read the file.");
}
if(Gdx.input.isKeyJustPressed(Input.Keys.SPACE)){
game.showText = true;
}
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // This cryptic line clears the screen.
game.batch.begin();
game.batch.draw(img, 0, 0);
if(game.showText) {
for(int i = 0; i < game.list.size(); i++) {
System.out.println(game.list.get(i));
game.bitmapFont.draw(game.batch, game.list.get(i), 100, 50);
}
}
game.batch.end();
}
Problem is here. Gdx.input.isKeyPressed returns true if only key is pressing currently.
if(Gdx.input.isKeyPressed(Input.Keys.SPACE)){
game.bitmapFont.draw(game.batch, game.txtFileString,Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2);
}
To fix this add a boolean flag activate it after key is only just pressed:
if(Gdx.input.isKeyJustPressed(Input.Keys.SPACE)){
showText = true;
}
And in render method:
if (showText) {
game.bitmapFont.draw(game.batch, game.txtFileString,Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2);
}
I found out what I was doing wrong in the end. I put everything in render method, and that's why file was being read endlessly. I need to do it only once in the constructor class and then put it in the render method.
I'm trying to make a game for school, like Puralax. This is my first year of Java.
Currently I'm testing through 'viewTest' and the 'DitMoetWerken.java' class to make my complete JFrame.
My guess is that the VakUI doesn't get painted but I don't know why. These should be the squares in my matrix.
This is where I call all my JFrames:
public class DitMoetWerken extends JFrame {
Spel spel;
public DitMoetWerken(Spel spel, int level) throws HeadlessException {
this.spel = spel;
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(800,500);
setTitle("Puralax");
setVisible(true);
spel.beginLevel(level);
SpelFrame spelFrame = new SpelFrame(spel,new JButton("terugknop"),new JButton("resetknop"));
this.add(spelFrame,BorderLayout.CENTER);
This is where I make my roster for my game. It is a matrix where the length is 3x3 in this level:
public class SpelbordUI extends JPanel {
private final Spel spel;
private SpelRooster spelRooster;
private boolean vakChecker = false;
private Vak bewaardVak;
public SpelbordUI(Spel spel) {
this.spel = spel;
this.spelRooster = spel.getSpelRooster();
initAll();
}
private void initAll(){
this.removeAll();
this.setLayout(new GridLayout(spelRooster.getLengte(),spelRooster.getLengte(),20,20));
for (int i = 0; i < spelRooster.getLengte(); i++) {
for (int j = 0; j < spelRooster.getLengte(); j++) {
VakUI vak = new VakUI(spelRooster.getRooster()[i][j]);
this.add(vak);
}
}
}}
A 'vak' is meant to be a square in my language. Sorry for any possible confusion.
The class of this VakUI looks like this, where I think my problem is with the paintComponent. I think it should just fill up the vak's in VakUI because of the this.setBackground(kleur) or should I draw them in new squares?
public class VakUI extends JPanel {
private Color kleur;
private Vak vak;
public VakUI(Vak vak) {
this.vak = vak;
this.kleur = vak.getKleur();
}
public Vak getVak() {
return vak;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(kleur);
}}
In the class DitMoetWerken. setVisible(); is supposed to be placed underneath this.add(spelFrame,BorderLayout.CENTER);. this solved my empty window problem.
From what I understand when reading other peoples code on how to make different screens. You do a main handler class sort of... And then create a new class for each screen.
The thing that confuses me is that whenever you create a new screen, you have to redefine everything that's going to be rendered, like SpriteBatch, sprites, fonts, etc. Is there any way to reuse these kind of things in all screens? I mean, if I have 10 screens, and want to be able to draw text on every screen. Is it really good programming practice to make a new BitmapFont for all 10 screen classes?
I've created an Abstract Screen class that contains all the common objects for a screen, every one of my screens extend this abstract class. And that looks like this:
public abstract class AbstractScreen implements Screen {
protected final Game game;
protected InputMultiplexer multiInputProcessor;
protected ScreenInputHandler screenInputHandler;
protected Stage uiStage;
protected Skin uiSkin;
public AbstractScreen(Game game) {
this.game = game;
this.uiStage = new Stage();
this.uiSkin = new Skin();
this.screenInputHandler = new ScreenInputHandler(game);
this.multiInputProcessor = new InputMultiplexer();
multiInputProcessor.addProcessor(uiStage);
multiInputProcessor.addProcessor(screenInputHandler);
Gdx.input.setInputProcessor(multiInputProcessor);
}
private static NinePatch processNinePatchFile(String fname) {
final Texture t = new Texture(Gdx.files.internal(fname));
final int width = t.getWidth() - 2;
final int height = t.getHeight() - 2;
return new NinePatch(new TextureRegion(t, 1, 1, width, height), 3, 3, 3, 3);
}
#Override
public void render (float delta) {
Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
uiStage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f));
uiStage.draw();
Table.drawDebug(uiStage);
}
#Override
public void resize (int width, int height) {
}
#Override
public void show() {
}
#Override
public void hide() {
dispose();
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
uiStage.dispose();
uiSkin.dispose();
}
}
When I want to create a new class I just extend the abstract screen and add what I need. For example I have a basic credits screen, I just need to create the components but the abstract screen draws it:
public class CreditsScreen extends AbstractScreen {
public CreditsScreen(final Game game) {
super(game);
// Generate a 1x1 white texture and store it in the skin named "white".
Pixmap pixmap = new Pixmap(1, 1, Format.RGBA8888);
pixmap.setColor(Color.WHITE);
pixmap.fill();
uiSkin.add("white", new Texture(pixmap));
// Store the default libgdx font under the name "default".
BitmapFont buttonFont = new BitmapFont();
buttonFont.scale(scale);
uiSkin.add("default", buttonFont);
// Configure a TextButtonStyle and name it "default". Skin resources are stored by type, so this doesn't overwrite the font.
TextButtonStyle textButtonStyle = new TextButtonStyle();
textButtonStyle.up = uiSkin.newDrawable("white", Color.DARK_GRAY);
textButtonStyle.down = uiSkin.newDrawable("white", Color.DARK_GRAY);
textButtonStyle.checked = uiSkin.newDrawable("white", Color.BLUE);
textButtonStyle.over = uiSkin.newDrawable("white", Color.LIGHT_GRAY);
textButtonStyle.font = uiSkin.getFont("default");
uiSkin.add("default", textButtonStyle);
// Create a table that fills the screen. Everything else will go inside this table.
Table table = new Table();
table.setFillParent(true);
uiStage.addActor(table);
table.debug(); // turn on all debug lines (table, cell, and widget)
table.debugTable(); // turn on only table lines
// Label
BitmapFont labelFont = new BitmapFont();
labelFont.scale(scale);
LabelStyle labelStyle = new LabelStyle(labelFont, Color.BLUE);
uiSkin.add("presents", labelStyle);
final Label myName = new Label("Credits and all that stuff", uiSkin, "presents");
table.add(myName).expand().center();
}
}
I also have a single class that handles the input for all the screens, the specific purpose for this is to handle how the back button works around the different screens. And this input handler class is created in the abstract class.
public class ScreenInputHandler implements InputProcessor {
private final Game game;
public ScreenInputHandler(Game game) {
this.game = game;
}
#Override
public boolean keyDown(int keycode) {
if(keycode == Keys.BACK || keycode == Keys.BACKSPACE){
if (game.getScreen() instanceof MainMenuScreen) {
Gdx.app.exit();
}
if (game.getScreen() instanceof GameScreen) {
World.getInstance().togglePause(false);
}
if (game.getScreen() instanceof CreditsScreen) {
game.setScreen(new MainMenuScreen(game));
}
}
return false;
}
}
I'm new at the Java world, and I started to take the Stanford cs106A course. I made the "breakout" problem which consists of making a simple breakout game.
I want to go even further, and my point is to create new Classes that can incorporate objects on the GCanvas of the main class.
So, now I have something like this:
public class Breakout extends GraphicsProgram {
//...
public void run();
private void playGame();
private void checkForPaddleCollisions();
private boolean passedBorderline();
private boolean moreBricksRemainig();
private void checkForCollisions();
private void updatePuntuation(GObject obj);
private void changeDirection(int temp);
private GObject getCollidingObject(double x, double y);
private void moveBall();
private void checkForBounderies();
private boolean hitsLeftWall();
private boolean hitsRightWall();
private boolean hitsRoof();
private void setRandomVx();
private void setBall();
private void setUp();
private void setLabels();
private void setPaddle();
public void mouseDragged (MouseEvent e);
public void mousePressed(MouseEvent i);
private void placeBricks();
private GOval ball;
private GRect paddle;
private GLabel win, lose, lifes, puntuationLabel;
private GPoint last;
private double vx, vy = 3.0;
private RandomGenerator rgen = RandomGenerator.getInstance();
private int Delay = 50;
private int counterBricks = NBRICKS_PER_ROW * NBRICK_ROWS;
private AudioClip bounceClip = MediaTools.loadAudioClip("bounce.au");
private int noPaddleBugs = 0;
private int puntuation = 0;
private int actualPunt = 0;
}
This is the main class of the game. What I want to do is to create a new class named PowerUps. This class can put any object on the GCanvas object of the main class at any point of the game. I tried to access the GCanvas of the main class by saying something like Breakout."canvasproperty".add(newObject), but it seems like it's not permitted.
Then I thought: I can create a class that extends GCanvas and then initialize a public property in the main class of that "new" canvas. With this method, I am able to insert new objects in this canvas from outer classes, but the problem is that when I run the Breakout class, the "new" canvas property doesn't show...
I don't know if I expressed myself well, but I tried, if anyone can help me, i would be very grateful?
Thanks in advance.
This is my first blackberry app and I am attempting to make a simple game for a touch screen device.
Its the typical image split into tiles and you have to unscramble them so the tiles are in the correct order and show the picture.
The intention is that the user will be able to "drag" a tile anywhere they want on the screen and they will swap places with the tile they drop it over.
I am using bitmapbuttons for my tiles
HorizontalFieldManager hfm = new HorizontalFieldManager();
add(hfm);
hfm.add(button1);
hfm.add(button2);
etc...
I have a class called Puzzle screen as follows:
class PuzzleScreen extends MainScreen implements FieldChangeListener {
I have added the following to try and detect the movement of the persons touch on the screen
protected boolean touchEvent(TouchEvent event) {
case TouchEvent.MOVE:
PuzzleTile fieldMove = (PuzzleTile) this.getLeafFieldWithFocus();
// Dialog.alert("MOVE");
int[] x_points;
int[] y_points;
int[] time_points;
int size = event.getMovePointsSize();
x_points = new int[size];
y_points = new int[size];
time_points = new int[size];
event.getMovePoints(1, x_points, y_points, time_points);
return true;
}
return false;
}
I need to find which image tile (bitmapbutton) is at the position of the upevent.
I have the coordinates (I think) above but not sure how to find which tile that relates to.
Bex
Something like this.
static class TestScreen extends MainScreen {
private static String down;
public TestScreen () {
HorizontalFieldManager hfm = new HorizontalFieldManager();
add(hfm);
hfm.add(new TestButton("bt1"));
hfm.add(new TestButton("bt2"));
hfm.add(new TestButton("bt3"));
hfm.add(new TestButton("bt4"));
hfm.add(new TestButton("bt5"));
hfm.add(new TestButton("bt6"));
}
public static void touchDown(TestButton tb) {
down = tb.getText();
System.out.println("DOWN in " + tb.getText());
}
public static void touchUp(TestButton tb) {
System.out.println("UP in " + tb.getText());
if(!down.equals(tb.getText()))
System.out.println("swap " + down + " and " + tb.getText());
down = "";
}
class TestButton extends LabelField {
public TestButton (String label) {
super(label);
}
protected boolean touchEvent(TouchEvent event) {
if(event.getEvent() == TouchEvent.UP)
TestScreen.touchUp(this);
else if(event.getEvent() == TouchEvent.DOWN)
TestScreen.touchDown(this);
return super.touchEvent(event);
}
}
}