Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (494)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  [Solved] Procedural Graphics  (Read 2497 times)
0 Members and 1 Guest are viewing this topic.
Offline ReBirth
« Posted 2011-06-17 04:04:36 »

I don't want to make an entry for 4k competition. I just want to draw something for my little desktop game but can't find suitable free sprite and I don't have art skill  Grin

I read that Procedural Graphics is "using combinations of the line, oval, and rectangle functions to produce a sprite.". I took source code of Crack Attack game. Unsurprisingly Cool I can't find how to create such great sprite with just a bunch of integer values, complete with all the shapes and colors. So, how can you create sprite like that without any image? sample code could be good. Thx.

Offline krasse
« Reply #1 - Posted 2011-06-17 06:59:38 »

I am not completely sure but I think that Crack Attack (and many 4k games) uses this method:
* Create/get the sprites manually
* Compress the sprites to a string
* Add the string to the source code
* Uncompress the sprites everytime the game starts

Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #2 - Posted 2011-06-17 07:12:17 »

http://www.ahristov.com/tutorial/java4k-tips/Visual-effects-index.html

has a few random hints/tips for getting started.
Although it has more of background and static type things.

Though in my recommendation, I'd try harder searching for free sprites or learn a little basic programming.

I am a huge huge fan of procedural graphics, especially in creating different entities and terrain. But typically you do this to have more dynamic control over the appearance, you don't do it because of lack of art skill, because in my opinion it takes even more skill and knowledge for minimal outcome.   

Perhaps aside from not finding free sprite and lack of traditional art skill, you could try and explain what type of sprites/graphics you are looking for, and what you want to do with them?  Or why exactly you feel you could better leverage procedural arts.


"Experience is what you get when you did not get what you wanted"
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline steveyO
« Reply #3 - Posted 2011-06-17 12:07:58 »

You can also get relatively nice graphics using randomly generated graphics (using Java2D, ovals, arcs, lines etc).
One technique is to draw only half your randomly drawn image and then flip the image horizontally (or vertically).  Or draw a quarter of your image and rotate 3 times for a nice square block.

