How is the abstract component class used in slick 2d? - java

I'm somewhat new to slick 2d and in my project I was playing around with things like buttons. I would draw an image and listen for a click at the coordinates and it ended up being like 50 lines long which seemed pretty unnecessary.
But then I saw this thread Slick 2d Button Listener; sadly it was dead so didn't help. What the guy was working on seemed really efficient but i have so far been unable to find any information on how to use it. If anyone can explain to me or show me how to use it that would be awesome.

I implemented a button like this in Slick 2D
protected Shape hitbox;
private boolean inside = false;
public void render(GameContainer container, Graphics g) {
.
.//drawing the picture of the button
.
if(inside && container.getInput().isMousePressed(Input.MOUSE_LEFT_BUTTON)){
//someone clicked the button
}
}
public void init(GameContainer container) {
//setting a hitbox up to recognize when the mouse is over the picture/button
hitbox = new Rectangle(/*dimensions of your picture*/);
}
public void update(GameContainer container, int delta) {
//this code finds out if the mouse is over the button
int mouseX = container.getInput().getMouseX();
int mouseY = container.getInput().getMouseY();
inside = hitbox.contains(mouseX, mouseY))
}

After some testing I found out how i could do this, in the button class I wrote :
import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.gui.AbstractComponent;
import org.newdawn.slick.gui.GUIContext;
public class Button extends AbstractComponent{
protected int width;
protected int height;
protected int x;
protected int y;
protected int mouseX;
protected int mouseY;
protected boolean pressed;
protected Shape hitbox;
protected boolean over;
protected String text;
public Button(GUIContext container, int x, int y, int width, int height, String text) {
super(container);
setLocation(x, y);
this.width = width;
this.height = height;
this.text = text;
hitbox = new Rectangle(x, y, width, height);
}
#Override
public int getHeight() {
return height;
}
#Override
public int getWidth() {
return width;
}
#Override
public int getX() {
return x;
}
#Override
public int getY() {
return y;
}
public boolean isPressed() {
return pressed;
}
public void update(GUIContext container) {
mouseX = container.getInput().getMouseX();
mouseY = container.getInput().getMouseY();
over = hitbox.contains(mouseX, mouseY);
if (over && container.getInput().isMousePressed(Input.MOUSE_LEFT_BUTTON)) {
pressed = true;
}else{
pressed = false;
}
}
#Override
public void render(GUIContext container, Graphics g) throws SlickException {
g.setColor(Color.blue);
g.fillRect(x, y, width, height);
g.setColor(Color.black);
g.drawString(text, x + width/2, y + height/2);
}
#Override
public void setLocation(int x, int y) {
this.x = x;
this.y = y;
}
and to use it in my frame i simply write:
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 Menu extends BasicGameState{
public static final int ID = 1;
private StateBasedGame game;
private Button button;
public int getID() {
return ID;
}
#Override
public void init(GameContainer container, StateBasedGame game) throws SlickException {
this.game = game;
button = new Button(container, 1280/2, 720/2, 200, 200, "Works");
}
#Override
public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
button.render(container, g);
}
#Override
public void update(GameContainer container, StateBasedGame game, int delta) {
button.update(container);
if (button.isPressed()) {
System.out.println("Works");
}
}
}

Related

Implementing java mouse listeners, custom gui

