[Don't even look] I think I've found a bug in my brain

I think I’ve found a bug.

I got this result, from some code:

Obviously, I’m drawing green rectangles, underneath the pictures.

Now, if I comment it out (and that is the ONLY change made to the code):

and

Depending on where the X-coord for the camera is set.
…also, this doesn’t move smoothly, like normally, but in 10 pixel steps.

Boils down to just odd behavoir, because this shouldn’t work that way.

Code, for people interrested:


// World-rendering
		int startingX = cameraX / 10;
		g.setColor(Color.green);
		for (int x = startingX; x < 50 + startingX; x++) {
			for (int y = 0; y < 20; y++) {
				if (level.getBrick(x, y) != null) {
					int k = x * 10;
					int startDrawX = k - cameraX;
					int startDrawY = 200 - ((y + 1) * 10);
					g.drawRect(startDrawX, startDrawY, 10, 10);
					
					Brick brick = level.getBrick(x, y);
					BRICK_TYPE type = brick.getType();
					ResourceManager.TILE image = type.getImage();
					g.drawImage(graphics.getSprite(image.getX(), image.getY()), startDrawX, startDrawY);
				}
			}
		}

EDIT:
Can anyone explain this behavoir, or suggest a way to fix it? I got no ideas as to why this is happening. I just cleaned up my code, so it shouldn’t be spaggetthi-loops and oddness.

Your code, to me, is a bit confusing.

I’d suggest that you’d implement the drawing of the Brick inside the Brick class instead. You could, for example, make 2 methods. One to draw a green rectangle at the Bricks position and another to draw the sprite.

class Brick {
int xPosition = 0;
int yPosition = 0;
int width = 10;
int height = 10;
Image image = null;

// Constructor
public Brick(int x, int y) {
     this.xPosition = x;
     this.yPosition = y;
     this.image = ResourceManager.getImage();
}

// Paint methods
public void drawRect(Graphics g, int x_offset, int y_offset) {
     // the offset values are used to shift the bricks to any position relative to the screen.
     g.setColor(Color.green);
     g.drawRect(xPosition + x_offset, yPosition + y_offset, width, height);
}

public void drawImage(Graphics g, int x_offset, int y_offset) {
      if (image = null) return; // If we have no image, don't draw anything
     g.drawImage(image, xPosition + x_offset, yPosition + yOffset);
}
}

And then to draw the bricks, just loop through them all and decide if they are within the view and if they are, call their paint methods:

// World-rendering
Iterator itr = (level.listOfBricks).iterator();
// Assuming you've saved all Brick objects in an ArrayList called listOfBricks in the level object.
while (itr.hasNext()) {
      Brick b = itr.next();
     b.drawRect(g, 0, 0);
     b.drawImage(g, 0, 0);
}

Also, if you hold down ALT while you take a screenshot with PrintScreen, you will only take a screen shot of the active window ( so you don’t have to crop out the whole desktop in paint:) )

@JonJava
Uh, and how would that fix the seams he’s experiencing?

Don’t assume that a problem is a bug in someone else’s released code. Only accuse others when you’ve tried everything.
You’re also not posting much of the relevant code either. I mean, you have a draw problem, so why not post the code concerning drawing? Also more code comparisons between when it works and when it doesn’t. You’re probably either removing some vital part for all rendering when you comment out the green box drawing (you’re forgetting to set something) or you have leftover code in your green box drawing that corrupts some setting. Either way, it’s impossible to tell for me with only this code to go by.

The bug is not in LWJGL. It’s unlikely that it is in Slick too but not impossible.

Cas :slight_smile:

Cannot comment on that code, since, yeah its confusing

First of all it is always most likely that the code you write is buggy instead of the libraries you use.

But I gotta say Slick has a couple of bugs which nobody seems to know/fix/care for - whatever
bugs with colors
textures that aren’t destroyed / loaded / rendered under certain circumstances; related: textures stay whit, black or show a different texture in shrinked form
and especially the blending modes are screwed up / or draw modes as they are called

I did not mean to promote my code, over Slick, or saying that mine is better. I have a lot of respect for kevglass’ code. However, I am stating that the only thing changing in MY code, is that one call to g.drawRect, which seems to change a lot. More than just a rect. Now, this seems to me, like something is wrong.

I’m having my drawing logic in the screen, and not in the brick, because my Brick is only a data object. I find it more correct, to have it in screen.
Screen is drawing brick - not brick.

The code I posted is very relevant:


