I'm still a bit new at Java and need some help with a game I'm currently working on. I've already implemented the core of the game where balls drop from the top of the screen and the user controls platforms to bounce the balls to the right side of the screen. If the player succeeds, then a point is awarded. I already implemented the code for the bouncing balls, platforms, score, and various states.
The thing I'm stuck on is controlling the number of balls that drop depending on the score. I already have a rough idea of the algorithm. Without going into too much detail it goes something like this:
public class BallContainer{
public ArrayList<Ball> balls;
public BallContainer(ArrayList<Ball> balls){
this.balls = balls;
}
public void drop(int howMany){
//code to activate the gravity of "howMany" random balls with a .5 second delay between them
}
public class MainGame{
public void update(float dt){
//check score and drop a selection of balls with random seconds of delay between each group of balls dropped at a time
}
}
I already have an idea of how many balls and how much of a random delay will occur depending on the score. One thing I'm just stuck on the delaying of the action. I know we can use the java.util.Timer and TimerTask, but I also hear libgdx also has some built in delay methods. Anyway, any help would be appreciated.
Thanks.
You can use libgx Timer class to provide actions to happen after a certain delay.
Here is an example -
Timer.schedule(new Task() {
#Override
public void run() {
//create new balls here or do whatever you want to do.
}
}, DELAY_TIME_IN_SECONDS);
What happens here is you are calling a static method of Timer class called schedule which takes a Task and delaySeconds in float as parameters.
Now as parameter you are creating a new Anonymous inner class object as Task is an abstract class. In the anonymous inner class object, you override the run method and put what you want it to do.
Place the above snippet in the place where you want to create new balls or do some action.
You can just create a new thread, where you will place a flag, then sleep the newly created thread, and after sleep finishes - set your flag to true.
So ur game won't freeze like it will if you gonna sleep the main thread.
Related
Hello this is my first time posting on here and am relatively new to coding. I've been playing around with java and libgdx for a month or two and I'm confused about one thing for screens.
If I have a GameScreen class that is active when playing the game, and then wanted to switch momentarily to another screen for inventory or a pause screen or something, if I make the game switch back to the game screen it seems everything resets and a new game starts. What would be the correct way to make sure the screen reloads in the same state it was just in?
If you want to keep a screen alive in the background such as you described, you need to make sure you separate your game initialization code so it is only called when you are starting a new level. There are a million ways you could do this. Here's an example:
public class MyGameScreen {
public MyGameScreen (){
//load textures and sounds here if you aren't managing them somewhere else.
startNewGameRound();
}
#Override
public void show (){
//this is only for stuff you need to reset every time the screen comes back.
//Generally, you would undo stuff that you did in `hide()`.
}
public void startNewGameRound (){
//Reset all your variables and reinitialize state for a new game round.
//This is called in the constructor for first time setup, and then it
//can also be called by a button anywhere that starts a new round.
//But do not load textures and sounds here. Do that in the constructor
//so it only happens once.
}
}
Then in your Game class, you also need to make sure you keep your game screen instance and reuse it.
Don't do this:
setScreen(new MyGameScreen());
Do this instead:
//member variable:
private MyGameScreen myGameScreen;
//In some method:
if (myGameScreen == null)
myGameScreen = new MyGameScreen();
setScreen(myGameScreen);
I'm working on a game in Java. In the game, the player will be able to control a tank that moves on the screen using Key Bindings. Each arrow-button moves the tank in a different direction.
I'd like to know, if the way I used Key Bindings in the program, is correct and isn't supposed to cause problems with the EDT or with anything else later on.
I will explain in short the structure of the program, and how I used Key Bindings.
There's a Board class, a class that extends JPanel and has
most of the game logic. It also displays the graphics.
There's a KeyBindingsRunnabel class, a class that implements Runnable. This
class has all the KeyBindings code.
Board contains the game-loop. The game loop happens inside a
thread. In the thread, but before the game loop, a new thread is
created and started, that thread runs KeyBindingsRunnabel.
(There's also a Main class that extends JFrame and creates an instance of Board, but that's irrelevant).
I'll demonstrate all of this in short:
Here is the code for the KeyBindingsRunnabel class:
public class KeyBindingsRunnable implements Runnable {
Board b;
Action upAction,leftAction;
InputMap inputMap;
ActionMap actionMap;
public KeyBindingsRunnable (Board b){
this.b = b;
inputMap = b.getInputMap();
actionMap = b.getActionMap();
public void run() {
leftAction = new AbstractAction(){
public void actionPerformed(ActionEvent e){
// Code to move tank left.
}
};
rightAction = new AbstractAction(){
public void actionPerformed(ActionEvent e){
// Code to move tank right.
}
};
inputMap.put(KeyStroke.getKeyStroke("LEFT"),"leftAction");
inputMap.put(KeyStroke.getKeyStroke("RIGHT"),"rightAction");
actionMap.put("leftAction",leftAction);
actionMap.put("rightAction",rightAction);
}
}
The way the Board class uses KeyBindingsRunnable is as follows:
The Board class also implements Runnable. It contains a thread declaration in it's constructor:
Thread gameloop = new Thread(this);
gameloop.start();
In Board's run() method, there are two thing: a game-loop, and before the loop, the creation of a new thread that runs KeyBindingRunnable.
The run() method of Board looks like this:
public void run(){
Thread keyBindingsThread = new Thread(new KeyBindingRunnable(this));
keyBindingsThread.start();
while(gameIsRunning){
// The loop.
// .....
}
}
My question is: Is this the correct way to use Key Bindings without interupting with the EDT, and in general the correct way?
Is there a more effecient/safer/shorter way of using Key Bindings in a 2D game?
Thanks a lot :)
Too many comments for me to read so I don't know if I'm saying anything new or just repeating something.
The way I see it. KeyBindings are just used to indicate the state of keys on the keyboard.
Take a look at KeyboardAnimtion.java from Motion Using the Keyboard. In that example wen the key is pressed the key is added to the Map and when the key is released the key is removed from the map. That is the sole function of the key bindings, to track the keys that are pressed and the associated movement of that key.
The example then uses a Timer to schedule the animation of the object. When the Timer fires the move() method is invoked and the object is moved based on the keys in the Map.
Swing Timer doesn't allow me to use a type of game-loop that has proven to run the game at constant speed without problems.
There is no reason to use the Timer. If your game does its own looping then you should be able to invoke the move() method directly. However, all this does is control that the repaint request is made at a constant time, it does not guarantee that the painting is done immediately, although normally painting requests should be handled right away unless the system is really busy.
I would start by using the Timer an see what happens.
In a simple card game (human vs. CPU) the logic works, but I want to delay the computer's turn.
I have tried using Thread.sleep(int milliseconds) which works, but it messes up the order images are displayed. I'm not using a game loop, I am just dynamically updating ImageViews whenever cards are changed. The problem with Thread.sleep is all the images only update after Thread.sleep, there is no displaying only the human card before Thread.sleep. The human's card and computer's card display after Thread.sleep.
I've used Thread.sleep like so:
playPlayerCard(player); // Human first
displayPile(); // Display card pile (ImageView's)
player = nextPlayer(player); // Get's next player in Player mPlayers List<Player>
// Wait for computer to 'Think'
Thread.sleep(500);
playPlayerCard(player); //Computer's turn
displayPile(); // Display card pile (ImageView's)
Am I using Thread.sleep() wrong? Is there a better/correct way? I've searched online and tried using new Thread(), using handler.postDelayed(Runnable r, long milliseconds) and also CountDownTimer but none work since my variables: playPlayerCard(player); aren't final variables.
I've always had problems delaying actions and the images appearing at the correct times. Any suggestions? Thanks in advance.
Couldn't you just implement the Computer Playing logic in a AsyncTask and fire it when the human turn is done ?
I think it would make much more sense, that way, as soon as the computer is done "playing" you can determine the actions to take in the onPostExecute() method, in your case I think that would be dealing cards.
It would also be really simple to block user inputs while the computer is playing, either with a progress dialog (which isn't all that pleasent for a game I understand) or simply by disabling buttons :)
Here's the documentation for it.
Hope this helps!
I used the solution from #Jakar and changed my variables to class-scope in order to use the Handler and Runnable correctly. This worked, the delay works correctly using
Runnable r = new Runnable() {
public void run() {
playPlayerCard();
}
};
mHandler.postDelayed(r, 500);
To clarify the solution, I had to take out the arguments from playPlayerCard(Player player) and use a class-scope Player mPlayer; variable in playPlayerCard() instead.
I'm currently making a game of Reversi for my programming class and I wanted to try and implement a computer into the game. I got this working successfully, but the computer makes their move instantly so you can't see how your move worked.
I tried solving this by using the following method:
public void wait (int n) {
long t0, t1;
t0 = System.currentTimeMillis();
do {
t1 = System.currentTimeMillis();
} while ((t1-t0) < n);
}
I then called this method after the player made their move, right before it called my computerAI() method.
However, it didn't work quite right and it seems like it hit the wait before it changes the colors of the board, because the player clicks, the background changes to the default light gray, and then after it waits a second, it performs the color changes of your move and the computers.
Anyone have any suggestions for fixing this?
Use:
Thread.sleep(5000);
This causes the current thread to sleep for 5 seconds.
You may need not only change button's color property, but also call its .repaint() or even .update() method often enough, e.g. every 100 ms. That is, you need to make the button actually redraw itself on the screen when you need it, not when the system determines it has time to render the accumulated changes.
I wanted to rewrite my simple game engine to run on Android and I am wondering how can I synchronize two running threads. Right now I have the following:
Runner is the main activity, entry point for this game;
CanvasView is just a canvas on which drawing is being made;
GameWorld is - as the name suggests - class which stores the current information about the state of the game. For now, lets just say that it also contains a Level.
GameLoop is a separate thread which is updating the game state;
CanvasThread is a separate thread, which is being run to draw the current Level on CanvasView.
As the level is just a simple array, CanvasThread just iterates through the array and draws it on screen. And I have few questions regarding this:
is there a possibility to run the onDraw() method of CanvasThread on demand? In current state of the engine it is just being relaunched when the execution of previous one is finished.
I want to implement some kind of three way handshake between GameLoop and CanvasThread, something similar to:
GameLoop -> CanvasThread: please stop updating
Canvas -> GameLoop: ok, stopped
GameLoop -> CanvasThread: ok, you may resume.
What is the best way to do so? I am a total Java / Android newbie so my way of setting the engine is most probably not the best / optimal one. If you have any suggestions to the design, I will gladly appreciate them.
Thank you.
PS: If I had violated all best practices while creating the diagram above, please forgive me.
Android has an easy way to handle thread communication. You can use a Looper and a Handler to send messages, or complete Runnables, between the Threads.
Look at Android Guts: Intro to Loopers and Handlers on mindtherobot.com for an introduction.
You can send an "empty" message to signal something, or supply some arguments. You can send the message immediately, or with some delay.
If you design your game loop by sending messages to itself, it would be easy to inject messages from other threads.
What I created long long time ago. Maybe it helps a little
http://code.google.com/p/candroidengine/
I believe you'll find it a lot easier if they don't communicate.
Instead, put a couple constraints on to keep yourself sane:
Make a very tight game loop. If you're going to be updating your canvas at, let's say, 30 fps (about 33 ms) make your game loop take no longer than 10 or 20 ms.
Put a lock on your game loop and canvas update. Now, each one will wait for the other to finish before doing their thing. You won't end up with a canvas that has the half the screen representing before the loop and the other half of the screen after the loop.
Example:
class GameLoop extends Thread {
public void run() {
while(true) {
synchronized(theGameWorldObject) {
// update game info here
}
}
}
}
class Canvas {
updateCanvas() { // or whatever you call it
synchronized(theGameWorldObject) {
// update canvas here
}
}
}