how to Rotate only one object by using glrotate in java - 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;
}
}

Related

Line not drawing in LWJGL

I'm trying to draw a line LWJGL 3. I can change the background colors in the box render() method but I can't draw a line.
Here's the code:
import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.opencl.*;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
public class Main {
// The window handle
private long window;
enum GameState {
MAIN, GAME, PAUSED;
}
GameState state;
GLFWKeyCallback keyCallback;
Box box;
public void run() {
try {
init();
loop();
}catch(Exception e) {
e.printStackTrace();
}
}
private void init() {
if ( !glfwInit() )
throw new IllegalStateException("Unable to initialize GLFW");
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
int WIDTH = 300;
int HEIGHT = 300;
window = glfwCreateWindow(WIDTH, HEIGHT, "Hello World!", NULL, NULL);
if ( window == NULL )
throw new RuntimeException("Failed to create the GLFW window");
glfwSetKeyCallback(window, keyCallback = new Input());
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(
window,
(vidmode.width() - WIDTH) / 2,
(vidmode.height() - HEIGHT) / 2
);
glfwMakeContextCurrent(window);
glfwShowWindow(window);
state = GameState.MAIN;
box = new Box(100, 100, 10, 10, 10);
}
private void loop() {
GL.createCapabilities();
// Set the clear color
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Run the rendering loop until the user has attempted to close
// the window or has pressed the ESCAPE key.
while ( !glfwWindowShouldClose(window) ) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
render();
update();
updateKeys();
}
}
void update() {
// Poll for window events. The key callback above will only be
// invoked during this call.
glfwPollEvents();
switch(state){
case MAIN:
break;
case GAME:
break;
}
}
void updateKeys() {
switch(state) {
case MAIN:
if(Input.keys[GLFW_KEY_SPACE]) { state = GameState.GAME; }
break;
case GAME:
if(Input.keys[GLFW_KEY_UP]) {
}
break;
default:
break;
}
}
void render() {
glfwSwapBuffers(window); // swap the color buffers
switch(state) {
case MAIN:
break;
case GAME:
System.out.println("game rendering");
box.render();
break;
}
}
public static void main(String[] args) {
new Main().run();
}
class Box {
int x, y;
int dx, dy;
float speed;
float r, g, b;
boolean up, down, left, right;
void setUp(boolean b) { up = b; }
void setDown(boolean b) { down = b; }
void setLeft(boolean b) { left = b; }
void setRight(boolean b) { right = b; }
Box(int x, int y, float r, float g, float b) {
this.x = x;
this.y = y;
dx = 0;
dy = 0;
speed = 5;
this.r = r;
this.g = g;
this.b = b;
}
void update() {
if(up)
y += (int) speed;
if(down)
y += (int) -speed;
if(left)
x = (int) -speed;
if(right)
x = (int) speed;
x += dx;
y += dy;
dx = 0;
dy = 0;
}
void render() {
glColor3f(1, 1, 1);
glBegin(GL_LINES);
glVertex2f(10, 10);
glVertex2f(20, 20);
glEnd();
}
}
static class Input extends GLFWKeyCallback {
public static boolean[] keys = new boolean[65535];
#Override
public void invoke(long window, int key, int scancode, int action, int mods) {
keys[key] = action != GLFW_RELEASE;
}
}
}
You need to surround your render method with a glPushMatrix() and a glPopMatrix() I am fairly sure

How to make code move the ball?

I try to make a ping pong game but my ball don't move so how to make the ball is move?
This is my code
package test;
import java.awt.*;
import java.awt.event.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
public class pingpong1 extends JFrame implements Runnable {
public static void main(String[] args) {
pingpong1 ping = new pingpong1("PingPong Hard Game");
new Thread(ping).start();
ping.setSize(600, 300);
ping.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
ping.setVisible(true);
} private int width, height;
private User user;
private Computer computer;
private Ball ball;
static int UserScore = 0;
int ComputerScore=0;
public pingpong1(String title){
}
#Override
public void paint(Graphics g){
super.paint(g);
Image img2;
ImageIcon img = new ImageIcon("pingpong.png");
img2 = img.getImage();
g.drawImage(img2,0,0, this);
ball.paint(g);
}
#Override
public void run(){
while(true){
ball.moveBall();
repaint();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
Logger.getLogger( getName()).log(Level.SEVERE,null,e);
}
}
}
public void paintComponent(Graphics g) {
if (user == null) {
width = getWidth();
height = getHeight();
user = new User();
computer = new Computer();
ball = new Ball();
}
ball.draw(g);
}
public class User{
}
public class Computer{
}
public class Ball{
private int x,y;
private int centerX , centerY;
private Color color;
boolean go;
Ball(){
go=false;
}
public void paint(Graphics g) {
// TODO Auto-generated method stub
}
public Ball(int x,int y,Color color){
this.x=x;
this.y=y;
this.color=color;
this.centerX=5;
this.centerY=5;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public void moveBall(){
centerX=5;
x+=centerX;
y+=centerY;
} void draw(Graphics g){
Image img2;
ImageIcon img = new ImageIcon("pingpong.png");
img2 = img.getImage();
g.drawImage(img2, centerX - -35, centerY -10 , null);
}
}
}
Firstly your code for moving it, need to have some sort of input to actually move the ball. Right now it doesn't do anything but add x, y and doesnt repaint it, so you basically tell it to do nothing.
if you are looking for user controlled something like this will work?
public void moveIt(KeyEvent evt) {
switch (evt.getKeyCode()) {
case KeyEvent.VK_DOWN:
myY += 5;
break;
case KeyEvent.VK_UP:
myY -= 5;
break;
case KeyEvent.VK_LEFT:
myX -= 5;
break;
case KeyEvent.VK_RIGHT:
myX += 5;
break;
}
}
If you are looking for a way to move the ball automatically, then you will need to look at a few things in your code. As you don't take in to consideration the speed/ direction etc...
This is a basic example of a moving ball http://introcs.cs.princeton.edu/java/34nbody/Ball.java.html
I would of made a comment but my rep is under 50.
In your code you are correctly updating the ball's position in your game loop:
class pingpong1
while(true){
ball.moveBall(); // You update movement here
repaint();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
System.err.println("Interrupted.");
}
}
But you never actually redraw the ball at the updated position:
public void paint(Graphics g){
super.paint(g);
Image img2;
ImageIcon img = new ImageIcon("pingpong.png");
img2 = img.getImage();
g.drawImage(img2,0,0, this);
ball.paint(g); // this method is empty
}
Because the ball method paint is empty:
class Ball
public void paint(Graphics g) {
// TODO Auto-generated method stub
}
To correct that:
public void paint(Graphics g) {
ImageIcon icon = new ImageIcon("ball.png");
Image image = icon.getImage();
g.drawImage(image, x, y, null);
}
Or just call ball.draw() instead but you still have to correct the x and y because they are currently constant, change:
g.drawImage(img2, centerX + 35, centerY - 10, null);
To:
g.drawImage(img2, x, y, null);

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

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);
...

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.

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.

Categories