Show Posts
|
|
Pages: [1] 2 3
|
|
3
|
Game Development / Newbie & Debugging Questions / Re: Why is this stuttering?
|
on: 2012-04-29 21:15:53
|
For anyone curious, this is what ended up working O_o 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
| private void gameLoop5() {
if (System.getProperty("os.name").startsWith("Win")) { new Thread() {
{ setDaemon(true); start(); }
public void run() { while (true) { try { Thread.sleep(Long.MAX_VALUE); } catch (Exception exc) { } } } }; }
long lastTime = 0; long nanosInSecond = 1000L * 1000L * 1000L; long updateFrequency = 60; long updateInterval = nanosInSecond / updateFrequency; long nextUpdateTick = System.nanoTime(); long now = 0; long start = 0; long FPS = 60;
while (running) { long deltaTime = System.nanoTime() - lastTime; lastTime += deltaTime; start = System.nanoTime(); for (now = System.nanoTime(); now > nextUpdateTick; nextUpdateTick += updateInterval) { this.update(); } process_time += System.nanoTime() - start; render(); Toolkit.getDefaultToolkit().sync(); long sleepTime = Math.round((1000000000 / FPS - (System.nanoTime() - lastTime)) / 1000000); if (sleepTime < 0) continue; long prev = System.nanoTime(), diff; while ((diff = System.nanoTime() - prev) < sleepTime) { if (diff < sleepTime * 0.8) try { Thread.sleep(1); } catch (Exception exc) { } else Thread.yield(); } } } |
|
|
|
|
|
8
|
Game Development / Newbie & Debugging Questions / Why is this stuttering?
|
on: 2012-04-29 01:00:21
|
Here's a demo of the applet http://www.joeysturgis.com/roguelikeHere's the game loop: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| private void gameLoop3(long ufreq) { long nanosInSecond = 1000L * 1000L * 1000L; long updateFrequency = ufreq; long updateInterval = nanosInSecond / updateFrequency; long nextUpdateTick = System.nanoTime(); while (true) { long start = System.nanoTime(); for (long now = System.nanoTime(); now > nextUpdateTick; nextUpdateTick += updateInterval) { this.update(); } process_time += System.nanoTime() - start; render(); Sync.sync(60); } } |
Here's sync: 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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
| package com.ingamedev.util;
public class Sync {
private static final long NANOS_IN_SECOND = 1000L * 1000L * 1000L;
private static long nextFrame = 0; private static boolean initialised = false; private static RunningAvg sleepDurations = new RunningAvg(10); private static RunningAvg yieldDurations = new RunningAvg(10); public static void sync(int fps) { if (fps <= 0) return; if (!initialised) initialise(); try { for (long t0 = getTime(), t1; (nextFrame - t0) > sleepDurations.avg(); t0 = t1) { Thread.sleep(1); sleepDurations.add((t1 = getTime()) - t0); } sleepDurations.dampenForLowResTicker(); for (long t0 = getTime(), t1; (nextFrame - t0) > yieldDurations.avg(); t0 = t1) { Thread.yield(); yieldDurations.add((t1 = getTime()) - t0); } } catch (InterruptedException e) { } nextFrame = Math.max(nextFrame + NANOS_IN_SECOND / fps, getTime()); } private static void initialise() { initialised = true; sleepDurations.init(1000 * 1000); yieldDurations.init((int) (-(getTime() - getTime()) * 1.333)); nextFrame = getTime(); String osName = System.getProperty("os.name"); if (osName.startsWith("Win")) { Thread timerAccuracyThread = new Thread(new Runnable() { public void run() { try { Thread.sleep(Long.MAX_VALUE); } catch (Exception e) {} } }); timerAccuracyThread.setDaemon(true); timerAccuracyThread.start(); } }
private static long getTime() { return System.nanoTime(); }
private static class RunningAvg { private final long[] slots; private int offset; private static final long DAMPEN_THRESHOLD = 10 * 1000L * 1000L; private static final float DAMPEN_FACTOR = 0.9f; public RunningAvg(int slotCount) { this.slots = new long[slotCount]; this.offset = 0; }
public void init(long value) { while (this.offset < this.slots.length) { this.slots[this.offset++] = value; } }
public void add(long value) { this.slots[this.offset++ % this.slots.length] = value; this.offset %= this.slots.length; }
public long avg() { long sum = 0; for (int i = 0; i < this.slots.length; i++) { sum += this.slots[i]; } return sum / this.slots.length; } public void dampenForLowResTicker() { if (this.avg() > DAMPEN_THRESHOLD) { for (int i = 0; i < this.slots.length; i++) { this.slots[i] *= DAMPEN_FACTOR; } } } } }
|
Here's render: 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
| public void render() { frames++; frame_count++; long start = System.nanoTime();
Graphics2D g = tmp.createGraphics(); g.setColor(Color.black); g.fillRect(0, 0, WIDTH, HEIGHT); level.draw_edge_persepctive(g, SpriteType.ranger, x, y, pixel_x, pixel_y, 13, 9); for(Entity e : entities) { e.render(g, level.p_screen_x, level.p_screen_y); } Font.printString(tmp, "Rogu3", 4, 4, 5, 0x65DE31, 0x454545); Font.printString(tmp, "Power: " + score, 4, Font.h * 2 + 4, 24, 0xFA1122, 0x911122); Font.printString(tmp, "Entities: " + Level.ent_count, 4, Game.HEIGHT - (Font.h * 2) - 4, 24, 0xFFFFFF, 0x000000); Font.printString(tmp, "FPS: " + fps, 800 - 80 - 16, 4, 50, 0xABABAB, 0x232323); announce(g); g.drawImage(Art.border, 0, 0, 8, 8, 0, 0, 8, 8, null); g.drawImage(Art.border, Game.WIDTH - 8, 0, Game.WIDTH, 8, 24, 0, 32, 8, null); g.drawImage(Art.border, 0, Game.HEIGHT - 8, 8, Game.HEIGHT, 0, 24, 8, 32, null); g.drawImage(Art.border, Game.WIDTH - 8, Game.HEIGHT - 8, Game.WIDTH, Game.HEIGHT, 24, 24, 32, 32, null); for(int ix = 0; ix <= 50; ix ++) { g.drawImage(Art.border, 8 + (ix * 16), 0, 8 + (ix * 16) + 16, 8, 8, 0, 24, 8, null); } for(int ix = 0; ix <= 50; ix ++) { g.drawImage(Art.border, 8 + (ix * 16), Game.HEIGHT - 8, 8 + (ix * 16) + 16, Game.HEIGHT, 8, 24, 24, 32, null); } for(int iy = 0; iy <= 34; iy ++) { g.drawImage(Art.border, 0, 8 + (iy * 16), 8, 8 + (iy * 16) + 16, 0, 8, 8, 24, null); } for(int iy = 0; iy <= 34; iy ++) { g.drawImage(Art.border, Game.WIDTH - 8, 8 + (iy * 16), Game.WIDTH, 8 + (iy * 16) + 16, 24, 8, 32, 24, null); }
g.dispose(); g = getGraphics(); if(g != null) { g.drawImage(tmp, 0, 0, null); g.dispose(); flip(); } render_time = System.nanoTime() - start; if (System.nanoTime() > next_frame_count) { next_frame_count = System.nanoTime() + 1000000000; fps = frame_count; frame_count = 0; System.out.println("FPS: " + fps + ", Process Time: " + process_time / 60 + " Render Time: " + render_time); process_time = 0; } } |
A few seconds of running... FPS: 1, Process Time: 7992 Render Time: 138639760 FPS: 57, Process Time: 161622 Render Time: 9624389 FPS: 60, Process Time: 104913 Render Time: 11918064 FPS: 61, Process Time: 103605 Render Time: 8334624 FPS: 60, Process Time: 101535 Render Time: 12660010 FPS: 61, Process Time: 107089 Render Time: 8015489 FPS: 42, Process Time: 142956 Render Time: 18470568 FPS: 62, Process Time: 129872 Render Time: 8149031 FPS: 60, Process Time: 93706 Render Time: 10992659 FPS: 60, Process Time: 93977 Render Time: 11397550 FPS: 60, Process Time: 89091 Render Time: 12375007 FPS: 60, Process Time: 88103 Render Time: 12378847 FPS: 61, Process Time: 90599 Render Time: 10045067 FPS: 60, Process Time: 105866 Render Time: 11264862 FPS: 61, Process Time: 79250 Render Time: 11252489 FPS: 59, Process Time: 96743 Render Time: 16203345 FPS: 61, Process Time: 104095 Render Time: 13690799 FPS: 61, Process Time: 107302 Render Time: 10396627 FPS: 60, Process Time: 95676 Render Time: 12034540 FPS: 61, Process Time: 95185 Render Time: 12393353 FPS: 61, Process Time: 88039 Render Time: 12382261 FPS: 61, Process Time: 86411 Render Time: 12071659 FPS: 60, Process Time: 91651 Render Time: 13107567 FPS: 61, Process Time: 96309 Render Time: 10673097
|
|
|
|
|
9
|
Game Development / Newbie & Debugging Questions / Re: Java2D drawing colored bitmap fonts
|
on: 2012-04-27 23:14:13
|
Just to make sure - I assume you're rendering text in lots (hundreds maybe?) of different colors, maybe cycling through them for effect? Because if you're only writing text in a few different colors, why not simply create a Map<Color, Font>, where each value is created as a copy of the original font image with the original color (e.g. white or black) changed to the new one, and lazily create entries per color?
Just wanted a system that was "smart enough" to do any color without having a version of it in memory. Considering we're just putting pixels on the screen, it should be doable via mathematical equation.
|
|
|
|
|
10
|
Game Development / Newbie & Debugging Questions / Re: Render tiles for RPG game
|
on: 2012-04-27 22:36:04
|
I managed to draw the tiles and now I'm working on the player.  And I have a green bg in the tiles file can I remove it when it renders or is it better to remove the bg from the image file? Just make it transparent in the image, as J2D and OGL both fully support transparent image formats (like PNG).
|
|
|
|
|
11
|
Game Development / Newbie & Debugging Questions / Re: Java2D drawing colored bitmap fonts
|
on: 2012-04-27 22:25:23
|
Of course, that's fine. Why would you think it wouldn't work? The only "slow" part is actually drawing the bitmap images and the color, but that should be much faster than copying each pixel one by one, unmanaging the image in the process.
Ok, cool. I think I will experiment a lot with this. This could perhaps lead to dynamic lighting of some sort as well by maybe rendering a light map image to composite over the scene.
|
|
|
|
|
12
|
Game Development / Newbie & Debugging Questions / Re: Java2D drawing colored bitmap fonts
|
on: 2012-04-27 20:21:08
|
The original font image is never modified, so you can simply redraw the white letters with a different color rect later  I was never under the impression or assumption that the original font image is modified. I am asking if I can do this (and if it is fast, and if its the right way to go about it): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ...public void drawString(String s, Color r) { blah blah blah draw bitmap images / letters to font buffer image change composite set color, draw color rect reset composite back } ...Font.drawString("hello", red); Font.drawString("cool", orange); ... Font.clear(); GuiCode(); Font.render(g);... |
If the above is slow or not the proper way to do it, then the only other way to do it with one composite change and multiple colors would be some sort of batch buffer.
|
|
|
|
|
13
|
Game Development / Newbie & Debugging Questions / Re: Java2D drawing colored bitmap fonts
|
on: 2012-04-27 09:41:09
|
|
Thanks so much for this. The reason I am really forcing the J2D is because I don't want to go down that spiral of signed jar's for browser applets etc. etc. If there's a really easy way to get OGL in a Java applet without asking the user anything... and I can use a pixel-level screen format (1 + 1 = 2 pixels) I'M IN!!
|
|
|
|
|
17
|
Game Development / Newbie & Debugging Questions / Re: Java2D drawing colored bitmap fonts
|
on: 2012-04-27 06:11:01
|
|
oh are you saying to do all of that within one frame, per text && text_color?
so if i wanna draw something in red, then something in orange, i'm "drawing the letters, setting the composite, setting the color, filling the image, drawing the image, clearing the image" once for red, and once again for orange (all in the same rendering frame)
|
|
|
|
|
26
|
Game Development / Newbie & Debugging Questions / Re: Java2D drawing colored bitmap fonts
|
on: 2012-04-27 03:20:30
|
You're supposed to set the Composite before you draw the rect  Also, make sure you reset the AlphaComposite to what it was previously after drawing the rect. Oh wait, you're assuming that I'm rendering text to a image which gets drawn to another image, I think... which would explain why none of this is working because I'm just drawing the text (bitmapped font) directly onto the canvas. So I'm guessing this would work if I was using a BufferedImage just for text rendering, clearing it to black every frame (  ) and then using alpha composite to draw that to the canvas.
|
|
|
|
|
29
|
Game Development / Newbie & Debugging Questions / Re: Java2D drawing colored bitmap fonts
|
on: 2012-04-26 17:50:41
|
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
| public static void test(Graphics2D g, String string, int x, int y, int cwidth, int color, int bgcolor) { int px = 0; int py = 0; char c; int sx; int sy; int pixel_x = 0; int pixel_y = 0; int ix = 0; int iy = 0; int i = 0; int src_color = 0; for(i = 0; i < string.length(); i++) { c = string.charAt(i); if(c == 32) { px += w * 2; if(px / (w * 2) > cwidth) { px = 0; py += h * 2; } continue; } sx = c; sy = 0; while(sx > 15) { sx -= 16; sy++; } sx *= w; sy *= h; pixel_x = x + px; pixel_y = y + py; g.drawImage(Art.font_white, pixel_x, pixel_y, pixel_x + w * 2, pixel_y + h * 2, sx, sy, sx + w, sy + h, null); px += w * 2; if(px / (w * 2) > cwidth) { px = 0; py += h * 2; } } Composite comp = g.getComposite(); g.setComposite(AlphaComposite.SrcIn); g.setColor(Color.red); g.fillRect(x, y, cwidth * 16, 32); g.setComposite(comp); } |
 What am I doing wrong? Here's what happens if I comment out the composite / fillrect section 
|
|
|
|
|
|
Add your game by posting it in the WIP section,
or publish it in Showcase.
The first screenshot will be displayed as a thumbnail.
|
|