I'm working on a game currently using slick2d + lwjgl and I am trying to implement listeners for the gui components. I was wondering on how to do that since I am currently stumped. I was thinking I could do something like this
GuiComponent class....
public void addListener(MouseAdapter e){
// Stuck on this part
}
Than implement it into a menu like this
gComponent.addListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent e){
// listener logic
}
}
I don't know how to actually trigger the method mouseClicked inside the addListener method, because when i ran it like this nothing happened unless I am delusional. Anyway, any help does help even if you just send me to a javadoc or something like that. Thanks guys & merry christmas :)
EDIT:
GuiComponent class
package com.connorbrezinsky.turbulent.gui;
import java.awt.event.MouseAdapter;
import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
public class GuiComponent {
int x, y, width, height;
Color color;
Image i;
public GuiComponent(Gui gui, int _x, int _y, int w, int h, Color c) {
gui.components.add(this);
x = _x;
y = _y;
width = w;
height = h;
color = c;
}
public GuiComponent(int _x, int _y, int w, int h, Color c) {
x = _x;
y = _y;
width = w;
height = h;
color = c;
}
public GuiComponent(Gui gui, int _x, int _y, int w, int h) {
gui.components.add(this);
x = _x;
y = _y;
width = w;
height = h;
color = Color.white;
}
public GuiComponent(int _x, int _y, int w, int h) {
x = _x;
y = _y;
width = w;
height = h;
color = Color.white;
}
public void addText(String s){
}
public void addSprite(Image s){
i = s;
}
public void render(Graphics g){
if(i == null) {
g.setColor(color);
g.fillRect(x, y, width, height);
}else{
i.draw(x,y,width,height);
}
}
public void addListener(MouseAdapter e){
// stuck here
}
}
Example in menu class
GuiComponent guiTest = new GuiComponent(20, 20, 50, 10);
public void update(GameContainer arg0, StateBasedGame arg1, int arg2) throws SlickException{
guiTest.addListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent e){
System.out.println("click");
}
});
}
Slick2D offers several components, I don't know if you've seen them. Maybe can you use the AbstractComponent, by inherits from it to do what you expect. It seems to provide the addListeners method that you want to implement by yourself. It say simplify you own code.
Then to add a listener, you can use your gameContainer. Through gc.getInput().addListener().
With your code it would be something like :
GuiComponent guiTest = new GuiComponent(20, 20, 50, 10);
public void update(GameContainer arg0, StateBasedGame arg1, int arg2) throws SlickException{
arg0.getInput().addListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent e){
System.out.println("click");
}
});
}

JFrame add only one class

