Jump to content


Photo
- - - - -

Stylistic Fake 3d


  • Please log in to reply
11 replies to this topic

#1 NAL

NAL

    凸ʕಠᴥಠʔ凸

  • YoYo Games Staff
  • 686 posts
  • Version:GM:Studio

Posted 01 May 2010 - 09:30 PM

  • Title: Stylistic Fake 3D tutorial
  • Description: Shows one method of making an unrealistic, but stylish, fake 3D compatible with both Lite and Pro
  • GM Version: 5-8
  • Registered: No*
  • File Type: .gmk (GM8)
  • File Size: 9.84kb
  • File Link: http://dl.dropbox.co...isticfake3d.gmk

*everything listed in this tutorial can be done in Lite or Pro. However, some things you may want to achieve with the same effect may require Pro.

Posted Image

A technique I frequently use in games is fake 3D. This may just be seen as a ploy for attention - "why use fake 3D when Game Maker has REAL 3D built-in right off the bat?" Well, there are advantages to it. It's much easier to manipulate object depth manually. You can draw something ontop of another without any of those odd graphical issues where the two seem to keep "striping" into each other. You can use surfaces. You can ignore the concept of perspective. You can even do it in Game Maker Lite. There are plenty of things you can do with it. So how do you?

Firstly, you should know how to use lengthdir_x and lengthdir_y properly. If you don't, it doesn't take much to learn - here's something that will hopefully help.

