so I've been working on getting my boxes to save their position in an array all day and finally thought i came up with something (with a lot of help from you guys) and it just isn't working... can someone please tell me why?
Control class:
import java.awt.Point;
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 Control extends BasicGameState {
public static final int ID = 1;
public Methods m = new Methods();
public Point[] point = new Point[(800 * 600)];
int pressedX;
int pressedY;
int num = 0;
public void init(GameContainer container, StateBasedGame game) throws SlickException{
}
public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
m.drawParticle(pressedX, pressedY);
}
public void update(GameContainer container, StateBasedGame game, int delta) {
}
public void mousePressed(int button, int x, int y) {
pressedX = x;
pressedY = y;
num = num + 1;
point[num].x = pressedX;
point[num].y = pressedY;
}
public int getID() {
return ID;
}
}
Methods class:
import org.newdawn.slick.Graphics;
public class Methods {
public Graphics g = new Graphics();
public int sizeX = 1;
public int sizeY = 1;
public void drawParticle(float x, float y){
g.drawRect(x, y, sizeX, sizeY);
}
}
While you've initialised the size of the point array, you've not initialised the contents.
public void mousePressed(int button, int x, int y) {
pressedX = x;
pressedY = y;
num++;
point[num] = new Point(pressedX, pressedY);
}
Also think in your render method, you need to re-render the graphics (I could be mistaken, I've not used Slick2D before)...
Withing something like...
public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
for (Point p : point) {
if (p != null) {
m.drawParticle(p.x, p.y);
}
}
m.drawParticle(pressedX, pressedY);
}
I'm also curious about you creating you're own Graphics, especially when the render method passes you one, you may want to check into that further and make sure that this is acceptable...
Related
For some reason, every time I jump in my the game I'm making, the jump gets shorter than the previous jump. Jumps start long and majestic (my game is set in space) and after about 10 jumps, my character is literally twitching against the ground because the jump is practically less than one pixel in height. I honestly cannot find out what is wrong with it, but I feel like it has something to do with the way I find deltaTime. Please help. I'm usually able to solve my own problems with a bit of troubleshooting and/or a bit of Googling, but I honestly don't know what's wrong and it all looks logical to me.
Sorry for the lack of comments. As you can probably tell from my nasty styles of implementing, this is kinda just a quick-write project so I don't really care much to look at the code later. I'm making this mainly to learn and practice Java.
I know there are a lot of out of class references so if you need to see one (I believe I included the important ones), just let me know.
Player Class (which extends Entity):
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import main.Main;
import scenes.Scene;
import threads.Time;
public class Player extends Entity {
private Scene scene;
private int HorizontalAxis = 0;
public float speed = 0.5f;
public float gravity = 0.001f;
public float jumpSpeed = 1f;
private float moveVelX = 0, moveVelY = 0;
public Player(String name, String tag, int x, int y, int w, int h, String spritePath, Scene scene) {
super(name, tag, x, y, w, h, spritePath);
this.scene = scene;
}
public void Update() {
//System.out.println(isGrounded());
if (Main.keyInput.getKeyState("MoveLeft")) {
HorizontalAxis = -1;
}
if (Main.keyInput.getKeyState("MoveRight")) {
HorizontalAxis = 1;
}
if (Main.keyInput.getKeyState("MoveLeft") == Main.keyInput.getKeyState("MoveRight")) {
HorizontalAxis = 0;
}
moveVelX = (HorizontalAxis * speed);
if (isGrounded()) {
moveVelY = 0;
if (Main.keyInput.getKeyState("Jump") || Main.keyInput.getKeyState("JumpAlt")) {
moveVelY = -jumpSpeed;
}
} else {
moveVelY += gravity * Time.deltaTime.getSeconds();
}
setTrueX(getTrueX() + moveVelX);
setTrueY(getTrueY() + moveVelY);
System.out.println(moveVelY);
}
public void render(Graphics2D g) {
g.drawImage(getSprite(), getX(), getY(), getWidth(), getHeight(), Main.display);
}
public boolean isGrounded() {
ArrayList<Entity> groundEntities = scene.FindEntitiesWithTag("Ground");
if (groundEntities.size() > 0) {
for (int i = 0; i < groundEntities.size(); i++) {
if (this.hitbox.intersects(groundEntities.get(i).hitbox)) {
return true;
}
}
return false;
} else {
System.err.println("There is no ground in the scene!");
return false;
}
}
}
Entity Class:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import main.Main;
public class Entity {
public static enum AutoDrawTypes { NONE, RECTANGLE, RECTANGLE_ROUND, OVAL };
public static AutoDrawTypes autoDrawType = Entity.AutoDrawTypes.NONE;
public String name;
public String tag;
protected float x, y;
protected int arcWidth, arcHeight;
protected Rectangle hitbox = new Rectangle();
protected Image sprite;
protected Color color;
public Entity(String tag, String name, int x, int y, int w, int h, String spritePath) {
this.name = name;
this.tag = tag;
this.x = x;
this.y = y;
hitbox.setBounds((int)(getTrueX() - Camera.getX()), (int)(getTrueY() - Camera.getY()), w, h);
setSprite(spritePath);
this.autoDrawType = Entity.AutoDrawTypes.NONE;
}
public Entity(String tag, String name, int x, int y, int w, int h) {
this.name = name;
this.tag = tag;
this.x = x;
this.y = y;
hitbox.setBounds((int)(getTrueX() - Camera.getX()), (int)(getTrueY() - Camera.getY()), w, h);
this.autoDrawType = Entity.AutoDrawTypes.NONE;
}
public Entity(String tag, String name, int x, int y, int w, int h, Entity.AutoDrawTypes autoDrawType, Color color) {
this.name = name;
this.tag = tag;
this.x = x;
this.y = y;
hitbox.setBounds((int)(getTrueX() - Camera.getX()), (int)(getTrueY() - Camera.getY()), w, h);
this.autoDrawType = autoDrawType;
this.color = color;
}
public Entity(String tag, String name, int x, int y, int w, int h, Entity.AutoDrawTypes autoDrawType, Color color, int arcWidth, int arcHeight) {
this.name = name;
this.tag = tag;
this.x = x;
this.y = y;
hitbox.setBounds((int)(getTrueX() - Camera.getX()), (int)(getTrueY() - Camera.getY()), w, h);
this.autoDrawType = autoDrawType;
this.color = color;
this.arcWidth = arcWidth;
this.arcHeight = arcHeight;
}
public void UpdatePositionRelativeToCamera() {
hitbox.setBounds((int)(getTrueX() - Camera.getX()), (int)(getTrueY() - Camera.getY()), getWidth(), getHeight());
}
public Entity() {
}
public void Update() {
}
public void render(Graphics2D g) {
g.setColor(color);
if (autoDrawType == Entity.AutoDrawTypes.RECTANGLE) {
g.fillRect(getX(), getY(), getWidth(), getHeight());
}
if (autoDrawType == Entity.AutoDrawTypes.RECTANGLE_ROUND) {
g.fillRoundRect(getX(), getY(), getWidth(), getHeight(), arcWidth, arcHeight);
}
if (autoDrawType == Entity.AutoDrawTypes.OVAL) {
g.fillOval(getX(), getY(), getWidth(), getHeight());
}
}
public void setTrueX(float x) {this.x = x;}
public void setTrueY(float y) {this.y = y;}
public void setX(int x) {hitbox.x = x;}
public void setY(int y) {hitbox.y = y;}
public void setWidth(int width) {hitbox.width = width;}
public void setHeight(int height) {hitbox.height = height;}
public void setSprite(String path) {
Toolkit tk = Toolkit.getDefaultToolkit();
if (tk == null) {
System.err.println("Default Toolkit could not be fetched.");
return;
}
sprite = tk.getImage(Main.class.getResource(path));
if (sprite == null) {
System.err.println("Image not found at + '" + path + "'. Check path in resources folder.");
return;
}
}
public float getTrueX() {return this.x;}
public float getTrueY() {return this.y;}
public int getX() {return hitbox.x;}
public int getY() {return hitbox.y;}
public int getWidth() {return hitbox.width;}
public int getHeight() {return hitbox.height;}
public Image getSprite() {return sprite;}
}
Timing Class (which is run as a thread at the start of the application):
import java.time.Duration;
import java.time.Instant;
public class Time implements Runnable {
public static boolean running = false;
public static Duration deltaTime = Duration.ZERO;
public static Instant beginTime = Instant.now();
public void run() {
while (running) {
deltaTime = Duration.between(beginTime, Instant.now());
}
}
}
Nevermind, I fixed it. It was the way I calculated deltaTime. I decided just to remove deltaTime and reduce the gravity (even though it's already insanely small lol). That fixed the weird "smaller jumps over time" bug thing.
Take a look at this code for causing the player to fall down:
moveVelY += gravity * Time.deltaTime.getSeconds();
Notice that this causes the player's y velocity to increase by an amount that increases as a function of time. That is, it's as if gravity is constantly increasing as time passes. As a result, if you jump early on, it's like jumping on the moon, and if you jump later it's like jumping on Jupiter or the surface of a neutron star.
To fix this, remove the dependency on the current time. Just increase the y velocity by the gravity term, which should probably just be a fixed constant unless you're doing something cool with the world physics.
I want to make the code so that when I click somewhere in the container, I create a new image with the coordinates of mouseX and Y of where I clicked.
I tried to do this, but I'm not sure how I will draw a new image, without the old image getting the same coordinates as the new one, and I'm not sure if I'm even creating different images right now, or if it's just the same image I'm changing the coordinates of whenever I click.
I was thinking about creating an array list of images, and then whenever I click somewhere, it adds a new image to the list, and then the render just keeps rendering the entire list, but here I'm not sure how to tell the render where each image was clicked (the coordinates).
Here's what I have so far, I'd really appreciate if someone could help me. Let me know if there's something you need me to clarify :)
package example;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.input.Mouse;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
public class SimpleSlickGame extends BasicGame
{
public String mouseCoords;
public String testClick ="Nothing clicked";
public int mouseX;
public int mouseY;
public SimpleSlickGame(String gamename)
{
super(gamename);
}
#Override
public void init(GameContainer gc) throws SlickException {
mouseCoords = "";
}
#Override
public void update(GameContainer gc, int i) throws SlickException {
int mouseX = Mouse.getX();
int mouseY = Mouse.getY();
mouseCoords = "Mouse X: "+ mouseX + " Mouse Y: "+ mouseY;
}
#Override
public void render(GameContainer gc, Graphics g) throws SlickException
{
g.drawString(mouseCoords, 250, 200);
g.drawRect(100, 100, 100, 100);
g.drawString(testClick, 200, 400);
g.drawImage(new Image("images/house.png"), mouseX, mouseY);
}
public void mousePressed(int button, int x, int y){
mouseX = x;
mouseY = y;
if (button == 0){
if((x> 100 && x<200) && (y > 100 && y < 200)){
testClick = "inside box";
}
else{
testClick = "outside box";
}
}
}
public static void main(String[] args)
{
try
{
AppGameContainer appgc;
appgc = new AppGameContainer(new SimpleSlickGame("Simple Slick Game"));
appgc.setDisplayMode(600, 600, false);
appgc.start();
}
catch (SlickException ex)
{
Logger.getLogger(SimpleSlickGame.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Ok so I did some reading of documents and googling and found a solution :P, although I'm not sure if it's the most optimal way of doing this (would really like some critique!!)
Here's what I did:
The main class:
package example;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.input.Mouse;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
public class SimpleSlickGame extends BasicGame
{
public String mouseCoords;
public String testClick ="Nothing clicked";
public int mouseX;
public int mouseY;
private House[] house = new House[10];
public List<House> houses = new ArrayList<House>();
public House houseTest, houseTest2, houseTest3;
public SimpleSlickGame(String gamename)
{
super(gamename);
}
#Override
public void init(GameContainer gc) throws SlickException {
mouseCoords = "";
}
#Override
public void update(GameContainer gc, int i) throws SlickException {
int mouseX = Mouse.getX();
int mouseY = Mouse.getY();
mouseCoords = "Mouse X: "+ mouseX + " Mouse Y: "+ mouseY;
}
#Override
public void render(GameContainer gc, Graphics g) throws SlickException
{
g.drawString(mouseCoords, 250, 200);
g.drawRect(100, 100, 100, 100);
g.drawString(testClick, 200, 400);
for(int i = 0; i<houses.size();i++){
if(houses.get(i) != null){
houses.get(i).render(gc, g);
}
}
}
public void mousePressed(int button, int x, int y){
mouseX = x;
mouseY = y;
if (button == 0){
if((x> 100 && x<200) && (y > 100 && y < 200)){
testClick = "inside box";
houses.add(new House(mouseX,mouseY));
}
else{
testClick = "outside box";
}
}
}
public static void main(String[] args)
{
try
{
AppGameContainer appgc;
appgc = new AppGameContainer(new SimpleSlickGame("Simple Slick Game"));
appgc.setDisplayMode(600, 600, false);
appgc.start();
}
catch (SlickException ex)
{
Logger.getLogger(SimpleSlickGame.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
House class:
package example;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
public class House {
int x;
int y;
int width = 20;
int height = 20;
House(int x, int y){
this.x = x;
this.y = y;
}
public void render(GameContainer gc, Graphics g) throws SlickException
{
g.setColor(Color.white);
g.drawRect(x, y, width, height);
}
}
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'm trying to make a java sand game and can't get past one bit. i've made my method that draws a rectangle at mouseX and mouseY, and i have set it up so it updates every frame so it constantly follows the mouse.
what i assume is that i would use an array to create each rectangle, and from there would use a pre-defined algorithm to float to the ground, I'm all good with that, i just don't understand how to 'hook my method' up to an array.
This is the method i am using to draw the rectangle (in it's own class called Methods)
import org.newdawn.slick.Graphics;
public class Methods {
public Graphics g = new Graphics();
public int sizeX = 4;
public int sizeY = 4;
public void drawParticle(float x, float y){
g.drawRect(x, y, sizeX, sizeY);
}
}
And this is my main class
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 Control extends BasicGameState {
public static final int ID = 1;
public Methods m = new Methods();
int mouseX;
int mouseY;
public void init(GameContainer container, StateBasedGame game) throws SlickException{
}
public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
m.drawParticle(mouseX, mouseY);
}
public void update(GameContainer container, StateBasedGame game, int delta) {
}
public void mouseReleased(int button, int x, int y){
mouseX = 0;
mouseY = 0;
}
public void mouseDragged(int oldx, int oldy, int newx, int newy) {
mouseX = newx;
mouseY = newy;
}
public int getID() {
return ID;
}
}
but when i click, just one rectangle follows the mouse, instead of many being created AT the mouse :L
Public Variables:
Rectangle boxes[] = new Rectangle[maxnum];
int boxnum = 0;
On mouse move:
boxes[boxnum] = new Rectangle[e.getX(), e.getY(), sizeX, sizeY);
boxnum = boxnum + 1;
When drawing your particles:
counter = 0;
do
{
g.drawRect(boxes[counter].x, boxes[counter].y, sizeX, sizeY);
counter = counter + 1;
} while (counter < maxnum);
Where maxnum is the maximum number of boxes you will have. This way you can store multiple rectangles in your array and go through the array and draw them when you update the screen. Hope this helps.
okay, so i have my image move straight down along the y axis whenever i click the mouse, my only problem is i don't know how to get it to stop when it hits the bottom of the screen, can someone please help?
import java.awt.Point;
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 Control extends BasicGameState {
public static final int ID = 1;
public Methods m = new Methods();
public Point[] point = new Point[(800 * 600)];
int pressedX;
int pressedY;
int num = 0;
String Build = "1.1";
public void init(GameContainer container, StateBasedGame game) throws SlickException{
}
public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
for (Point p : point) {
if (p != null) {
m.drawParticle(p.x, p.y += 1);
}
}
g.drawString("Particle Test", 680, 0);
g.drawString("Build: " + Build, 680, 15);
g.drawString("Pixels: " + num, 10, 25);
}
public void update(GameContainer container, StateBasedGame game, int delta) {
}
public void mousePressed(int button, int x, int y) {
pressedX = x;
pressedY = y;
num = num + 1;
point[num] = new Point(pressedX, pressedY);
}
public int getID() {
return ID;
}
}
I'd imagine somewhere you will want to check the x/y pos of the particle before you renderer it and remove it from the array when it's out of bounds...
public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
for (int index = 0; index < point.length; index++) {
Point p = point[index];
if (p != null) {
p.y++;
if (p.y > height) { // You'll need to define height...
point[index] = null; // Or do something else with it??
} else {
m.drawParticle(p.x, p.y);
}
}
}
g.drawString("Particle Test", 680, 0);
g.drawString("Build: " + Build, 680, 15);
g.drawString("Pixels: " + num, 10, 25);
}
You could also do a preemptive check, which would allow you to know what points are at the bottom of the screen...
if (p != null) {
if (p.y >= height) { // You'll need to define height...
// Do something here
} else {
p.y++;
m.drawParticle(p.x, p.y);
}
}