This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
ComputerCraftFan11's profile picture

How to make a Game with it's own API

Started by ComputerCraftFan11, 09 May 2012 - 02:44 AM
ComputerCraftFan11 #1
Posted 09 May 2012 - 04:44 AM
IndexFor the people who have seen games with characters in the program library and wondered how to make one, here is my tutorial.

This game will be bird's eye view and scrolling.

Let's start from the cursor tutorial.

So, after you finished that tutorial, your code should look like this:

Drawing The Character

local currentX = 1 --Saves the current X of the cursor
local currentY = 1 --Saves the current Y of the cursor

function drawCursor()
  term.clear() --Clears the screen
  term.setCursorPos(currentX, currentY)  --Draws a cursor at the current X/Y
  write(">")
end

while true do
  drawCursor()
  local e,key = os.pullEvent( "key" )
  if key == 17 or key == 200 then --up
		currentY = currentY -1
  elseif key == 31 or key == 208 then --down
		currentY = currentY +1
  elseif key == 203 or key == 30 then --left
		currentX = currentX -1
  elseif key == 205 or key == 32 then --right
		 currentX = currentX +1
  end
end


Let's create something to store what direction you are looking at. This is needed for collision detectors. We also need to get the size of your terminal. Add these to your code:

local x1, y1 = term.getSize() --Returns the size of your terminal
local char = ">" --Stores your character direction

Then change write(">") to write(char) so your character will face that direction
It should look like this:

local x1, y1 = term.getSize() --Returns the size of your terminal
local char = ">" --Stores your character direction
local currentX = 1 --Saves the current X of the cursor
local currentY = 1 --Saves the current Y of the cursor

function drawCursor()
  term.clear() --Clears the screen
  term.setCursorPos(currentX, currentY)  --Draws a cursor at the current X/Y
  write(char)
end

while true do
  drawCursor()
  local e,key = os.pullEvent( "key" )
  if key == 17 or key == 200 then --up
		currentY = currentY -1
  elseif key == 31 or key == 208 then --down
		currentY = currentY +1
  elseif key == 203 or key == 30 then --left
		currentX = currentX -1
  elseif key == 205 or key == 32 then --right
		 currentX = currentX +1
  end
end

Now, if you run the code, not much will change. Try to make it update the direction when you press a button. To do this, change your code to this:


local x1, y1 = term.getSize() --Returns the size of your terminal
local char = ">" --Stores your character direction
local currentX = 1 --Saves the current X of the cursor
local currentY = 1 --Saves the current Y of the cursor

function drawCursor()
  term.clear() --Clears the screen
  term.setCursorPos(currentX, currentY)  --Draws a cursor at the current X/Y
  write(char)
end

while true do
  drawCursor()
  local e,key = os.pullEvent( "key" )
  if key == 17 or key == 200 then --up
		currentY = currentY -1
		char = "^" --Change your direction to face up
  elseif key == 31 or key == 208 then --down
		currentY = currentY +1
		char = "v" --Change your direction to face down
  elseif key == 203 or key == 30 then --left
		currentX = currentX -1
		char = "<" --Change your direction to face left
   elseif key == 205 or key == 32 then --right
		currentX = currentX +1
		char = ">" --Change your direction to face right
   end
end

If you did this correctly, your character should walk around and look where you press.
Lets try to create a object with a collision detector.
Collision Detector and objects (&amp; scrolling!)
Since your character is limited to the size of the screen, let's try to make the maps endless.

Change

  term.setCursorPos(currentX, currentY)  --Draws a cursor at the current X/Y
to

  term.setCursorPos(x1/2, y1/2)  --Draws a cursor at the center of the screen

If your wondering why did we change that? It is because for scrolling, you don't want your character to move too, right? Really, right??

Now, don't delete currentX and currentY now. We need that to keep the position of the map.

To create a object, add this code right above drawCursor()

function newObject(oX, oY, title)
This allows you to create object. We didn't add that part yet but let me explain what (oX, oY, title) means.

oX is the X position of the item
oY is the Y position of the item
title is what the object looks like.

Now, lets code it and explain at the same time.
Add this inside of newObject(oX, oY, title)

  term.setCursorPos(oX - currentX, oY - currentY) --Set's the object at your position - map's position.
  write(title) --Draw the object