The GML code for the functions are (and note that you'll pretty much ALWAYS use them as a pair):

lengthdir_x(len,dir);
lengthdir_y(len,dir);

Their purpose is to give you a coordinate, if you take (0,0) and translate it len pixels in the direction dir (note the way direction is done in GM - 0 degrees is right, 90 degrees is up, 180 degrees is right, 270 degrees is down). Of course, it's unlikely you'd need anything to be relative to (0,0), so your typical code may be something like:

oBall.x=x+lengthdir_x(len,dir);
oBall.y=y+lengthdir_y(len,dir);

An example of lengthdir is shown here:

Posted Image

If you still don't understand lengthdir, look up some other tutorials on Game Maker Community - there are many very helpful ones.

Okay, so for the first little fake 3D test, you're going to need a circle, which you can move with the directional buttons. Furthermore, he should be taking the screen view with him as he moves. Create a circular sprite (centralising its origin), give it an object and name it oCircle, and put this in Step:

if keyboard_check(vk_left) {x-=4;}
if keyboard_check(vk_right) {x+=4;}
if keyboard_check(vk_up) {y-=4;}
if keyboard_check(vk_down) {y+=4;}

view_xview[0]=x-320;
view_yview[0]=y-240;

Make a quick background which just needs to be a non-solid colour. A square will do fine. Make a new room, put the background in with it looping forever, put the guy somewhere in the room, and activate views and View 0 (tick "Enable the use of views", make sure View 0 is highlighted, then click "Visible when room starts") but DO NOT have it set to follow the player character (this is already done with the two last lines of code above, and holds the extra advantage of not stopping when the view hits the end of the room).

Now, to start with some fake 3D, make another object, calling it oPole. It doesn't need a sprite, it will be drawn to be visible. Open up Draw, put in something like "draw_set_color(vk_red)" just to make sure it's visible when drawn, then follow it up with the start of a draw_line code. Put x1 and y1 as x and y. x2 and y2 will be where the perspective is given.

Imagine you're looking down on an area, where a number of poles are stuck into the ground perfectly vertically. You'll notice that, as the poles get further away from the centre, from a 2D perspective two things happen. They appear longer, and they appear to point away from the centre. This is the effect we need to recreate.

Save and close the Draw event. Open up Create. Initialise two variables like so:

drawlength=0;
drawdirection=0;

Save and close Create, then open Step (click Step again afterwards). Because, in that world, poles looked to be longer as they were further away, the length and direction of the end point of the drawn line will need to be altered depending on their position. It's made easier because oCircle, thanks to its view code, will ALWAYS be central. Therefore, the two variables can be relative to the player's position. Add this to the open Step code box:

drawlength=point_distance(x,y,oCircle.x,oCircle.y);
drawdirection=point_direction(x,y,oCircle.x,oCircle.y)+180;

The +180 added at the end of point_direction is to ensure the line is pointing AWAY from oCircle, not TOWARDS it. point_distance is useful for length in this situation because of the line's need to appear shorter as the player gets closer.

So now we have what's necessary to finish off that draw_line. Save and close Step and reopen Draw. The code should now be modified to read as such:

draw_set_color(c_red);
draw_line(x,y,x+lengthdir_x(drawlength,drawdirection),y+lengthdir_y(drawlength,drawdirection));

Save and close the object, open the room again, and dot some oPoles around in it. Save and close the room, and run the game. Have a walk about and see what it's like.

Provided it's working (which it should be), that's the bare bones to making one kind of fake 3D with Game Maker. I won't keep going with the details, but here are some things to think about if you're wanting to make a game with this style.

  • draw_triangle is very useful for making thick-looking items such as buildings. To make a wall you'll need two triangles.
  • To draw things at the right depth (from the 3D point of view), you can generally work it by simply setting depth to point_distance(x,y,oCircle.x,oCircle.y);. The further away something is, the further back it will appear. There may be minor graphical hitches with this, particularly if you have objects of varying sizes right next to each other, but it'll work generally.
  • To alter the 3D-POV height of something, DIVIDE (less high) or MULTIPLY (higher) the drawlength code. Do not add or subtract, it will look wrong.
  • Most objects will require more than one set of drawlength/drawdirection variables (either make an array or just add a number to the end of the variable names). For example, cuboids will require two sets - one for calculating the top left corner, and one for the bottom right (top right and bottom left are just done by mixing the codes of these two).
  • If you're using the effect frequently in a game you'll probably want to shorten the variable names for the sake of convenience - dl and dd or even just l and d will work fine and don't require a massive amount of interpretation.

Around eight months ago I released a game using this kind of 3D, along with its source code. If you're having a bit of trouble, or simply want to see how I did it, you can download the source here. It will work with Game Maker 7 or 8, and in Pro or Lite.

As a quick note, I originally posted this on Game Maker Blog.
  • 0

#2 GMkizzle

GMkizzle

    GMC Member

  • GMC Member
  • 374 posts

Posted 02 May 2010 - 11:41 AM

I must say.. those are some pretty sexy graphics.
  • 0

#3 guppylover

guppylover

    GMC Member

  • New Member
  • 112 posts

Posted 02 May 2010 - 12:07 PM

reall nice example im using this beast
easy to understand as well
  • 0

#4 RamboFox

RamboFox

    Tainted Fortune

  • New Member
  • 992 posts

Posted 02 May 2010 - 11:56 PM

"You can use surfaces"

Well, you can use surfaces in d3d mode now too, since the creation of the surface-fix.dll (You can easily find it on this forum) so d3d mode is just as useful. But I have to agree, being able to adjust minute details has an advantage over the many graphical glitches that the inbuilt 3d functions give.

The other important thing is that not everyone is registered, and that graphics cards are'nt exactly top-grade all around.
  • 0

#5 CaptainLepidus

CaptainLepidus

    GMC Member

  • GMC Member
  • 850 posts
  • Version:GM:HTML5

Posted 02 May 2010 - 11:59 PM

Awesome! But could you use this method to create a first person or third person view?
  • 0

#6 NAL

NAL

    凸ʕಠᴥಠʔ凸

  • YoYo Games Staff
  • 686 posts
  • Version:GM:Studio

Posted 03 May 2010 - 01:15 AM

Awesome! But could you use this method to create a first person or third person view?

It's unlikely without beginning to enter the world of mathematics, a skill I don't really possess. If you're looking into that sorta stuff, I'd recomment TheSnidr's tutorials on 3D - he's a lot more skilled than I am and has plenty of tutorials on fake 3D in FP/TP perspectives. :D
  • 0

#7 Robert3DG+

Robert3DG+

    VR Games

  • GMC Member
  • 1848 posts
  • Version:GM:Studio

Posted 03 May 2010 - 06:15 AM

Really cool effect. With some work it could make a nice parallax scrolling effect for 2D games.
  • 0

#8 CRxTRDUDE

CRxTRDUDE

    GMC Member

  • GMC Member
  • 64 posts
  • Version:GM8

Posted 03 May 2010 - 09:00 AM

By the way, how can one implement this as a background? Can it be possible?
  • 0

#9 NAL

NAL

    凸ʕಠᴥಠʔ凸

  • YoYo Games Staff
  • 686 posts
  • Version:GM:Studio

Posted 03 May 2010 - 10:37 AM

By the way, how can one implement this as a background? Can it be possible?

What, so the effect is underneath everything else? That's where the depth altering comes in handy - just set all the fake-3D-drawn objects to a very, very high depth (something like 999999). If you're using the code for automatic depth (depth=point_distance(...)) just add "999999+" directly after the equals sign. :blink:
  • 0

#10 yes23

yes23

    GMC Member

  • New Member
  • 8 posts

Posted 06 May 2010 - 01:20 PM

Thank you for labor. You've been very helpful.

Edited by yes23, 06 May 2010 - 01:21 PM.

  • 0

#11 peng007

peng007

    GMC Member

  • New Member
  • 42 posts

Posted 07 May 2010 - 07:27 AM

There is a much easier way to do this that I found out.

var getx,gety;
getx = x-oCircle.x;
gety = y-oCircle.y;
draw_set_color(c_red);
draw_line(x,y,x+getx,y+gety);

  • 0

#12 busydude

busydude

    GMC Member

  • New Member
  • 31 posts

Posted 02 August 2010 - 09:41 PM

totally confused? maybe im just dumb....better stick to easier stuff =/
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users