// World-rendering
        int startingX = cameraX / 10;
        g.setColor(Color.green);
        for (int x = startingX; x < 50 + startingX; x++) {
            for (int y = 0; y < 20; y++) {
                if (level.getBrick(x, y) != null) {
                    int k = x * 10;
                    int startDrawX = k - cameraX;
                    int startDrawY = 200 - ((y + 1) * 10);
                    g.drawRect(startDrawX, startDrawY, 10, 10);
                     
                    Brick brick = level.getBrick(x, y);
                    BRICK_TYPE type = brick.getType();
                    ResourceManager.TILE image = type.getImage();
                    g.drawImage(graphics.getSprite(image.getX(), image.getY()), startDrawX, startDrawY);
                }
            }
        }

Applies to the first picture.


// World-rendering
        int startingX = cameraX / 10;
        g.setColor(Color.green);
        for (int x = startingX; x < 50 + startingX; x++) {
            for (int y = 0; y < 20; y++) {
                if (level.getBrick(x, y) != null) {
                    int k = x * 10;
                    int startDrawX = k - cameraX;
                    int startDrawY = 200 - ((y + 1) * 10);
                    //g.drawRect(startDrawX, startDrawY, 10, 10);
                     
                    Brick brick = level.getBrick(x, y);
                    BRICK_TYPE type = brick.getType();
                    ResourceManager.TILE image = type.getImage();
                    g.drawImage(graphics.getSprite(image.getX(), image.getY()), startDrawX, startDrawY);
                }
            }
        }

Applies to the second, and third.

Also, I believe I’ve tried everything with this. I mean; there isn’t much to try. The comment should remove the green rects. Obviously, it’s not doing that.

EDIT: It seems to boil down to, wether I draw the rects first, or the images first. If the rect if not drawn before the images, it f’s up.
Can anyone suggest a better way to debug this? Things I could try?


if (level.getBrick(x, y) != null) {
					Brick brick = level.getBrick(x, y);
					BRICK_TYPE type = brick.getType();
					ResourceManager.TILE image = type.getImage();
					
					int k = x * 10;
					int startDrawX = k - cameraX;
					int startDrawY = 200 - ((y + 1) * 10);
					Image drawImage = graphics.getSprite(image.getX(), image.getY());
					g.drawImage(drawImage, startDrawX, startDrawY);
					//g.drawRect(startDrawX, startDrawY, 10, 10);
				}

Same exact result.

Why isn’t the FPS, yVelocity etc (like the one in the first picture) shown in the 2 others screenshots?

[EDIT]

[quote]I’m having my drawing logic in the screen, and not in the brick, because my Brick is only a data object. I find it more correct, to have it in screen.
Screen is drawing brick - not brick.
[/quote]
It irks me greatly to hear this since I would find my method way more in line with good OOP design and much more clean, clear and organized and efficient etc. The screen does of course paint the Bricks - it just lets the Brick handle its painting. The screen doesn’t care HOW the brick works or how it looks or how it paints itself - let the Brick handle that. I just felt I had to give you my opinion.:slight_smile:

After reading the original post I still don’t understand what the problem is.

What is the expected behaviour and what are you seeing and how does it differ from what you expect?

This what I am assuming: you have commented out the green rectangle drawing. Now the bricks are being drawn in the incorrect location because in the original frame the arch took up most of the screen and in the latter two frames you can only see the bottom.

yes. I actually recall that behavior when we tried to implement or LWJGL particle system in our game which is Slick - and those blending modes just clashed.
my conclusion was that, drawing images in Slick somehow changes the blending mode also - so the order matters

try to make a simple isolated example
I haven’t really bothered because it seems that Kevin is quite busy and these things are so… well hard to detect, and few people use Slick for big things… you know
which is why I will switch to pure LWJGL soon, only using Slicks Audio implementation

First image, is what I want. However, without the green rects.

Second image, is what happens when I comment them out.

Third image, is when moving the world over the X axis, which works just fine if i draw the rects. Without the rects, it even moves on the y-axis as well.

It irks me greatly to hear this since I would find my method way more in line with good OOP design and much more clean, clear and organized and efficient etc. The screen does of course paint the Bricks - it just lets the Brick handle its painting. The screen doesn’t care HOW the brick works or how it looks or how it paints itself - let the Brick handle that. I just felt I had to give you my opinion.:slight_smile:
[/quote]
Good observation. To be honest, all the other code, except form the rects, are exactly the same.
No clue why they get left out.

