Im not sure what is a MVC. But by what I read I believe this is the minimal code needed for this case.
As you can see my code is not wrong and the prove for that is it works at least 10-20 seconds and then my player start intersect with the walls for no reason.
It is static because I was testing to see if would make a difference,but it didnt…
I changed the code,but with no results… Im going to show you my 3 class that im using for this simple collision test:
Player.class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Player implements KeyListener{
public boolean right,left,up,down;
public int x,y;
private int speed = 2;
public Player(int x,int y){
this.x = x;
this.y = y;
}
public void tick(){
if(right)
{
if(move(x+speed,y))x+=speed;
}
if(left)
{
if(move(x-speed,y))x-=speed;
}
if(up)
{
if(move(x,y-speed))y-=speed;
}
if(down)
{
if(move(x,y+speed))y+=speed;
}
Camera.x = x - (Game.WIDTH/2);
Camera.y = y - (Game.HEIGHT/2);
}
public boolean move(int nextx,int nexty)
{
int w = World.tiles.length;
int h = World.tiles[0].length;
for(int xp = (nextx/32); xp <= (nextx/32) + 1; xp++)
{
for(int yp = (nexty/32); yp <= (nexty/32) + 1; yp++)
{
if(xp < 0 || xp >= w || yp < 0 || yp >= h) continue;
if(World.tiles[xp][yp] == 1)
{
int x1 = xp*32;
int y1 = yp*32;
Rectangle player = new Rectangle(nextx,nexty,32,32);
Rectangle tile = new Rectangle(x1,y1,32,32);
if(player.intersects(tile)) return false;
}
}
}
return true;
}
public void render(Graphics g){
g.setColor(Color.blue);
g.fillRect(x - Camera.x, y - Camera.y, 32, 32);
}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_RIGHT){
right = true;
}
else if(e.getKeyCode() == KeyEvent.VK_LEFT){
left = true;
}
else if(e.getKeyCode() == KeyEvent.VK_UP){
up = true;
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN){
down = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_RIGHT){
right = false;
}
else if(e.getKeyCode() == KeyEvent.VK_LEFT){
left = false;
}
else if(e.getKeyCode() == KeyEvent.VK_UP){
up = false;
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN){
down = false;
}
}
@Override
public void keyTyped(KeyEvent e) {}
}
World.class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class World {
public static byte[][] tiles;
public World(String path){
try {
BufferedImage bitmap = ImageIO.read(getClass().getResource(path));
int w = bitmap.getWidth();
int h = bitmap.getHeight();
tiles = new byte[w][h];
int pixels[] = new int[w*h];
bitmap.getRGB(0, 0,w,h,pixels,0,w);
for(int x = 0; x < w; x++)
{
for(int y = 0; y < h; y++){
if(pixels[x+(y*w)] == 0xFFFFFFFF)
{
//Grass
tiles[x][y] = 0;
}else if(pixels[x+(y*w)] == 0xFFFF0000)
{
//Enemy
tiles[x][y] = 0;
}else if(pixels[x+(y*w)] == 0xFF0000FF)
{
//Player
tiles[x][y] = 0;
Game.player.x = x*32;
Game.player.y = y*32;
}else
{
//Wall
tiles[x][y] = 1;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void render(Graphics g){
int minX = Camera.x / 32;
int minY = Camera.y / 32;
int maxX = (Camera.x / 32) + (Game.WIDTH / 32);
int maxY = (Camera.y / 32) + (Game.HEIGHT / 32);
for(int x = minX; x <= maxX; x++){
for(int y = minY; y <= maxY; y++){
if(x >= 0 && x < tiles.length && y >= 0 && y < tiles[0].length){
if(tiles[x][y] == 0)
{
g.setColor(Color.red);
g.fillRect(x*32 - Camera.x,y*32 - Camera.y,32,32);
}else if(tiles[x][y] == 1){
g.setColor(Color.gray);
g.fillRect(x*32 - Camera.x,y*32 - Camera.y,32,32);
}
}
}
}
}
}
Game.class
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable{
private static final long serialVersionUID = 1L;
public static final int WIDTH = 480, HEIGHT = 480;
public static final String TITLE = "Simple test";
public static final Dimension DIM = new Dimension(WIDTH, HEIGHT);
private static boolean running = false;
private Thread thread;
public static Player player;
public static World world;
public Game(){
setPreferredSize(DIM);
setMaximumSize(DIM);
setMinimumSize(DIM);
new Camera();
player = new Player(0,0);
world = new World("/level1.png");
addKeyListener(player);
}
public void tick(){
player.tick();
}
public void render(){
BufferStrategy bs = this.getBufferStrategy();
if(bs == null){
createBufferStrategy(2);
requestFocus();
return;
}
Graphics g = bs.getDrawGraphics();
g.clearRect(0, 0, Game.WIDTH, Game.HEIGHT);
g.setColor(Color.green);
g.fillRect(0, 0, WIDTH, HEIGHT);
world.render(g);
player.render(g);
bs.show();
g.dispose();
}
public void run(){
long lastTime = System.nanoTime();
final double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
int fps = 0,ups = 0;
double timer = System.currentTimeMillis();
while(running){
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if(delta >= 1){
tick();
delta--;
ups++;
render();
fps++;
}
if(System.currentTimeMillis() - timer >= 1000){
timer+=1000;
System.out.println("FPS: " + fps + " UPS: " + ups);
fps = 0;
ups = 0;
}
}
stop();
}
public synchronized void start(){
if(running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop(){
if(!running)
return;
running = false;
}
public static void main(String[] args){
Game game = new Game();
JFrame frame = new JFrame(TITLE);
frame.add(game);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
game.start();
}
}
OBS: I know Im using to much static and it is not prety code…