end --End the function

Now your code should look like this


local x1, y1 = term.getSize() --Returns the size of your terminal
local char = ">" --Stores your character direction
local currentX = 1 --Saves the current X of the cursor
local currentY = 1 --Saves the current Y of the cursor

function newObject(oX, oY, title)
  term.setCursorPos(oX-currentX,oY-currentY)
  write(title)
end

function drawCursor()
  term.clear() --Clears the screen
  term.setCursorPos(x1/2, y1/2)  --Draws a cursor at the current X/Y
  write(char)
end

while true do
  drawCursor()
  local e,key = os.pullEvent( "key" )
  if key == 17 or key == 200 then --up
		currentY = currentY -1
		char = "^" --Change your direction to face up
  elseif key == 31 or key == 208 then --down
		currentY = currentY +1
		char = "v" --Change your direction to face down
  elseif key == 203 or key == 30 then --left
		currentX = currentX -1
		char = "<" --Change your direction to face left
   elseif key == 205 or key == 32 then --right
		currentX = currentX +1
		char = ">" --Change your direction to face right
   end
end

Try to add this code below term.clear()

newObject(3, 3, "X")
If it works correctly, it should draw "X" on 3,3.

This is where the "char" becomes the most useful.

This code detects if you touch the object.

if oX-currentX == x1/2 and oY-currentX == y1/2 then
  --Will run this code if u are touching it
end

Now that we got that down, let's move the player back when you touch it.
Do this:

  if oX- currentX == x/2 and oY- currentY == y/2 then
   if char == "v" then --up
	currentY = currentY -1
   elseif char == "^" then --down
	 currentY = currentY +1
   elseif char == ">" then --left
	 currentX = currentX -1
   elseif char == "<" then --right
	  currentX = currentX +1
   end

   drawCursor() --redraw
  end

If you did this all correctly, your code should look like this:



local x1, y1 = term.getSize() --Returns the size of your terminal
local char = ">" --Stores your character direction
local currentX = 1 --Saves the current X of the cursor
local currentY = 1 --Saves the current Y of the cursor

function newObject(oX, oY, title)
  term.setCursorPos(oX-currentX,oY-currentY)
  write(title)

  if oX- currentX == x/2 and oY- currentY == y/2 then
   if char == "v" then --up
	currentY = currentY -1
   elseif char == "^" then --down
	 currentY = currentY +1
   elseif char == ">" then --left
	 currentX = currentX -1
   elseif char == "<" then --right
	  currentX = currentX +1
   end

   drawCursor() --redraw
  end
end

function drawCursor()
  term.clear() --Clears the screen
  term.setCursorPos(x1/2, y1/2)  --Draws a cursor at the current X/Y
  write(char)
end

while true do
  drawCursor()
  local e,key = os.pullEvent( "key" )
  if key == 17 or key == 200 then --up
		currentY = currentY -1
		char = "^" --Change your direction to face up
  elseif key == 31 or key == 208 then --down
		currentY = currentY +1
		char = "v" --Change your direction to face down
  elseif key == 203 or key == 30 then --left
		currentX = currentX -1
		char = "<" --Change your direction to face left
   elseif key == 205 or key == 32 then --right
		currentX = currentX +1
		char = ">" --Change your direction to face right
   end
end

Everything should work fine but theres one bug with scrolling. Try moving right/left for a long time. The game will glitch because your map is going off screen. This code will stop drawing your objects one they go off screen so the map size doesn't get too big.


function newObject(oX, oY, title)
if oX - currentX < x then
  term.setCursorPos(oX- currentX, oY- currentY)
  write(title)
  if oX- currentX == x/2 and oY- currentY == y/2 then
   if char == "v" then --up
	currentY = currentY -1
   elseif char == "^" then --down
	 currentY = currentY +1
   elseif char == ">" then --left
	 currentX = currentX -1
   elseif char == "<" then --right
	  currentX = currentX +1
   end

   drawCursor()
  end
end

That's about it for this tutorial. Check back for more :)/>/>

IndexFor the people who have seen games with characters in the program library and wondered how to make one, here is my tutorial.

This game will be bird's eye view and scrolling.

Let's start from the cursor tutorial.

So, after you finished that tutorial, your code should look like this:

Drawing The Character