Well, that is a design question :wink: I respect your opinion though. Would you also let the bricks update themselfes? What about the player?
How is level, monster and player interference going to work, if each class handles ifself in that manner?
That’s just questions I don’t want to deal with. Also, I can use my creature class for all creatures in the game - including the player.

Thanks for the post. Good to know I’m not the only one.

I tried this, while altering showRects on keyPress.


if (showRects) {
   g.drawRect(startDrawX, startDrawY, 10, 10);
}
Image drawImage = graphics.getSprite(image.getX(), image.getY());
g.drawImage(drawImage, startDrawX, startDrawY); 

Problem persists, but only when showRects are off. I can’t seem to reproduce the problem, but it can’t seem to make it disappear.
Anything I could try? Any graphics trickery, or anything that could help?

yeah I can’t find any misuses of glBlendFunc in the code

if you can create like a simple Slick class which shows this problem…

I can’t reproduce the problem, but I can definitely hand over my source, and a runable jar for you to look at.
http://www.javadaemon.com/problemjar.zip contains both the source, and a runnable jar.

controls:
k - toggle wether or not to draw the rects
a and d - move camera
arrow keys and space - move around

Please look at the source, and even decompile if you don’t believe me. This is very odd

EDIT:
This is the whole render loop:


@Override
	public void render(GameContainer container, Graphics g)
			throws SlickException {
		StaticWorld level = model.getLevel();
		Creature player = model.getPlayer();
		
		final SpriteSheet graphics = ResourceManager.getRessourceManager().getGraphics(); // Get the sprite sheet
		graphics.startUse();

		// World-rendering
		int startingX = cameraX / 10;
		g.setColor(Color.green);
		for (int x = startingX; x < 50 + startingX; x++) {
			for (int y = 0; y < 20; y++) {
				if (level.getBrick(x, y) != null) {
					Brick brick = level.getBrick(x, y);
					BRICK_TYPE type = brick.getType();
					ResourceManager.TILE image = type.getImage();
					
					int k = x * 10;
					int startDrawX = k - cameraX;
					int startDrawY = 200 - ((y + 1) * 10);
					if (showRects) {
						g.drawRect(startDrawX, startDrawY, 10, 10);
					}
					Image drawImage = graphics.getSprite(image.getX(), image.getY());
					//g.drawImage(drawImage, startDrawX, startDrawY);
					drawImage.draw(startDrawX, startDrawY);
				}
			}
		}

		// Player rendering
		g.setColor(Color.orange);
		int screenX = (int) player.getWorldX() - cameraX;
		int screenY = 200 - (int) (player.getWorldY());
		g.drawRect(screenX, screenY, player.getWidth(), player.getHeight());
		
		g.drawString("yVelocity: " + player.getYVelocity(), 10, 20);
		g.drawString(player.getWorldX() + " " + player.getWorldY(), 10, 30);
		g.drawString(player.isJumping()+"", 10, 40);
		
		graphics.endUse(); 
	}

Calling g.setColor() or g.drawRect() or g.drawImage() is always going to go wrong up inside a startUse()/endUse(). Start/End uses one set of geometry to speed things up, it’s described on the wiki and in the javadoc.

In your case you don’t need to startUse() or endUse(). If you want to use them you need to use Image.drawEmbedded()

Cheers

Kev

YES! Thank you so much! Ofcourse it was something like that :smiley: Appriciation++;

It irks me greatly to hear this, since I think throwing in an argument of “good OOP design” just because it would look more familar to you is just complete BS. And to say, that it is more organized and efficient id plainly wrong. Actually all abstractly designed graph/scene/3D engines use a clear separation of data and drawing code. Either to enable them to visualize the same data in different ways or to switch the backend renderers to take advantage of new hardware features or different drawing APIs.

I just had to say you, that your opinion is exactly that - an opinion - nothing more :stuck_out_tongue:

All of OOP is opinion and wankery :slight_smile: There are many ways to kill a cat other than skinning it.

Cas :slight_smile:

This topic name change looks EPIC ;D ;D ;D ;D and makes me laugh.
I think that all people have some bugs in they brains, but only programmers can understand that ;D (or other clever people). And it is common for people to make mistakes. If we don’t do them we will be computers :smiley:
P.S. sorry for offtopic ;D

The scary thing about that is that you think programmers are “clever” :slight_smile:

Kev

Yeah, literally implying that you have to be clever to be a Programmer with a big P at a big company.