• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.

PixelPrime11

Members
  • Content count

    10
  • Joined

  • Last visited

Community Reputation

108 Neutral

About PixelPrime11

  • Rank
    Member
  1. Thanks, I can see your point about it potentially closing the door to using further instances of the class for other reasons. It might help to give some background on the class. It's a Canvas for a drawing / modelling application, so I know for a certainty that there can only ever be one instance of the class active at any time (this isn't a multiple-workspace type of project). A workspace can only have one canvas. Perhaps I need to think about reorganising the communication of data between the classes outside of the workspace so that rather than relying on a call directly to a static method inside of the Canvas object, I can pass a reference to the (only) instance of the Canvas to the required classes as an argument. It'll just mean a bunch of refactoring - but eh, if we had a few bucks everytime we did that... [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img]
  2. This is a general OOP question, as I didn't know if this is an 'accepted' practice in programming! I have some classes in my application that only ever get instantiated once - for example, a class that defines application settings and properties. However, when I want to reference this class instance from another class, I'm kinda stumped because I don't have a visible reference to my class instance. Sure, I could pass the class instance reference into the functions that need it, but that seems ugly. Instead, I've added a static reference to the class instance, and can therefore refer to that instance from any other class. Example: [source lang="java"]public class Settings { // static reference to a settings object public static Settings ref; public Settings() { // apply a self-reference settings = self; } private void doSomething() { ... } }[/source] So, from another class file entirely, I can refer to my single Settings class instance by using the in-built static reference, giving me access to its private methods: [source lang="java"]Settings.ref.doSomething();[/source] Is this an acceptible method of doing this? Or is this type of self-referencing frowned upon? Should I just make all required 'public' members and methods in the class static instead? [source lang="java"]public class Settings { public Settings() { // do nothing } public static void doSomething() { ... } }[/source] I'm looking forward to some insight on this! Thanks all!
  3. I'm not sure what you mean by which Matrix Library, unless you mean LWJGL's implementation of this? The methods I use to accomplish the transformations are as follows: [source lang="java"]glLoadIdentity(); glTransform3f(camera.x, camera.y, camera.z); glRotate3f(camera.yaw, 0.0f, 1.0f, 0.0f); glRotate3f(camera.pitch, 1.0f, 0.0f, 0.0f); [/source] So, if I were trying to draw an object in the world, I'd call the above code first, then this: [source lang="java"] // move to the object's coordinates glTranslate3f(position.x, position.y, position.z); // rotate the object (Y axis only) glRotate3f(rotation.y, 0.0f, 1.0f, 0.0f); // draw the object glBegin(GL_QUADS); // vertex draw operations glEnd();[/source]
  4. Hi All, I'm currently having some positioning problems using OpenGL and LWJGL, but figured this would be generic enough for the OGL forum! I wanted to know whether my method for positioning objects in the world is correct, as I'm not sure my matrix operations are in the right order. For every object that's placed in the world, I'm doing the following:[list] [*]Load the Identity Matrix (reset everything) [*]Translate to the [b]camera's [/b]X, Y, Z position [*]Rotate the camera around the X and Y axes (I'm not doing Z rolling) [*]Translate to the [b]object's[/b] X, Y, Z position [*]Rotate the [b]object [/b]around the X, Y, Z axes. [/list] I keep tweaking things and somehow getting it to work, but I'd like to know the de-facto method for accomplishing this. I'm aware that you're normally supposed to rotate before a translation, but I think it works different in LWJGL? I might be wrong on this, though. Every object has its own X, Y, Z position in the world, as has the camera. But the whole interation between them has confused me to no end now! Thanks for any assistance anyone can offer : )
  5. Hi fellow coders, I'm having real issues with identifying the 'player' position in 3D space in relation to other objects in the world. In the render pass, this happens: [source lang="java"] public void render() { float halfBlock = BLOCKSIZE / 2f; float originX = (position.x * BLOCKSIZE) - halfBlock; float originY = (position.y * BLOCKSIZE) - halfBlock; float originZ = (position.z * BLOCKSIZE) - halfBlock; glPushMatrix(); // bind the sides texture texForSides.bind(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBegin(GL_QUADS); // back face glColor3f(lightBack, lightBack, lightBack); glTexCoord2d(1, 0); glVertex3f(originX, originY + BLOCKSIZE, originZ); glTexCoord2d(0, 0); glVertex3f(originX + BLOCKSIZE, originY + BLOCKSIZE, originZ); glTexCoord2d(0, 1); glVertex3f(originX + BLOCKSIZE, originY, originZ); glTexCoord2d(1, 1); glVertex3f(originX, originY, originZ); // front face glColor3f(lightFront, lightFront, lightFront); glTexCoord2d(0, 1); glVertex3f(originX, originY, originZ + BLOCKSIZE); glTexCoord2d(1, 1); glVertex3f(originX + BLOCKSIZE, originY, originZ + BLOCKSIZE); glTexCoord2d(1, 0); glVertex3f(originX + BLOCKSIZE, originY + BLOCKSIZE, originZ + BLOCKSIZE); glTexCoord2d(0, 0); glVertex3f(originX, originY + BLOCKSIZE, originZ + BLOCKSIZE); // left face glColor3f(lightLeft, lightLeft, lightLeft); glTexCoord2d(1, 1); glVertex3f(originX, originY, originZ + BLOCKSIZE); glTexCoord2d(1, 0); glVertex3f(originX, originY + BLOCKSIZE, originZ + BLOCKSIZE); glTexCoord2d(0, 0); glVertex3f(originX, originY + BLOCKSIZE, originZ); glTexCoord2d(0, 1); glVertex3f(originX, originY, originZ); // right face glColor3f(lightRight, lightRight, lightRight); glTexCoord2d(1, 1); glVertex3f(originX + BLOCKSIZE, originY, originZ); glTexCoord2d(1, 0); glVertex3f(originX + BLOCKSIZE, originY + BLOCKSIZE, originZ); glTexCoord2d(0, 0); glVertex3f(originX + BLOCKSIZE, originY + BLOCKSIZE, originZ + BLOCKSIZE); glTexCoord2d(0, 1); glVertex3f(originX + BLOCKSIZE, originY, originZ + BLOCKSIZE); glEnd(); // bind the top texture texForBottom.bind(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBegin(GL_QUADS); // bottom face glColor3f(lightBottom, lightBottom, lightBottom); glTexCoord2d(0, 0); glVertex3f(originX + BLOCKSIZE, originY, originZ); glTexCoord2d(1, 0); glVertex3f(originX + BLOCKSIZE, originY, originZ + BLOCKSIZE); glTexCoord2d(1, 1); glVertex3f(originX, originY, originZ + BLOCKSIZE); glTexCoord2d(0, 1); glVertex3f(originX, originY, originZ); glEnd(); // bind the bottom texture texForTop.bind(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBegin(GL_QUADS); // top face glColor3f(lightTop, lightTop, lightTop); glTexCoord2d(0, 0); glVertex3f(originX, originY + BLOCKSIZE, originZ); glTexCoord2d(1, 0); glVertex3f(originX, originY + BLOCKSIZE, originZ + BLOCKSIZE); glTexCoord2d(1, 1); glVertex3f(originX + BLOCKSIZE, originY + BLOCKSIZE, originZ + BLOCKSIZE); glTexCoord2d(0, 1); glVertex3f(originX + BLOCKSIZE, originY + BLOCKSIZE, originZ); glEnd(); glPopMatrix(); } [/source] The following shows the code that renders a block into the world: [source lang="java"] public void render() { float halfBlock = BLOCKSIZE / 2f; float originX = (position.x * BLOCKSIZE) - halfBlock; float originY = (position.y * BLOCKSIZE) - halfBlock; float originZ = (position.z * BLOCKSIZE) - halfBlock; glPushMatrix(); // bind the sides texture texForSides.bind(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBegin(GL_QUADS); // back face glColor3f(lightBack, lightBack, lightBack); glTexCoord2d(1, 0); glVertex3f(originX, originY + BLOCKSIZE, originZ); glTexCoord2d(0, 0); glVertex3f(originX + BLOCKSIZE, originY + BLOCKSIZE, originZ); glTexCoord2d(0, 1); glVertex3f(originX + BLOCKSIZE, originY, originZ); glTexCoord2d(1, 1); glVertex3f(originX, originY, originZ); // front face glColor3f(lightFront, lightFront, lightFront); glTexCoord2d(0, 1); glVertex3f(originX, originY, originZ + BLOCKSIZE); glTexCoord2d(1, 1); glVertex3f(originX + BLOCKSIZE, originY, originZ + BLOCKSIZE); glTexCoord2d(1, 0); glVertex3f(originX + BLOCKSIZE, originY + BLOCKSIZE, originZ + BLOCKSIZE); glTexCoord2d(0, 0); glVertex3f(originX, originY + BLOCKSIZE, originZ + BLOCKSIZE); // left face glColor3f(lightLeft, lightLeft, lightLeft); glTexCoord2d(1, 1); glVertex3f(originX, originY, originZ + BLOCKSIZE); glTexCoord2d(1, 0); glVertex3f(originX, originY + BLOCKSIZE, originZ + BLOCKSIZE); glTexCoord2d(0, 0); glVertex3f(originX, originY + BLOCKSIZE, originZ); glTexCoord2d(0, 1); glVertex3f(originX, originY, originZ); // right face glColor3f(lightRight, lightRight, lightRight); glTexCoord2d(1, 1); glVertex3f(originX + BLOCKSIZE, originY, originZ); glTexCoord2d(1, 0); glVertex3f(originX + BLOCKSIZE, originY + BLOCKSIZE, originZ); glTexCoord2d(0, 0); glVertex3f(originX + BLOCKSIZE, originY + BLOCKSIZE, originZ + BLOCKSIZE); glTexCoord2d(0, 1); glVertex3f(originX + BLOCKSIZE, originY, originZ + BLOCKSIZE); glEnd(); // bind the top texture texForBottom.bind(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBegin(GL_QUADS); // bottom face glColor3f(lightBottom, lightBottom, lightBottom); glTexCoord2d(0, 0); glVertex3f(originX + BLOCKSIZE, originY, originZ); glTexCoord2d(1, 0); glVertex3f(originX + BLOCKSIZE, originY, originZ + BLOCKSIZE); glTexCoord2d(1, 1); glVertex3f(originX, originY, originZ + BLOCKSIZE); glTexCoord2d(0, 1); glVertex3f(originX, originY, originZ); glEnd(); // bind the bottom texture texForTop.bind(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBegin(GL_QUADS); // top face glColor3f(lightTop, lightTop, lightTop); glTexCoord2d(0, 0); glVertex3f(originX, originY + BLOCKSIZE, originZ); glTexCoord2d(1, 0); glVertex3f(originX, originY + BLOCKSIZE, originZ + BLOCKSIZE); glTexCoord2d(1, 1); glVertex3f(originX + BLOCKSIZE, originY + BLOCKSIZE, originZ + BLOCKSIZE); glTexCoord2d(0, 1); glVertex3f(originX + BLOCKSIZE, originY + BLOCKSIZE, originZ); glEnd(); glPopMatrix(); } [/source] Everything seems to render fine, and I'm able to navigate around the world by manipulating the camera position. I have a method inside of my Block class (shown below) that checks to see whether a given Vector3f point in space is within the block's volume. The block is drawn from the middle, so 0,0,0 would be at the center of the cube. For example, a block created at grid location (0, 0, -8) reports the following data when the player is 'inside' the cube: Camera position: [-0.03],[-0.14],[-0.03] Block: [-0.5 > 0.5],[-0.5 > 0.5],[-8.5 > -7.5] N.B. The 'Block' line above shows the bounds for each axis (X min = -0.5, X max = 0.5, etc.). I can't figure out why the camera isn't showing similar coords to the block [img]http://public.gamedev.net//public/style_emoticons/default/sad.png[/img] Here's the Block class method for determining if a point in space is within its own volume: [source lang="java"] public boolean isPointInside(Vector3f point) { float minX = position.x - (BLOCKSIZE / 2); float maxX = position.x + (BLOCKSIZE / 2); float minY = position.y - (BLOCKSIZE / 2); float maxY = position.y + (BLOCKSIZE / 2); float minZ = position.z - (BLOCKSIZE / 2); float maxZ = position.z + (BLOCKSIZE / 2); System.out.println("Block: [" + minX + " > " + maxX + "],[" + minY + " > " + maxY + "],[" + minZ + " > " + maxZ + "]"); if (point.x > minX && point.y > minY && point.z > minZ) { if (point.x < maxX && point.y < maxY && point.z < maxZ) { return true; } } return false; } [/source] Any assistance with this would be greatly appreciated. P.S. I know there are likely to be some heinous mistakes or irregularities with my code. I'm new to 3D Java programming (and LWJGL), so I'm likely to be making mistakes at the moment!
  6. [font="Impact"][size="3"][b]SOLVED![/b][/size][/font] Ok, so the solution was a combination of things actually, but in the end I've found something that's now producing the perfect result - no more sticking, jittering or unsightly artefacts! And all this with pixel-perfect collision responses. I finished with an implementation of the checking of X intersections first, then the Y. The Y checks would only run if the X checks failed. Here's the final collision code: [b]N.B. This code assumes that the player's bounding box will be smaller than the bounding boxes of objects it needs to be stopped by (i.e. walls, floors etc)[/b]. [CODE] function DoCollisions() { var newX = Player.x + speedX; var newY = Player.y + speedY; var runCheckY = true; var runCheckX = true; for (var i = 0; i < Level.numChildren; i++) { var clip = Level.getChildAt(i); if (getQualifiedClassName(clip) == "BLOCK") { var objectBothAxes = new Rectangle(newX, newY, Player.width, Player.height); if (WillIntersect(objectBothAxes, clip)) { var objectOnlyMoveX = new Rectangle(newX, Player.y, Player.width, Player.height); if (WillIntersect(objectOnlyMoveX, clip)) { if (runCheckX) { // we've intersected on the X axis, so stop horizontal movement if (speedX > 0) { // moving right, colliding with the LEFT side of the block speedX = 0; Player.x = clip.x - Player.width; runCheckX = false; } else { // moving left, colliding with the RIGHT side of the block speedX = 0; Player.x = clip.x + clip.width; runCheckX = false; } } } else { if (runCheckY) { var objectOnlyMoveY = new Rectangle(Player.x, newY, Player.width, Player.height); if (WillIntersect(objectOnlyMoveY, clip)) { // we've intersected on the Y axis, so stop vertical movement if (speedY > 0) { // moving down, colliding with the TOP side of the block speedY = 0; Player.y = clip.y - Player.height; runCheckY = false; } else { // moving up, colliding with the BOTTOM side of the block speedY = 0; Player.y = clip.y + clip.height; runCheckY = false; } } } } } } } } [/CODE] This code, however, strongly relies on important checks made to this function, which looks for the intersect: [CODE] function WillIntersect(object, clip) { if (object.x + object.width - 1 < clip.x || object.y + object.height - 1 < clip.y || object.x + 1 > clip.x + clip.width || object.y + 1 > clip.y + clip.height) { return false; } else { return true; } } [/CODE] I discovered that the problem wasn't with zeroing out the [b]speedX[/b] and [b]speedY[/b] values, but with the code I was using the reposition the object in the collision response. I found out that if I change the line of code [b]Player.x = clip.x + clip.width[/b] (in response to moving left into the right side of a block) to the following code: [b]Player.x = clip.x + clip.width + 1 [/b]I wouldn't get any more 'sticking' or jumping artefacts. However, it left me with a 1 pixel gap between the collision surface and the player. Solving it was simply a matter of changing the collision intersection threshold by 1 pixel, thus moving it from collision response to collision detection. You can see the 1 pixel threshold has been moved into the [b]WillIntersect(...) [/b]method. This means, technically, that you're actually allow to invade the block by 1 pixel before the check returns a valid collision, whereas before you could still trigger it by being slightly outside, or on the edge. Wow, that has been a week-and-a-half long problem now resolved. I can't thank you both enough for giving me a fresh perspective on this, and I hope the information contained in my reply above will help others overcome this issue.
  7. These are both quality suggestions, thank you both so much! I'll see if I can implement a good checking method taking these points into account. It's unfortunate that something so simple can turn out to be so complicated to resolve! I'll post my findings, and if solved, my final code for anyone else having these problems too!
  8. [quote name='Methodic' timestamp='1318864195' post='4873475'] It really does sound like the way to go. So basically the player position (possibly the center of the screen) would tell which node the player is currently at, and then it would page back from there loading entities till it reaches a node that covers the entire screen? I should probably do a lot of reading up on quadtrees first before asking to many questions as I believe there there are lots of information on this to read, but any more input on this is still appreciated of course. Thanks PixelPrime11 for the response! [/quote] No worries at all. I just had a thought - if you're making a 3D game then a quadtree might not be the ultimate solution since that deals mainly with 2D data structures. The last time I checked we lived in more than 2-dimensions! Octrees are the 3D equivalent, although it's possible to still represent a galaxy in a Quadtree - providing, of course, you don't have one element sharing the same Y position in space as another. Of course, that's impractical, so looking at Octress for full space partitioning would be the way forward, I think. Your reasoning is sound, however. You'd locate your player's position in relation to the relevant tree node and work outwards until you've encompassed your entire 'active' region. Superimposing your intended new position into the quadtree should give you the overlapping nodes and give you the new data structures to peek inside. Quad or Octree, it's pretty much the same theory either way, just more dimensions to think about. I don't have a tremendous amount of experience working with anything other than quadtrees, though, so you might need some advice from someone else much more versed in these matters
  9. [quote name='Methodic' timestamp='1318860394' post='4873456'] Hello, I'm thinking of making an space exploration game and I'm wondering what would be the most effective way of storing and retrieving information about entities existing in the universe. Say, for instance, the player is moving in a direction in space - how would I load the incoming planets and stars from a storage without having to go through all existing entities and check their relative position to the player? [/quote] Hi There, I read somewhere else regarding a similar topic to this, that the answer could like in quadtrees or a similar data structure - where you can recursively page back through local nodes in order to retrieve 'nearby' objects without having to traverse too far. A similarly intelligent data structure would be your answer, though.
  10. Hi All, I'm wondering if someone can help offer some insight into a very frustrating problem I'm having. I've currently written a small platform test demo, but some of the collision detection is causing strange movement problems (teleporting to the tops of blocks, sticking to the sides etc.). The player is moved every frame using inertia / velocity values, as such: [code]Player.x += speedX; Player.y += speedY;[/code] Before the player movement is updated, however, I run a collision check against all blocks in the level. Naturally, in the final version I'll be limiting the number of these checks to only nearby objects, but I need the theory to work first! When testing collison, I first run a quick exclusion text to see if the player and block are going to intersect: [code] function WillIntersect(block) { var newX = Player.x + speedX; var newY = Player.y + speedY; if (Player.x > block.x + block.width || Player.y > block.y + block.height || Player.x + Player.width < clip.x || Player,y + Player.height < clip.y) { // no intersection, thus no collision return false; } else { // the two object bounding boxes intersect in some way return true; } }[/code] Then, as a result of this check, I then move into a collision detection method that attempts to resolve the collision that occured. The following rules persist for movement around the game level: [list][*]If no intersection was detected with any object, the [b]speedX [/b]and [b]speedY [/b]values will remain unmodified.[*]If the player falls onto the top of a block, the [b]speedY [/b]value is zeroed-out and they are [b]repositioned[/b] on top of the block with pixel precision[*]If the player hits the underside of a block, the [b]speedY[/b] value is zeroed-out and they are [b]repositioned[/b] directly underneath the block[*]If the player hits the left, or right side of a block, the [b]speedX[/b] value is zeroed-out and they are [b]repositioned[/b] to the relevant edge.[/list] The problem I have is when a combination of these factors occur. When the player jumps sideways against a wall (or the edge of a platform), the player will 'stick' to the vertical surface because the code generating the 'push to top' or 'push to bottom' check is running and canceling out any other checks. [b]Video of the effect in question: [/b][url="http://www.youtube.com/watch?v=nFusvi8U_-A"]http://www.youtube.c...h?v=nFusvi8U_-A[/url] Finally, here's the code I'm currently using for the collisions. I've been tearing my hair out over this for over a week now, and just need some fresh viewpoints - you know what it's like when you've been staring at the same problem for days on end! [CODE] function DoCollisions() { txtOutput.text = ""; var newX = Player.x + speedX; var newY = Player.y + speedY; for (var i = 0; i < Level.numChildren; i++) { var clip = Level.getChildAt(i); if (getQualifiedClassName(clip) == "BLOCK") { if (WillIntersect(clip)) { if (speedX > 0) { speedX = 0; Player.x = clip.x - Player.width; } else if (speedX < 0) { speedX = 0; Player.x = clip.x + clip.width; } else { } if (speedY > 0) { speedY = 0; Player.y = clip.y - Player.height; } else if (speedY < 0) { speedY = 0; Player.y = clip.y + clip.height; } else { } } } } } [/CODE] Thanks to anyone who can offer some advice here.