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);
Related
So I made Pong in a applet for a project in school but I realized that I can't hand in the project without creating an HTML file, so I'm attempting to change all my code from a applet to a JFrame. It all works, but my paint method isn't being called, any help will be great. Thanks for the help but to be honest im new to programming so if someone could make the changes to my code and then explain what you did, that would be great
package pong;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
class Main extends JPanel implements Runnable, KeyListener{//whatever class holds you main method
private static final long serialVersionUID = 1L;
int width = 600;
int height = width *9/16;
int Pwidth = 10, Pheight = 50, Px = 30, Py = height / 2-Pwidth, Pv = 3;
int Ewidth = 10, Eheight = 50, Ex = width - Ewidth - 30, Ey = height / 2-Ewidth - 50;
double Ev = 2.7;
int Bwidth = 10, Bheight = 10, Bx = width / 2 + 50, By = height / 2, Bvx = 3, Bvy = 3;
int TimeD = 0;
int Ms = 0, sec = 0, min = 0;
int Pscore = 0, Escore = 0, Pwinx = 800, Pwiny = height / 2, Ewinx = 800, Ewiny = height / 2;
boolean Bleft = true, Bright = false, Bup = true, Bdown = false;
boolean Pup = false, Pdown = false;
boolean Pa = false;
String string = new String();
public static JFrame frame;//public and static so other classes can access it. Might want to use a getter and setter here
public Main(){
frame=new JFrame("Pong, A game re-made by Camron Warren");// Create new JFrame
frame.setSize(width,height);//Set the size of the window
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);//Make sure all processes are closed when the window is closed
frame.setLocationRelativeTo(null);//Centers window
frame.setVisible(true);//Make the window visible
Thread th = new Thread(this);
addKeyListener(this);
th.start();
}
public static void main(String[] args){
new Main();//instantiate the Main class, this has to happen
}
#Override
public void run() {
while(true){
if(Pscore >= 5){
Pwinx = 100;
Py = height / 2 - Pheight / 2;
Bx = width / 2 - Bwidth;
By = height /2 - Bheight /2;
}
if(Escore >= 5){
Ewinx = 400;
Py = height / 2-Pwidth;
Bx = width / 2 - Bwidth;
By = height /2;
}
if(Escore >= 5 && Pa == true){
Pscore = 0;
Escore = 0;
Ewinx = 800;
Ms = 0;
sec = 0;
min = 0;
}
if(Pscore >= 5 && Pa == true){
Pscore = 0;
Escore = 0;
Pwinx = 800;
Ms = 0;
sec = 0;
min = 0;
}
//ball movement class
ballMovement();
//TIME COUNTER
Ms++;
if(Ms >= 60){
sec++;
Ms = 0;
}
if(sec >= 60){
min++;
sec = 0;
}
//BALLMOVEMENT
if(Bleft == true){
Bx-=Bvx;
}
if(Bright == true){
Bx+=Bvx;
}
if(Bup == true){
By-=Bvy;
}
if(Bdown == true){
By+=Bvy;
}
//BALLHITBOX
if(By <= 0){
Bup = false;
Bdown = true;
}
if(By + Bheight >= height){
Bdown = false;
Bup = true;
}
//SCORE SYSTEM
if(Bx <= 0){
Escore++;
Bx = width / 2 - Bwidth;
By = height / 2;
}
if(Bx+Bwidth >= width){
Pscore++;
Bx = width /2 - Bwidth;
By = height / 2;
}
//PHITBOX
if(Bx+Bwidth >= Px && Bx <= Px+Pwidth && By+Bheight >= Py && By <= Py+Pheight){
System.out.println("Phit");
Bleft = false;
Bright = true;
}
//EHITBOX
if(Bx+Bwidth >= Ex && Bx <= Ex + Ewidth && By+Bheight >= Ey && By <= Ey + Eheight){
System.out.println("Ehit");
Bright = false;
Bleft = true;
}
//PMOVEMENT
if(Pup == true){
Py-=Pv;
}
if(Pdown == true){
Py+=Pv;
}
//PHITBOX/APPLETHITBOX
if(Py <= 0){
Py = 0;
}
if(Py + Pheight >= height){
Py = height - Pheight;
}
//EHITBOX/APPLETHITBOX
if(Ey <= 0){
Ey = 0;
}
if(Ey + Eheight >= height){
Ey = height - Eheight;
}
//REPAINT
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
public void ballMovement()
{
if(By >= Ey)
{
Ey += Ev;
}
if(By <= Ey)
{
Ey -= Ev;
}
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_W){
Pup = true;
}
if(key == KeyEvent.VK_S){
Pdown = true;
}
if(key == KeyEvent.VK_UP){
Pup = true;
}
if(key == KeyEvent.VK_DOWN){
Pdown = true;
}
if(key == KeyEvent.VK_F1){
Pa = true;
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_W){
Pup = false;
}
if(key == KeyEvent.VK_S){
Pdown = false;
}
if(key == KeyEvent.VK_UP){
Pup = false;
}
if(key == KeyEvent.VK_DOWN){
Pdown = false;
}
if(key == KeyEvent.VK_F1){
Pa = false;
}
}
#Override
public void keyTyped(KeyEvent arg0) {}
#SuppressWarnings("deprecation")
public void update(Graphics g) {
Graphics offgc;
Image offscreen = null;
Dimension d = size();
offscreen = createImage(d.width, d.height);
offgc = offscreen.getGraphics();
offgc.setColor(getBackground());
offgc.fillRect(0, 0, d.width, d.height);
offgc.setColor(getForeground());
paint(offgc);
g.drawImage(offscreen, 0, 0, this);
}
#Override
public void paint(Graphics g){
g.setColor(Color.green);
g.fillRect(Px, Py, Pwidth, Pheight);
g.setColor(Color.RED);
g.fillRect(Ex, Ey, Ewidth, Eheight);
g.setColor(Color.BLACK);
g.fillOval(Bx, By, Bwidth, Bheight);
g.setColor(Color.BLACK);
g.drawRect(0, 0, width - 1, height - 1);
g.drawString("Score: " + Pscore, 20, 20);
g.drawString("Score " + Escore , width - 60, 20);
g.drawString("Time played: " + min + ": " + sec, width / 2 - 50, 20);
g.setColor(Color.BLACK);
g.fillRect(width / 2, height, 1, height);
g.setColor(Color.BLACK);
g.drawLine(width / 2, 0, width / 2, height);
g.setColor(Color.BLACK);
g.drawString("Pong: a game re-made by Camron Warren", 10, height - 10);
g.drawString("Congrat's, you win!", Pwinx, Pwiny);
g.drawString("Press F1 to play again!", Pwinx, Pwiny + 10);
g.drawString("Enemy win's", Ewinx, Ewiny);
g.drawString("Press F1 to play again!", Ewinx, Ewiny + 10);
}
}
This is my game project. It's very simple version of "Flappy Bird" and I have some serious problems with how the collisions algorithm works. I wrote 2 separate code fragments for collision, for wall1 and wall2. The problem begins when the ball is trying to go through a hole because somehow the program is detecting a collision with a wall. I'm almost positive that the collision algorithm was written correctly because I have been checking it all day.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Game extends Applet implements KeyListener, Runnable {
Image bground;
Random generator = new Random();
int r1;
int wall1x;
int wall1y;
int wall1long;
int wall2x;
int wall2y;
int wall2long;
Timer timer;
private Image i;
private Graphics doubleG;
int r2;
int blok_x1 = 800;
int blok_y1;
int blok_x = 800;
int blok_y = 0;
int blok_x_v = 2;
int ballX = 20;
int ballY = 20;
int dx = 0;
int dyclimb = 1;
int dyrise = 1;
double gravity = 3;
double jumptime = 0;
int FPS = 100;
public int tab[];
public boolean grounded = true, up = false;
boolean OVER = false;
#Override
public void init() {
bground = getImage(getCodeBase(), "12.png");
this.setSize(600, 400);
tab = new int[100];
for (int t = 0; t < 100; t++) {
tab[t] = generator.nextInt(380) + 1;
}
addKeyListener(this);
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
ballX -= 10;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
ballX += 10;
}
if (e.getKeyCode() == KeyEvent.VK_UP) {
ballY -= 10;
up = true;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
ballY += 10;
}
}
#Override
public void paint(Graphics g) {
g.drawImage(bground, 0, 0, this);
if (OVER == false) {
for (int i = 0; i < 100; i++) {
g.setColor(Color.green);
wall1x = blok_x + i * 400;
wall1y = blok_y;
wall1long = tab[i];
g.fillRect(wall1x, wall1y, 20, wall1long);
g.setColor(Color.green);
wall2x = blok_x1 + i * 400;
wall2y = tab[i] + 60;
wall2long = 400 - tab[i];
g.fillRect(wall2x, wall2y, 20, wall2long);
g.setColor(Color.green);
}
g.setColor(Color.red);
g.fillOval(ballX, ballY, 20, 20);
} else {
g.drawString("GAME OVER", 300, 300);
}
}
#Override
public void update(Graphics g) {
if (i == null) {
g.setColor(Color.green);
i = createImage(this.getSize().width, this.getSize().height);
doubleG = i.getGraphics();
g.setColor(Color.green);
}
doubleG.setColor(getBackground());
g.setColor(Color.green);
doubleG.fillRect(0, 0, this.getSize().width, this.getSize().height);
doubleG.setColor(getForeground());
g.setColor(Color.green);
paint(doubleG);
g.drawImage(i, 0, 0, this);
}
#Override
public void run() {
int time = 10;
while (true) {
if (up == true) {
ballY -= dyclimb;
time--;
} else {
ballY += dyrise;
}
if (time == 0) {
time = 10;
up = false;
}
blok_x--;
blok_x1--;
if (ballX > 600 || ballX < 0 || ballY > 400 || ballY < 0) {
OVER = true;
}
for (int i = 0; i < 100; i++) { // collision algorithm
wall1x = blok_x + i * 400;
wall1y = blok_y;
wall1long = tab[i];
if (ballX + 20 >= wall1x && ballX <= wall1x + 20 && ballY <= wall1y + wall1long && ballY >= wall1x - 20) { //wall1
OVER = true;
}
}
for (int i = 0; i < 100; i++) {
wall2x = blok_x1 + i * 400;
wall2y = tab[i] + 60;
wall2long = 400 - tab[i];
if (ballX + 20 >= wall2x && ballX <= wall2x + 20 && ballY <= wall2y + wall2long && ballY >= wall2x - 20) { //wall2
OVER = true;
}
}
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException ex) {
Logger.getLogger(NewApplet.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
#Override
public void start() {
Thread thread = new Thread(this);
thread.start();
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
}
Use Rectangle class. There's a method called Intersect or Intersection or something like that.
Say you have one object moving. Make a Rectangle to match the object in position(basically an invisible cover for the object).
Do the same things with another object.
When both are to collide, use the intersection method to check on the collision by using the rectangles.
These might help
http://docs.oracle.com/javase/7/docs/api/java/awt/Rectangle.html
Java method to find the rectangle that is the intersection of two rectangles using only left bottom point, width and height?
java.awt.Rectangle. intersection()
I'm looking for help in finding the source of jitter when using collision detection.
I've implemented a java game (using eclipse and slick2d) and have been loosely following this guide:
http://katyscode.wordpress.com/2013/01/18/2d-platform-games-collision-detection-for-dummies
but of course changing bits where necessary to suit my game and java not cpp.
From the research I have done I think the root cause of my jitter is coming from rounding errors.
Despite that being my main suspect, I still haven't been able to identify where it's occurring.
Sorry if the indentation isn't quite right there, had a little trouble using the code block recognition.
Basically I'm creating variables in the class.
In init() I set up most of the resources.
In render() all the drawing takes place. Note the graphics translation so the camera follows the player.
In update I'm of course updating the position of the player according to user input, gravity and friction.
I also call my collision detection from this method.
Collision detection is working on a penetration resolution method.
(Yes I know I'm exhaustively comparing with every single world object. I will be improving my efficiency with AABB's when I have sorted more fundamental problems out. Like jitter!)
My method first calculates how much the player expects to move in each axis, then for each world object it checks for intersection with the players bounding points (floating point values that represent coordinates around the player). It checks this in each direction and uses the result to determine in which axis the collision occurred, if any, so that the appropriate action can be taken.
Sorry it's a put load of code, but it's collision detection after all, which isn't a small thing.
Here is my Play class where all the updating goes on for the game:
package GameFiles;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.newdawn.slick.*;
import org.newdawn.slick.state.*;
import java.awt.Rectangle;
//import java.awt.geom.Rectangle2D;
public class Play extends BasicGameState{
static int tileSize = 32;
File levelMap;
SpriteSheet spriteSheet;
int[][] currentMap;
Image[] groundTiles = new Image[4];
//List<Rectangle2D> levelBounds = new ArrayList<Rectangle2D>();
List<Rectangle> levelBounds = new ArrayList<Rectangle>();
Player player;
float playerX, playerY;
int dir;
float acc, mov, friction, gravity;
float runSpeed;
float maxAcc;
boolean inAir, jumping, keyDown;
boolean exitFlag;
int mapHeight, mapWidth;
float mapX, mapY;
float speedX, speedY;
int worldObjectCount;
int iterations;
public Play(int state){
}
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException{
playerX = Game.scrWidth/2;
playerY = Game.scrHeight - tileSize - tileSize;
player = new Player(playerX, playerY);
levelMap = new File("maps/lvl1.txt");
spriteSheet = new SpriteSheet("res/tiles/tilesets/DungeonCrawlTilesetBW.png", tileSize, tileSize);
try
{
currentMap = readMap(levelMap);
}
catch (IOException e)
{
System.out.println("Array size mismatch when copying arrays.");
e.printStackTrace();
}
levelBounds.clear();
for(int x = 0; x < mapWidth; x++)
{
for(int y = 0; y < mapHeight; y++){
if(currentMap[x][y] == 1){
levelBounds.add(new Rectangle(x*tileSize, Game.scrHeight - mapHeight*tileSize + y*tileSize, tileSize, tileSize));
//levelBounds.add(new Rectangle2D.Float(x*tileSize, Game.scrHeight - mapHeight*tileSize + y*tileSize, tileSize, tileSize));
System.out.println("Added new bounding box: " + (x*tileSize) + ", " + (Game.scrHeight - mapHeight*tileSize + y*tileSize) + ", " + tileSize);
}
}
}
worldObjectCount = levelBounds.size();
System.out.println("World object count: " + worldObjectCount);
groundTiles[0] = spriteSheet.getSubImage(4, 16);
groundTiles[1] = spriteSheet.getSubImage(13, 19);
dir = 1;
acc = 0.0f;
mov = 0.0f;
friction = 4f;
gravity = 4f;
runSpeed = 0.6f;
maxAcc = -1f;
inAir = false;
jumping = false;
keyDown = false;
exitFlag = false;
speedX = 0.0f;
speedY = 0.0f;
iterations = 3;
}
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
//determine cameraX and cameraY
float cameraX, cameraY;
cameraX = player.getX() - Game.scrWidth/2;
cameraY = player.getY() - (Game.scrHeight/2 - tileSize - tileSize);
g.translate(-cameraX, -cameraY);
player.render(g);
for(int x = 0; x < mapWidth; x++)
{
for(int y = 0; y < mapHeight; y++){
if(currentMap[x][y] == 1){
groundTiles[0].draw(x*tileSize, Game.scrHeight - mapHeight*tileSize + y*tileSize);
}
}
}
g.translate(cameraX, cameraY);
}
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException{
Input input = gc.getInput();
float secondsElapsed = delta/1000.0f;
checkCollisions(secondsElapsed);
player.setX((player.getX() + speedX));
player.setY((player.getY() - speedY));
//check inputs
checkKeyEvents(input);
//slow down / friction
if(!keyDown){
if(mov < 0)
mov += friction * secondsElapsed;
else
mov -= friction * secondsElapsed;
}
speedX = mov;
if (speedX > 0 && speedX < friction * secondsElapsed) speedX = 0;
if (speedX < 0 && speedX > -friction * secondsElapsed) speedX = 0;
//jump or fall
acc -= gravity * secondsElapsed;
if (acc < maxAcc){
acc = maxAcc;
}
speedY = acc;
//exit when exitFlag true
if(exitFlag){
gc.exit();
}
}
public void checkCollisions(float secondsElapsed){
boolean contactX = true, contactYbottom = true, contactYtop = true;
// Keep iterating the contact solver until the maximum number of iterations is reached
// or no collisions are detected
for (int iteration = 0; iteration < iterations && (contactX || contactYbottom || contactYtop); iteration++)
{
float nextMoveX = speedX * secondsElapsed;
float nextMoveY = speedY * secondsElapsed;
contactX = contactYbottom = contactYtop = false;
float projectedMoveX, projectedMoveY, originalMoveX, originalMoveY;
originalMoveX = nextMoveX;
originalMoveY = nextMoveY;
for (int o = 0; o < worldObjectCount && !contactX && !contactYbottom && !contactYtop; o++)
{
for (int dir = 0; dir < 6; dir++)
{
//top, bottom, left, left, right, right.
if (dir == 0 && nextMoveY < 0) continue;
if (dir == 1 && nextMoveY > 0) continue;
if (dir == 2 && nextMoveX > 0) continue;
if (dir == 3 && nextMoveX > 0) continue;
if (dir == 4 && nextMoveX < 0) continue;
if (dir == 5 && nextMoveX < 0) continue;
projectedMoveX = (dir >= 2? nextMoveX : 0);
projectedMoveY = (dir < 2? nextMoveY : 0);
float[][] collisionPoint = player.getBounds();
Rectangle curRect = new Rectangle(levelBounds.get(o).x, levelBounds.get(o).y, levelBounds.get(o).width, levelBounds.get(o).height);
//Rectangle2D curRect = levelBounds.get(o).getBounds2D();
while (curRect.contains(collisionPoint[dir][0] + projectedMoveX, collisionPoint[dir][1] + projectedMoveY)
|| curRect.intersects(collisionPoint[dir][0] + projectedMoveX, collisionPoint[dir][1] + projectedMoveY, 1, 1))
{
if (dir == 0) projectedMoveY += 0.05f; //top collision
if (dir == 1) projectedMoveY -= 0.05f; //bottom collision
if (dir == 2) projectedMoveX += 0.05f; //left collision
if (dir == 3) projectedMoveX += 0.05f;
if (dir == 4) projectedMoveX -= 0.05f; //right collision
if (dir == 5) projectedMoveX -= 0.05f;
}
if (dir >= 2 && dir <= 5)
nextMoveX = projectedMoveX;
if (dir >= 0 && dir <= 1)
nextMoveY = projectedMoveY;
}
if (nextMoveY > originalMoveY && originalMoveY != 0)
{
contactYtop = true;
}
if (nextMoveY < originalMoveY && originalMoveY != 0)
{
contactYbottom = true;
}
if (Math.abs(nextMoveX - originalMoveX) > 0.01f)
{
contactX = true;
}
if (contactX && contactYtop && speedY > 0)
speedY = nextMoveY = 0;
}
if (contactYbottom || contactYtop)
{
player.setY(player.getY() + nextMoveY);
speedY = 0;
acc = 0;
if (contactYbottom)
jumping = false;
}
if (contactX)
{
player.setX(player.getX() + nextMoveX);
speedX = 0;
mov = 0;
}
}//end collisions
}
public int[][] readMap(File level) throws IOException, SlickException{
BufferedReader br = new BufferedReader(new FileReader(level));
mapWidth = Integer.parseInt(br.readLine());
mapHeight = Integer.parseInt(br.readLine());
int[][] map = new int[mapWidth][mapHeight];
for(int row = 0; row < mapHeight; row++)
{
String line = br.readLine();
if(line == null || line.isEmpty())
{
System.out.println("Line is empty or null");
}
else
{
String[] tileValues = line.split(",");
for(int col = 0; col < mapWidth; col++)
{
map[col][row] = Integer.parseInt(tileValues[col]);
}
}
}
br.close();
return map;
}
public void checkKeyEvents(Input input){
//key input events
if(input.isKeyPressed(Input.KEY_DOWN)){
}
if(input.isKeyPressed(Input.KEY_UP)){
if(!jumping){
acc = 1f;
}
jumping = true;
}
if(input.isKeyDown(Input.KEY_LEFT) && !input.isKeyDown(Input.KEY_RIGHT)){
keyDown = false;
mov -= 0.006f;
if (mov < -runSpeed){
mov = -runSpeed;
}
}
if(input.isKeyDown(Input.KEY_RIGHT) && !input.isKeyDown(Input.KEY_LEFT)){
keyDown = false;
mov += 0.006f;
if (mov > runSpeed){
mov = runSpeed;
}
}
if(input.isKeyPressed(Input.KEY_ESCAPE)){
exitFlag = true;
}
}
public int getID(){
return 1;
}
}
Since I can't predict what more info a potential helper might need, I'll leave it at that for now, but of course I can provide any more info when/where needed.
Thanks,
J.
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 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.