local currentX = 1 --Saves the current X of the cursor
local currentY = 1 --Saves the current Y of the cursor

function drawCursor()
  term.clear() --Clears the screen
  term.setCursorPos(currentX, currentY)  --Draws a cursor at the current X/Y
  write(">")
end

while true do
  drawCursor()
  local e,key = os.pullEvent( "key" )
  if key == 17 or key == 200 then --up
		currentY = currentY -1
  elseif key == 31 or key == 208 then --down
		currentY = currentY +1
  elseif key == 203 or key == 30 then --left
		currentX = currentX -1
  elseif key == 205 or key == 32 then --right
		 currentX = currentX +1
  end
end


Let's create something to store what direction you are looking at. This is needed for collision detectors. We also need to get the size of your terminal. Add these to your code:

local x1, y1 = term.getSize() --Returns the size of your terminal
local char = ">" --Stores your character direction

Then change write(">") to write(char) so your character will face that direction
It should look like this:

local x1, y1 = term.getSize() --Returns the size of your terminal
local char = ">" --Stores your character direction
local currentX = 1 --Saves the current X of the cursor
local currentY = 1 --Saves the current Y of the cursor

function drawCursor()
  term.clear() --Clears the screen
  term.setCursorPos(currentX, currentY)  --Draws a cursor at the current X/Y
  write(char)
end

while true do
  drawCursor()
  local e,key = os.pullEvent( "key" )
  if key == 17 or key == 200 then --up
		currentY = currentY -1
  elseif key == 31 or key == 208 then --down
		currentY = currentY +1
  elseif key == 203 or key == 30 then --left
		currentX = currentX -1
  elseif key == 205 or key == 32 then --right
		 currentX = currentX +1
  end
end

Now, if you run the code, not much will change. Try to make it update the direction when you press a button. To do this, change your code to this:


local x1, y1 = term.getSize() --Returns the size of your terminal
local char = ">" --Stores your character direction
local currentX = 1 --Saves the current X of the cursor
local currentY = 1 --Saves the current Y of the cursor

function drawCursor()
  term.clear() --Clears the screen
  term.setCursorPos(currentX, currentY)  --Draws a cursor at the current X/Y
  write(char)
end

while true do
  drawCursor()
  local e,key = os.pullEvent( "key" )
  if key == 17 or key == 200 then --up
		currentY = currentY -1
		char = "^" --Change your direction to face up
  elseif key == 31 or key == 208 then --down
		currentY = currentY +1
		char = "v" --Change your direction to face down
  elseif key == 203 or key == 30 then --left
		currentX = currentX -1
		char = "<" --Change your direction to face left
   elseif key == 205 or key == 32 then --right
		currentX = currentX +1
		char = ">" --Change your direction to face right
   end
end

If you did this correctly, your character should walk around and look where you press.
Lets try to create a object with a collision detector.
Collision Detector and objects (&amp; scrolling!)
Since your character is limited to the size of the screen, let's try to make the maps endless.

Change

  term.setCursorPos(currentX, currentY)  --Draws a cursor at the current X/Y
to

  term.setCursorPos(x1/2, y1/2)  --Draws a cursor at the center of the screen

If your wondering why did we change that? It is because for scrolling, you don't want your character to move too, right? Really, right??

Now, don't delete currentX and currentY now. We need that to keep the position of the map.

To create a object, add this code right above drawCursor()

function newObject(oX, oY, title)
This allows you to create object. We didn't add that part yet but let me explain what (oX, oY, title) means.

oX is the X position of the item
oY is the Y position of the item
title is what the object looks like.

Now, lets code it and explain at the same time.
Add this inside of newObject(oX, oY, title)

  term.setCursorPos(oX - currentX, oY - currentY) --Set's the object at your position - map's position.
  write(title) --Draw the object
end --End the function

Now your code should look like this


local x1, y1 = term.getSize() --Returns the size of your terminal
local char = ">" --Stores your character direction
local currentX = 1 --Saves the current X of the cursor
local currentY = 1 --Saves the current Y of the cursor

function newObject(oX, oY, title)
  term.setCursorPos(oX-currentX,oY-currentY)
  write(title)
end

function drawCursor()
  term.clear() --Clears the screen
  term.setCursorPos(x1/2, y1/2)  --Draws a cursor at the current X/Y
  write(char)
