Game window flickers - java

Every couple seconds, the window in which my game is playing will briefly disappear and then reappear. I'm on Windows 7 with the latest version of Slick (a game library for Java). Here's the code I'm using:
package Main;
import org.newdawn.slick.*;
public class Main extends BasicGame{
public Main() {
super("Flashing window issue");
}
#Override
public void init(GameContainer gc) throws SlickException {
}
#Override
public void update(GameContainer gc, int delta) throws SlickException {
}
#Override
public void render(GameContainer gc, Graphics g) throws SlickException {
}
public static void main(String[] args) throws SlickException {
AppGameContainer app = new AppGameContainer(new Main());
app.setDisplayMode(800, 600, false);
app.start();
}
}
How can I fix this issue?
Progress so far:
Update: No solution found yet, but playing the game in fullscreen mode eliminates the flicker. Perhaps this will lead to a solution...
Update 2: Monitering the task manager shows that while the game is flickering its status in the task manager is 'Not Responding'.
Update 3: It seems to only happen when the mouse leaves the game area (regardless of whether the game window loses focus).
Update 4 - Current workaround:
app.setMouseGrabbed(true); // force the mouse to stay in the game area
then in update(...):
// exit when escape is pressed:
if (gc.getInput().isKeyDown(Input.KEY_ESCAPE)) {
gc.exit();
}

I'm not familiar with slick2d but does it have a concept of double buffering? that would be something you would want to turn on if you get flickering.

Related

Loading a false Tiled Map (.tmx) using Slick in Java

I try to create a mere 2D game in Java and with my researches I found out that the best motor should be Slick.
I used the softaware Tiled to create the map and try to run my Java program to see the result and after many problem of compression I already solved, it turned out that the map is simply false (the tiles are not placed well).
I tried to change see the .tmx code in a text editor but I found nothing to change.
Here's my Java code I run in Eclipse :
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.tiled.*;
public class Lecon_1 extends BasicGame {
GameContainer container;
TiledMap map;
public Lecon_1() {
super("Lesson 1 :: WindowGame");
}
public static void main(String[] args) throws SlickException {
new AppGameContainer(new Lecon_1(), 321, 321, false).start();
}
#Override
public void init(GameContainer container) throws SlickException {
this.container = container;
this.map = new TiledMap("src/map/Essai1.tmx");
}
#Override
public void render(GameContainer container, Graphics g) throws SlickException {
this.map.render(0, 0);
}
#Override
public void update(GameContainer container, int delta) throws SlickException {
}
#Override
public void keyReleased(int key, char c) {
if (Input.KEY_ESCAPE == key) {
container.exit();
}
}
}
The Map I created:
The Map I get after running the code:
I tried many things and search in a lot of websites but nobody seems to have this problem. It may be a problem from the Slick classes but I don't know which one and don't know why. Does anyone have an idea?
Thanks in advance,
Alburkerk

LibGdx Screen: render and lifecycle