I'am making a game, and my JFrame add only one class, i don't getting error, but one of two classes dosen't show. I am try to make JFrame frame 2 = new JFrame();, but nothing.
Game.java:
import java.awt.Component;
import javax.swing.JFrame;
public class Game{
private static final int WIDTH = 800;
private static final int HEIGHT = 600;
private static final String TITLE = "Game Dev [ Week #1 ]";
public static void main(String[] args){
JFrame frame = new JFrame();
Player player = new Player();
Rabbit rabbit = new Rabbit();
// Draw on the map
player.setPlayer(250,250);
rabbit.setRabbit(200,200);
// Draw on the map
frame.add(player);
frame.add(rabbit); // Add only this
// Window
frame.setVisible(true);
frame.setSize(WIDTH,HEIGHT);
frame.setTitle(TITLE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Player.java:
public class Player extends JPanel implements ActionListener, KeyListener{
// Varibles
Timer time = new Timer(5, this);
static int x; double velX = 0;
static int y; double velY = 0;
private BufferedImage player;
boolean W = false;
boolean A = false;
boolean S = false;
boolean D = false;
public void setPlayer(int x, int y){
this.x = x;
this.y = y;
}
public Player(){
time.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
try {
player = ImageIO.read(getClass().getResourceAsStream("/Player.png"));
} catch (IOException e){
e.printStackTrace();
}
}
// Draw player
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(player, (int)x, (int)y, 100, 100, null);
}
// Set the start up position of player
public void actionPerformed(ActionEvent e){
x += velX;
y += velY;
repaint();
}
// Functions for keyEvent
public void keyPressed(KeyEvent e){
int key = e.getKeyCode();
if(key == KeyEvent.VK_W) // UP
velY = -0.5;
if(key == KeyEvent.VK_A) // LEFT
velX = -0.5;
if(key == KeyEvent.VK_S) // DOWN
velY = 1.5;
if(key == KeyEvent.VK_D) // RIGHT
velX = 1.5;
}
public void keyTyped(KeyEvent e){}
// IF any key released
public void keyReleased(KeyEvent arg0) {
velX = 0;
velY = 0;
W = false;
A = false;
S = false;
D = false;
}
}
Rabbit.java:
public class Rabbit extends JPanel implements ActionListener{
static int x; double velX = 0;
static int y; double velY = 0;
BufferedImage rabbit;
public void setRabbit(int x, int y){
this.x = x;
this.y = y;
}
public Rabbit(){
try {
rabbit = ImageIO.read(getClass().getResourceAsStream("/Rabbit.png"));
} catch (IOException e){
e.printStackTrace();
}
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(rabbit, (int)x, (int)y, 100, 100, null);
}
public void actionPerformed(ActionEvent e){
x += velX;
y += velY;
repaint();
}
}
What's happening is that the JFrame is not combining the graphics for Player and Rabbit; rather, it is placing the player as a panel, and then placing the rabbit. So, the player and the rabbit are always separated. What you want is the Player and Rabbit classes NOT to extend JPanel, but to have a method called paint(Graphics). That way, you can make a class called GamePanel that extends JPanel, and create new methods setPlayer(Player) and setRabbit(Rabbit). The GamePanel class should look like this:
public class GamePanel extends JPanel {
Player player;
Rabbit rabbit;
public void setPlayer(Player player) {
this.player = player;
}
public void setRabbit(Rabbit rabbit) {
this.rabbit = rabbit;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
player.paint(g);
rabbit.paint(g);
}
}
and your Player class should look like this:
public class Player {
public void paint(Graphics g) {
// How to paint the graphics in the player class
}
}
and your Rabbit class should look the same, except as public class Rabbit.
Hope that helps!
EDIT: Full Script
package game;
import java.awt.Graphics;
public interface Displayable {
public void paint(Graphics graphics);
}
package game;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Rabbit implements Displayable {
private int x, y;
private Image image;
public Rabbit(int x, int y) throws IOException {
this.x = x;
this.y = y;
this.image = ImageIO.read(new File("RABBIT_FILE")); // Replace
// "RABBIT_FILE"
// with the image
// file you have
}
public void paint(Graphics graphics) {
graphics.drawImage(this.image, this.x, this.y, new ImageObserver() {
public boolean imageUpdate(Image img, int infoflags, int x, int y,
int width, int height) {
return false;
}
});
/**
* Optional: JDK 8 only:
*
* graphics.drawImage(this.image, this.x, this.y, (Image img, int
* infoflags, int x0, int y0, int width0, int height0) -> false);
* //Lambda Expression
*/
}
public void setCoordinates(int x, int y) {
this.x = x;
this.y = y;
}
}
package game;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Player implements Displayable {
private int x, y;
private Image image;
public Player(int x, int y) throws IOException {
this.x = x;
this.y = y;
this.image = ImageIO.read(new File("PLAYER_FILE")); // Replace
// "PLAYER_FILE"
// with the image
// file you have
}
public void paint(Graphics graphics) {
graphics.drawImage(this.image, this.x, this.y, new ImageObserver() {
public boolean imageUpdate(Image img, int infoflags, int x, int y,
int width, int height) {
return false;
}
});
/**
* Optional: JDK 8 only:
*
* graphics.drawImage(this.image, this.x, this.y, (Image img, int
* infoflags, int x0, int y0, int width0, int height0) -> false);
* //Lambda Expression
*/
}
public void setCoordinates(int x, int y) {
this.x = x;
this.y = y;
}
}
package game;
import java.awt.Graphics;
import javax.swing.JPanel;
public final class GamePanel extends JPanel {
private static final long serialVersionUID = -385535147711891740L;
private Player player;
private Rabbit rabbit;
public void setPlayer(Player player) {
this.player = player;
}
public void setRabbit(Rabbit rabbit) {
this.rabbit = rabbit;
}
public GamePanel(Player player, Rabbit rabbit) {
this.setPlayer(player);
this.setRabbit(rabbit);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.player.paint(g);
this.rabbit.paint(g);
}
}
package game;
import javax.swing.JFrame;
public final class Main {
public static void main(String... args) {
try {
JFrame frame = new JFrame("Player & Rabbit Game"); // Or whatever
// title
// you have in mind
GamePanel panel = new GamePanel(new Player(0, 0), new Rabbit(0, 0));
frame.add(panel);
frame.setVisible(true);
frame.setDefaultCloseOperation(3);
frame.setExtendedState(6);
} catch (Exception e) {
// Handle Exception if file is corrupted, unable to be read to an
// image, or does not exist
}
}
}

Java Game Dev: Checking if player is in-between two y coords

I'm making a game with Slick2D. When a player get's under a window with an enemy in it, they can shoot, and points will be added. I have every mechanic completed besides the shooting one. Here is my "plan" on how it'll work.
When the player gets below the window(which the program picks up on via y coordinate) and fires, points will be added to a counter.
How can I get my program to realize that the player is indeed below a window?
Thanks, and here's my PlayState code.
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.Image;
import org.newdawn.slick.state.transition.FadeInTransition;
import org.newdawn.slick.state.transition.FadeOutTransition;
import java.util.Random;
import java.util.TimerTask;
import java.util.Timer;
public class PlayState extends BasicGameState{
int stateID = -1;
int w = SwegBoi.WIDTH;
int h = SwegBoi.HEIGHT;
static int enemylocation;
float s = SwegBoi.SCALE;
Image playbackground;
Image swegboiplayer;
Image quit;
Image enemy1;
Image enemy2;
float playery;
int score = 0;
final static Random ran = new Random();
static Timer tm = new Timer();
static long startTime = System.currentTimeMillis();
public static void main(String args){
}
public PlayState(int stateID){
this.stateID = stateID;
}
#Override
public void init(GameContainer gc, StateBasedGame sbg)
throws SlickException {
swegboiplayer = new Image("resources/swegboibackgun.png");
playbackground = new Image("resources/playstatebackground.png");
quit = new Image("resources/mainmenuquit.png");
enemy1 = new Image("resources/enemy1.png");
enemy2 = new Image("resources/enemy1.png");
tm.schedule(new TimerTask() {
#Override
public void run() {
enemylocation = ran.nextInt(4) + 1;
}
}, 1, 2000);
}
#Override
public void render(GameContainer gc, StateBasedGame sbg, Graphics g)
throws SlickException {
playbackground.setFilter(Image.FILTER_NEAREST);
playbackground.draw(0, 0, s*10);
quit.draw((w-175*s),5 *s,s/2);
if(enemylocation==1){
enemy1.setFilter(Image.FILTER_NEAREST);
enemy1.draw(200,170,s*10);
}
if(enemylocation==2){
enemy1.setFilter(Image.FILTER_NEAREST);
enemy1.draw(200,360,s*10);
}
if(enemylocation==3){
enemy1.setFilter(Image.FILTER_NEAREST);
enemy1.draw(950,170,s*10);
}
if(enemylocation==4){
enemy1.setFilter(Image.FILTER_NEAREST);
enemy1.draw(950,360,s*10);
}
swegboiplayer.setFilter(Image.FILTER_NEAREST);
swegboiplayer.draw((w*s)/2-(playery*s), 450*s, s*5);
g.drawString("Alpha V0.1",6,6);
}
#Override
public void update(GameContainer gc, StateBasedGame sbg, int delta)
throws SlickException {
Input input = gc.getInput();
if(input.isKeyDown(Input.KEY_LEFT)){playery += 17;}
if(input.isKeyDown(Input.KEY_RIGHT)){playery -= 17;}
int mouseX = input.getMouseX();
int mouseY = input.getMouseY();
if(mouseHover(mouseX,mouseY,(w-175*s),5*s,quit.getHeight()/2,quit.getWidth()) == true){
if(input.isMousePressed(0)){
sbg.enterState(SwegBoi.MAINMENUSTATE,new FadeOutTransition(), new FadeInTransition());
}
quit = new Image("resources/mainmenuquithover.png");
}else{
quit = new Image("resources/mainmenuquit.png");
}}
#Override
public int getID() {
return stateID;
}
public boolean mouseHover(int mouseX, int mouseY, float x, float y, float height, float width){
if((mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height)){
return true;
}else{
return false;
}
}}
Something like this should work. Every time you move, check if you are in a range of an enemy x position and determine if shooting should be enabled or disabled. Define some kind of range for each enemies X position.
private void checkShootStatus()
{
// Calculate image bounds X Position + width
float swegboiplayerEndBound = swegboiplayer.getX() + swegboiplayer.getWidth();
float enemyEndBound = enemy.getX() + enemy.getWidth();
// Check enemy 1
if (swegboiplayerEndBound > enemy.getX() && swegboiplayer.getX() < enemyEndBound)
{
canShoot = true;
}
else
{
canShoot = false;
}
}
Since you cannot get the x location of an image, create a wrapper class to track the x/y positions of the player and enemy.
public class Player extends Image
{
private String image;
private float x = 0;
private float y = 0;
public Player(String image) throws SlickException
{
super(image);
this.setImage(image);
}
public float getY()
{
return y;
}
public void setY(float y)
{
this.y = y;
}
public String getImage()
{
return image;
}
public void setImage(String image)
{
this.image = image;
}
public float getX()
{
return x;
}
public void setX(float x)
{
this.x = x;
}
}
Enemy
public class Enemy extends Image
{
private String image;
private int x;
private int y;
public Enemy(String image) throws SlickException
{
super(image);
this.setImage(image);
}
public int getY()
{
return y;
}
public void setY(int y)
{
this.y = y;
}
public String getImage()
{
return image;
}
public void setImage(String image)
{
this.image = image;
}
public int getX()
{
return x;
}
public void setX(int x)
{
this.x = x;
}
}

Button Doesn't Coordinate As Supposed

So I got two buttons on this state Click here to see the screenshot
And what is actually happening is that my second button "Start", doesn't work with this values:
backButton.renderImage(g, CONTAINER_CENTER_X - backButton.getWidth() - 10, CONTAINER_MAX_Y - backButton.getHeight() - 30);
startButton.renderImage(g, CONTAINER_CENTER_X + 10, CONTAINER_MAX_Y - startButton.getHeight() - 30);
Here is output of button coordinates and values I set for x and y:
BACK BUTTON: [x=245, y= 535, width= 145, height=35] / CURRENT X: 245 /
CURRENT Y: 535 START BUTTON: [x=410, y= 535, width= 0, height=35] /
CURRENT X: 410 / CURRENT Y: 535
Then I found out, that by adding and subtracting button.getWidth(), I get the button to work
backButton.renderImage(g, CONTAINER_CENTER_X - backButton.getWidth() - 10, CONTAINER_MAX_Y - backButton.getHeight() - 30);
startButton.renderImage(g, CONTAINER_CENTER_X + startButton.getWidth() - startButton.getWidth() + 10, CONTAINER_MAX_Y - startButton.getHeight() - 30);
which is pretty strange, and is very ugly... :D
Here is output of button coordinates and values I set for x and y:
BACK BUTTON: [x=245, y= 535, width= 145, height=35] / CURRENT X: 245 /
CURRENT Y: 535
START BUTTON: [x=410, y= 535, width= 145, height=35] / CURRENT X: 410 / CURRENT Y: 535
So, check this state code and button class, and tell me what do you think?
ThisState
package poker;
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.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.state.transition.FadeInTransition;
import org.newdawn.slick.state.transition.FadeOutTransition;
import poker.gui.PButton;
import poker.gui.UIConstants;
import static poker.gui.UIConstants.CONTAINER_CENTER_X;
import static poker.gui.UIConstants.CONTAINER_MAX_Y;
import poker.util.RandomUtility;
public class SetupScreenState extends BasicGameState implements UIConstants, StatePanelInterface {
public static final int ID = 2;
private Image titleImage;
private PButton backButton;
private PButton startButton;
public SetupScreenState() {
}
#Override
public int getID() {
return ID;
}
#Override
public void init(GameContainer container, StateBasedGame game) throws SlickException {
titleImage = new Image("res/gui/title_setup.png");
backButton = new PButton("res/gui/button_back.png", "res/gui/button_back_hover.png");
startButton = new PButton("res/gui/button_start.png", "res/gui/button_start_hover.png");
}
#Override
public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
RandomUtility.bgTheme(container, g);
renderTopPanel(container, game, g);
renderCenterPanel(container, game, g);
renderBottomPanel(container, game, g);
}
#Override
public void update(GameContainer container, StateBasedGame game, int delta) throws SlickException {
Input input = container.getInput();
int mx = input.getMouseX();
int my = input.getMouseY();
if (backButton.contains(mx, my)) {
if (backButton.isButtonPressed(input)) {
game.enterState(StartScreenState.ID, new FadeOutTransition(), new FadeInTransition());
}
} else if (startButton.contains(mx, my)) {
if (startButton.isButtonPressed(input)) {
game.enterState(PlayScreenState.ID, new FadeOutTransition(), new FadeInTransition());
}
}
}
#Override
public void renderTopPanel(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
g.drawImage(titleImage, 50, 50);
}
#Override
public void renderCenterPanel(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
}
#Override
public void renderBottomPanel(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
backButton.renderImage(g, CONTAINER_CENTER_X - backButton.getWidth() - 10, CONTAINER_MAX_Y - backButton.getHeight() - 30);
startButton.renderImage(g, CONTAINER_CENTER_X + startButton.getWidth() - startButton.getWidth() + 10, CONTAINER_MAX_Y - startButton.getHeight() - 30);
}
}
BUTTON CLASS
package poker.gui;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
public class PButton {
private int x;
private int y;
private int width;
private int height;
private Image image;
private String classicImage;
private String hoverImage;
public PButton() {
}
public PButton(String classicImage, String hoverImage) throws SlickException {
this.classicImage = classicImage;
this.hoverImage = hoverImage;
image = new Image(classicImage);
}
public PButton(String classicImage, String hoverImage, int x, int y) throws SlickException {
this.classicImage = classicImage;
this.hoverImage = hoverImage;
this.x = x;
this.y = y;
image = new Image(classicImage);
}
public void renderImage(Graphics g) {
g.drawImage(image, x, y);
}
public void renderImage(Graphics g, int x, int y) throws SlickException {
this.x = x;
this.y = y;
g.drawImage(image, x, y);
}
public boolean contains(int x, int y) throws SlickException {
int minX = this.x;
int minY = this.y;
int maxX = this.x + this.width;
int maxY = this.y + this.height;
if ((x > minX && x < maxX) && (y > minY && y < maxY)) {
if (hoverImage != null) {
image = new Image(hoverImage);
}
return true;
}
image = new Image(classicImage);
return false;
}
public boolean isButtonPressed(Input input) throws SlickException {
return input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON);
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void setWidth(int width) {
this.width = width;
}
public int getWidth() {
return width = image.getWidth();
}
public void setHeight(int height) {
this.height = height;
}
public int getHeight() {
return height = image.getHeight();
}
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
}
#Override
public String toString() {
return "[x=" + x + ", y= " + y + ", width= " + width + ", height=" + height + "]";
}
}
Your problem is that you don't initialize the width fields properly.
In contains(), you use this.width, but it has not been initialized (or precisely it has been default initialized to 0 because it is an instance variable).
When you call getWidth(), width initializes because return width = image.getWidth(); assigns this.width = image.getWidth(), which explains why you have to call getWidth() to get your button to work.
Make sure you initialize your button fields properly. For example, when you create the button (i.e. in the constructor), you should set width to image.getWidth()

