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()
Related
package abdclient.gui.hud;
import org.lwjgl.input.Keyboard;
import org.newdawn.slick.opengl.renderer.Renderer;
import com.google.common.base.Predicate;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Optional;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.ScaledResolution;
public class HUDConfigScreen extends GuiScreen {
private final HashMap<IRenderer, ScreenPosition> renderers = new HashMap<IRenderer, ScreenPosition>();
private Optional<IRenderer> selectedRenderer = Optional.empty();
private int prevX, prevY;
public HUDConfigScreen(HUDManager api) {
Collection<IRenderer> registeredRenderers = api.getRegisteredRenderers();
for(IRenderer ren : registeredRenderers) {
if(!ren.isEnabled()) {
continue;
}
ScreenPosition pos = ren.load();
if(pos == null) {
pos = ScreenPosition.fromRelativePosition(0.5, 0.5);
}
adjustBounds(ren, pos);
this.renderers.put(ren, pos);
}
}
#Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
super.drawDefaultBackground();
final float zBackup = this.zLevel;
this.zLevel =200;
this.drawHollowRect(0, 0, this.width - 1, this.height - 1, 0xFF0000FF);
for(IRenderer renderer : renderers.keySet()) {
ScreenPosition pos = renderers.get(renderer);
renderer.renderDummy(pos);
this.drawHollowRect(pos.getAbsoluteX(), pos.getAbsoluteY(), renderer.getWidth(), renderer.getHeight(), 0xFF00FFFF);
}
this.zLevel = zBackup;
}
private void drawHollowRect(int x, int y, int w, int h, int color) {
this.drawHorizontalLine(x, x + w, y, color);
this.drawHorizontalLine(x, x + w, y + h, color);
this.drawVerticalLine(x, y + h, y, color);
this.drawVerticalLine(x + w, y + h, y, color);
}
#Override
protected void keyTyped(char typedChar, int keyCode) throws IOException {
if(keyCode == Keyboard.KEY_ESCAPE) {
renderers.entrySet().forEach((entry) ->{
entry.getKey().save(entry.getValue());
});
this.mc.displayGuiScreen(null);
}
}
#Override
protected void mouseClickMove(int x, int y, int bButton, long time) {
if(selectedRenderer.isPresent()) {
moveSelectedRendererBy(x - prevX, y - prevY);
}
this.prevX = x;
this.prevY = y;
}
private void moveSelectedRendererBy(int offsetX, int offsetY) {
IRenderer renderer = selectedRenderer.get();
ScreenPosition pos = renderers.get(renderer);
pos.setAbsolute(pos.getAbsoluteX() + offsetX, pos.getAbsoluteY() + offsetY);
adjustBounds(renderer, pos);
}
#Override
public void onGuiClosed() {
for(IRenderer renderer : renderers.keySet()) {
renderer.save(renderers.get(renderer));
}
}
#Override
public boolean doesGuiPauseGame() {
return true;
}
private void adjustBounds(IRenderer renderer, ScreenPosition pos) {
ScaledResolution res = new ScaledResolution(Minecraft.getMinecraft());
int screenWidth = res.getScaledWidth();
int screenHeight = res.getScaledHeight();
int absoluteX = Math.max(0, Math.min(pos.getAbsoluteX(), Math.max(screenWidth - renderer.getWidth(),0)));
int absoluteY = Math.max(0, Math.min(pos.getAbsoluteY(), Math.max(screenHeight - renderer.getHeight(),0)));
pos.setAbsolute(absoluteX, absoluteY);
}
#Override
protected void mouseClicked(int x, int y, int button) throws IOException {
this.prevX = x;
this.prevY = y;
loadMouseOver(x, y);
}
private void loadMouseOver(int x, int y) {
this.selectedRenderer = renderers.keySet().stream().filter(new MouseOverFinder(x, y)).findFirst();
}
private class MouseOverFinder implements Predicate<IRenderer> {
private int mouseX, mouseY;
public MouseOverFinder(int x, int y) {
this.mouseX = x;
this.mouseY = y;
}
public boolean test(IRenderer renderer) {
ScreenPosition pos = renderers.get(renderer);
int absoluteX = pos.getAbsoluteX();
int absoluteY = pos.getAbsoluteY();
if(mouseX >= absoluteX && mouseX <= absoluteX + renderer.getWidth()) {
if(mouseY >= absoluteY && mouseY <= absoluteY + renderer.getHeight()) {
return true;
}
}
return false;
}
#Override
public boolean apply(IRenderer arg0) {
// TODO Auto-generated method stub
return false;
}
}
}
The main issue is on line 146
Sorry if the format is bad, I just have little experence with Java and StackOverflow
The game would boot as normal, open the gui as normal but the moment I clicked my game (with my mouse) to interact with the draggable GUI it would instantly crash. These are the logs; This is a minecraft 1.8.9 PVP client containing optifine. I am making it on eclipse IDE.
Time: 2023-02-07, 11:10 p.m.
Description: Updating screen events
java.lang.ClassCastException: class abdclient.gui.hud.HUDConfigScreen$MouseOverFinder cannot be cast to class java.util.function.Predicate (abdclient.gui.hud.HUDConfigScreen$MouseOverFinder is in unnamed module of loader 'app'; java.util.function.Predicate is in module java.base of loader 'bootstrap')
at abdclient.gui.hud.HUDConfigScreen.loadMouseOver(HUDConfigScreen.java:146)
at abdclient.gui.hud.HUDConfigScreen.mouseClicked(HUDConfigScreen.java:142)
at net.minecraft.client.gui.GuiScreen.handleMouseInput(GuiScreen.java:530)
at net.minecraft.client.gui.GuiScreen.handleInput(GuiScreen.java:502)
at net.minecraft.client.Minecraft.runTick(Minecraft.java:1666)
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1025)
at net.minecraft.client.Minecraft.run(Minecraft.java:354)
at net.minecraft.client.main.Main.main(Main.java:113)
at Start.main(Start.java:11)
A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------
-- Head --
Stacktrace:
at abdclient.gui.hud.HUDConfigScreen.loadMouseOver(HUDConfigScreen.java:146)
at abdclient.gui.hud.HUDConfigScreen.mouseClicked(HUDConfigScreen.java:142)
at net.minecraft.client.gui.GuiScreen.handleMouseInput(GuiScreen.java:530)
at net.minecraft.client.gui.GuiScreen.handleInput(GuiScreen.java:502)
-- Affected screen --
Details:
Screen name: abdclient.gui.hud.HUDConfigScreen
So, i coding a minecraft client from quickdaffy tutorial (click gui is in 7ep)..
Another So, if i click on "testMod" button, nothing happends
Link for this tutorial: www.youtube.com/watch?v=SR_NAVTTD5o&t
This is the code for click gui (without imports):
package moonlight.ui.clickgui;
public class ClickGUI extends GuiScreen {
ArrayList<ModButton> modButtons = new ArrayList();
#Override
public void initGui() {
super.initGui();
this.modButtons.add(new ModButton(210, 60, 240, 100, Moonlight.INSTANCE.hudManager.testMod));
}
#Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
ScaledResolution sr = new ScaledResolution(mc);
super.drawScreen(mouseX, mouseY, partialTicks);
Gui.drawRect(200, 50, sr.getScaledWidth(), sr.getScaledHeight(), 0x20000000);
for(ModButton m : modButtons) {
m.draw();
}
}
#Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
super.mouseClicked(mouseX, mouseY, mouseButton);
}
}
And this is for gui button (without imports):
package moonlight.ui.clickgui.comp;
public class ModButton {
public int x, y, w, h;
public HudMod m;
public ModButton(int x, int y, int w, int h, HudMod m) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.m = m;
}
public void draw() {
Gui.drawRect(y, x, h, w, 0x20000000);
Minecraft.getMinecraft().fontRendererObj.drawString(m.name, x + 2, y + 2, getColor());
}
private int getColor() {
if(m.isEnabled()) {
return new Color(0,255,0,255).getRGB();
} else {
return new Color(255,0,0,255).getRGB();
}
}
public void ocClick(int mouseX, int mouseY, int button) {
if (mouseX >= x && mouseX <= x + w && mouseY >= y && mouseY <= y + h) {
m.toggle();
System.out.println("HELLO");
}
}
}
Rly, please help
I'm in despair, because my animation isn't as smooth as I expected. So I know, there is a lot of stuff around this problem, but mine is different in that way, that I know the common problems and I think, I'm doing it right. So firstly, this is my code:
Game.java
import de.lwerner.collisions.CircleCollision;
import de.lwerner.collisions.math.Vector2D;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
public class Game extends JPanel implements ActionListener {
private static final Color BACKGROUND_COLOR = new Color(0, 0, 25);
private static final Color TEXT_COLOR = Color.WHITE;
private static final int TARGET_FPS = 60;
private javax.swing.Timer swingTimer;
private JFrame window;
private Timer timer;
private Timer fpsTimer;
private int counter;
private long[] diffs;
private int fps;
private LinkedList<Circle> circles;
private LinkedList<Sprite> sprites;
public Game() {
timer = new Timer();
fpsTimer = new Timer(System.currentTimeMillis());
diffs = new long[TARGET_FPS];
circles = new LinkedList<>();
circles.add(new Circle(100, 100, 50, 300, 300, Color.WHITE));
// circles.add(new Circle(250, 250, 50, 300, 300, Color.WHITE));
// circles.add(new Circle(400, 400, 50, 300, 300, Color.WHITE));
// circles.add(new Circle(550, 550, 50, 300, 300, Color.WHITE));
// circles.add(new Circle(700, 700, 50, 300, 300, Color.WHITE));
// circles.add(new Circle(100, 700, 50, -300, 300, Color.WHITE));
// circles.add(new Circle(250, 550, 50, 300, -300, Color.WHITE));
// circles.add(new Circle(550, 250, 50, 300, -300, Color.WHITE));
// circles.add(new Circle(700, 100, 50, -300, 300, Color.WHITE));
sprites = new LinkedList<>();
sprites.addAll(circles);
window = new JFrame("Game");
window.setContentPane(this);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLocationRelativeTo(null);
window.setUndecorated(true);
window.setResizable(false);
window.validate();
window.addKeyListener(new KeyAdapter() {
#Override
public void keyTyped(KeyEvent e) {
stop();
}
});
window.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
stop();
}
});
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(window);
}
#Override
protected void paintComponent(Graphics g) {
g.setColor(BACKGROUND_COLOR);
g.fillRect(0, 0, getWidth(), getHeight());
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (Sprite s: sprites) {
s.render(g);
}
g.setColor(TEXT_COLOR);
g.drawString(fps + " FPS", 10, 20);
diffs[counter % TARGET_FPS] = fpsTimer.tick();
if (++counter % TARGET_FPS == 0) {
int sum = 0;
for (long diff: diffs) {
sum += diff;
}
fps = 1000 / (sum / TARGET_FPS);
}
}
private void step() {
long tick = timer.tick();
for (Sprite s: sprites) {
s.update(tick);
}
repaint();
checkCollisions();
}
private void checkCollisions() {
for (Sprite s1: sprites) {
BoundingBox bb = s1.getBoundingBox();
int offset = 0;
if (s1 instanceof Circle) {
offset = ((Circle) s1).getRadius();
}
if (bb.getLeft() < 0 || bb.getRight() >= getWidth()) {
s1.setVelX(-s1.getVelX());
if (bb.getLeft() < 0) {
s1.setX(0 + offset);
} else {
s1.setX(getWidth() - 1 - offset);
}
}
if (bb.getTop() < 0 || bb.getBottom() >= getHeight()) {
s1.setVelY(-s1.getVelY());
if (bb.getTop() < 0) {
s1.setY(0 + offset);
} else {
s1.setY(getHeight() - 1 - offset);
}
}
}
// Set<Set<Circle>> collidingPairs = new HashSet<>();
// for (Circle c1: circles) {
// for (Circle c2: circles) {
// if (c1 == c2) {
// continue;
// } else {
// if (c1.intersects(c2)) {
// Set<Circle> pair = new HashSet<>(Arrays.asList(c1, c2));
// if (!collidingPairs.contains(pair)) {
// collidingPairs.add(pair);
// de.lwerner.collisions.Circle cc1 = new de.lwerner.collisions.Circle(c1.getX(), c1.getY(), c1.getRadius(), new Vector2D(c1.getVelX(), c1.getVelY()));
// de.lwerner.collisions.Circle cc2 = new de.lwerner.collisions.Circle(c2.getX(), c2.getY(), c2.getRadius(), new Vector2D(c2.getVelX(), c2.getVelY()));
// CircleCollision collision = new CircleCollision(cc1, cc2);
// collision.resolveCollision();
// Vector2D v1New = cc1.getV();
// Vector2D v2New = cc2.getV();
// c1.setVelX((int) v1New.getX());
// c1.setVelY((int) v1New.getY());
// c2.setVelX((int) v2New.getX());
// c2.setVelY((int) v2New.getY());
// }
// }
// }
// }
// }
}
private void stop() {
if (swingTimer.isRunning()) {
swingTimer.stop();
window.dispose();
}
}
public void start() {
swingTimer = new javax.swing.Timer(1000 / TARGET_FPS, this);
swingTimer.start();
}
#Override
public void actionPerformed(ActionEvent e) {
step();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Game().start());
}
}
Sprite.java
import java.awt.*;
public abstract class Sprite {
protected double x;
protected double y;
protected int width;
protected int height;
protected int velX;
protected int velY;
public Sprite(int x, int y, int width, int height) {
this(x, y, width, height, 0, 0);
}
public Sprite(int x, int y, int width, int height, int velX, int velY) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.velX = velX;
this.velY = velY;
}
public int getX() {
return (int)Math.round(x);
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return (int)Math.round(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 int getVelX() {
return velX;
}
public void setVelX(int velX) {
this.velX = velX;
}
public int getVelY() {
return velY;
}
public void setVelY(int velY) {
this.velY = velY;
}
public void update(long tick) {
x += tick * velX / 1000.0;
y += tick * velY / 1000.0;
}
public BoundingBox getBoundingBox() {
return new BoundingBox(getY(), getX() + width, getY() + height, getX());
}
public boolean intersects(Sprite other) {
return getBoundingBox().intersects(other.getBoundingBox());
}
public abstract void render(Graphics g);
}
Circle.java
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
public class Circle extends Sprite {
private Color color;
private BufferedImage image;
public Circle(int x, int y, int r, Color c) {
super(x, y, r * 2, r * 2);
color = c;
// try {
// loadImage();
// } catch (Exception e) {
//
// }
}
public Circle(int x, int y, int r, int velX, int velY, Color c) {
super(x, y, r * 2, r * 2, velX, velY);
color = c;
// try {
// loadImage();
// } catch (Exception e) {
//
// }
}
private void loadImage() throws IOException {
image = ImageIO.read(getClass().getResource("/bubble.png"));
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public int getRadius() {
return width / 2;
}
public boolean intersects(Circle other) {
int dx = Math.abs(getX() - other.getX());
int dy = Math.abs(getY() - other.getY());
int r1 = getRadius();
int r2 = other.getRadius();
return dx * dx + dy * dy < (r1 + r2) * (r1 + r2);
}
#Override
public BoundingBox getBoundingBox() {
return new BoundingBox(getY() - getRadius(), getX() + getRadius(), getY() + getRadius(), getX() - getRadius());
}
#Override
public void render(Graphics g) {
if (image == null) {
g.setColor(color);
g.fillOval(getX() - getRadius(), getY() - getRadius(), width, height);
} else {
g.drawImage(image, getX() - getRadius(), getY() - getRadius(), null);
}
}
}
Timer.java
public class Timer {
private long lastTime;
public Timer() {
this(0L);
}
public Timer(long initialTime) {
lastTime = initialTime;
}
public long tick() {
if (lastTime == 0) {
lastTime = System.currentTimeMillis();
return 0;
}
long current = System.currentTimeMillis();
long diff = current - lastTime;
lastTime = current;
return diff;
}
}
BoundingBox.java
import java.awt.*;
public class BoundingBox {
private int top;
private int right;
private int bottom;
private int left;
public BoundingBox(int top, int right, int bottom, int left) {
this.top = top;
this.right = right;
this.bottom = bottom;
this.left = left;
}
public int getTop() {
return top;
}
public int getRight() {
return right;
}
public int getBottom() {
return bottom;
}
public int getLeft() {
return left;
}
public Rectangle getRectangle() {
return new Rectangle(left, top, right - left, bottom - top);
}
public boolean intersects(BoundingBox other) {
return getRectangle().intersects(other.getRectangle());
}
#Override
public String toString() {
return "BoundingBox{" +
"top=" + top +
", right=" + right +
", bottom=" + bottom +
", left=" + left +
'}';
}
}
So I don't know, what I'm doing wrong. Common problems such as calling paint(), using not-doublebuffered components, using wrong methods for periodically run code and so on aren't present, yet it's flickering. The FPS are constant.
So, please help me! I'd be very glad to come over this...
Thanks!
i have looked all over the internet and in my school books but I can't seem to slove my problem.
In my program "bouncing ball" (got the code from our teacher) i need to change the size of the ball from small to bigger and reverse. I understand that i need a boolean to do that and maybe alsow an if statment. This is what I have in the Ball class rigth now regarding the size change:
private boolean changeSize = true;
int maxSize = 10;
int minSize = 1;
public void changeSize(boolean size ){
if(size == maxSize ){
return minSize;
}
else return maxSize;
}
public void changeBallSize(int d, int f){
diameter = d*f;
This is the whole code for the class Ball:
class Ball {
static int defaultDiameter = 10;
static Color defaultColor = Color.yellow;
static Rectangle defaultBox = new Rectangle(0,0,100,100);
// Position
private int x, y;
// Speen and angel
private int dx, dy;
// Size
private int diameter;
// Color
private Color color;
// Bouncing area
private Rectangle box;
// New Ball
public Ball( int x0, int y0, int dx0, int dy0 ) {
x = x0;
y = y0;
dx = dx0;
dy = dy0;
color = defaultColor;
diameter = defaultDiameter;
}
// New color
public void setColor( Color c ) {
color = c;
}
public void setBoundingBox( Rectangle r ) {
box = r;
}
// ball
public void paint( Graphics g ) {
// Byt till bollens färg
g.setColor( color );
g.fillOval( x, y, diameter, diameter );
}
void constrain() {
// Ge absoluta koordinater för det rektangulära området
int x0 = box.x;
int y0 = box.y;
int x1 = x0 + box.width - diameter;
int y1 = y0 + box.height - diameter;
// Setting speed and angels
if (x < x0)
dx = Math.abs(dx);
if (x > x1)
dx = -Math.abs(dx);
if (y < y0)
dy = Math.abs(dy);
if (y > y1)
dy = -Math.abs(dy);
}
// movingt the ball
x = x + dx;
y = y + dy;
constrain();
}
}
I am a total rookie of java! Thanks for the help!
Add the following into your Ball class:
private int changeFlag=-1;
In your constrain() function, just before the last line, after moving the ball:
if(diameter==maxSize) {
changeFlag=-1;
}
else if (diameter==minSize) {
changeFlag=1;
}
diameter=diameter+changeFlag;
Add this code to your Ball Class
private minSize = 1;
private maxSize = 10;
public void setDiameter(int newDiameter) {
this.diameter = newDiameter;
}
public int getMinSize() {
return minSize;
}
public int getMinSize() {
return maxSize;
}
Use this when you use the ball
Ball ball = new Ball(1,1,1,1);
int newDiameter = 10;
if(newDiameter == ball.getMinSize()) {
ball.setDiameter(ball.getMaxSize());
}
id(newDiameter == ball.getMaxSize()) {
ball.setDiameter (ball.getMinSize());
}
I've edited it, is this what you mean?
Main Class:
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
public class Main extends JFrame {
public static void main(String[] args) {
new Main();
}
public Main() {
// configure JFrame
setSize(640, 360);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create ball
Ball ball = new Ball(this.getWidth()/2, this.getHeight()/2, 50, 100);
add(ball);
Thread t = new Thread(ball);
t.start();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
}
}
Ball Class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JComponent;
public class Ball extends JComponent implements Runnable {
private int x, y, minDiameter, maxDiameter, currentDiameter, growRate = -1;
private Color color = Color.BLUE;
public Ball(int x, int y, int minDiameter, int maxDiameter) {
this.x = x;
this.y = y;
this.minDiameter = minDiameter;
this.maxDiameter = maxDiameter;
this.currentDiameter = minDiameter;
setVisible(true);
}
#Override
public void run() {
while (true) {
// coerce max and min size
if (this.currentDiameter + growRate > maxDiameter) {
this.currentDiameter = maxDiameter;
this.growRate = -1;
}
if (this.currentDiameter + growRate < minDiameter) {
this.currentDiameter = minDiameter;
this.growRate = 1;
}
this.currentDiameter += this.growRate;
repaint();
try {
Thread.sleep(10);
}
catch(Exception e) {
System.out.println(e.toString());
}
}
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
g2.setColor(this.color);
g2.fillOval(this.x, this.y, this.currentDiameter, this.currentDiameter);
}
}
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;
}
}