All the bugs in (http://www.bullsquared.com/gameTwoThousand.html) were done using this technique (in only a few lines of code). You just need to experiment with the colours, line thickness, amount of lines drawn, arc parameters etc.  I recently started work on a random graphic generator,  will maybe release 1 day when am happy with the results.

https://play.google.com/store/apps/details?id=com.bullsquared.alggame Annoying Little Gits (Android)
www.bullsquared.com   Play java (applet) games! www.chessclockpro.com Free Online Chess Clock
Offline ReBirth
« Reply #4 - Posted 2011-06-18 02:45:59 »

I am not completely sure but I think that Crack Attack (and many 4k games) uses this method:
* Create/get the sprites manually
* Compress the sprites to a string
* Add the string to the source code
* Uncompress the sprites everytime the game starts
Then how to compress the sprites to a string?
http://www.ahristov.com/tutorial/java4k-tips/Visual-effects-index.html

Perhaps aside from not finding free sprite and lack of traditional art skill, you could try and explain what type of sprites/graphics you are looking for, and what you want to do with them?  Or why exactly you feel you could better leverage procedural arts.
I'm trying to make a top-look shooter with control like Ultratron. I need some sprites of zombie, human male and human female. Each of them must have all four direction sprites. I don't need very great art so I think maybe I can draw some simple rectangles to make simple sprites. Your given link is great, thx Smiley

Offline krasse
« Reply #5 - Posted 2011-06-18 10:57:22 »

Quote
Then how to compress the sprites to a string?

Here is an example (taken from a string in Legend of Zelda 4K) where you specify 16-bit numbers in a String. Here you can put your image bytes. Look in the source code of that game to see how the images are created.
1  
String S = "\u002a\ua800\u00aa\uaa00\u0c95";



Offline ReBirth
« Reply #6 - Posted 2011-06-18 15:33:28 »

@krasse
Okay. I've already played the game. So is there any tutorial for that? like explanation of each numbers on the string etc.

Offline krasse
« Reply #7 - Posted 2011-06-18 17:32:06 »

@krasse
Okay. I've already played the game. So is there any tutorial for that? like explanation of each numbers on the string etc.

Have you looked at the source code? Look at the part where the sprites are constructed.

Offline ReBirth
« Reply #8 - Posted 2011-06-19 03:31:20 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
    int[] pixels = new int[16];
    int[] pixels2 = new int[16];
    BufferedImage[] sprites = new BufferedImage[64];
    for(i = 0; i < SPRITE_COUNT; i++) {
      sprites[i] = new BufferedImage(16, 16, 2);
      sprites[i + SPRITE_FLIPPED] = new BufferedImage(16, 16, 2);
      for(y = 0; y < 16; y++) {
        for(x = 0; x < 16; x++) {
          j = (S.charAt((x < 8 ? 1 : 0) + (y << 1) + (i << 5))
              >> ((x & 7) << 1)) & 3;
          pixels2[15 - x] = pixels[x] = j == 0 ? 0 : 0xFF000000
              | (i < SPRITE_ROCK ? (j == 1 ? 0x994E00 : j == 2
                      ? 0x88D800 : 0xEA9E22)
                  : i <= SPRITE_CRACKED_ROCK
                      ? (j == 1 ? 0 : j == 2 ? 0x994E00 : 0xF7D8A5)
                  : i < SPRITE_WATER
                      ? (j == 1 ? 0xB53120 : j == 2 ? 0xEA9E22 : 0xFFFFFF)
                  : i < SPRITE_BRIDGE
                      ? (j == 1 ? 0x4240FF : 0x0D9300)
                  : i < SPRITE_PRINCESS
                      ? (j == 1 ? 0x4240FF : j == 2 ? 0x994E00 : 0)
                  : i < SPRITE_LADDER
                      ? (j == 1 ? 0xB53120 : j == 2 ? 0xEA9E22 : 0x994E00)
                      : (j == 1 ? 0 : j == 2 ? 0x4240FF : 0x994E00));
        }
        sprites[i].setRGB(0, y, 16, 1, pixels, 0, 16);
        sprites[i + SPRITE_FLIPPED].setRGB(0, y, 16, 1, pixels2, 0, 16);
      }
    }

So that 6 numbers of hexa tells what RGB color to be drawn on each sprites (BufferedImage)? if yes, how to explain texture of the wall/rock? it's not simple as giving brown color to that like the river :S

Offline krasse
« Reply #9 - Posted 2011-06-19 08:39:43 »

That part doesn't explain how to create the actual images, it just shows how to put image data in Strings. The actual images are created manually.

If you want to create procedural graphics, check out the book: Texturing and modeling: a procedural approach

Also, check out the tool Genetica to see how basic textures can be made procedurally.

I can also recommend the book: Algorithmic beauty of plants. It explains L-systems that can be used for many things.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online CommanderKeith
« Reply #10 - Posted 2011-06-19 13:36:28 »

Great links, particularly that one about the plants. Thanks.

Offline pitbuller
« Reply #11 - Posted 2011-06-19 16:49:35 »

My game Kers use only procedural graphics. Creating random 2d landscapes are easy task. Making clouds was really just trying and error process and at the end I was happy to see really detailed transparent clouds.
I noticed that it was faster to produce all graphics everytime at start than loading those at file. Actually landscape data size is about 250megabytes so I would be impossible to do that big playable applet.
Offline krasse
« Reply #12 - Posted 2011-06-19 17:26:03 »

Here is my crazy procedural node system that can create a lot of stuff (graphics, L-systems, sound effects, music). It is an old version though, I will release a newer one after my game is finished.

Right-click and select one of the presets Smiley

Offline ReBirth
« Reply #13 - Posted 2011-06-20 04:41:24 »

Wow really thanks for the links
I noticed that it was faster to produce all graphics everytime at start than loading those at file. Actually landscape data size is about 250megabytes so I would be impossible to do that big playable applet.
did you mean call teh procedures once? I thought the procedures are called every times draw() on main loop.

Offline pitbuller
« Reply #14 - Posted 2011-06-20 05:21:09 »

You can also produce once per level and save to buffered image. It was possible to regenerate all graphcis per frame but it was little too much for slower computers. This is my cloud class.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
   private class Cloud implements Comparable<Object> {
      private float x;
      private float y;
      private float dx;
      int cloudColor;
      private BufferedImage image;

      private Cloud(GraphicsConfiguration gc) {
         this.x = (float) (r.nextInt(screenSizeX));
         this.y = (float) (r.nextInt(3 * (screenSizeY >>> 2)));
         int height = 60 + r.nextInt(80);
         int width = height + r.nextInt(170);

         if (simpleClouds) {
            image = gc.createCompatibleImage(width, height,
                  Transparency.BITMASK);
         } else {
            image = gc.createCompatibleImage(width, height,
                  Transparency.TRANSLUCENT);
         }
         Graphics2D g = (Graphics2D) image.getGraphics();
         int monta = (width * height) / (250 + r.nextInt(50));
         cloudColor =(180 + monta);
         if (cloudColor > 255)
            cloudColor = 255;
         int cloudAlpha = 5 + monta >>> 2;
         if (cloudAlpha > 20)
            cloudAlpha = 20;
         this.dx = 0.15f + (0.65f + 0.4f * r.nextFloat())
               * (float) ((cloudColor - 190) >>> 6);
         for (int i = 0; i < monta; i++) {
            int sizeY = 20 + r.nextInt(height >>> 1);
            int sizeX = sizeY + r.nextInt(width >>> 2);
            if (simpleClouds) {
               g.setColor(new Color(cloudColor, cloudColor, cloudColor));
            } else {
               g.setColor(new Color(cloudColor, cloudColor, cloudColor,
                     cloudAlpha));

            }
           
            g.fillOval(random(width - sizeX), random(height - sizeY),
                  sizeX, sizeY);
           
         }
         g.dispose();

         if (!simpleClouds) {
            for (int i = 0; i < 5; i++) {
               image = (filter(image));
            }
         }

      }

      private final int getCloudColor() {
         return this.cloudColor;
      }

      public final int compareTo(Object o) {
         int tmpInt = ((Cloud) o).getCloudColor();
         return this.cloudColor - tmpInt;
      }

      private final void draw(Graphics2D g) {
         g.drawImage(image, (int) (x), (int) (y), null);

      }

      final void move() {
         this.x -= this.dx;
         if ((this.x + image.getWidth() < 0)) {
            this.x = screenSizeX + this.image.getWidth();
            this.y = r.nextInt(3 * (screenSizeY >>> 2));
            this.dx = 0.15f + (0.65f + 0.4f * r.nextFloat())
                  * (float) ((cloudColor - 190) >>> 6);
         }
      }

      final void destroy() {
         image.flush();
         image = null;
      }
   }

When its created it's build random cloud with random size and position at Z axel. Usually I produce 30 clouds. Lots of random circles with random color and alpha and some filtering for smoothing. Then I just order the arraylist so black ones are drawed first. This class handles also moving and resetting the position. I have also class wich do sunset sky animation and mountains. It's produce 90frames when created and after that loop images slowly. Deleting any frames that will not be used anymore.

http://en.wikipedia.org/wiki/Procedural_generation


Offline ReBirth
« Reply #15 - Posted 2011-06-27 00:41:55 »

Thanks. I created a simple class for drawing background (terrain) from ahristov's tutorial and put it on BufferedImage gives a better performance
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.GeneralPath;
import java.awt.image.BufferedImage;
import java.awt.BasicStroke;
import java.util.Random;

public class Background{
   private static final int WIDTH = 800;
   private static final int HEIGHT = 600;

   private BufferedImage bi;

   public Background(){
      bi = new BufferedImage(WIDTH,HEIGHT,1);
      drawTerrain(bi.createGraphics());
   }

   private void drawTerrain(Graphics2D g){
      g.setColor(Color.white);
      g.fillRect(0,0,WIDTH,HEIGHT);
      Random rnd = new Random();
       float baseH = 190/360f;
       float baseS = 245/255f;
       float baseB = 233/255f;

       int MIN_Y = 50; //Y
      int MAX_Y = HEIGHT;
       int MIN_X = 0;
       int MAX_X = WIDTH;
       int LAYERS = 8;
       float BRIGHTNESS_STEP=163/255f/15;

       for (int y = MIN_Y; y<=MAX_Y; y+=(MAX_Y-MIN_Y)/LAYERS) {
         g.setColor(Color.getHSBColor(baseH,baseS,baseB));
         GeneralPath gp = new GeneralPath();
         gp.moveTo(MIN_X,MAX_Y);
         gp.lineTo(MIN_X,y);
         int x = 0;
         for (int i = 1; x < WIDTH; i++) {
            int deltaY = rnd.nextInt(150)-75;
            int deltaX = rnd.nextInt(200)+50;
            gp.quadTo(x+deltaX/2,y+deltaY,x+deltaX,y);
            x+=deltaX;
         }
         gp.lineTo(MAX_X,MAX_Y);
         g.fill(gp);
         g.setStroke(new BasicStroke(7));
         g.setColor(Color.getHSBColor(baseH,baseS,baseB+BRIGHTNESS_STEP*3/2));
         g.draw(gp);
         baseB -= BRIGHTNESS_STEP;
       }
   }

   public void draw(Graphics2D g){
      g.drawImage(bi,0,0,null);
   }
}

Honestly it's my first time to meet GeneralPath class and it's quite useful. Some background can be created from this I think Smiley

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Dwinin (22 views)
2014-09-12 09:08:26

Norakomi (55 views)
2014-09-10 13:57:51

TehJavaDev (66 views)
2014-09-10 06:39:09

Tekkerue (33 views)
2014-09-09 02:24:56

mitcheeb (54 views)
2014-09-08 06:06:29

BurntPizza (38 views)
2014-09-07 01:13:42

Longarmx (24 views)
2014-09-07 01:12:14

Longarmx (30 views)
2014-09-07 01:11:22

Longarmx (28 views)
2014-09-07 01:10:19

mitcheeb (37 views)
2014-09-04 23:08:59
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!