Tic Tac Toe game in Java using MouseAdapter

I have a CLickableBox class that creates boxes for me and now I need to make it so that when clicked, either an X or an O will be displayed in place. Here is the ClickableBox class.
import java.awt.event.MouseAdapter;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.Container;
public class ClickableBox extends MouseAdapter {
private int x, y, width, height;
private Color borderColor, backColor, oldColor;
private boolean drawBorder, clicked;
private Container parent;
public ClickableBox(int x, int y, int width, int height, Color borderColor,
Color backColor, boolean drawBorder, Container parent) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.borderColor = borderColor;
this.backColor = backColor;
this.drawBorder = drawBorder;
this.parent = parent;
}
public void draw(Graphics g) {
oldColor = g.getColor();
g.setColor(backColor);
g.fillRect(x, y, width, height);
if(drawBorder) {
g.setColor(borderColor);
g.drawRect(x, y, width, height);
}
g.setColor(oldColor);
}
public void mouseReleased(MouseEvent e) {
if(x < e.getX() && e.getX() < x + width &&
y < e.getY() && e.getY() < y + height) {
clicked = true;
parent.repaint();
}
}
public boolean isClicked() {
return clicked;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public Color getBorderColor() {
return borderColor;
}
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
public Color getBackColor() {
return backColor;
}
public void setBackColor(Color backColor) {
this.backColor = backColor;
}
public Color getOldColor() {
return oldColor;
}
public void setOldColor(Color oldColor) {
this.oldColor = oldColor;
}
public boolean isDrawBorder() {
return drawBorder;
}
public void setDrawBorder(boolean drawBorder) {
this.drawBorder = drawBorder;
}
public void setClicked(boolean clicked) {
this.clicked = clicked;
}
}
The TicTacToeBox class should extend ClickableBox, so that each box will be a listener. It needs to be designed so that each Box object will take care of itself- it knows if it's been clicked or not, and if so, whether it's going to be showing an x or an o.
The TicTacToeBox class is what I am having trouble with. This is what I will need for my game board. Any suggestions on how to implement this, simply? Below is my TicTacToeBox so far (not much):
Some direction and/or assistance would be greatly appreciated! Thanks.
import java.awt.Color;
import java.awt.Container;
public class TicTacToeBox extends ClickableBox {
public TicTacToeBox(int x, int y, int width, int height, Color borderColor,
Color backColor, boolean drawBorder, boolean mask, Container parent)
{
super(x, y, width, height, borderColor, backColor, drawBorder, parent);
}
}
Perhaps you need to override mouseReleased() - something like this:
public void mouseReleased(MouseEvent e) {
if ( this.value == NONE ) {
if ( currentTurn == Turn.X ) {
this.value = X;
}
else {
this.value = O;
}
}
super.mouseReleased();
}
With some global currentTurn variable to keep track of whose turn it is, and a value field to represent what the current value of this box is. You'd also probably want to override draw() to make it render the "X" or "O"...

Categories

Resources