I have a problem, I think its related to Screen render and its lifecycle.
Basically I have two screens (Menu and Game). In GameScreen render method i call World.update and after that my Render. In hide method (of GameScreen) i dispose of the SpriteBatch from Redner class.
So when I change the screen from Game to Menu (within World.update) Java crashes. As far as I can tell, the dispose is making the crash.
So my question is, when i set a new screen in the middle of the render cycle, is that render cycle still going to finish with its old screen? Meaning, am I calling batch.dispose before the rendering was finished, and that is why i get the problem?
Thank you for all the help
public class GameScreen extends AbstractGameScreen {
private static final String TAG = GameScreen.class.getName();
private WorldController worldController;
private WorldRenderer worldRenderer;
private boolean paused;
public GameScreen(Game game) {
super(game);
}
#Override
public void render(float deltaTime) {
// Do not update game world when paused
if (!paused) {
// Update game world by the time that has passed since last render time
worldController.update(deltaTime);
}
// Sets the clear screen color to: Cornflower Blue
Gdx.gl.glClearColor(0x64 / 255.0f, 0x95 / 255.0f, 0xed / 255.0f, 0xff / 255.0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// Render game world to screen
worldRenderer.render();
}
#Override
public void resize(int width, int height) {
worldRenderer.resize(width, height);
}
#Override
public void show() { // Similar as create method
worldController = new WorldController(game);
worldRenderer = new WorldRenderer(worldController);
Gdx.input.setCatchBackKey(true);
}
#Override
public void hide() { // Similar to dispose method
worldRenderer.dispose();
Gdx.input.setCatchBackKey(false);
}
#Override
public void pause() {
paused = true;
}
#Override
public void resume() {
super.resume();
// Only called on Android
paused = false;
}
}
That's basically correct. The screen that calls setScreen from within its render method will have hide called on itself and then will continue through the rest of its code in its render method. So you are killing your sprite batch right before trying to draw with it.
So don't call dispose from within your hide method. In fact, it is probably bad practice for a Screen to ever call dispose on itself. You can reserve that for the Game class that owns it. For example, you could do something like this in your game class:
#Override
public void render() {
super.render();
if (getScreen() != gameScreen && gameScreen != null) {
gameScreen.dispose();
gameScreen = null;
}
}
By the way, you should probably put the SpriteBatch in your Game subclass and let all the different screens share it. It's a fairly big object to be allocating and deallocating for no reason.

Moving a rectangle incredibly choppy

I've created a simple program that draws a rectangle which falls down the screen at a constant rate. I first run Main.java:
package highst;
public class Main {
public static void main(String args[]){
new GameFrame();
}
}
which creates a new instance of GameFrame.java:
package highst;
import javax.swing.JFrame;
public class GameFrame extends JFrame {
public GameFrame() {
super("Falling rectangle");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(800, 600);
GameLogic game = new GameLogic();
this.getContentPane().add(game);
this.setVisible(true);
game.run();
}
}
Which in turn creates a new instance of GameLogic.java:
package highst;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
public class GameLogic extends JPanel implements Runnable, KeyListener {
Marvin marvin;
private enum GameState{
Running, Dead
}
GameState state = GameState.Running;
public GameLogic(){
marvin = new Marvin(50, 50);
Thread thread = new Thread(this);
thread.start();
addKeyListener(this);
setFocusable(true);
this.setBackground(Color.black);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.white);
g.fillRect(marvin.getX(), marvin.getY(), 50, 50);
}
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_SPACE){
marvin.jump();
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void run() {
if(state == GameState.Running){
while(true){
marvin.update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Which finally makes use of what will be my playable character, Marvin.java who is now a white rectangle:
package highst;
public class Marvin {
private int x, y;
public Marvin(int x, int y){
this.x = y;
this.y = y;
}
public void update(){
y -= -1;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void jump() {
x += 1;
}
}
It runs fine but the rectangle is not painted smoothly as it falls down the page. It seems to jump a few pixels at a time. I thought sleeping the thread for 17 milliseconds would cause everything to render smoothly. What am I doing wrong?
To have smooth animation, you need to make updates to the screen at a constant rate.
Here, you're doing a graphic repaint, which could take any amount of time, then waiting 17ms no matter what. This leads to each frame taking a different amount of time. The first frame might be done in 2ms, the next might take 5ms, then 3ms and so on... your frames will be displayed for 19ms then 22ms then 20ms...
What you need is a dedicated thread whose only job is to wait the right amount of time and then signal the main thread to repaint. Then your frames (provided they don't take more than 17ms to paint) come out every 17ms, exactly on cue.
Here's an tutorial on animation in Java applets, you should find it relevant.
Try these:
1> Reducing the sleeping time of the thread to see the effects and get the optimum speed of falling.
2> Make use of Double Buffering (a concept in which the screen is painted first in memory and then painted onto the display monitor):
Double Buffering - Docs
Double Buffering - Google Search Results
3> Simple suggestion: Avoid using sleep(). Instead use Timers. It is a very interesting and powerful substitute for threads. Also it will not create problems in the later stages of your game development. Check these links out:
Concurrency in java
Timer in Java
4> Check out these interesting tutorials about animation in Java:
Java World
Clear Rice
There are several things wrong...
You're ignoring the Initial Threads of Swing and not starting your UI within the context of the EDT, which leads to...
You are calling run on the instance of GameLogic AND creating a Thread which will call run again, setting up to loops. It's actually dumb luck that this worked at all. What this does is calls marvin.update twice...and random intervals, meaning that the object is moved at inconsistent rates
Basically, you should remove the line game.run() and wrap new GameFrame(); within the context of a EventQueue.invokeLater call...
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
GameFrame frame = new GameFrame();
}
});
}
Personally, I'd recommend against extending from JFrame directly, you're not adding any functionality to the class, and simply create an instance within the main which you add your GameLogic panel to. This makes the game infinitely more flexible in terms of deployment as you're not locking yourself into a single container.
I'd also encourage you not use KeyListener, but instead, make use the Key Bindings API instead, as it solves the focus issues associated with KeyListener

Error when hitting Run in Eclipse 2D

I am a noob learning basic game programming in Slick 2D Using Eclipse and java
I am following a tutorial at https://www.youtube.com/watch?annotation_id=annotation_871076&feature=iv&src_vid=NoksHLldlcM&v=oWm5JY6IlUo and when i hit run it does not work. I get this error
Exception in thread "main" java.lang.RuntimeException: Resource not found: testdata/alphamap.png
at org.newdawn.slick.util.ResourceLoader.getResourceAsStream(ResourceLoader.java:69)
at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:169)
at org.newdawn.slick.Image.<init>(Image.java:196)
at org.newdawn.slick.Image.<init>(Image.java:170)
at org.newdawn.slick.Image.<init>(Image.java:158)
at org.newdawn.slick.Image.<init>(Image.java:136)
at org.newdawn.slick.tests.AlphaMapTest.init(AlphaMapTest.java:33)
at org.newdawn.slick.AppGameContainer.setup(AppGameContainer.java:390)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:314)
at org.newdawn.slick.tests.AlphaMapTest.main(AlphaMapTest.java:79)
This is what I am attempting
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
public class Main extends BasicGame{
private static final String Slick2D = null;
public Main(String title) {
super(title);
// TODO Auto-generated constructor stub
}
//this is where execution starts
public static void man(String args[]) throws SlickException {
AppGameContainer app = new AppGameContainer(new Main("First Slick2D"));
app.setDisplayMode(800, 600, false);
app.start();
}
#Override
public void render(GameContainer gc, Graphics g) throws SlickException {
// draw all the graphics
g.fillOval(200, 200, 100, 300)
g.fillRect(300, 200, 100, 200)
g.fillRoundRect(500, 200, 100, 50, 30)
g.drawLine(0, 0, 800, 600)
g.drawString(Welcome to Slick2D, 400, 0)
}
#Override
public void init(GameContainer arg0) throws SlickException {
// load all fonts, graphics, sounds, etc.
}
#Override
public void update(GameContainer arg0, int arg1) throws SlickException {
// game logic (AI, user input)
}
}
it's simply can't find image. check your scr folder for testdata folder and check if it contains alphamap.png (or you can delete some code where you getting and setting this picture)
Slick expects images to be in a folder called images. I'm not sure why, but it does.
Your direcetories should look like this:
\src\Main.java
\images\alphamap.png
If that doesn't work, make sure your directories are properly named and are within the project folder, not the src folder.
Example:
\MyProject\src\Main.java is your source code
\MyProject\images\alphamap.png

How do you toggle an image with a button event in Slick?

So I am trying to get a simple GUI setup for my teams game we are starting and I'm trying to make a drop down inventory using "I" as the hot key for it and it drops fine but I can't seem to figure out a way without using a different key to make it retract or in essence "un" draw the image'
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws
SlickException {
mapHud.draw(440, 1);
hotBar.draw(160, 454);
if(inv){
inventory.draw(-40, 1);
}
}
#Override
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
Input input = gc.getInput();
if(input.isKeyPressed(Input.KEY_I)){
inv = true;
}
if(input.isKeyPressed(Input.KEY_ESCAPE)) {
sbg.enterState(0);
}
}
Try something like this:
if(input.isKeyPressed(Input.KEY_I)){
inv = !inv;
}

Categories