• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Is it possible to build an image using fillRect etc then draw that image to screen?

 
Ranch Hand
Posts: 287
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm nearly finished a game where the sky changes colour dynamically with the users health etc. I draw the sky with lots of fillRect commands and changing the colours gradually as the y position moves down the screen. I like the effect but I'm finding my method of drawing the sky is quite slow.

Is there a way of drawing to some sort of Image variable so that I can just display the image once rather than filling lots of rectangles each time?

Code at the moment is like this:



Thanks for any suggestions. If possible, I'd prefer suggestions that don't use fancy libraries as I simply prefer using the basics. Thanks for your time.
 
Marshal
Posts: 79469
379
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Go through the Java™ Tutorials. You will probably find that you can fill the entire rectangle in one statement, and apply a gradient to the painting, so you get darker blue at the top.
 
Bartender
Posts: 5478
212
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Indeed, have a look at the Paint-interface and the Gradient- and TexturePaint classes. And there is also the MultipleGradientPaint class, in the forms of a Linear and Radial version.
 
Mich Robinson
Ranch Hand
Posts: 287
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Piet Souris wrote:Indeed, have a look at the Paint-interface and the Gradient- and TexturePaint classes. And there is also the MultipleGradientPaint class, in the forms of a Linear and Radial version.

Thanks but I worry that this seems like a really complex way of doing what I want. I'll freely admit my current solution is too slow on low powered laptops but, if I could build an image using setColor and fillRect, then that wouldn't be an issue - can I not do this in Java?

The sky in question is this one.
exampleNep_Med.png
[Thumbnail for exampleNep_Med.png]
 
Saloon Keeper
Posts: 10804
86
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You'd have to explain for us how you determine your starting and finishing colors and the colors in between, and the Y distance between the start and end rows.

Do you compute them or use a look up table?
 
Piet Souris
Bartender
Posts: 5478
212
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Apart from that, it is possible to create several BufferedImages that you can draw to, so that in a repaint you only have to draw the correct BI, and do some custom painting over that. Whether that is suitable, I don't know. Another possibility is that you do the drawing in another thread, so that a repaint only requires drawing that BI. If you repaint every 20 ms, say, than this will give you 20 ms to get that drawing done. Just some thoughts.
 
Mich Robinson
Ranch Hand
Posts: 287
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Carey Brown wrote:You'd have to explain for us how you determine your starting and finishing colors and the colors in between, and the Y distance between the start and end rows.

Do you compute them or use a look up table?

In the example code I gave there's an array of colours called SkyColours. These are adjusted each time the sky colour changes (if the health is low, if the weather is bad, if a something bad is about to happen). The array goes from 0 to 80 as the rectangles of colour are 5 y pixels wide and the sky is drawn down to about 2/3 of the screen.  
 
Mich Robinson
Ranch Hand
Posts: 287
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Piet Souris wrote:Apart from that, it is possible to create several BufferedImages that you can draw to, so that in a repaint you only have to draw the correct BI, and do some custom painting over that. Whether that is suitable, I don't know. Another possibility is that you do the drawing in another thread, so that a repaint only requires drawing that BI. If you repaint every 20 ms, say, than this will give you 20 ms to get that drawing done. Just some thoughts.


That was roughly how I was hoping to do it but I don't know how to set a colour in a BufferedImage and then start filling rectangles. I can easily handle all the timing issues but I just don't know how to draw to the image variable. Was hoping for a really simple code snippet. Is it something like:
 
Carey Brown
Saloon Keeper
Posts: 10804
86
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

 
Mich Robinson
Ranch Hand
Posts: 287
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks, that's what I needed to know. Thanks for everyone's help.
 
Saloon Keeper
Posts: 15630
366
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Mich, I started writing some example code for you to use, but then I got distracted and forgot about it until after your problem was solved. If you're interested, here it is anyway:

Here's a utility class that I often use for Swing user interfaces:
 
Rancher
Posts: 3324
32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
1) Don't override paint(). Custom painting should be done by overriding paintComponent().
2) Invoke super.paintComponent(...) first to make sure background is cleared before you do custom painting

 
Mich Robinson
Ranch Hand
Posts: 287
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Carey Brown wrote:

This worked great when using a single buffered image and fixed the performance issue. I then figured why not create an array of 25 bufferedImages and initialise them all before play and that would fix things completely. I couldn't work out how to change the declaration of the buffered image into an array. I tried various ways but couldn't work out the syntax. I tried the following plus variations and also trying things in a loop but no luck. Any suggestions for the correct syntax?
 
Carey Brown
Saloon Keeper
Posts: 10804
86
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
"skyImgs" should begin with a lower case letter as all variables should. Because it holds a number of items it should be plural.
 
Stephan van Hulst
Saloon Keeper
Posts: 15630
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Camick wrote:1) Don't override paint(). Custom painting should be done by overriding paintComponent().

2) Invoke super.paintComponent(...) first to make sure background is cleared before you do custom painting


You're correct, and I was absolutely certain that I had done both things in some version of the code I prepared. It seems I rewrote some stuff and then accidentally did it wrongly.

The second thing isn't absolutely necessarily if the paintComponent() implementation guarantees that it paints every pixel of the component though.
 
Piet Souris
Bartender
Posts: 5478
212
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Your panel has no border and no children, so by overriding paint you prevent needless invoking of those methods
 
reply
    Bookmark Topic Watch Topic
  • New Topic