end

while true do
  drawCursor()
  local e,key = os.pullEvent( "key" )
  if key == 17 or key == 200 then --up
		currentY = currentY -1
		char = "^" --Change your direction to face up
  elseif key == 31 or key == 208 then --down
		currentY = currentY +1
		char = "v" --Change your direction to face down
  elseif key == 203 or key == 30 then --left
		currentX = currentX -1
		char = "<" --Change your direction to face left
   elseif key == 205 or key == 32 then --right
		currentX = currentX +1
		char = ">" --Change your direction to face right
   end
end

Try to add this code below term.clear()

newObject(3, 3, "X")
If it works correctly, it should draw "X" on 3,3.

This is where the "char" becomes the most useful.

This code detects if you touch the object.

if oX-currentX == x1/2 and oY-currentX == y1/2 then
  --Will run this code if u are touching it
end

Now that we got that down, let's move the player back when you touch it.
Do this:

  if oX- currentX == x/2 and oY- currentY == y/2 then
   if char == "v" then --up
	currentY = currentY -1
   elseif char == "^" then --down
	 currentY = currentY +1
   elseif char == ">" then --left
	 currentX = currentX -1
   elseif char == "<" then --right
	  currentX = currentX +1
   end

   drawCursor() --redraw
  end

If you did this all correctly, your code should look like this:



local x1, y1 = term.getSize() --Returns the size of your terminal
local char = ">" --Stores your character direction
local currentX = 1 --Saves the current X of the cursor
local currentY = 1 --Saves the current Y of the cursor

function newObject(oX, oY, title)
  term.setCursorPos(oX-currentX,oY-currentY)
  write(title)

  if oX- currentX == x/2 and oY- currentY == y/2 then
   if char == "v" then --up
	currentY = currentY -1
   elseif char == "^" then --down
	 currentY = currentY +1
   elseif char == ">" then --left
	 currentX = currentX -1
   elseif char == "<" then --right
	  currentX = currentX +1
   end

   drawCursor() --redraw
  end
end

function drawCursor()
  term.clear() --Clears the screen
  term.setCursorPos(x1/2, y1/2)  --Draws a cursor at the current X/Y
  write(char)
end

while true do
  drawCursor()
  local e,key = os.pullEvent( "key" )
  if key == 17 or key == 200 then --up
		currentY = currentY -1
		char = "^" --Change your direction to face up
  elseif key == 31 or key == 208 then --down
		currentY = currentY +1
		char = "v" --Change your direction to face down
  elseif key == 203 or key == 30 then --left
		currentX = currentX -1
		char = "<" --Change your direction to face left
   elseif key == 205 or key == 32 then --right
		currentX = currentX +1
		char = ">" --Change your direction to face right
   end
end

Everything should work fine but theres one bug with scrolling. Try moving right/left for a long time. The game will glitch because your map is going off screen. This code will stop drawing your objects one they go off screen so the map size doesn't get too big.


function newObject(oX, oY, title)
if oX - currentX < x then
  term.setCursorPos(oX- currentX, oY- currentY)
  write(title)
  if oX- currentX == x/2 and oY- currentY == y/2 then
   if char == "v" then --up
	currentY = currentY -1
   elseif char == "^" then --down
	 currentY = currentY +1
   elseif char == ">" then --left
	 currentX = currentX -1
   elseif char == "<" then --right
	  currentX = currentX +1
   end

   drawCursor()
  end
end

That's about it for this tutorial. Check back for more :)/>/>
ComputerCraftFan11 #2
Posted 09 May 2012 - 04:49 AM
Easier world drawing
Now, for some of you that don't know where to put the objects, create a function called world and call it right after term.clear(). It should look like this:


local x1, y1 = term.getSize() --Returns the size of your terminal
local char = ">" --Stores your character direction
local currentX = 1 --Saves the current X of the cursor
local currentY = 1 --Saves the current Y of the cursor


function newObject(oX, oY, title)
if oX - currentX < x then
  term.setCursorPos(oX- currentX, oY- currentY)
  write(title)
  if oX- currentX == x/2 and oY- currentY == y/2 then
   if char == "v" then --up
	currentY = currentY -1
   elseif char == "^" then --down
	 currentY = currentY +1
   elseif char == ">" then --left
	 currentX = currentX -1
   elseif char == "<" then --right
	  currentX = currentX +1
   end
  
   drawCursor()
  end
