I have made a kind of gravity in a 2D Java game and I am attempting to create a jumping algorithm. I have had a look around and cannot seen to find any help for an algorithm which moves up and down in a wave.
Here is the code in Game.java:
package game;
import java.awt.*;
public class Game extends GameLoop{
public void init(){
setSize(864,480);
Thread th = new Thread(this);
th.start();
offscreen = createImage(864,480);
d = offscreen.getGraphics();
addKeyListener(this);
}
public void paint(Graphics g){
d.clearRect(0, 0, 864, 480);
d.drawImage(background, 0, 0, this);
d.drawImage(person, x, y, this);
g.drawImage(offscreen, 0, 0, this);
}
public void update(Graphics g){
paint(g);
}
}
And here is the code in GameLoop.java:
package game;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.*;
public class GameLoop extends Applet implements Runnable, KeyListener{
public int x, y;
public Image offscreen;
public Graphics d;
public boolean up, down, left, right;
public BufferedImage background, w1, w2, w3, w4, w5, w6, w7, w8, person, s1, s2;
public int counter, counter2;
public void run(){
x = 100;
y = 100;
try {
background = ImageIO.read(new File("background.png"));
w1 = ImageIO.read(new File("walk1.png"));
w2 = ImageIO.read(new File("walk2.png"));
w3 = ImageIO.read(new File("walk3.png"));
w4 = ImageIO.read(new File("walk4.png"));
w5 = ImageIO.read(new File("walk5.png"));
w6 = ImageIO.read(new File("walk6.png"));
w7 = ImageIO.read(new File("walk7.png"));
w8 = ImageIO.read(new File("walk8.png"));
s1 = ImageIO.read(new File("stancel.png"));
s2 = ImageIO.read(new File("stancer.png"));
} catch (IOException e1) {
e1.printStackTrace();
}
person = s1;
while(true){
x = 100;
y = 100;
while(true){
if (y <= 304 && up != true){
y+=10;
}
counter++;
counter2++;
if (counter >= 20){
counter = 0;
}
if (counter >= 0 && counter <= 5 && right == true){
person = w1;
}
if (counter > 5 && counter < 10 && right == true){
person = w2;
}
if (counter >= 10 && counter <= 15 && right == true){
person = w3;
}
if (counter > 15 && right == true){
person = w4;
}
if (counter2 >= 20){
counter2 = 0;
}
if (counter2 >= 0 && counter2 <= 5 && left == true){
person = w5;
}
if (counter2 > 5 && counter2 < 10 && left == true){
person = w6;
}
if (counter2 >= 10 && counter2 <= 15 && left == true){
person = w7;
}
if (counter2 > 15 && left == true){
person = w8;
}
if (left == true){
x-=4;
}
if (right == true){
x+=4;
}
if (up == true){
y-=4;
}
if (down == true){
y+=4;
}
if ( x <= -10 ){
x = -10;
}
if ( y <= 0 ){
y = 0;
}
if ( x >= 824 ){
x = 824;
}
if ( y >= 304 ){
y = 304;
}
repaint();
try{
Thread.sleep(20);
} catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
//#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == 37){
left = true;
}
if(e.getKeyCode() == 38){
up = true;
}
if(e.getKeyCode() == 39){
right = true;
}
if(e.getKeyCode() == 40){
down = true;
}
}
//#Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == 37){
left = false;
person = s2;
}
if(e.getKeyCode() == 38){
up = false;
}
if(e.getKeyCode() == 39){
right = false;
person = s1;
}
if(e.getKeyCode() == 40){
down = false;
}
}
//#Override
public void keyTyped(KeyEvent e) {
}
}
I think I need a counter , counter3 as a double, but I am not sure of an algorithm that will go up to a certain point on the y axis, then move down. Any help is appreciated.
One of the simplest wave functions is our old friend sine:
So for a jump motion, you would probably like the first half of a sine period. You could use java.util.Math, passing a sequence of numbers from 0 to 180 (how many depends on the number of frames you want the jump to last). e.g.:
Math.sin(0.0); // = 0.0
Math.sin(30.0); // = 0.5
Math.sin(60.0); // = 0.9
Math.sin(90.0); // = 1.0
Math.sin(120.0); // = 0.9
Math.sin(150.0); // = 0.5
Math.sin(180.0); // = 0.0
I'm not entirely sure by what you mean by "moves up and down in a wave".
But anyway, in real world physics, the altitude of an object in free-fall (ignoring air resistance) follows a parabola; i.e. it obeys a formula like:
altitude = maxAltitude - (acceleration * (t - timeOfMaxAltitude))^2
(There are other ways of formulating the laws of motion, but this approach is probably what you need for a simple game.)
A 1/2 sine wave looks rather like a truncated parabola, and could be used instead in a game. However, you need to realize that it is not an accurate simulation of real-world physics, especially for high jumps.
You can use a variable to represent the vertical velocity. When you jump, set the vertical velocity to a negative value. On each frame, add the vertical velocity to the vertical position, and add a constant to the velocity to simulate gravity. When there is something underneath, set the velocity back to 0. Experiment with the constant values to get an appropriate jump height.
Related
I'm having fun to build a 2D tile game (without Slick2D of libgdx) and I'm working on collision since more than 15 hours. I think it's time to ask question. I searched a lot but none really responds what I searched for.
So, this is what it look like : 2D game capture (The dark tile are were the player can't walking in) and Another 2D game capture
The rectangle are were collision can happen. There, when they collide, it's still moving just enough to be lock in the tile. (can't do nothing anymore)
So, my class is called by the input handler, the update and the draw. Theses three by the "play" class. Who just update stuff. (Player.MoveUp(), Player.draw, ...)
The "WorldManager" is where the tiles are managed (the only 4 of them and the getType() is to look up if it's blocked (0 valid and 1 blocked)
The "LevelGeneration" is where level, position of tiles and their ID is
mapped (with a int[][]) (he is ok' it create map with ID and when I
show then they are all good).
The AssetManager is where I cut sprites sheets to transform then in BufferedImage
The tilesize is 50 and the player is 41x36.
I have a problem since I want to have a liberty of mouvements (4 sides to make 8 mouvements sides ) and the anchor point seem to be at upperleft side
So here is my class (without imports and packages):
public class Player {
public static double SPEED;
public static int WIDTH, HEIGHT;
public static float XPos, YPos;
public static float destXPos, destYPos;
public static BufferedImage presentImage;
public static int[] position;
public static boolean moving;
public static boolean movementlock;
public static int side; // 0 up 1 right 2 down 3 left
public static Rectangle p = null;
public static Rectangle e = null;
private static boolean mouvementlock;
private static boolean collision;
public static void CreateHero(){
// Valeurs de test
position = new int[2];
SPEED = 1;
XPos = destXPos = 100;
YPos = destYPos = 100;
presentImage = AssetManager.Player[0][0];
moving = false;
movementlock = false;
collision = false;
position[0] = (int) (XPos/WorldManager.TileSize);
position[1] = (int) (YPos/WorldManager.TileSize);
}
public static void MoveUp(){
side = 0;
destYPos -= SPEED;
moving = ValidateNextPosition();
}
public static void MoveRight(){
side = 1;
destXPos += SPEED;
moving = ValidateNextPosition();
}
public static void MoveDown(){
side = 2;
destYPos += SPEED;
moving = ValidateNextPosition();
}
public static void MoveLeft(){
side = 3;
destXPos -= SPEED;
moving = ValidateNextPosition();
}
static void updateMovement(){
if(moving == true && mouvementlock == false){
mouvementlock = true;
System.out.println("Mouvement");
System.out.println("X : " + XPos);
System.out.println("Y : " + YPos);
XPos = destXPos;
YPos = destYPos;
System.out.println("Xdest : " + destXPos);
System.out.println("Ydest : " + destYPos);
System.out.println("" + moving);
moving = false;
mouvementlock = false;}
else{
destXPos = XPos;
destYPos = YPos;
}
}
public static boolean ValidateNextPosition(){
if(moving) return false;
if(collision) return false;
p = new Rectangle((int) XPos, (int) YPos, presentImage.getWidth(null),presentImage.getHeight(null));
int tileid = 0;
boolean validate = true;
int destpos[] = new int[2];
double TileCollision[] = new double[2];
destpos[0] = (int) destXPos/WorldManager.TileSize;
destpos[1] = (int) destYPos/WorldManager.TileSize;
TileCollision[0] = 0;
TileCollision[1] = 0;
if(side == 0 && collision != true){
if(destpos[1] - 1 > 0){
tileid = LevelGenerator.getIdmap()[destpos[0]][destpos[1] - 1];
if(destYPos + 1 < 0 || WorldManager.Tuiles[tileid].getType() == 1 ){
destpos[1] -= 1;collision = true;}}
}
if(side == 1 && collision != true){
tileid = LevelGenerator.getIdmap()[destpos[0] + 1][destpos[1]];
if(destXPos + 1 < 0 || WorldManager.Tuiles[tileid].getType() == 1 ){
destpos[0] += 1;collision = true;}
}
if(side == 2 && collision != true){
tileid = LevelGenerator.getIdmap()[destpos[0]][destpos[1] + 1];
if(destYPos - 1 < 0 || WorldManager.Tuiles[tileid].getType() == 1 ){
destpos[1] += 1;collision = true;}
}
if(side == 3 && collision != true){
tileid = LevelGenerator.getIdmap()[destpos[0]][destpos[1]];
if(destXPos - 1 < 0 || WorldManager.Tuiles[tileid].getType() == 1 ){
/*destpos[0] -= 1*/;collision = true;}
}
if (collision == true){
TileCollision[0] = LevelGenerator.getPosmap()[destpos[0]][destpos[1]][0];
TileCollision[1] = LevelGenerator.getPosmap()[destpos[0]][destpos[1]][1];
e = new Rectangle((int) TileCollision[0], (int) TileCollision[1],WorldManager.TileSize,WorldManager.TileSize);}
if(e != null && p.intersects(e)){
validate = false;
System.out.println("collision");}
return validate;
}
public static void update() {
updateMovement();
}
public static void draw(Graphics2D g) {
g.drawImage(presentImage,(int) XPos,(int) YPos,presentImage.getWidth(null),presentImage.getWidth(null),null);
if(p != null){
g.setColor(Color.BLACK);
g.drawRect(p.x, p.y, p.width, p.height);}
if(e != null){
g.setColor(Color.BLACK);
g.drawRect(e.x, e.y, e.width, e.height);}
}
}
To resume,
The collision happen too late and the player get stuck in the blocked block.
Sometimes it pass through it since the (I suppose) the top left don't hit the block.
It can go out of the map without problems and then it crashed, but everything I tried keep crashing the game
Thank you very much and have a nice day
Hell'no
(P.S. : English is my third language, so ask me if you don't completely understand)
When collision gets set to true and your ValidateNextPosition method returns false, collision (and by extension your moving variable) can never be toggled again because of your if(collision) return false statement at the top.
i just searched on the forum but I couldn't find anything that helps me.. My problem is the following : I was trying to create a little game in which you have to walk right in your friend's back in order to win, the game ends when one of them achieves this..
Here's a simple code I made to explain my problem
I have 3 classes in my application (which belong in the package code) :
Main
Game
Position
I have 9 .png in my application (which belong in the package img) :
0.png
j1_0.png
j1_1.png
j1_2.png
j1_3.png
j2_0.png
j2_1.png
j2_2.png
j2_3.png
Both packages are at the src root
First class :
package code;
public class Main{
public static Game game;
public static void main(String[] args){
game = new Game(8, 8);
}
}
Seconds class :
package code;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
#SuppressWarnings("serial")
public class Game extends JFrame{
private Position j1, j2;
private JPanel panel;
private JLabel[][] grid;
private int largeur, hauteur;
public Game(int hauteur, int largeur){ // >= 2
super("Rattrape l'autre");
this.largeur = largeur;
this.hauteur = hauteur;
this.panel = new JPanel(new GridBagLayout());
this.add(this.panel);
this.grid = new JLabel[largeur][hauteur];
int x1 = (int) (Math.random() * largeur), y1 = (int) (Math.random() * hauteur), x2, y2;
do{
x2 = (int) (Math.random() * largeur);
y2 = (int) (Math.random() * hauteur);
}while(x2 == x1 && y2 == y1);
this.j1 = new Position(x1, y1, (int) (Math.random() * 4));
this.j2 = new Position(x2, y2, (int) (Math.random() * 4));
updatePanel();
this.setResizable(false);
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
this.addKeyListener(new KeyListener(){
#Override
public void keyPressed(KeyEvent e){
boolean over = false;
if(e.getKeyCode() == KeyEvent.VK_Z){
if(j1.getY() != 0 && !(j1.getY() == j2.getY() + 1 && j1.getX() == j2.getX())){
j1.goesUp();
}else if(j2.getDirection() == 0 && j1.getY() == j2.getY() + 1 && j1.getX() == j2.getX()){
over = true;
}
j1.turnUp();
}else if(e.getKeyCode() == KeyEvent.VK_D){
if(j1.getX() != largeur - 1 && !(j1.getX() == j2.getX() - 1 && j1.getY() == j2.getY())){
j1.goesRight();
}else if(j2.getDirection() == 1 && j1.getX() == j2.getX() - 1 && j1.getY() == j2.getY()){
over = true;
}
j1.turnRight();
}else if(e.getKeyCode() == KeyEvent.VK_S){
if(j1.getY() != hauteur - 1 && !(j1.getY() == j2.getY() - 1 && j1.getX() == j2.getX())){
j1.goesDown();
}else if(j2.getDirection() == 2 && j1.getY() == j2.getY() - 1 && j1.getX() == j2.getX()){
over = true;
}
j1.turnDown();
}else if(e.getKeyCode() == KeyEvent.VK_Q){
if(j1.getX() != 0 && !(j1.getX() == j2.getX() + 1 && j1.getY() == j2.getY())){
j1.goesLeft();
}else if(j2.getDirection() == 3 && j1.getX() == j2.getX() + 1 && j1.getY() == j2.getY()){
over = true;
}
j1.turnLeft();
}
if(e.getKeyCode() == KeyEvent.VK_UP){
if(j2.getY() != 0 && !(j2.getY() == j1.getY() + 1 && j2.getX() == j1.getX())){
j2.goesUp();
}else if(j1.getDirection() == 0 && j2.getY() == j1.getY() + 1 && j2.getX() == j1.getX()){
over = true;
}
j2.turnUp();
}else if(e.getKeyCode() == KeyEvent.VK_RIGHT){
if(j2.getX() != largeur - 1 && !(j2.getX() == j1.getX() - 1 && j2.getY() == j1.getY())){
j2.goesRight();
}else if(j1.getDirection() == 1 && j2.getX() == j1.getX() - 1 && j2.getY() == j1.getY()){
over = true;
}
j2.turnRight();
}else if(e.getKeyCode() == KeyEvent.VK_DOWN){
if(j2.getY() != hauteur - 1 && !(j2.getY() == j1.getY() - 1 && j2.getX() == j1.getX())){
j2.goesDown();
}else if(j1.getDirection() == 2 && j2.getY() == j1.getY() - 1 && j2.getX() == j1.getX()){
over = true;
}
j2.turnDown();
}else if(e.getKeyCode() == KeyEvent.VK_LEFT){
if(j2.getX() != 0 && !(j2.getX() == j1.getX() + 1 && j2.getY() == j1.getY())){
j2.goesLeft();
}else if(j1.getDirection() == 3 && j2.getX() == j1.getX() + 1 && j2.getY() == j1.getY()){
over = true;
}
j2.turnLeft();
}
updatePanel();
if(over){
end();
}
}
#Override
public void keyReleased(KeyEvent e){}
#Override
public void keyTyped(KeyEvent e){}
});
}
public void updatePanel(){
GridBagConstraints c = new GridBagConstraints();
this.panel.removeAll();
for(int x = 0; x < largeur; x++){
for(int y = 0; y < hauteur; y++){
if(x == j1.getX() && y == j1.getY()){
this.grid[x][y] = new JLabel(new ImageIcon(Main.class.getResource("/img/j1_" + j1.getDirection() + ".png")));
}else if(x == j2.getX() && y == j2.getY()){
this.grid[x][y] = new JLabel(new ImageIcon(Main.class.getResource("/img/j2_" + j2.getDirection() + ".png")));
}else{
this.grid[x][y] = new JLabel(new ImageIcon(Main.class.getResource("/img/0.png")));
}
c.gridx = x;
c.gridy = y;
this.panel.add(this.grid[x][y], c);
}
}
this.panel.revalidate();
}
public void end(){
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
Main.game.dispose();
}
}
Third class :
package code;
public class Position{
private int x, y, direction;
public Position(int x, int y, int direction){
this.x = x;
this.y = y;
this.direction = direction;
}
public int getX(){
return this.x;
}
public int getY(){
return this.y;
}
public int getDirection(){
return this.direction;
}
public void goesUp(){
this.y--;
}
public void goesRight(){
this.x++;
}
public void goesDown(){
this.y++;
}
public void goesLeft(){
this.x--;
}
public void turnUp(){
this.direction = 0;
}
public void turnRight(){
this.direction = 1;
}
public void turnDown(){
this.direction = 2;
}
public void turnLeft(){
this.direction = 3;
}
}
Finally, my problem is this one :
I wanted that, for example, when the Player 1 looks left and he's just on top of the Player 2, while the Player 2 looks down, if the player 1 moves down, it should wins the game, but AFTER displaying the Player 1 looking down.
I tried a lot of input o test, and it seems to work because when over is set to true, then the program goes in updatePanel() and then it launches end() which should sleep for 1 second and then dispose the frame.. but it doesn't, it does launch updatePanel() at the end, it update the value of j1 (as the previous algorithm, i mean the one that assignes values in function of the keyboard inputs, made him look down) but it doesn't display the new grid so, i'm lost :p
Thanks in advice I hope you got the problem, plus the algorithm is easy and not that long so it shouldn't be hard for you guys to understand it :)
should sleep for 1 second and then dispose the frame..
You can't use Thread.sleep() on the Event Dispatch Thread(EDT). This will cause the GUI to sleep which means it will not get repainted.
Instead you need to use a separate Thread, probably a SwingWorker. A SwingWorker will allow you to use Thread.sleep() and then you can publish results when you are finished sleeping.
Read the section from the Swing tutorial on Concurrency for more information and examples.
I'm working on a little jump an run game, but my collision detection don't work properly.
This is the backbone of my collision detection:
for(int i = 0; i < Frame.teilesArray.size();i++){
if(Frame.teilesArray.get(i).getimgInt()== 0 || Frame.teilesArray.get(i).getimgInt()== 1){
if(bounding.intersects(Frame.teilesArray.get(i).getBounding())){
Rectangle intersection = (Rectangle) bounding.createIntersection(Frame.teilesArray.get(i).getBounding());
}
}
}
And this is how I try to solve but it doesn't work:
public void update() {
for(int i = 0; i < Frame.teilesArray.size();i++){ //teilesArray is a Array with all tiles from the map (every block has 64x64 px)
if(Frame.teilesArray.get(i).getimgInt()== 0 || Frame.teilesArray.get(i).getimgInt()== 1){ // means that only the two special blocks will check of collision not all blocks only this blocks
if(bounding.intersects(Frame.teilesArray.get(i).getBounding())){ // bounding is the rectangle of the Player and Frame.teilesArray.get(i).getBounding() is the rectangle of one block in the Array list
Rectangle intersection = (Rectangle) bounding.createIntersection(Frame.teilesArray.get(i).getBounding()); // made a new rectangle out off the intersection
if (bounding.OUT_TOP < Frame.teilesArray.get(i).getBounding().OUT_BOTTOM ) {
ply_y += intersection.getHeight();
}
if (bounding.OUT_LEFT < Frame.teilesArray.get(i).getBounding().OUT_RIGHT && richtung == 2) { //richtung links
ply_x += intersection.getWidth();
}
if (bounding.OUT_BOTTOM > Frame.teilesArray.get(i).getBounding().OUT_TOP ) {
ply_y -= intersection.getHeight();
}
if (bounding.OUT_RIGHT > Frame.teilesArray.get(i).getBounding().OUT_LEFT && richtung == 1) { //richtung rechts
ply_x -= intersection.getWidth();
}
}
}
}
the hole code:
package main;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Player {
private Rectangle bounding;
private float ply_x;
private float ply_y;
private float f_dx;
private float f_dy;
private float f_gravity;
private float f_counter;
private float neededTime;
private boolean b_air;
private boolean b_airimg;
private boolean letzterichtung;
private int richtung;
private BufferedImage playerImage;
private BufferedImage[] laufr;
private BufferedImage[] laufl;
public Player() {
laufr = new BufferedImage[3];
laufl = new BufferedImage[3];
ply_x = 0;
ply_y = 640;
f_counter = 0;
neededTime = 10;
f_dx = 5;
f_dy = -9;
f_gravity = 0.4f;
b_air = false;
b_airimg = false;
letzterichtung = true;
richtung = 0;
try {
playerImage = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic\\player1.png")).getSubimage(0, 0, 64, 64);
laufr[0] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic\\player1.png")).getSubimage(64, 0, 64, 64);
laufr[1] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic\\player1.png")).getSubimage(128, 0, 64, 64);
laufr[2] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic\\player1.png")).getSubimage(192, 0, 64, 64);
laufl[0] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic\\player1.png")).getSubimage(64, 64, 64, 64);
laufl[1] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic\\player1.png")).getSubimage(128, 64, 64, 64);
laufl[2] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic\\player1.png")).getSubimage(192, 64, 64, 64);
} catch (IOException e) {e.printStackTrace();}
bounding = new Rectangle((int) ply_x, (int) ply_y, playerImage.getWidth(), playerImage.getHeight());
}
#SuppressWarnings("static-access")
public void update() {
for(int i = 0; i < Frame.teilesArray.size();i++){ //teilesArray is a Array with all tiles from the map (every block has 64x64 px)
if(Frame.teilesArray.get(i).getimgInt()== 0 || Frame.teilesArray.get(i).getimgInt()== 1){ // means that only the two special blocks will check of collision not all blocks only this blocks
if(bounding.intersects(Frame.teilesArray.get(i).getBounding())){ // bounding is the rectangle of the Player and Frame.teilesArray.get(i).getBounding() is the rectangle of one block in the Array list
Rectangle intersection = (Rectangle) bounding.createIntersection(Frame.teilesArray.get(i).getBounding()); // made a new rectangle out off the intersection
// adding variables for the object the player can collide with
double minX = Frame.teilesArray.get(i).getBounding().getMinX();
double maxX = Frame.teilesArray.get(i).getBounding().getMaxX();
double minY = Frame.teilesArray.get(i).getBounding().getMinY();
double maxY = Frame.teilesArray.get(i).getBounding().getMaxY();
if (bounding.getMinY() < maxY && bounding.getMaxY() > minY ) {
// collision is vertical
if (bounding.getMaxY() > minY) {
System.out.println("Player auf Block: Block: MinX="+minX+", MaxX="+maxX+", MinY="+minY+", MaxY="+maxY+" | Playerrec: MinX="+bounding.getMinX()+", MaxX="+bounding.getMaxX()+", MinY="+bounding.getMinY()+", MaxY="+bounding.getMaxY()+" | Player: Ply_y="+ply_y +", Ply_x="+ply_x+" | Intersection Höhe="+intersection.getHeight());
// bottom of player has passed the top border of collision object, move up
ply_y -= intersection.getHeight();
bounding.x = (int) ply_x;
bounding.y = (int) ply_y;
} else {
System.out.println("Player unter Block: Block: MinX="+minX+", MaxX="+maxX+", MinY="+minY+", MaxY="+maxY+" | Playerrec: MinX="+bounding.getMinX()+", MaxX="+bounding.getMaxX()+", MinY="+bounding.getMinY()+", MaxY="+bounding.getMaxY()+" | Player: Ply_y="+ply_y +", Ply_x="+ply_x+" | Intersection Höhe="+intersection.getHeight());
// opposite case, move down
ply_y += intersection.getHeight();
bounding.x = (int) ply_x;
bounding.y = (int) ply_y;
}
}
if (bounding.getMinX() < maxX && bounding.getMaxX() > minX ) {
// collision is horizontal
if (bounding.getMaxX() > minX) {
System.out.println("Player Links von Block: Block: MinX="+minX+", MaxX="+maxX+", MinY="+minY+", MaxY="+maxY+" | Playerrec: MinX="+bounding.getMinX()+", MaxX="+bounding.getMaxX()+", MinY="+bounding.getMinY()+", MaxY="+bounding.getMaxY()+" | Player: Ply_y="+ply_y +", Ply_x="+ply_x+" | Intersection Breite="+intersection.getWidth());
// right border of player has passed the left border of collision object, move left
ply_x -= intersection.getWidth();
bounding.x = (int) ply_x;
bounding.y = (int) ply_y;
} else {
System.out.println("Player Rechts von Block: Block: MinX="+minX+", MaxX="+maxX+", MinY="+minY+", MaxY="+maxY+" | Playerrec: MinX="+bounding.getMinX()+", MaxX="+bounding.getMaxX()+", MinY="+bounding.getMinY()+", MaxY="+bounding.getMaxY()+" | Player: Ply_y="+ply_y +", Ply_x="+ply_x+" | Intersection Breite="+intersection.getWidth());
// opposite case, move right
ply_x += intersection.getWidth();
bounding.x = (int) ply_x;
bounding.y = (int) ply_y;
}
}
}
}
}
if(getBounding().x >= 400){
ply_x = 399;
}
if(getBounding().x <=0 ){
ply_x = 0;
}
if(keyCheck.keysCheck(KeyEvent.VK_A)){
ply_x -= f_dx;
if(b_air == false){
if(f_counter >= neededTime*1.5f){
f_counter = 0;
}
if(f_counter == 0) {
playerImage = laufl[0];
f_counter++;
}else if(f_counter == 5){
playerImage = laufl[1];
f_counter++;
}else if(f_counter == 10){
playerImage = laufl[2];
f_counter++;
}else {
f_counter++;
}
richtung = 2;
letzterichtung = false;
}
}
if(keyCheck.keysCheck(KeyEvent.VK_D)){
ply_x += f_dx;
if(b_air == false){
if(f_counter >= neededTime*1.5f){
f_counter = 0;
}
if(f_counter == 0) {
playerImage = laufr[0];
f_counter++;
}else if(f_counter == 5){
playerImage = laufr[1];
f_counter++;
}else if(f_counter == 10){
playerImage = laufr[2];
f_counter++;
}else {
f_counter++;
}
}
richtung = 1;
letzterichtung = true;
}
if(keyCheck.keysCheck(KeyEvent.VK_D)==false && keyCheck.keysCheck(KeyEvent.VK_A)==false){
if(richtung == 1 || letzterichtung == true && b_air == false && b_airimg ==false){
try {
playerImage = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic\\player1.png")).getSubimage(0, 0, 64, 64);
} catch (IOException e) {e.printStackTrace();}
}
else if(richtung == 2 || letzterichtung == false && b_air == false && b_airimg ==false){
try {
playerImage = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic\\player1.png")).getSubimage(0, 64, 64, 64);
} catch (IOException e) {e.printStackTrace();}
}
richtung = 0;
}
if(keyCheck.keysCheck(KeyEvent.VK_SPACE)){
b_air = true;
}
if(b_air ==true){
if(b_airimg == false){
if (letzterichtung == true)
{
try {
playerImage = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic\\player1.png")).getSubimage(256, 0, 64, 64);
} catch (IOException e) {e.printStackTrace();}
}else {
try {
playerImage = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic\\player1.png")).getSubimage(256, 64, 64, 64);
} catch (IOException e) {e.printStackTrace();}
}
b_airimg = true;
}
if(ply_y >= 646){
f_dy = -9;
b_air = false;
b_airimg = false;
}
f_dy += f_gravity;
ply_y += f_dy;
}
bounding.x = (int) ply_x;
bounding.y = (int) ply_y;
}
public Rectangle getBounding() {
return bounding;
}
public BufferedImage getPlayerimage() {
return playerImage;
}
public void setPlayerLocation(int ply_x, int ply_y){
this.ply_x = ply_x;
this.ply_y = ply_y;
bounding.x = (int) this.ply_x;
bounding.y = (int) this.ply_y;
System.out.println(""+this.ply_x+" "+this.ply_y);
}
}
Try this instead of your 4 if cases:
// adding variables for the object the player can collide with
double minX = Frame.teilesArray.get(i).getBounding().getMinX();
double maxX = Frame.teilesArray.get(i).getBounding().getMaxX();
double minY = Frame.teilesArray.get(i).getBounding().getMinY();
double maxY = Frame.teilesArray.get(i).getBounding().getMaxY();
if (bounding.getMinY() < maxY && bounding.getMaxY() > minY ) {
// collision is vertical
if (bounding.getMaxY() > minY) {
// bottom of player has passed the top border of collision object, move up
ply_y -= intersection.getHeight();
} else {
// opposite case, move down
ply_y += intersection.getHeight();
}
}
if (bounding.getMinX() < maxX && bounding.getMaxX() > minX ) {
// collision is horizontal
if (bounding.getMaxX() > minX) {
// right border of player has passed the left border of collision object, move left
ply_x -= intersection.getWidth();
} else {
// opposite case, move right
ply_x += intersection.getWidth();
}
}
I got a (to me, at least) very strange situation.
I am trying to rewrite snake, and moving is going very well, only the snake is eating itself, although I am removing 1 segment, and adding 1 (x + 1 - 1 = x?) but the snake disappears, while the Arraylist keeps the same size (printing it).
The function to calculate the position of the snake (I think that is causing it):
private void move() {
System.out.println(position.size());
Point toAdd = position.get(position.size() - 1);
position.remove(0);
if(dir == 1)
toAdd.y -= 5;
else if(dir == 2)
toAdd.x -= 5;
else if(dir == 3)
toAdd.x += 5;
else if(dir == 4)
toAdd.y += 5;
if(toAdd.x < 0) toAdd.x = 150;
else if(toAdd.x > 150) toAdd.x = 0;
if(toAdd.y < 0) toAdd.y = 150;
else if(toAdd.y > 150) toAdd.y = 0;
position.add(toAdd);
}
But, to make it a Short, Self Contained, Correct Example:
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.*;
import java.util.ArrayList;
class Snake extends JPanel implements Runnable {
int x,y;
boolean horizontal;
ArrayList<Point> position = new ArrayList<Point>();
byte dir = 3;
public Snake(JFrame parent) {
for(int i = 0; i < 5; i++)
position.add(new Point(i*5 + 10, 10));
parent.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
byte change = dir;
switch (e.getKeyCode()) {
case KeyEvent.VK_DOWN:
change = 4;
break;
case KeyEvent.VK_UP:
change = 1;
break;
case KeyEvent.VK_LEFT:
change = 2;
break;
case KeyEvent.VK_RIGHT:
change = 3;
break;
}
changeDirection(change);
}
});
System.out.println("starting thread");
new Thread(this).start();
}
private void changeDirection(byte change) {
if(change != dir && (change - 2 != dir || change + 2 != dir)) {
dir = change;
}
}
public void run() {
for(int i = 0; i != -1; i++){
try {
move();
this.repaint();
Thread.sleep(1000);
}
catch (InterruptedException e) {
System.out.println("INTERRUPTED");
}
}
}
private void move() {
System.out.println(position.size());
Point toAdd = position.get(position.size() - 1);
position.remove(0);
if(dir == 1)
toAdd.y -= 5;
else if(dir == 2)
toAdd.x -= 5;
else if(dir == 3)
toAdd.x += 5;
else if(dir == 4)
toAdd.y += 5;
if(toAdd.x < 0) toAdd.x = 150;
else if(toAdd.x > 150) toAdd.x = 0;
if(toAdd.y < 0) toAdd.y = 150;
else if(toAdd.y > 150) toAdd.y = 0;
position.add(toAdd);
}
public void paintComponent(Graphics g) {
g.clearRect(0,0,150,150);
for(Point p : position)
g.drawRect(p.x, p.y, 5, 5);
}
public static void main(String[] args) {
Snake snake;
JFrame f = new JFrame("Snake");
f.setSize(150, 150);
f.add((snake = new Snake(f)));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
f.setVisible(true);
}
}
Movement was the first thing I tried to implement, I have not yet come to collision-detection/food, that's not the question here.
My question is:
Why is the snake shrinking while the arraylist isn't and how can I fix it, i.e. stop the snake from disappearing except for the front segment?
Ok. This is simple!
You are changing point that is already in the list position and at the end you add the same point to this list. You end up with more and more the same (by reference) elements with same positions.
You should create new instance of Point and add it to the list.
Point lastPoint = position.get(position.size() - 1);
Point toAdd = new Point(lastPoint.x, lastPoint.y);
EDIT:
OH!!!!!
it works!!!
It seems that at one point it was fixed However the wrong HTML file was opening up so the wrong code was running. I feel stupid, that should have been obvious.
But THANKYOU!!!
Its so awesome to actually get some help with this stuff. whenever i ask for some help anywhere else or even ask my teacher im usually ignored or get useless advice.
(end of edit)
Im making a game for my final project in a java class. I just got mouse aiming to work using AffineTransform, however When ever the player object rotates to 90 degrees(or a multiple of it), it does this weird stutter thing.
Heres the code im specifically concerned with.
g2.drawImage(img, x_pos,y_pos,this);
AffineTransform oldTransform = g2.getTransform();
g2.setTransform(AffineTransform.getRotateInstance(radAngle,x_pos + (img.getWidth() / 2),y_pos+(img.getHeight() / 2)));
Could someone please help me figure out how to fix this? my project is due tomorrow so im slim on time.
Here are the images i use
Heres the code.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.lang.Math.*;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import javax.imageio.ImageIO;
import java.io.*;
import java.net.URL;
public class Game extends Applet implements Runnable, KeyListener, MouseMotionListener
{
int x_pos = 250;
int y_pos = 250;
float x_speed = 0;
float y_speed = 0;
int radius = 20;
int appletsize_x = 800;
int appletsize_y = 600;
int x = 0;
int y = 0;
int up = 0;
int down= 0;
int left = 0;
int right= 0;
int mouse_x;
int mouse_y;
int tracking_angle;
private BufferedImage dbImage;
private Graphics dbg;
private Image curser;
BufferedImage img = null;
BufferedImage round = null;
AffineTransform at = new AffineTransform();
double radAngle;
public void init()
{
try {
URL url = new URL(getCodeBase(), "Player.png");
img = ImageIO.read(url);
} catch (IOException e) {System.out.println("Cant find player image");
}
try {
URL url = new URL(getCodeBase(), "round.png");
round = ImageIO.read(url);}
catch (IOException e) {}
setBackground (Color.blue);
setFocusable(true);
addKeyListener( this );
curser = getImage(getDocumentBase(), "mouse.png");
addMouseMotionListener(this);
try
{
Toolkit tk = Toolkit.getDefaultToolkit();
Cursor c = tk.createCustomCursor( curser,new Point( 5, 5 ), "Inodrop" );
setCursor( c );
}
catch( IndexOutOfBoundsException x )
{}
}
public class Shot {
int x_loc = -50;
int y_loc = -50;
public Shot(){
if(x_loc < 0){
x_loc = x_pos;}
if(y_loc < 0){
y_loc = y_pos;}
paint(dbg);}
public void paint(Graphics g){
System.out.println("hi");
Graphics2D g2d = (Graphics2D)g;
Graphics g2D = round.getGraphics();
g2d.drawImage(round, x_loc,y_loc,null);}}
public void start ()
{
Thread th = new Thread (this);
th.start ();
}
public void stop()
{
}
public void destroy()
{
}
public void mouseMoved(MouseEvent e){
//get position of mouse
mouse_x = e.getX();
mouse_y = e.getY();
double x_dist = mouse_x - x_pos;
double y_dist = mouse_y - y_pos;
if (x_dist == 0) {
radAngle = 90;
} else if ((x_dist == 0) && (y_dist == 0)) {
radAngle = 0;
} else {
radAngle = Math.atan(y_dist / x_dist);
}
tracking_angle = (int)(Math.sin(radAngle) * 100);
//System.out.println(Math.toRadians(tracking_angle));
}
public void mouseDragged(MouseEvent e){}
public void keyReleased(KeyEvent r)
{
//Left
if (r.getKeyCode() == 39 ){
x = 0;
left = 0;
Shot shoot = new Shot();
}
//Right
if (r.getKeyCode() == 37){
x = 0;
right = 0;
}
//Down
if (r.getKeyCode() == 38 ) {
//y_speed = 0;
down = 0;}
//Up
if (r.getKeyCode() == 40 ) {
//y_speed = 0;
up = 0;}
//move();
}
public void keyTyped(KeyEvent t){}
public void keyPressed(KeyEvent r){
//Left
if (r.getKeyCode() == 39 ){
left = 1;}
//Right
if (r.getKeyCode() == 37){
right = 1;}
//Down
if (r.getKeyCode() == 38 ) {
down = 1;}
//Up
if (r.getKeyCode() == 40 ) {
up = 1;}
//move();
}
public void run ()
{
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
while (true)
{
if (left == 1 && x_speed < 11){
x = 0;
x_speed += 1;
}
//Right
if (right == 1 && x_speed > -11){
x = 0;
x_speed -= 1;
}
//Down
if (down == 1 && y_speed > -11) {
y_speed -= 1;}
//Up
if (up == 1 && y_speed < 11) {
y_speed += 1;}
if( x == 0 && x_speed > 0){
x_speed -=.2;}
if( x == 0 && x_speed < 0){
x_speed +=.2;}
if( y == 0 && y_speed > 0){
y_speed -=.2;}
if( y == 0 && y_speed < 0){
y_speed +=.2;}
if (x_pos > appletsize_x - radius && x_speed > 0)
{
x_pos = radius;
}
else if (x_pos < radius && x_speed < 0)
{
x_pos = appletsize_x + radius ;
}
//System.out.println(y_pos);
if (y_pos > appletsize_y - radius && y_speed > 0){
y_speed = 0;}
else if ( y_pos < radius && y_speed < 0 ){
y_speed = 0;}
x_pos += (int)x_speed;
y_pos += (int)y_speed;
repaint();
try
{
Thread.sleep (15);
}
catch (InterruptedException ex)
{
}
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
}
}
public void update (Graphics g)
{
if (dbImage == null)
{
dbImage = new BufferedImage(this.getSize().width, this.getSize().height, BufferedImage.TYPE_INT_RGB);
dbg = dbImage.getGraphics ();
}
dbg.setColor (getBackground ());
dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);
dbg.setColor (getForeground());
paint (dbg);
g.drawImage (dbImage, 0, 0, this);
}
public void paint (Graphics g)
{
//g = img.getGraphics();
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(img, x_pos,y_pos,this);
AffineTransform oldTransform = g2.getTransform();
g2.setTransform(AffineTransform.getRotateInstance(radAngle,x_pos + (img.getWidth() / 2),y_pos+(img.getHeight() / 2)));
System.out.println(img.getWidth());
}
}
double x_dist = mouse_x - x_pos;
double y_dist = mouse_y - y_pos;
double radAngle = Math.atan(y_dist / x_dist);
tracking_angle = (int) (Math.sin(radAngle) * 100);
I think the error is somewhere in this part. You're definitely dividing by 0 here if x_dist is 0. Better do something like this:
if (x_dist == 0) {
radAngle = 90;
} else {
radAngle = Math.atan(y_dist / x_dist);
}
EDIT: Additionally, I think you should throw away the tracking_angle line completely and just do this later:
g2.setTransform(AffineTransform.getRotateInstance(rad_angle,
x_pos + (img.getWidth() / 2),y_pos+(img.getHeight() / 2)));
Also you should change that new code you posted in the comments:
double radAngle;
if (x_dist == 0) {
radAngle = 90;
} else if (y_dist == 0) {
radAngle = 90;
} else {
radAngle = Math.atan(y_dist / x_dist);
}
You are solving this for x_dist == 0 or y_dist == 0 (which isn't an edge case), but not for the case that both are 0 where you simply can't compute an angle and I think you should go with 0. So use this instead:
double radAngle;
if (x_dist == 0) {
radAngle = 90;
} else if ((x_dist == 0) && (y_dist == 0)) {
radAngle = 0;
} else {
radAngle = Math.atan(y_dist / x_dist);
}
Also, as trashgod pointed out, you're ignoring exceptions, for example:
try {
URL url = new URL(getCodeBase(), "Player.png");
img = ImageIO.read(url);
} catch (IOException e) {
}
You should not just continue in such cases but f.e. display an useful error message and quit the program, in any case do something instead of just catching the exception and continue as if nothing happened.
I haven't tested this, but try:
double radAngle = Math.atan2(y_dist, x_dist);