Trying to move a quad/square with the mouse - LWJGL - java

Im trying to make a square follow my mouse after i left click on it . When i right click the square should stop following my mouse .
My program detects that im clicking inside the square , but for some reason it doesn't update its position based on Mouse.getDX/DY .
import static org.lwjgl.opengl.GL11.*;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
public class SimpleOGLRenderer {
private static boolean somethingIsSelected = false;
public static void main(String args[]) {
try {
Display.setDisplayMode(new DisplayMode(800,600));
Display.setTitle("Hello World");
Display.create();
} catch (LWJGLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Initializare OPENGL
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 800, 600, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
while(!Display.isCloseRequested())
{
//Render
glClear(GL_COLOR_BUFFER_BIT);
Box box = new Box(100,100);
if(Mouse.isButtonDown(0) && box.inBounds(Mouse.getX(), Display.getHeight()-Mouse.getY()-1) && !somethingIsSelected)
{
System.out.println("Box clicked");
somethingIsSelected = true;
box.selected = true;
}
if(Mouse.isButtonDown(1))
{
box.selected = false;
somethingIsSelected = false;
System.out.println("Box released");
}
if(box.selected)
{
box.update(Mouse.getDX(), -Mouse.getDY());
}
box.drawQuad();
Display.update();
// Display.sync(60);
}
Display.destroy();
}
private static class Box{
public int x, y;
public boolean selected=false;
Box(int x, int y) {
this.x = x;
this.y = y;
}
void drawQuad()
{
glBegin(GL_QUADS);
glVertex2i(x,y);
glVertex2i(x+50,y);
glVertex2i(x+50,y+50);
glVertex2i(x,y+50);
glEnd();
}
void update(int dx,int dy)
{
x = x + dx;
y = y + dy;
}
boolean inBounds(int mouseX, int mouseY) {
return mouseX > x && mouseX < x + 50 && mouseY > y && mouseY < y + 50;
}
}
}

The program works fine and the Box does update!
The problem lies in where you create the Box.
while(!Display.isCloseRequested())
{
//Render
glClear(GL_COLOR_BUFFER_BIT);
Box box = new Box(100,100);
...
See, you create the Box inside the main-loop, therefore it gets deleted and initialized each time it loops. Simply move it outside the loop, so it doesn't get initialized at every loop, like this.
Box box = new Box(100,100);
while(!Display.isCloseRequested())
{
//Render
glClear(GL_COLOR_BUFFER_BIT);
...

Related

how to Rotate only one object by using glrotate in java

I am trying to rotate only one square but it did not work it rotates all of them
in this code when I click N it creates a new square and pushes it in the array I want when I click R to
rotates specific square not all of them
when I search on google I found that glrotate move all the objects created after the calling and I did
know if it is right
package assignment;
import static org.lwjgl.opengl.GL11.*;
import java.util.ArrayList;
import java.util.Random;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
public class input {
private static final ArrayList<Square> shapes = new ArrayList<Square>();
private static boolean thingselected=false;
private static boolean flag=true;
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
Display.setDisplayMode(new DisplayMode(640, 480));
Display.setTitle("Input Demo");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
Display.destroy();
System.exit(1);
}
glMatrixMode(GL_PROJECTION);
glOrtho(0, 640, 480, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
shapes.add(new Square(20,20));
while (!Display.isCloseRequested()) {
glClear(GL_COLOR_BUFFER_BIT);
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
Display.destroy();
System.exit(0);
}
while(Keyboard.next()) {
if(Keyboard.getEventKey()==Keyboard.KEY_N && Keyboard.getEventKeyState()) {
shapes.add(new Square(15,15));
}
}
for (final Square square:shapes) {
System.out.println(square.rotated);
if(Mouse.isButtonDown(0) && square.ismoved(Mouse.getX(),480-`Mouse.getY())&&!thingselected) {`
square.selected=true;
thingselected=true;
}
if(square.selected) {
square.update(Mouse.getDX(), -Mouse.getDY());
}
if(Mouse.isButtonDown(1) ) {
square.selected=false;
thingselected=false;
}
if(Keyboard.isKeyDown(Keyboard.KEY_C)&&square.ismoved(Mouse.getX(),480-Mouse.getY())&&!thingselected ) {
square.changeColor();
}
if(Keyboard.getEventKey() == Keyboard.KEY_R && square.ismoved(Mouse.getX(),480-Mouse.getY())){
if(flag)
square.rotated=true;
if(square.rotated)
{
square.rotate();
}
flag = false;
}
if(Keyboard.getEventKey() == Keyboard.KEY_T) {
square.transelate();
}
square.draw();
}
Display.update();
Display.sync(60);
}
Display.destroy();
}
private static class Square{
public int x,y;
private float red,green,blue;
public boolean selected=false;
public boolean rotated=false;
Square(int x, int y){
this.x=x;
this.y=y;
Random random=new Random();
red=random.nextFloat();
green=random.nextFloat();
blue=random.nextFloat();
}
void draw() {
glColor3f(red, green, blue);
glBegin(GL_QUADS);
glVertex2f(x, y);
glVertex2f(x+50, y);
glVertex2f(x+50, y+50);
glVertex2f(x, y+50);
glEnd();
}
boolean ismoved(int mousex,int mousey) {
return mousex > x && mousex < x+50 && mousey > y && mousey < y+50;
}
void update(double dx,double dy) {
x+=dx;
y+=dy;
}
void changeColor() {
Random random=new Random();
red=random.nextFloat();
green=random.nextFloat();
blue=random.nextFloat();
}
void transelate() {
glTranslated(0.1, 0, 0);
}
void rotate() {
glRotated(0.1, 0, 0, 1);
}
}
glRotate and glTranslate manipulate the current matrix. You have to do the rotation and translation before drawing the object. Use glPushMatrix and glPopMatrix (see glPushMatrix / glPopMatrix) to save the current matrix on the matrix stack before changing it and to restore it after the object is drawn.
Add variables for the rotation and translation and change them in translate an roatate. Use the variables in draw:
private static class Square {
private double translateX, angleZ;
// [...]
void draw() {
glPushMatrix();
glTranslated(translateX, 0, 0);
glRotated(angleZ, 0, 0, 1);
glColor3f(red, green, blue);
glBegin(GL_QUADS);
glVertex2f(x, y);
glVertex2f(x+50, y);
glVertex2f(x+50, y+50);
glVertex2f(x, y+50);
glEnd();
glPopMatrix();
}
void transelate() {
translateX += 0.1;
}
void rotate() {
angleZ += 0.1;
}
}

Error: Main method not found

Error: main method not found in class essence.Game, please define the main method as: public static void main(String[] args)
The code:
package essence;
import static org.lwjgl.opengl.GL11.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
import org.lwjgl.input.*;
import org.lwjgl.opengl.*;
import org.lwjgl.*;
public class Game{
List<Box> shapes = new ArrayList<Box>(16);
public Game(){
try {
Display.setDisplayMode(new DisplayMode(800,600));
Display.setTitle("Essence");
Display.create();
} catch (LWJGLException e){
e.printStackTrace();
}
shapes.add(new Box(15, 15));
shapes.add(new Box(100, 150));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 800, 600, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
while(!Display.isCloseRequested()){
glClear(GL_COLOR_BUFFER_BIT);
if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
Display.destroy();
System.exit(0);
}
for (Box box : shapes) {
box.draw();
}
Display.update();
Display.sync(60);
}
Display.destroy();
}
private static class Box {
public boolean selected = false;
public int x, y;
private float colorRed, colorBlue, colorGreen;
Box (int x, int y){
this.x = x;
this.y = y;
Random randomGenerator = new Random();
colorRed = randomGenerator.nextFloat();
colorBlue = randomGenerator.nextFloat();
colorGreen = randomGenerator.nextFloat();
}
boolean inBounds(int mouseX, int mouseY){
if(mouseX > x && mouseX < x + 50 && mouseY > y && mouseY < y + 50)
return true;
else
return false;
}
void randomizeColors(){
Random randomGenerator = new Random();
colorRed = randomGenerator.nextFloat();
colorBlue = randomGenerator.nextFloat();
colorGreen = randomGenerator.nextFloat();
}
void update(int dx, int dy){
x += dx;
y += dy;
}
void draw(){
glColor3f(colorRed, colorGreen, colorBlue);
glBegin(GL_QUADS);
glVertex2f(x, y);
glVertex2f(x + 50, y);
glVertex2f(x + 50, y + 50);
glVertex2f(x, y + 50);
glEnd();
}
}
public static void main(String[] args) {
new Game();
}
}
Now let's say I change it to:
package essence;
public class Game{
public static void main(String[] args) {
}
}
It will still give the same error. I checked the folder layout, but I confirmed that its Eclipse\Data\workspace\Essence\src\essence and Eclipse\Data\workspace\Essence\bin\essence
It cannot be my Java installation, because all my other projects work fine. Here's a screenshot of the project within Eclipse:
http://gyazo.com/296d53b33fa2619ca300c8a896d097dc
What could be the cause of this error and the way to fix it?
It happens to me as well. Restarting the Compiler fix the problem. For Example, If you are running Eclipse, just restart Eclipse.

Sliding a little bit after stopping

Remember playing Super Mario Bros.? When Mario moves, he runs, and then when the player stops moving, he stops, but he doesn't come to a complete stop. He slides a little bit. I need to accomplish that. Over the past 2 days, I've been completely rewriting the movement my Mario clone/platformer game, because the model I had before was inefficient and just crappy overall. Right now, I'm not sure how to continue that small bit of velocity so that the stop isn't so sudden. How would I accomplish this? All the code for movement below is in the Player class and the code for controls is in the Main class. So what can I do to detect when the player stops, and use that to add just a little bit of velocity?
Main:
import com.hasherr.platformer.entity.Player;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import static org.lwjgl.opengl.GL11.*;
public class Main {
private void display() {
try {
Display.setDisplayMode(new DisplayMode(1000, 550));
Display.setTitle("Unnamed Platformer Game");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
// OpenGL
while (!Display.isCloseRequested()) {
Display.update();
Display.sync(60); // sync to 60 fps
initGL();
player.update();
handleKeyboardInput();
}
Display.destroy();
}
private boolean keyboardInUse() {
boolean keyboardInUse;
if (!(Keyboard.isKeyDown(Keyboard.KEY_A)
|| Keyboard.isKeyDown(Keyboard.KEY_D) || Keyboard
.isKeyDown(Keyboard.KEY_SPACE))) {
keyboardInUse = false;
} else {
keyboardInUse = true;
}
return keyboardInUse;
}
private void handleKeyboardInput() {
if (!keyboardInUse()) {
player.goingLeft = false;
player.goingRight = false;
player.resetVelocity();
}
if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
player.goingLeft = false;
player.goingRight = true;
player.moveRight();
} else if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
player.goingLeft = true;
player.goingRight = false;
player.moveLeft();
} else if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {
player.jump();
}
}
private void initGL() {
// initial OpenGL items for 2D rendering
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho(0, 1000, 0, 550, 1, -1);
// start rendering player image
player.grabTexture().bind();
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(player.xPos, player.yPos);
glTexCoord2f(1, 0);
glVertex2f(player.xPos + 150, player.yPos);
glTexCoord2f(1, 1);
glVertex2f(player.xPos + 150, player.yPos + 150);
glTexCoord2f(0, 1);
glVertex2f(player.xPos, player.yPos + 150);
glEnd(); // stop rendering this image
}
Player player = new Player();
public static void main(String[] args) {
Main main = new Main();
main.display();
}
}
Player:
import java.io.IOException;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;
public class Player {
public Texture playerTexture;
// Positions & speed
public float xPos = 20.0f; // This is initial
public float yPos = 0.0f; // Same as above.
public float xVel, yVel;
public static int gravityForce = 6;
public static int jumpVelocity = 100;
private float moveSpeed = 8.0f;
private static int MAX_MOVE_SPEED = 25;
public boolean isSupported = true; // Once again, initial value.
public boolean goingRight, goingLeft, canJump;
// movement methods & constants
public void update() {
applyGravity();
checkForSupport();
}
public Texture grabTexture() {
try {
playerTexture = TextureLoader.getTexture("PNG",
ResourceLoader.getResourceAsStream("res/test_char.png"));
} catch (IOException e) {
e.printStackTrace();
}
return playerTexture;
}
private void checkForSupport() {
if (yPos == 0) {
isSupported = true;
} else if (yPos > 0 /* and is not on a platform */) {
isSupported = false;
}
}
private void applyGravity() {
if (!isSupported) {
yPos -= gravityForce;
}
}
public void printPos(String moveMethod) {
System.out.println(" X: " + xPos + " Y: " + yPos + " Going Right: "
+ goingRight + " Going Left: " + goingLeft);
}
// movement methods
public void resetVelocity() {
moveSpeed = 15;
}
private void accelerateX() {
moveSpeed += (float) (moveSpeed * 0.0096);
if (moveSpeed >= MAX_MOVE_SPEED) {
moveSpeed = MAX_MOVE_SPEED;
}
System.out.println(moveSpeed);
}
private void accelerateY() {
}
public void moveRight() {
printPos("Moving Right!");
accelerateX();
xPos += moveSpeed;
}
public void moveLeft() {
printPos("Moving Left!");
accelerateX();
xPos -= moveSpeed;
}
public void jump() {
printPos("Jumping!");
accelerateY();
yPos += jumpVelocity;
}
}
Every update decrement Mario's velocity, and move mario's position by his velocity.
You should be allowing his velocity to persist across multiple updates. Currently you're only moving mario when a left or right arrow key is depressed. This is a fine approach, and works for some games, but now that you're wanting more physical behavior a new approach is necessary. Time to conserve some energy!
Try this instead:
float acceleration = 15;
private void accelerateX(float speed) {
moveSpeed += (float) (speed * 0.0096);
if (moveSpeed >= MAX_MOVE_SPEED) {
moveSpeed = MAX_MOVE_SPEED;
}else if(moveSpeed<=-MAX_MOVE_SPEED){ moveSpeed= - MAX_MOVE_SPEED;}
}
public void moveRight() {
printPos("Moving Right!");
accelerateX(acceleration);
}
public void moveLeft() {
printPos("Moving Left!");
accelerateX(-acceleration);
}
//call this every update.
public void update(){
float minMoveSpeed = 1;
//snap to zero movement if movespeed is too slow.
//this is so the player actually stops moving eventually. otherwise
//the dampening affect would constantly shift the player to and fro.
if(this.moveSpeed<minMoveSpeed && this.moveSpeed>-minMoveSpeed){
this.moveSpeed = 0;
}
else{
float dampening = 1f;
//Counter velocity. this will bring mario to a halt over a number of updates
//play with the value of dampening to get right effect.
double sign = -(int)Math.signum(moveSpeed);
float dampeningValue = dampening*sign;
this.moveSpeed += dampeningValue;
}
xPos+= this.moveSpeed;
}
This code allows his velocity to persist across updates and slowing brings Mario to a stop if velocity isn't being incremented/decremented by moveRight/moveLeft.
Also you should be scaling your velocity by time so the game runs similarly on different hardware. This is less important at this point in development; just keep it in mind for the future.

Java Applet Game 2D Window Scrolling

I'm trying to develop a 2D RPG Game in a Java Applet. Right now I've got a simple oval that the player can use Left, Right, Up and Down to move, and collisions against the borders of the applet stops them. The problem is, I want to create a giant world(2000px by 2000x) of area that the player can move. However, I want them only to see 600px by 400x of the screen at one time. If they keep moving right, I want the screen to follow them, same goes for up, down and left. Can anyone tell me how to do this? Here is my code so far:
import java.awt.*;
import java.awt.event.KeyEvent;
import java.applet.Applet;
import java.awt.event.KeyListener;
import javax.swing.*;
public class Main extends Applet implements Runnable, KeyListener
{
private Image dbImage;
private Graphics dbg;
Thread t1;
int x = 0;
int y = 0;
int prevX = x;
int prevY = y;
int radius = 40;
boolean keyReleased = false;
public void init()
{
setSize(600, 400);
}
public void start()
{
addKeyListener(this);
t1 = new Thread(this);
t1.start();
}
public void destroy()
{
}
public void stop()
{
}
public void paint(Graphics g)
{
//player
g.setColor(Color.RED);
g.fillOval(x, y, radius, radius);
}
public void update(Graphics g)
{
dbImage = createImage (this.getSize().width, this.getSize().height);
dbg = dbImage.getGraphics();
// initialize buffer
if (dbImage == null)
{
}
// clear screen in background
dbg.setColor(getBackground());
dbg.fillRect(0, 0, this.getSize().width, this.getSize().height);
// draw elements in background
dbg.setColor(getForeground());
paint(dbg);
// draw image on the screen
g.drawImage(dbImage, 0, 0, this);
}
#Override
public void run()
{
while (true)
{
//x++;
repaint();
try
{
t1.sleep(17);
}
catch (Exception e)
{
}
}
}
public boolean CheckCollision(String dir)
{
if (x <= 0 && dir.equals("L"))
{
x = prevX;
return true;
}
else if (y <= 0 && dir.equals("U"))
{
y = prevY;
return true;
}
else if (x >= (getWidth() - radius) && dir.equals("R"))
{
System.out.println(getWidth());
x = prevX;
return true;
}
else if (y >= (getHeight() - radius) && dir.equals("D"))
{
y = prevY;
return true;
}
return false;
}
#Override
public void keyPressed(KeyEvent e)
{
switch (e.getKeyCode())
{
case KeyEvent.VK_RIGHT:
if (!CheckCollision("R"))
{
x += 4;
prevX = x;
}
break;
case KeyEvent.VK_LEFT:
if (!CheckCollision("L"))
{
x -= 4;
prevX = x;
}
break;
case KeyEvent.VK_UP:
if (!CheckCollision("U"))
{
y -= 4;
prevY = y;
}
break;
case KeyEvent.VK_DOWN:
if (!CheckCollision("D"))
{
y += 4;
prevY = y;
}
break;
}
}
#Override
public void keyReleased(KeyEvent arg0)
{
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0)
{
// TODO Auto-generated method stub
}
}
This is a basic example of scrolling viewable area, where the virtual world is large then the view area.
This basically maintains a number of parameters. It maintains the point where in the world the top/left of the view is and the players position within the world.
These values are converted back to real world coordinates (where 0x0 is the top left corner of the viewable area).
The examples also use BufferedImage#getSubImage to make it easier to render. You could calculate the offset position of the map to the view as well, but that comes down to needs...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MiddleEarth {
public static void main(String[] args) {
new MiddleEarth();
}
public MiddleEarth() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new WorldPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class WorldPane extends JPanel {
private BufferedImage map;
private BufferedImage party;
private Point viewPort;
private Point partyPoint;
private BufferedImage view;
public WorldPane() {
try {
map = ImageIO.read(getClass().getResource("/MiddleEarth.jpg"));
party = ImageIO.read(getClass().getResource("/8BitFrodo.png"));
viewPort = new Point(0, (map.getHeight() / 2) - 100);
partyPoint = new Point(party.getWidth() / 2, (map.getHeight() / 2)); // Virtual Point...
} catch (IOException exp) {
exp.printStackTrace();
}
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "goRight");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "goLeft");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "goUp");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "goDown");
am.put("goRight", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
moveParty(10, 0);
}
});
am.put("goLeft", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
moveParty(-10, 0);
}
});
am.put("goUp", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
moveParty(0, -10);
}
});
am.put("goDown", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
moveParty(0, 10);
}
});
}
protected void moveParty(int xDelta, int yDelta) {
partyPoint.x += xDelta;
partyPoint.y += yDelta;
Point view = fromWorld(partyPoint);
if (view.x > getWidth() - (party.getWidth() / 2)) {
viewPort.x += xDelta;
if (viewPort.x + getWidth() > map.getWidth()) {
viewPort.x = map.getWidth() - getWidth();
partyPoint.x = map.getWidth() - (party.getWidth() / 2) - 1;
}
invalidate();
} else if (view.x < party.getWidth() / 2) {
viewPort.x += xDelta;
if (viewPort.x < 0) {
viewPort.x = 0;
partyPoint.x = (party.getWidth() / 2);
}
invalidate();
}
System.out.println(view + "; " + getHeight());
if (view.y > getHeight() - (party.getHeight() / 2)) {
viewPort.y += yDelta;
if (viewPort.y + getHeight() > map.getHeight()) {
viewPort.y = map.getHeight() - getHeight();
partyPoint.y = map.getHeight() - (party.getHeight() / 2) - 1;
}
invalidate();
} else if (view.y < party.getHeight() / 2) {
viewPort.y += yDelta;
if (viewPort.y < 0) {
viewPort.y = 0;
partyPoint.y = (party.getHeight() / 2);
}
invalidate();
}
repaint();
}
#Override
public void invalidate() {
view = null;
super.invalidate();
}
public BufferedImage getView() {
if (view == null && getWidth() > 0 && getHeight() > 0) {
view = map.getSubimage(viewPort.x, viewPort.y, getWidth(), getHeight());
}
return view;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (map != null) {
g2d.drawImage(getView(), 0, 0, this);
Point real = fromWorld(partyPoint);
int x = real.x - (party.getWidth() / 2);
int y = real.y - (party.getHeight()/ 2);
g2d.drawImage(party, x, y, this);
}
g2d.dispose();
}
protected Point fromWorld(Point wp) {
Point p = new Point();
p.x = wp.x - viewPort.x;
p.y = wp.y - viewPort.y;
return p;
}
}
}
This is how I do in my engine.
I'll keep two variables OffSetX and OffSetY
And calculate them every step to center the player like this.
OffSetX = 0;
OffSetY = 0;
if (MAP_WIDTH > WINDOW_WIDTH) {
OffSetX = Math.round(WINDOW_WIDTH / 2 - obj.getX() - TILE_SIZE);
OffSetX = Math.min(OffSetX, 0);
OffSetX = Math.max(OffSetX, WINDOW_WIDTH - MAP_WIDTH);
}
if (MAP_HEIGHT > WINDOW_HEIGHT) {
OffSetY = Math.round(WINDOW_HEIGHT / 2 - obj.getY() - TILE_SIZE);
OffSetY = Math.min(OffSetY, 0);
OffSetY = Math.max(OffSetY, WINDOW_HEIGHT - MAP_HEIGHT);
}
And then draw the map at the position (OffSetX, OffSetY) i.e., just add these to the original position of the object to draw.
You may want to skip rendering objects which are not visible.