end

function world()
  --Put code for the world in here.
  --Ex)
  --newObject(5,5, "O")
end

function drawCursor()
  term.clear() --Clears the screen
  world() --Draws the world
  term.setCursorPos(x1/2, y1/2)  --Draws a cursor at the current X/Y
  write(char)
end

while true do
  drawCursor()
  local e,key = os.pullEvent( "key" )
  if key == 17 or key == 200 then --up
		currentY = currentY -1
		char = "^" --Change your direction to face up
  elseif key == 31 or key == 208 then --down
		currentY = currentY +1
		char = "v" --Change your direction to face down
  elseif key == 203 or key == 30 then --left
		currentX = currentX -1
		char = "<" --Change your direction to face left
   elseif key == 205 or key == 32 then --right
		currentX = currentX +1
		char = ">" --Change your direction to face right
   end
end

Next:
  • NPCs
  • Multiplayer
ComputerCraftFan11 #3
Posted 10 May 2012 - 03:31 AM
Touch Detector
Now, if you wanted to make something like a sign but don't want to edit newObject, you can add this to check if you touch the object. First, open up newObject and change it to this:

function newObject(oX, oY, title)
if oX - currentX < x then
  term.setCursorPos(oX- currentX, oY- currentY)
  write(title)
  if oX- currentX == x/2 and oY- currentY == y/2 then
   if char == "v" then --up
	    currentY = currentY -1
   elseif char == "^" then --down
		 currentY = currentY +1
   elseif char == ">" then --left
		 currentX = currentX -1
   elseif char == "<" then --right
		  currentX = currentX +1
   end
 
   drawCursor()
   return "Touched" --Returns "Touched" when you touch it.
  end
end
Now it will notify you when it got touched. Then you can do if newObject(1,1, "X") == "Touched" then…

Examples:

objectA = newObject(3, 3, "I")
if objectA == "Touched" then
  os.shutdown()
end
or

if newObject(5,5, "X") == "Touched" then
  explode()
end

NOT

newObject(1,1,"V")
if newObject(1,1,"V") == "Touched" then
  explode()
end
The code above will create 2 objects
rex41043 #4
Posted 12 May 2012 - 11:09 AM
cool
LukeZaz #5
Posted 19 May 2012 - 06:12 AM
Great tutorial, Should look over the code, ran into a few issues I had to fix:

missing end:

if oX - currentX < x then

variable x &amp; y should be x1 &amp; y1:

if oX- currentX == x/2 and oY- currentY == y/2 then

if oX - currentX < x then

Also, I think functions should be listed in order so that they are defined before used to prevent errors, So that you've got:

function one()
--Code here
end

function two()
one()
end

not:

function two()
one()
end

function one()
--Code here
end
since one() wouldn't exist until after it was called.
I'm using Computercraft 1.3 since Technic doesn't have the most up-to-date version of it so I don't know if its supposed to be like that or not.
ComputerCraftFan11 #6
Posted 19 May 2012 - 06:23 AM
Great tutorial, Should look over the code, ran into a few issues I had to fix:

missing end:

if oX - currentX < x then

variable x &amp; y should be x1 &amp; y1:

if oX- currentX == x/2 and oY- currentY == y/2 then

if oX - currentX < x then

Also, I think functions should be listed in order so that they are defined before used to prevent errors, So that you've got:

function one()
--Code here
end

function two()
one()
end

not:

function two()
one()
end

function one()
--Code here
end
since one() wouldn't exist until after it was called.
I'm using Computercraft 1.3 since Technic doesn't have the most up-to-date version of it so I don't know if its supposed to be like that or not.

Actually, in


function two()
one()
end

function one()
--Code here
end

It would work because after you call one, or two, they will both be defined. (depending on when you call it)
tommyroyall #7
Posted 23 June 2012 - 05:24 PM
Man, this is great for OOP.
xWoody25 #8
Posted 17 August 2012 - 11:37 PM
can u help me please, i've copied all the code and when i run the program it just makes a new line for another command like "help"

> woodygame
> _

basically it just does the above on the terminal….. if it isnt clear ill try to paste the code