simpel 3D tutorial

Blitz3D Forums/Blitz3D Tutorials/simpel 3D tutorial

Fernhout(Posted 2006) [#1]
This is something for the early starters of Blitz3D. A simple 3D breakout clone. A help to get you starting using the 3D. A great way for starters.


Fernhout(Posted 2006) [#2]
Sorry was a forgotten a big part.

Ther is no sound or graphics needed.

Here is the tutorial

Tutorial #1.
Breakout clone.

Hallo good fruiends. I cal this #1 because this is my first tutorial i write. if this one is coming good by you and i here more quetions for making more, i wil make them.


The tutorials will be mostly directed to the beginners for programming in blitzBasic3D. And i hope they wil be good programmers at the end of all my tutorials. Altrough my english is maybe not that good. I hope you wil understand what i wil mean in my tutorial.

To learn the most out of programming is usualy to make a game.


Part 1: The idea
Part 2 : Deviding files
Part 3 : Working out the idea
Part 4 : The program

Part1 : the idea
To make a game you must have an idea. Every idea you wil have can be a good one. Never think its a bad idea or there is already a program that do this. You program i maybe better than the original. Thats why i have a idea of making a breakout clone. The basic idea you know. But if you have the complet soource code of this program feel free to change it to you own need. This tutotial is only a guidline of making a game.

So the idea is here. It wil be a clone of breakout.

Part 2 : Deviding files
For this tutorial we don not need any texture or pictures. But you can add them later on if you like. we know now what we wil make. The best way to store everything in a good place, is to devide everything. the sound files in a sound folder and the graphis in graphics folder. In this tutorial we wil not use function of premade code so we do not need a folder for this. This wil be something for the next tutorial. My dividing of the folders is looking like this. (Fig 1).


Fig1. Deviding the folders.

As you see the folder tutorial is in a folder (Not show) projects. Under tutorials there is a folder Data_Backup and a folder media. Under media the folders sound and graphics. And the folder TutPics are the pictures you see in this document. You see that all kind of data is devide so you can easely find your stuff.

For now the folders graphics and sounds are empty. Because we do not use any of that in this tutarial. But its the best wat to make a habbit of this to start on this way.

The folder Data_Backup is something i make always as i am starting a new project. For every day i make first a backup of the program. I there is somthing going completly wrong i have always a backup to fall back on.

After this tutorial i urge you to expand the program and complete it including sound and beautiful picturs. If you don't know how to do that or you want a tutorial on that part to. E-mail me and i wil make a tutorial for that. My e-mail adress is: bartfernhout@....

Part 3. Workin out the idea.
This is for here a short one. The idea was simple. So what do we need to make a game like this. Blocks, paddle and a ball. The question is how many blocks wil we need.
Lets make a something up. say 6 rows and 14 colums. We want the blocks in the upper center of the screen. We can make a drawing of how it wi look like. For this tutorial i have make a screen shot. and it wil look like this (Fig 2.)

fig 2. Layout of the game how we think it wil be.

As we can see how everthing is bulding up. The paddle at the bottom has a number on it. This is the score display. If the ball hits a block the score wil be updated with one. The background colour is gray. Even that is a choise you wil made. It is possible to change that if you like.
The blocks have random colours. You wil see that later in the program how that is done. for now the setup is worked out. We wil need also a screen before we start the game and and two screens ant the end of the game. One for winning and one for losing the game. In this tutorial we use simple screens. Just empty screens with plain text.

We have all what we want to make the game. Now we going to write te game in the program. Normal if the program is big (The game) we first write it on paper and make first big step discription and than cut the big steps in smaller steps. Untile the steps are smal enough to make the program. Here its not needed

Step 4 : The program.

The first thing we make in the program is

; Project: breakout clone
; Created: mm-dd-yyyy
; Created by: You
;
; Tutorial number 1

This was the hard part. Always make a header in a program, so you wil know when you make it. And sometime extra information why this program of from where you get it and modified it.

The main program
; ***** Main Source File *****

;Setup the display

Graphics3D 1024,678,32 ;Set the resolution to 1024x768x32
SetBuffer BackBuffer() ;Set the drawing screen to the back
.GameStart ;A label that'll take us to the games start.
ClsColor 128,128,128 ;Color the background to a dark gray.
Cls ;Clear everything from the video cards memory.

To start a program we need to set the screen. We do that bij using Graphic3D. Blitz know two kind of graphics settings Graphics and Graphics3D. the first is for 2d serrounding and the add on 3D is, you gust it, for 3D. The size chousen here is justy a nice format. 1024 by 678.
And because Blitz use actual 2 screens to work on we activate the screen you wil never seen unless you tell the program to do so. The screen you see. is a frontbuffer. standard Blitz set this as default. if you print something on the screen you wil seen it. But sometime you want to draw more things on the screen but not show the player all the build up of the screen. Therefor there is a backscreen, called backbuffer. To activate it simply say setbuffer backbuffer(). And now your invisable screen is active.

A label is a marker you can jump to or make a subroutine starting here. We use it to restart the game. Or start the game if this is the first time te program runs. A marker or LABEL because thats what it calls. Start always with a dot.

To give the background a colour we set the clearscreen colour to gray. The command ClsColor is a command that wil erase the screen from all data using this color. for our game is that gray.
And then we clear the screen using Cls. Stil nothing is happend on the screen. Remember we are working on de backbuffer.

Flip ; Refresh the screen
Text GraphicsWidth()*.5,GraphicsHeight()*.5,"Press any key to begin",True,True
Flip ; Refresh the screen again to ensure text is displayed.
WaitKey() ; Wait for a keypress to start the program.
Flip

Flip is a beautiful command. This tel Blitz that the backbuffer and the frontbuffer swap place. Now you see what is happend a gray screen wil appear.

We are stil working on the backbuffer. So don't worry. Even if the screens swap places you wil stil working on the screen what is not visual.
To print text on the screen there are differend ways to do it. TEXT is here the best option. Using text you can place everywhere om the screen you text. By giving the coordinates on the screen. The corner 0,0 starts top left. Text does alse center text on the coordinate you give. The line text is as follow:
TEXT Xpos,Ypos,"Your line",CenterX,CenterY. Blitz wil find out for you hou big the font is and how long the text is. This make sure that you text line is centered on the spot you has given.

We flip again to show the text. The text is standard white. So we don't have to change that.

Now we wait for the player until he is ready. And flip then again to lat the text dissapear.

;Setting up the grid
rows=6 ; Will setup how many rows(vertical) of blocks we have.
columns=14 ; Sets up how many columns(horizontal) of blocks we have.
totalobjects=(rows*columns)+rows ; We define the total Objects variable, that tells us
; how many objects we have. This will later be used, so
; we'll be able to tell how many blocks need to be removed
; to win the game.
Dim blocks(Totalobjects) ; Bring them in a array to find theme back

camera=CreateCamera() ;activate the camera
light=CreateLight() ; make some light
CameraClsColor camera,128,128,128 ;to keep the same gray color as the start screen


modify=0 ; Ensure the variable is 0
modifier=0 ; Ensure the variable is 0

;Set some identities or collision detection
Collision_ID_Blocks = 1
Collision_ID_Ball = 2
Collision_ID_Paddle = 3

The player got to play. So we set up some parameters for the game. Make the row and columns. Total of the blocks. Make a array of the blocks. Why you wil see later. And activate the camera. Because we gona work in a 3D world. Make the ligth to. standard it wil always behind the eye of the camera. We do not have to move it. But we have to say to the camera that the backgroud is gray.
Then 2 variables for placing later the blocks on the screen. And make all the collision identeties. Every object in the field must have his own collision id. I did it here the easy way. What you wil see later on in the tutorial.

;``Creating the objects```
; This for-next loop will create a cube, randomize the color, and then position it
; using the modify and modifier variable.
SeedRnd MilliSecs() ; Make the ramdom real random
For x= 1 To totalobjects
blocks(x)=CreateCube()
ScaleMesh blocks(x),0.45,0.2,0.05 ; Scale the cube
EntityBox blocks(x),-0.45,-0.2,-0.05,0.9,0.4,0.1 ; create hitbox because scaling alter the hit box
EntityColor blocks(x),Rnd(255),Rnd(255),Rnd(255) ; differend colors
EntityType blocks(x),Collision_ID_Blocks+10+x ; set collision number for entity
PositionEntity blocks(x),modify-(columns*.5),modifier+rows-1.5,10 ; Place on screen
modify=modify+1
If modify>columns ; If the modify variable is greater than the columns, add 1 to
modify=0 ; the modifier variable so a new row will start.
modifier=modifier-1
EndIf
next

The first line we see is the SeedRnd milliSecs(). this commando sets the radomizer to a real random. standard is the random not a real random. everytime the program starts. The same numbers appear again and again. We don't want that. Therfore this line.
We starting the for / next loop and create in the array alle the blocks bij assining them to a cube. The size of the cube is to large to use. We scale them down. Everything under 1 is scaling down. Above 1 is scaling up. You may say why scaling. why not put them furter away from the camera. we can do that but them we have squars on the screen. By scaling we can make them look like bars.
now come the tricky one, EntityBox. This box is our hit box. This one give us the detection if there is a hit with the ball. there are a lot of numbers behind it. and here is the secret of those numbers. first three are the X,Y,Z starting point seen front the position where the box wil be placed. If you plave a figure on the world you wil give its location in three positions. Left-right, up-down and depth. But its not a corner of that figure. Its the center of the figure. in our case the blocks. The seconde three numbers are the X,Y,Z position calculated from the first three points. NOT from the center point. KEEP THIS IN MIND. Thats why thous numbers are double the first three numbers.

Everyblock gets it's own color. this is don randomly.

And we give all the blocks its own collision ID. Adding 10 to make sure we don't mess up whit another entity.

Then by calculation using the 2 earlier used variables the position of the blocks. Here is alse the left-right, up-down and depth. On this part if you calculate the coordinates you wil disccover that the numbers are negative. because we using a 3D world. the center of the camera eye is 0,0. NOT the upper of lower corner of the screen. By moving the camera you can shift the center. But we don't need that.

Then a If then for seeing if we nog going of screen.

;```Creating the ball And paddle```
;`The paddle
Paddle = CreateCube() ;` Create the paddle
ScaleMesh Paddle,0.5,0.1,0.1 ;` Scale it. Notice the x And z values are increased And
;` the y value stays the same, so we have a longer sleaker
;` paddle.
EntityBox Paddle,-1,-0.25,-0.2,2,0.4,0.4 ; Create hit bok for paddle
EntityType paddle,Collision_ID_Paddle
PositionEntity paddle,0,-6.3,10 ;` Position it

;`the sphere
ball=CreateSphere(12) ;make the sphere
ScaleMesh ball,0.15,0.15,0.15 ;scale it
EntityType ball,Collision_ID_Ball
EntityColor ball,200,100,10 ; one color
EntityRadius ball,0.15
PositionEntity ball,0,-2.3,10 ;position it

This is the same as creating the blocks. the only extra line you wil see here is the EntityRadius. this is almost the same as a hitbox. But because we are using a sphere its round and making a radius is in this case better.

;```Setting up collision```
;`Add collision To all the blocks And the paddle
For x = 1 To totalobjects
Collisions Collision_ID_Ball,Collision_ID_Blocks+10+x,3,1
Next
;`Add collision To the ball
Collisions Collision_ID_Ball,Collision_ID_Paddle,3,1

Setting the collision detection between the ball and the blocks. Every block get his own ID. In blitz you can do it on another way. but i prefer this way. So the detection on is one way only. between ball and block(x)

Some extra information.
Standard a object hase his own hit box or mesh. But a soon as you scale a object the hit box don't scale with it. and stay the size it was original. this give you a bad way of detecting collision. Thats why there are created boxes around the object so that we have a new hit box.

;`The game variables
score=0 ;` Set the score To zero.
direction$="down" ;` This String defines the direction of the ball. When the ball
;` encounters a block Or the paddle, this variable will be modified
;` To change directions.
angle$="none" ;` This works the same way as the direction$ variable, but it defines
;` the angle of the ball instead.
ballspeed#=0.1 ;` Define the ball speed.
paddlespeed#=0.5 ;` Define the paddle speed(this is you).
positie# = 11.3
HidePointer ;` Because it's ugly ;)

Score is set and the direction we use text directions. Up down left or right. So we only have 4 directions. This is easy to see where the ball is going. For you a challange to exentend this in the program to give more directoins.

the speed of the paddle and the ball is set. And we hide the mouse pointer. this is nicer.

;set drawing screen in background
Color 0,0,0 ; set draw color to black

Repeat ;Begin our loop

;```Display```
;`Center our score in the bottom center of our screen.
Text GraphicsWidth()*.5,GraphicsHeight()-15,Str score,True,True
Flip ; flip screen to make the score visual

The paddle is white. the text is also white just make it black. And center it on the botom of the screen.

The repeat command is ouw start of the continue loop we use to let the ball bounce over the screen.

;```Paddle Movement```
If KeyDown(203) Then
MoveEntity paddle,-paddlespeed#,0,0
EndIf
If KeyDown(205) Then
MoveEntity paddle,paddlespeed#,0,0
EndIf

Check the ketyboard if ther is a key is hit or pushed down. KeyDown Scan the keyboard and give a true back if the selected key is pressed.
The moveEntity is a command to tell a object to move from its current position a X,Y and Z step forward. Because our paddle wil only go left and right. We have only one direction.

Extra note.
Position in a 3D world is given in a real number or location. thats why you at the and of every variable a # sign. This is a Blitz sign for a real number.


; move the bal in its direction
MoveEntity ball,Angles#,ballspeed#,0

Mover the ball now. And later we wil see if the direction is ok. Here we use 2 directions the X and Y direction.

;````Ball Movement```
;` Based on the direction variable, the ball is moved up our down.
If direction$="down" And ballspeed#<0 Then
ballspeed# = -ballspeed#
EndIf
If direction$="up" And ballspeed#>0 Then
ballspeed#= -ballspeed#
EndIf
;` Move the ball based on the angle.
If angle$="left" Then
Angles#=-0.1
EndIf
If angle$="right" Then
Angles#=0.1
EndIf
If angle$="none" Then
Angles#=0.0
EndIf

You wil think here i see a dubble line how van this work. The If statment check the state and execite the action. Or not. Because the directon or in this case speed is below zero or above zero the value of speed is changed from sign. Thats why the same line. And we don't need a subroutine because this is just two single lines.

The angle can go in three directions.

;````collision```
;`collision between ball And paddle
If EntityCollided(ball,Collision_ID_Paddle) Then
ResetEntity (paddle)
ResetEntity (ball)
If direction$="up" Then
direction$="down" ;` If the ball collides with the paddle, switch
Else
direction$="up" ;` its direction.
EndIf
;` If the paddles x position is greater than the balls, Then angle the ball Left.
If EntityX#(paddle)>EntityX#(ball)Then
angle$="left"
EndIf
;` If the paddles x position is less than the balls, Then angle the ball Right.
If EntityX#(paddle)<EntityX#(ball) Then
angle$="right"
EndIf
;` If the paddles x position is equal To the balls, Then the ball's angle is zero.
If EntityX#(paddle)=EntityX#(ball) Then
angle$="none"
EndIf
EndIf

Now we get to the impostant part of the program. See if the ball is hitting the paddle. And then we reset the hit flag. If we don't do that the flag stil stays and as the program returns here after a second run. The program wil see the flag again. If the hit is true then the direction of the ball has to reversed. Afther that we check if the position of the ball against the pasition of the paddle. According to that we set the Angle direction.

;`collision between ball And blocks
For x = 1 To totalobjects
If EntityCollided (ball,Collision_ID_Blocks+10+x) Then
; If the Object exists And collision occurs

HideEntity blocks(x) ; Delete the Object And add To the score.
score=score+1
If direction$="down" Then
direction$="up" ;` Switch the balls direction upon collision.
Else
direction$="down"
EndIf
EndIf
ResetEntity blocks(x)
Next

Its also posible that th ball hits a block. If he do, hide the block, updte the score and reversed the direction. This is also a option for you to extand this. If the ball hits the side of a block. in this program he will reversed its direction. But make it that only the angle wil changed.
And reset the hit flag.

;```Ball And paddle boundaries```
;` Paddle boundaries
;` If the paddle is outside these screen coordinates, move it the other direction.
If EntityX#(paddle)>9.4 Then PositionEntity paddle,9.4,-6.3,10
If EntityX#(paddle)<-9.4 Then PositionEntity paddle,-9.4,-6.3,10

;` If the ball is outside these screen coordinates, Then move it the opposite direction.
If EntityX#(ball)>9.5 And direction$="up" Then
angle$="left"
EndIf
If EntityX#(ball)<-9.5 And direction$="up" Then
angle$="right"
EndIf
If EntityX#(ball)>9.5 And direction$="down" Then
angle$="left"
EndIf
If EntityX#(ball)<-9.5 And direction$="down" Then
angle$="right"
EndIf

If EntityY#(ball)>6.5 Then direction$="up"


Now we control the paddle and the ball. Don't let them go of screen. First the paddle . And then the ball on all sides of the screen. Exept for the botom of the screen.

If the ball goes past that point then you lose.

;```Winning the game```
;` Once the score matches the total number of objects, you win, because there's nothing
;` left to hit. From there, every object is deleted if it exists, and then the game restarts.
if score=totalobjects
for x = 1 to totalobjects
HideEntity blocks(x)
next
HideEntity ball
HideEntity paddle
UpdateWorld
RenderWorld
Color 2550,255,255
Text GraphicsWidth()*.5,GraphicsHeight()*.5,"You Win!!",True,True
Text GraphicsWidth()*.5,GraphicsHeight()*.5+10,"hit any key",True,True

Flip
WaitKey()
Goto GameStart
EndIf

First we check to see if all the blocks is hit. If so you have won the game. Here is only one level. To you the task to make more levels.

You won so lets hide everything en display in the center of the screen that the player has won.
Wait for a keypress and jump back to our first label.

;```Losing the game```
;` If the balls position falls beneath the paddle, Then you lose the game And must restart.
;` All the objects are deleted, And you're sent To the GameStart label where everything is
;` reset.
If EntityY#(ball) <-6.6 Then
For x = 1 To totalobjects
HideEntity Blocks(x)
Next
HideEntity ball
HideEntity paddle
FlushKeys
UpdateWorld
RenderWorld
Color 255,255,255
Text GraphicsWidth()*.5,GraphicsHeight()*.5,"GAME OVER!!",True,True
Text GraphicsWidth()*.5,GraphicsHeight()*.5+10,"HIT ANY KEY",True,True
Flip
WaitKey() ;wait for key hit so the game starts again
Flip
Cls
Goto GameStart
EndIf

You lose. Whipe all from the screen and show the player that he lose. Here the same as the win option.

;```Debug```
;` It's always a good idea to have some sort of debugger in your game. This way, you'll be
;` able to tell what exactly is going on. It's usually a good idea to hide this from your
;` players, as you're the only one who really needs to see it. So set it to a key a player
;` normally wouldn't press, or you can implement some kind of console like in
;` first person shooters.
if KeyDown(15) ; The tab key
text 0,00,"-Debug-"
text 0,30,"Paddle: "+str EntityX#(paddle)
text 0,60,"Ball: "+str EntityX#(ball)
Text 0,90, "Ball y : "+ Str EntityY#(ball)
;text 0,90,"FPS: "+str$(screen fps())
Flip
endif


;display all changes
UpdateWorld ; update changes only 3D world
RenderWorld ; draw the screen again

Flip
Until False

As a programmer you muast always have a backdoor or a debug mode so you can trace what is happening.

This was the tutorial. I hope you can use it. If there are questions i open for it and if you have sugestions they are welcom to.