I have a problem when using Slick2D's TextField.
When using Slick's 'BasicGame' the TextField works fine - I am able to click on it, type words, and System.out.println the text fields contents.
However, when using the same code on a 'BasicGameState', the TextField is un-clickable and doesn't respond to any input.
So:
Working code:
package Help;
import java.awt.Font;
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;
import org.newdawn.slick.UnicodeFont;
import org.newdawn.slick.font.effects.ColorEffect;
import org.newdawn.slick.gui.AbstractComponent;
import org.newdawn.slick.gui.ComponentListener;
import org.newdawn.slick.gui.TextField;
public class TextFieldWorking extends BasicGame{
private TextField text1;
private UnicodeFont font = getNewFont("Arial" , 16);
public TextFieldWorking() {
super("Test");
}
#Override
public void init(GameContainer container) throws SlickException {
font.loadGlyphs();
text1 = new TextField(container, font, 50,50,100,25);
}
#Override
public void update(GameContainer gc, int delta) throws SlickException {
System.out.println(text1.getText());
}
#Override
public void render(GameContainer gc, Graphics g) throws SlickException {
text1.render(gc, g);
}
public UnicodeFont getNewFont(String fontName , int fontSize){
UnicodeFont returnFont = new UnicodeFont(new Font(fontName , Font.PLAIN , fontSize));
returnFont.addAsciiGlyphs();
returnFont.getEffects().add(new ColorEffect(java.awt.Color.white));
return (returnFont);
}
public static void main(String[] args) throws SlickException {
TextFieldWorking g = new TextFieldWorking();
AppGameContainer gc = new AppGameContainer(g);
gc.setDisplayMode(500, 500, false);
gc.start();
}
}
Non-Working code:
package Help;
import java.awt.Font;
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;
import org.newdawn.slick.UnicodeFont;
import org.newdawn.slick.font.effects.ColorEffect;
import org.newdawn.slick.gui.AbstractComponent;
import org.newdawn.slick.gui.ComponentListener;
import org.newdawn.slick.gui.TextField;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
public class TextFieldTest extends BasicGameState{
int WindowWidth, WindowHeight;
TextField text1;
private UnicodeFont font = getNewFont("Arial" , 16);
private int stateId = 0;
public TextFieldTest(int State) {
this.stateId = State;
}
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException{
WindowWidth = gc.getWidth();
WindowHeight = gc.getHeight();
font.loadGlyphs();
text1 = new TextField(gc, font, 50,50,100,25);
}
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
text1.render(gc, g);
}
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException{
System.out.println(text1.getText());
}
public UnicodeFont getNewFont(String fontName , int fontSize){
UnicodeFont returnFont = new UnicodeFont(new Font(fontName , Font.PLAIN , fontSize));
returnFont.addAsciiGlyphs();
returnFont.getEffects().add(new ColorEffect(java.awt.Color.white));
return (returnFont);
}
public int getID(){
return this.stateId; //Returns the Id of this state (menu is 0)
}
}
For convenience:
This goes with the BasicGameState - It's how Slick2D works - you can just copy - paste code now :P
package Help;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.StateBasedGame;
public class Game extends StateBasedGame{
public static final String gamename = "Problem!";
public static final int TextFieldTestNum = 1;
public Game(String gamename){
super(gamename);
this.addState(new TextFieldTest(TextFieldTestNum));
}
public void initStatesList(GameContainer gc) throws SlickException{
this.getState(TextFieldTestNum).init(gc, this);
this.enterState(TextFieldTestNum); //The First state to enter
}
#Override
public boolean closeRequested(){
System.exit(0);
return false;
}
public static void main(String[] args) {
AppGameContainer appgc;
try{
Game g = new Game(gamename);
appgc = new AppGameContainer(g);
appgc.setDisplayMode(500, 500, false);
appgc.start();
}catch(SlickException e){
e.printStackTrace();
}
}
}
Any ideas appreciated!
Your problem is how you are going about StateBasedGames in slick. If you refer to my wiki entry here: http://slick.ninjacave.com/wiki/index.php?title=Game_States
You will notice that in the initStatesList() method, I only use this.addState(new StateName()). This is because of what addState() method does. It calls the init method for you, so there is no need to do getState() or enterState() in the top level Application class (Game.java in your case).
To summarize how to fix your problem, remove everything in your initStatesList() method,
then move this.addState(new TextFieldTest(TextFieldTestNum));
from your main constructor to your initStatesList() method.
Once I corrected that in your program, it ran just fine for me.
Related
A little while after starting the game, the cursor disappears and starts bugging out whenever I try to bring it back into the game window before disappearing again once back inside the window. This is the code for the class that uses the custom cursor:
import org.lwjgl.input.Mouse;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
public class Clicker extends BasicGameState {
Flower flower = new Flower();
public Clicker(int state) {
}
public void init(GameContainer container, StateBasedGame game) throws SlickException {
container.setMouseCursor("res/cursor/cursor.png", 0, 0);
flower.flower = new Image("res/flower.png");
}
public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
g.drawImage(flower.flower, flower.X, flower.Y);
}
public void update(GameContainer container, StateBasedGame game, int delta) throws SlickException {
if (Mouse.isButtonDown(0)) {
container.setMouseCursor("res/cursor/cursor_pressed.png", 0, 0);
if (flower.hitbox.contains(Mouse.getX(), 750 - Mouse.getY())) {
flower.newX();
flower.newY();
}
} else {
container.setMouseCursor("res/cursor/cursor.png", 0, 0);
}
}
public int getID() {
return 2;
}
}
So I solved this a while ago, but the best thing to do was to replace the cursor with a blank image, and then make a new sprite for the actual cursor and set its position to that of the mouse.
Please help I'm kinda lost in my coding.
So I've created a bullet class:
package javagame.states;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Vector2f;
import org.newdawn.slick.state.StateBasedGame;
public class Bullet {
private Vector2f pos;
private Vector2f speed;
private int lived = 0;
private boolean aktiv = true;
private static int MAX_LIFETIME = 2000;
public Bullet (Vector2f pos, Vector2f speed){
this.pos = pos;
this.speed = speed;
}
public Bullet(){
aktiv = false;
}
public void update(int t){
rotation++;
if(aktiv){
Vector2f realSpeed = speed.copy();
realSpeed.scale((t/1000.0f));
pos.add(realSpeed);
lived += t;
if(lived > MAX_LIFETIME) aktiv = false;
}
}
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException{
}
public void render(GameContainer gc, Graphics g) throws SlickException {
if(aktiv){
g.setColor(Color.red);
g.fillOval(pos.getX(), pos.getY(), 10, 10);
}
}
public boolean isAktiv(){
return aktiv;
}
}
then called the bullet class here in my robot class:
package javagame.states;
import java.util.Iterator;
import java.util.LinkedList;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Vector2f;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
public class Robot2 extends BasicGameState{
private LinkedList<Bullet> bullets;
#Override
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {
bullets = new LinkedList<Bullet>();
}
#Override
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
for(Bullet b : bullets){
b.render(gc, g);
}
}
#Override
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
Iterator<Bullet> i = bullets.iterator();
while(i.hasNext()){
Bullet b = i.next();
if(b.isAktiv()){
b.update(delta);
}else{
i.remove();
}
}
Input input = gc.getInput();
int mouseX = input.getMouseX();
int mouseY = input.getMouseY();
int xDistance = (int) (RobotX() + Robotwidth() / 2 - mouseX); //RobotX is the robot image x position same to RobotY
int yDistance = (int) (RobotY() + Robotheight() / 2 - mouseY);
double angleToTurn = Math.toDegrees(Math.atan2(yDistance, xDistance));
if(mouseX != 0){
angleToTurn += 270;
}else{
if(mouseY != 0)
angleToTurn += 180;
}
robot.setRotation((float) angleToTurn); //robot is an image. didn't included the code here to shorten my codes
if(gc.getInput().isMousePressed(Input.MOUSE_LEFT_BUTTON)){
bullets.add(new Bullet(new Vector2f(Sprites.getRobotX(), Sprites.getRobotY()), new Vector2f(mouseX, mouseY)));
}
}
#Override
public int getID() {
return States.ROBOT;// has an integer value
}
}
the robot is rotating perfectly according to mouse's cursor movement but when I hit the mouse's left button to fire a bullet, it doesn't follow the mouse's cursor location. This is what I've got when i run these codes and pressing the left button of my mouse. Please check my sample image.
http://s12.postimg.org/kwsr41p71/Untitled_1.jpg
What I want to achieve is to correct the direction of the bullet according to mouse cursor location.
Any help would be greately much appreciated. Thank you very much.
I cannot find an answer in Google, but is there a Mouse Over Area for Slick2D? Google just gives me results of Java's MouseOverArea. I just want to know if there is a MouseOverArea for Slick2D, and how it looks like.
Here is my code:
Game class
import org.newdawn.slick.*;
import org.newdawn.slick.state.*;
public class Game extends StateBasedGame {
public static final String gamename = "Life - Alpha";
public static int splash = 0;
public static int menu = 1;
public static int loading = 2;
public static int play= 3;
public Game(String gamename) {
super(gamename);
}
public void initStatesList(GameContainer gc) throws SlickException {
this.addState(new SplashScreen (splash));
this.addState(new Menu (menu));
this.addState(new Exit (exit));
this.addState(new Loading (loading));
this.addState(new Play(play));
this.enterState(0);
}
public static void main(String[] args) {
AppGameContainer app;
try {
app = new AppGameContainer(new Game(gamename));
app.setDisplayMode(800, 600, false);
app.start();
} catch (SlickException e) {
e.printStackTrace();
}
}
}
SplashScreen class:
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
public class SplashScreen extends BasicGameState {
Image splash;
private int elapsedTime;
private final int DELAY = 3000;
public SplashScreen(int state) {
}
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {
splash = new Image("res/SplashScreen.png");
}
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
g.drawImage(splash, 0, 0);
}
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
elapsedTime += delta;
if(elapsedTime >= DELAY) {
sbg.enterState(1);
}
}
public int getID() {
return 0;
}
}
Menu class:
import org.lwjgl.input.Mouse;
import org.newdawn.slick.*;
import org.newdawn.slick.state.*;
public class Menu extends BasicGameState {
public Menu(int state) {
}
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {
}
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
Image background = new Image("res/Background.png");
g.drawImage(background, 0, 0);
Image logo = new Image("res/Logo.png");
g.drawImage(logo, 275, 50);
Image playButton = new Image("res/Play button.png");
g.drawImage(playButton, 210, 250);
}
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
Input input = gc.getInput();
int xpos = Mouse.getX();
int ypos = Mouse.getY();
if ((xpos > 300 && xpos < 510) && (ypos > 230 && ypos < 260)) {
if (input.isMousePressed(0)) {
sbg.enterState(2);
}
//I want to put the Slick2D MouseOverArea code here...
//So then when I put the mouse over the playButton, something will display.
}
}
public int getID() {
return 1;
}
}
Loading class:
import org.newdawn.slick.*;
import org.newdawn.slick.state.*;
public class Loading extends BasicGameState {
private int elapsedTime;
private final int DELAY = 5000;
public Loading(int state) {
}
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {
}
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
Image background = new Image("res/Back.png");
g.drawImage(background, 0, 0);
Image loading = new Image("res/Loading.png");
g.drawImage(loading, 210, 150);
}
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
elapsedTime += delta;
if(elapsedTime >= DELAY) {
sbg.enterState(3);
}
}
public int getID() {
return 2;
}
}
Play class:
I'm working on it still... but this class doesn't need the MouseOverArea, the Menu class does.
So that was my code above. I just need a MouseOverArea for Slick2D. Google doesn't help. Hope you can.
Also, can you have a TextField in Slick2D? I don't know if I can. I know in normal Java you can, but can you in Slick2D?
If there are any mistakes, don't worry, I can fix them.
Thanks
Isn't the code put in here?
if ((xpos > 300 && xpos < 510) && (ypos > 230 && ypos < 260)) {
//mouseover
if (input.isMousePressed(0)) {
sbg.enterState(2);
}
}
}
I am trying to use java slick to create a basic state based game. The 3 of my stages work fine, but for some reason the other 5 cause a null point exception when I call the get state method. All states are initialized and added to the game in the same manner, and the actual code for Load game (one of the working states) is exactly the same as all the broken ones, minus the class name. I have been looking over this for a day or so and have no idea, any help will be great. Thanks.
This is the code for my game class - containing my main method
package javagame.states;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.StateBasedGame;
public class Game extends StateBasedGame{
public static final String gamename = "An OOP Adventure";
public static final int menu = 0;
public static final int play = 1;
public static final int new_game = 2;
public static final int load_game = 3;
public static final int char_select = 4;
public static final int item_found = 5;
public static final int monster_fight = 6;
public static final int inventory = 7;
public Game(String gamename){
super(gamename);
this.addState(new Menu(menu));
this.addState(new Play(play));
this.addState(new Newgame(new_game));
this.addState(new Loadgame(load_game));
this.addState(new Charselect(char_select));
this.addState(new Itemfound(item_found));
this.addState(new Monsterfight(monster_fight));
this.addState(new Inventory(inventory));
}
/*
*/
public void initStatesList(GameContainer gc) throws SlickException{
this.getState(menu).init(gc, this);
this.getState(play).init(gc, this);
this.getState(load_game).init(gc, this);
//broken states
this.getState(new_game).init(gc, this);
this.getState(item_found).init(gc, this);
this.getState(char_select).init(gc, this);
this.getState(monster_fight).init(gc, this);
this.getState(inventory).init(gc, this);
//end broken states
this.enterState(menu);
}
public static void main(String[] args) {
AppGameContainer appgc;
try{
appgc = new AppGameContainer(new Game(gamename));
appgc.setDisplayMode(640, 360, false);
appgc.start();
}catch(SlickException e){
e.printStackTrace();
}
}
}
This is the code all the broken classes:
package javagame.states;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
public class Newgame extends BasicGameState{
public Newgame(int state){
}
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException{
}
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
}
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException{
}
public int getID(){
return 3;
}
}
code for Load game (one of the working states) is exactly the same as all the broken ones, minus the class name
all broken state classes and Loadgame class return getID() == 3.
in Game constructor only Loadgame is registered as state with id == 3 - the others are ignored and thus never registered.
then in initStatesList() other state classes cannot be found because there were no states registered with ids like 4, 5, 6, 7.
fix all the broken state classes (including Loadgame) as follows:
public class Newgame extends BasicGameState{
private int state; // !!!
public Newgame(int state){
this.state = state; // !!!
}
...
public int getID(){
return this.state; // !!!
}
}
I've tested TextField on a clean BasicGame and it worked. (I see the border and i can type.)
The code:
TextField lanText;
TrueTypeFont font;
public void init(........)
{
font = new TrueTypeFont(new java.awt.Font(java.awt.Font.SERIF,java.awt.Font.BOLD,8),false);
lanText = new TextField(gc, font, 50, 100, 350, 25);
}
public void render(.....)
{
lanText.render(gc, g);
}
But when i try it on my game with BasicGameState it doesn't work. What's wrong? (I can see the border but I cant type)
I have 4 states. Menu 0. Game 1. Coop 2. Options 3.
Im trying to add it to the state 2(Coop).
public class Game
extends StateBasedGame
{
public final int menu = 0;
public final int game = 1;
public final int option = 2;
public final int coop = 3;
public Game(String gamename)
{
super(gamename);
this.addState(new Menu(menu));
this.addState(new Game(game));
this.addState(new Option(option));
this.addState(new Coop(coop));
}
public void initStatesList(GameContainer gc)
throws SlickException
{
this.getState(menu).init(gc, this);
this.getState(game).init(gc, this);
this.getState(option).init(gc, this);
this.getState(coop).init(gc, this);
this.enterState(menu);
}
}
Ok, I figured it out. Here is the code for anyone who will have the same problem.
import java.awt.Font;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.UnicodeFont;
import org.newdawn.slick.font.effects.ColorEffect;
import org.newdawn.slick.gui.ComponentListener;
import org.newdawn.slick.gui.TextField;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
public class Coop
extends BasicGameState
{
TextField text;
UnicodeFont font;
public Coop(int state)
{
}
public void init(GameContainer gc , StateBasedGame sbg)
throws SlickException
{
font = getNewFont("Arial" , 16);
}
public void render(GameContainer gc , StateBasedGame sbg , Graphics g)
throws SlickException
{
text.render(gc , g);
g.setFont(font);
}
public void update(GameContainer gc , StateBasedGame sbg , int delta)
throws SlickException
{
font.loadGlyphs();
}
public int getID()
{
return 3;
}
public void enter(GameContainer gc , StateBasedGame sbg)
throws SlickException
{
text = new TextField(gc , font , 150 , 270 , 200 , 35);
}
public UnicodeFont getNewFont(String fontName , int fontSize)
{
font = new UnicodeFont(new Font(fontName , Font.PLAIN , fontSize));
font.addGlyphs("#");
font.getEffects().add(new ColorEffect(java.awt.Color.white));
return (font);
}
}
I don't know why it needs to use font.loadGlyphs(); but without it, it wont work.