[Java]Double buffering failing to double buffer

Well, as the title says, I am having trouble with double buffering. I read this Java Ebook and it doesn't give you code for what they are teaching you - at least not completely. So I have to do a lot of guess work.
Objective : Bouncing ball in an applet.
It's not working in the way that the ball is still flashing. Aka double buffering is failing to work.
I use three classes, ball class, double buffering class, and MainApplet class. MainApplet extends double buffering, and ball class extends MainApplet
import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
#SuppressWarnings("serial")
public class MainApplet extends DoubleBuffering implements Runnable {
public Ball ball;
public Graphics g;
private Thread ticker;
public boolean running = false;
public void init() {
setSize(100,100);
ball = new Ball(getWidth() / 5f, getHeight() / 4f, 1.5f,
2.3f, 12, Color.red);
moveBall();
}
public void run() {
while(running) {
try {
Rectangle bou = new Rectangle(getWidth(), getHeight());
ball.move(bou);
ball.update(getGraphics());
Thread.sleep(1000 / 15);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
repaint();
}
}
public void moveBall() {
start();
}
public synchronized void start() {
running = true;
ticker = new Thread(this);
ticker.setPriority(Thread.MIN_PRIORITY + 1);
ticker.start();
}
public synchronized void stop() {
running = false;
ticker.stop();
}
}
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
public class DoubleBuffering extends Applet
{
Image offScreenBuffer;
#SuppressWarnings("deprecation")
public void update(Graphics g)
{
System.out.println("We are buffing");
Graphics gr;
if (offScreenBuffer==null ||
(! (offScreenBuffer.getWidth(this) == this.size().width
&& offScreenBuffer.getHeight(this) == this.size().height)))
{
offScreenBuffer = this.createImage(size().width, size().height);
}
gr = offScreenBuffer.getGraphics();
System.out.println("Something else");
paint(gr);
g.drawImage(offScreenBuffer, 0, 0, this);
}
}
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
public class Ball extends MainApplet{
int size;
private Color color;
public float x, y, dx, dy;
public Ball ball;
public int width, height;
public Image offscreenImage;
public Graphics offscr;
private MainApplet ma;
Ball (float x, float y, float dx, float dy, int size,
Color color) {
this.x = x;
this.y = y;
this.dy = dx;
this.dy = dy;
this.color = color;
this.size = size;
}
public void draw (Graphics g) {
g.setColor(this.color);
g.fillOval((int) x, (int) y, size, size);
}
public void update(Graphics g) {
g.clearRect(0, 0, getWidth(), getHeight());
draw(g);
}
public void move(Rectangle bounds) {
// Add velocity values dx/dy to position to
// ball s new position
x += dx;
y += dy;
// Check for collision with left edge
if (x < bounds.x && dx < 0) {
dx = -dx;
x -= 2 * (x - bounds.x);
}
// Check for collision with right edge
else if (x + size > bounds.x + bounds.width &&
dx > 0) {
dx = -dx;
x -= 2 * ((x + size) - (bounds.x + bounds.width));
}
// Checks for collision with top edge
else if (y < bounds.y && dy < 0) {
dy = -dy;
y -= 2 * (y - bounds.y);
}
// Checks for collision with bottom edge
else if (y + size > bounds.y + bounds.height && dy >0) {
dy = -dy;
y -= 2 * ((y + size) - (bounds.y + bounds.width));
}
}
}
Note: I'm not too sure how this code will come out >.< it looks as if it's being choppy with the 'code:' function.
Anyways, don't hate too hard on my conventions, I'm still rather new. Tips and answers would be appreciated. Thanks.
Instead of calling Thread.Sleep() try using the swing Timer like this.
private Timer t;
public void moveBall() {
t = new Timer(1000/15, new ActionListener() {
public void actionPerformed(ActionEvent e) {
Rectangle bou = new Rectangle(getWidth(), getHeight());
ball.move(bou);
ball.update(getGraphics());
repaint();
}
});
t.start();
}
public void destroy() {
if(t!=null) t.stop();
super.destroy();
}
that should help at least a little bit.
I'm assuming the class DoubleBuffering is some tutorial class. I'm guessing it derives from Applet and not JApplet. If you use JApplet you will get double buffering by default.

Categories