l,h = term.getSize()
running = true
refreshRate = .5
gtID = os.startTimer(refreshRate)
local score = 00
local health = 100
player = {
xpos = math.floor(l/2);
ypos = h -2;
length = 1;
update = function(self, key)
if key == keys.left and self.xpos > 1 then
self.xpos = self.xpos - 1
elseif key == keys.right and self.xpos < l then
self.xpos = self.xpos + 1
elseif key == keys.up and self.ypos > 1 then
self.ypos = self.ypos - 1
elseif key == keys.down and self.ypos < h then
self.ypos = self.ypos + 1
end
end;
draw = function(self)
term.setCursorPos(self.xpos, self.ypos)
term.setBackgroundColour(colours.white)
term.write(string.rep(" ", self.length))
end;
}
food = {
xpos = math.random(1, l);
ypos = math.random(1, h);
amount = 1;
updateFood = function(self)
if self.xpos == player.xpos and self.ypos == player.ypos then
score = score + 20
self.amount = 0
self.xpos = math.random(1, l)
self.ypos = math.random(1, h)
end
end;
drawFood = function(self)
if self.amount == 0 then
self.amount = 1
elseif self.amount == 1 then
term.setCursorPos(self.xpos, self.ypos)
term.setBackgroundColor(colours.green)
term.write(" ")
end
end;
}
enemy = {
xpos = math.random(l);
ypos = math.random(h);
updateEnemy = function(self)
if self.xpos < player.xpos then
self.xpos = self.xpos + 1
elseif self.xpos > player.xpos then
self.xpos = self.xpos - 1
end
if self.ypos < player.ypos then
self.ypos = self.ypos + 1
elseif self.ypos > player.ypos then
self.ypos = self.ypos - 1
end
if self.xpos == player.xpos and self.ypos == player.ypos then
health = health - 20
sleep(.01)
end
end;
drawEnemy = function(self)
term.setCursorPos(self.xpos, self.ypos)
term.setBackgroundColour(colours.magenta)
term.write(" ")
end;
}
function gameDraw()
term.setBackgroundColour(colours.black)
term.clear()
term.setCursorPos(1, 1)
term.write("Health is "..health)
term.setCursorPos(1, 2)
term.write("Score is " ..score)
player:draw()
food:drawFood()
enemy:drawEnemy()
end
function gameUpdate()
local id, p1 = os.pullEvent()
food:updateFood()
if id == "key" then
if p1 == keys.q then running = false end
player:update(p1)
end
if id == "timer" and p1 == gtID then
enemy:updateEnemy()
gtID = os.startTimer(refreshRate)
end
end
function gameLoop()
while running do
gameUpdate()
gameDraw()
if health == 0 then
running = false
end
end
end
gameLoop()
term.setBackgroundColour(colours.black)
term.setCursorPos(math.floor(l/2) - #"Game Over"/2 + 1, math.floor(h/2))
term.write("Game Over")
sleep(3)
shell.run("clear")
sleep(0.01)
How to create multiple "enemies" from one table
Started by Joe3000, Jun 03 2013 11:52 PM
3 replies to this topic
#1
Posted 03 June 2013 - 11:52 PM
So I gave up on Tetris (too dificult) and I just decided to make my own game, it's not complete yet but the basic stuff is there. The one thing I do want is that the "Enemy" will sometimes be more than 1. Say if you get 200 points and then a second enemy comes along. How would I do that? Here is the code....
#2
Posted 04 June 2013 - 07:35 AM
Just add the enemy into a table again. (enemy = { ["enemy_1"] = { }, })
local enemy = {
["enemy_1"] = {
xpos = math.random(l);
ypos = math.random(h);
updateEnemy = function(self)
if self.xpos < player.xpos then
self.xpos = self.xpos + 1
elseif self.xpos > player.xpos then
self.xpos = self.xpos - 1
end
if self.ypos < player.ypos then
self.ypos = self.ypos + 1
elseif self.ypos > player.ypos then
self.ypos = self.ypos - 1
end
if self.xpos == player.xpos and self.ypos == player.ypos then
health = health - 20
sleep(.01)
end
end;
drawEnemy = function(self)
term.setCursorPos(self.xpos, self.ypos)
term.setBackgroundColour(colours.magenta)
term.write(" ")
end;
},
["enemy_2"] = {
},
}
#3
Posted 04 June 2013 - 05:12 PM
is that the only way to do it? I was hoping that I could make certain enemies appear at different times and disapear later
#4
Posted 04 June 2013 - 07:02 PM
There are lots of ways of doing it, but defining them manually isn't ideal. You want to do so automatically, a process which is going to be much harder if you've got functions in the table too.
If you want a system that can add enemies as the game goes on, you'll also want a system that can remove them. Two statements come in handy here: #<tablename> returns the amount of indexes in a table before the first one that contains nil. table.getn(<tablename>) returns the highest non-nil index.
So, say you construct the following table:
#mytable would return 1. table.getn(mytable) would return 3. The actual number of non-nil indexes in the table would be 2, something you'll need to track yourself because Lua doesn't have a function to return that.
With that in mind, consider what truly unique bits of information apply to each enemy: in your current code, there's only two variables that set any enemy apart from another, and that's their X/Y co-ords.
Start your program by defining an empty enemy table, a variable to track how many enemies are in play, and your score:
Now we need a function to create an enemy in the table.
And a function to make sure a certain number of enemies are in play, depending on your current score.
You could pass arguements to the spawnEnemy() function based on score, and have those added to the enemy table along with their positions. This'd allow you to eg change the colour of enemies as time goes on.
You can probably guess what the enemy despawn function looks like. You can come up with your own conditions as to when it's called. Maybe give each enemy a counter that counts towards 0?
Your enemy updater function (externalised from all tables) gets rigged to update ALL enemies in play:
Finally, in your game update function, you'll now be running something like this:
That should keep you going for a while.
If you want a system that can add enemies as the game goes on, you'll also want a system that can remove them. Two statements come in handy here: #<tablename> returns the amount of indexes in a table before the first one that contains nil. table.getn(<tablename>) returns the highest non-nil index.
So, say you construct the following table:
mytable = {34,nil,12}
#mytable would return 1. table.getn(mytable) would return 3. The actual number of non-nil indexes in the table would be 2, something you'll need to track yourself because Lua doesn't have a function to return that.
With that in mind, consider what truly unique bits of information apply to each enemy: in your current code, there's only two variables that set any enemy apart from another, and that's their X/Y co-ords.
Start your program by defining an empty enemy table, a variable to track how many enemies are in play, and your score:
local enemy = {}
local enemyCount, score = 0, 0
Now we need a function to create an enemy in the table.
local function spawnEnemy()
-- "#enemy + 1" gets the lowest index in the enemy table that's currently nil.
enemy[#enemy + 1] = {xpos = math.random(l), ypos = math.random(h)}
enemyCount = enemyCount + 1
end
And a function to make sure a certain number of enemies are in play, depending on your current score.
local function spawnEnemies() -- We want at least five enemies in play no matter what. while enemyCount < 5 do spawnEnemy() end -- If your score is more then 50, let's make that 10 enemies. if score > 50 then while enemyCount < 10 do spawnEnemy() end end -- Hit 100, and it's 20 enemies. if score > 100 then while enemyCount < 20 do spawnEnemy() end end -- etc end
You could pass arguements to the spawnEnemy() function based on score, and have those added to the enemy table along with their positions. This'd allow you to eg change the colour of enemies as time goes on.
You can probably guess what the enemy despawn function looks like. You can come up with your own conditions as to when it's called. Maybe give each enemy a counter that counts towards 0?
local function killEnemy(deadEnemyIndex)
if enemy[deadEnemyIndex] ~= nil then -- You cannot kill that which is dead...
enemy[deadEnemyIndex] = nil
enemyCount = enemyCount - 1
end
end
Your enemy updater function (externalised from all tables) gets rigged to update ALL enemies in play:
local function updateEnemies()
for i=1,table.getn(enemy) do if enemy[i] ~= nil then -- Loop through ALL valid enemies in play
if enemy[i].xpos < player.xpos then
enemy[i].xpos = enemy[i].xpos + 1
elseif enemy[i].xpos > player.xpos then
enemy[i].xpos = enemy[i].xpos - 1
end
if enemy[i].ypos < player.ypos then
enemy[i].ypos = enemy[i].ypos + 1
elseif enemy[i].ypos > player.ypos then
enemy[i].ypos = enemy[i].ypos - 1
end
if enemy[i].xpos == player.xpos and enemy[i].ypos == player.ypos then
health = health - 20
sleep(.01)
end
end end
end
Finally, in your game update function, you'll now be running something like this:
if id == "timer" and p1 == gtID then
spawnEnemies()
updateEnemies()
gtID = os.startTimer(refreshRate)
end
That should keep you going for a while.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users











