I left this question on "normal" stackOverFlow but they recommended I asked you guys! I am new to making games in Java but I made some games using the paintComponent method, however I felt like I was missing something. So I wanted to see different options of rendering graphics etc. I therefore googled around and I just got stuck on painting individual pixels. I thought that was really cool. However, I have some issues with it.
The main issue is that the collision system isn't working great. In my case I right now use an image of a block as a player. This block sometimes get overlapped by the level image.
Here is an image of the issue:
As you can see the level image overlaps the player image in the corner. I read some posts about fixing it, they mentioned that I should set the position of the block to the position right before colliding. However this made it even worse as the player just teleported back and forth.
I thought that making a GIF of the issue wouldn't hurt, so here you go!
It seems to me that the corners aren't correctly set?
Here is the code:
The Render method in GameManager (Handles the collision code):
@Override
public void render(GameContainer gc, Renderer renderer) {
for(GameObject obj : list) { //Draw objects
obj.setGoRight(true);
obj.setGoLeft(true);
obj.setGoUp(true);
obj.setGoDown(true);
obj.render(gc, renderer);
//Collision
for(int y = 2; y < obj.getHeight() - 2; y++) {
//TODO CORNERS DON'T HAVE COLLISION, FIX
if(collision[(obj.getxCord()) + ((obj.getyCord() + y) * gc.getWidth())] ) { //GLITCHES INTO BLOCK
obj.setxCord(obj.getxCord());
obj.setGoLeft(false); //MOVEMENT LEFT
}
if(collision[obj.getxCord() + obj.getWidth() + ((obj.getyCord() + y) * gc.getWidth())] ) {
//MOVEMENT RIGHT
obj.setxCord(obj.getxCord());
obj.setGoRight(false);
}
}
for(int x = 3; x < obj.getWidth() - 3; x++) { //SKJUTER SÅ DE INTE SKANNAR KANTERNA, DVS SÅ ATT X OCH Y AXELN HAR SAMMA HITBOX
if(collision[(obj.getxCord() + x) + ((obj.getyCord() + obj.getHeight()) * gc.getWidth())] ) {
//MOVEMENT DOWN
obj.setyCord(obj.getyCord());
obj.setGoDown(false);
}
if(collision[(obj.getxCord() + x) + (obj.getyCord() * gc.getWidth())] ) {
//MOVEMENT UP
obj.setGoUp(false);
obj.setyCord(obj.getyCord());
}
}
}
renderer.drawImage(backgroundImg, 0, 0);
}
The Player class
public class Player extends GameObject{
private Image image;
private int speed = 2;
String imagePath = "/picture.png";
public Player() {
this.xCord = 160;
this.yCord = 120;
image = new Image(imagePath);
tag = "player";
this.width = image.getWidth();
this.height = image.getHeight();
this.hitBox = new Rectangle(this.xCord,this.yCord,this.width,this.height);
}
@Override
public void update(GameContainer gc, float updatetime) {
if(goLeft) {
if(gc.getInput().isKeyPressed(KeyEvent.VK_A)) {
this.xCord -= speed;
}
}
if(goRight ) {
if(gc.getInput().isKeyPressed(KeyEvent.VK_D)) {
xCord += speed;
}
}
if(goUp) {
if(gc.getInput().isKeyPressed(KeyEvent.VK_W)) {
yCord -= speed;
}
}
if(goDown) {
if(gc.getInput().isKeyPressed(KeyEvent.VK_S)) {
yCord += speed;
System.out.println(yCord);
}
}
if(gc.getInput().isKeyPressed(KeyEvent.VK_K)) {
this.setDead(true);
}
this.setHitBox(hitBox);
}
@Override
public void render(GameContainer gc, Renderer renderer) {
renderer.drawImage(image,xCord,yCord);
}
public Image getImage() {
return image;
}
}
The Level loading method in GameManager:
public void loadLevel(String levelPath) {
backgroundImg= new Image(levelPath);
levelWidth = backgroundImg.getWidth();
levelHeight = backgroundImg.getHeight();
collision = new boolean[levelHeight * levelWidth];
for(int y = 0; y < levelHeight; y++) {
for(int x = 0; x < levelWidth; x++) {
if(backgroundImg.getPixels()[x + (y * levelWidth)] == new Color(0,0,0).getRGB()) {
collision[x + (y * levelWidth)] = true;
if(collision[x+(y * levelWidth)]) {
backgroundImg.getPixels()[x + (y * levelWidth)] = 56;
}
}
else collision[x + (y * levelWidth)] = false;
}
}
}
}
So what am I trying to do?
When the player collides with any of the pixels that I set as colliding pixels in the loadLevel() method earlier, I want him to stop moving. A simple idea but it turned out difficult.
I have the two for loops in the collision part of render() to change the hitbox.
If I don't use these loops I can't move up or down when I hit a wall on my left or right side. And if I hit the roof I can't move left and right etc.
The for loops therefore change where the player's hitbox is places. This makes the player's corner seem like it doesn't exist. If I paint the image right in my head it should look like:
TLDR;: I am trying to make so that the player cant go into the maps drawn objects. It this case it's these dark blue "rectangles". However, the maps items sometimes overlap my player image. The image goes too far before stopping. Happens with both borders and sides. If I increase the speed it struggles more. I had speed 2 and I added "+ 2" pixels to two of the if statements and it worked. When I increased the speed it didn't work once again..
Code snippet of the change I did:
if(collision[(obj.getxCord() - 2) + ((obj.getyCord() + y) * gc.getWidth())] ) { //-2 and it stays correct
Any tips regarding how I might change the code to solve the issue are appreciated! I looked at many posts regarding this before, but they used Rectangles which isn't really the same as checking the player x and y value with individual pixels?
People might also ask why I use a pixel system. Which is a fair question. My only answer is that I want to draw a level in paint then import that image instead of coding where things shall be placed? I just found that this might be a smarter solution! So I make a pixelart map, then I make a separate image where I put black pixels where collision blocks are etc. I hope you get my point!
I do however think this system is a bit complicated, but I didn't find a good way to do it.
Sorry for the complex question, I just want to give you as much information as possible!
Thanks in advance!


