From 6d338337d362af15f1038cf73ca154daa57b6b2b Mon Sep 17 00:00:00 2001 From: Fernando Carmona Varo Date: Wed, 21 Oct 2015 20:41:56 +0200 Subject: Some cleanup and refactoring, it should be possible now to have multiple pacman games running simultaneously in different boards --- ghost.lua | 212 ++++++++++++++++++++++++-------------------------------------- 1 file changed, 83 insertions(+), 129 deletions(-) (limited to 'ghost.lua') diff --git a/ghost.lua b/ghost.lua index 4774e94..2714710 100644 --- a/ghost.lua +++ b/ghost.lua @@ -1,24 +1,3 @@ ---The code used for the ghosts was made by Tenplus1 - -local myghosts = {} -local deathcount = 0 -local gravity = -10 - -clear_ghosts = function() - local pos = mypacman.start - - for index, object in ipairs(minetest.get_objects_inside_radius({x=pos.x+13,y=pos.y+0.5,z=pos.z+15},20)) do - --local obj = object:get_luaentity() - if object:is_player() ~= true then - object:moveto({x=pos.x+13,y=pos.y+0.5,z=pos.z+19}) - end - end - --minetest.add_entity({x=pos.x+13,y=pos.y+0.5,z=pos.z+19}, "mypacman:inky") - --minetest.add_entity({x=pos.x+15,y=pos.y+0.5,z=pos.z+19}, "mypacman:pinky") - --minetest.add_entity({x=pos.x+13,y=pos.y+0.5,z=pos.z+18}, "mypacman:blinky") - --minetest.add_entity({x=pos.x+15,y=pos.y+0.5,z=pos.z+18}, "mypacman:clyde") - -end local ghosts = { {"pinky","Pinky"}, @@ -30,122 +9,97 @@ for i in ipairs(ghosts) do local itm = ghosts[i][1] local desc = ghosts[i][2] -minetest.register_entity("mypacman:"..itm, { - - hp_max = 1, - physical = true, - collide_with_objects = true, - visual = "cube", - visual_size = {x = 0.6, y = 1}, - textures = - {"mypacman_"..itm.."s.png", - "mypacman_"..itm.."s.png", - "mypacman_"..itm.."s.png", - "mypacman_"..itm.."s.png", - "mypacman_"..itm.."f.png", - "mypacman_"..itm.."s.png", + minetest.register_entity("mypacman:"..itm, { + hp_max = 1, + physical = true, + collide_with_objects = true, + visual = "cube", + visual_size = {x = 0.6, y = 1}, + textures = { + "mypacman_"..itm.."s.png", + "mypacman_"..itm.."s.png", + "mypacman_"..itm.."s.png", + "mypacman_"..itm.."s.png", + "mypacman_"..itm.."f.png", + "mypacman_"..itm.."s.png", }, - velocity = {x=math.random(-1,1), y=0, z=math.random(-1,1)}, - collisionbox = {-0.25, -1.0, -0.25, 0.25, 0.48, 0.25}, - weight = 5, -- ?? - is_visible = true, - automatic_rotate = true, - automatic_face_movement_dir = -90, -- set yaw direction in degrees, false to disable - stepheight = 1.1, - makes_footstep_sound = false, - floats = 1, - view_range = 40, - speed = mypacman.spd, - jump_height = 0, + groups = {immortal = 1}, + velocity = {x=math.random(-1,1), y=0, z=math.random(-1,1)}, + collisionbox = {-0.25, -1.0, -0.25, 0.25, 0.48, 0.25}, + is_visible = true, + automatic_rotate = true, + automatic_face_movement_dir = -90, -- set yaw direction in degrees, false to disable + makes_footstep_sound = false, - set_velocity = function(self, v) - if not v then v = 0 end - local yaw = self.object:getyaw() - self.object:setvelocity({x=math.sin(yaw) * -v, y=self.object:getvelocity().y, z=math.cos(yaw) * v}) - end, + set_velocity = function(self, v) + if not v then v = 0 end + local yaw = self.object:getyaw() + self.object:setvelocity({x=math.sin(yaw) * -v, y=self.object:getvelocity().y, z=math.cos(yaw) * v}) + end, - on_step = function(self, dtime) - - -- every 1 second - self.timer = (self.timer or 0) + dtime - if self.timer < 1 then return end - self.timer = 0 + on_step = function(self, dtime) + -- every 1 second + self.timer = (self.timer or 0) + dtime + if self.timer < 1 then return end + self.timer = 0 - -- make sure object floats (or not) when in water - if minetest.get_item_group(minetest.get_node(self.object:getpos()).name, "water") ~= 0 then - if self.floats == 1 then - self.object:setacceleration({x = self.object:getacceleration().x, y = 1.5, z = self.object:getacceleration().z}) - end - else - self.object:setacceleration({x = self.object:getacceleration().x, y = gravity, z = self.object:getacceleration().z}) - end + -- Do we have game state? if not just die + local gamestate = mypacman.games[self.gameid] + if not gamestate then + minetest.log("action", "Removing pacman ghost from finished game " .. (self.gameid or "")) + self.object:remove() + return + end - local s, p, dist, nod - -- find player to follow - for _,player in pairs(minetest.get_connected_players()) do - s = self.object:getpos() - p = player:getpos() + -- Make sure we have a targetted player + if not self.target then + self.target = minetest.get_player_by_name(gamestate.player_name) + end + local player = self.target - -- find distance - dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5 - if dist < self.view_range then - local vec = {x=p.x-s.x, y=p.y-s.y, z=p.z-s.z} - local yaw = (math.atan(vec.z/vec.x)+math.pi/2) - if p.x > s.x then - yaw = yaw + math.pi - end - -- face player - self.object:setyaw(yaw) + local s = self.object:getpos() -- ghost + local p = player:getpos() -- player - -- find direction and show node facing - self.direction = {x = math.sin(yaw)*-1, y = 0, z = math.cos(yaw)} - nod = minetest.get_node_or_nil({x=s.x + self.direction.x,y=s.y+1,z=s.z + self.direction.z}) - - -- more than 2 nodes ahead then follow, otherwise stop - if dist > 0 then - if self.jump_height > 0 and self.object:getvelocity().y == 0 then - local v = self.object:getvelocity() - v.y = self.jump_height - self.object:setvelocity(v) - end - - self.set_velocity(self, self.speed) - else - self.set_velocity(self, 0) - end + -- find distance from ghost to player + local distance = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5 + if distance < 1.5 then + -- player is so close it got catched!! + gamestate.lives = gamestate.lives - 1 + if gamestate.lives < 1 then + minetest.chat_send_player(gamestate.player_name,"Game Over") + player:moveto(vector.add(gamestate.pos,{x=0.5,y=0.5,z=-1.5})) + mypacman.game_end(self.gameid) + elseif gamestate.lives == 1 then + minetest.chat_send_player(gamestate.player_name,"This is your last life") + mypacman.game_reset(self.gameid, player) + else + minetest.chat_send_player(gamestate.player_name,"You have ".. gamestate.lives .." lives left") + mypacman.game_reset(self.gameid, player) + end - -- break look after player found - break - end - end - - -- if touches player then death - local s = self.object:getpos() - local obs = {} - for _,oir in ipairs(minetest.get_objects_inside_radius(s, 1.5)) do - local obj = oir:get_luaentity() - if oir:is_player() then - local player = oir - local pos = mypacman.start - local name = player:get_player_name() - if deathcount == 0 then - player:moveto({x=pos.x+13,y=pos.y+0.5,z=pos.z+15.5}) - minetest.chat_send_player(name,"You have 1 more life after this") - deathcount = 1 - clear_ghosts() - elseif deathcount == 1 then - player:moveto({x=pos.x+13,y=pos.y+0.5,z=pos.z+15.5}) - minetest.chat_send_player(name,"This is your last life") - deathcount = 2 - clear_ghosts() - elseif deathcount == 2 then - player:moveto({x=pos.x+0.5,y=pos.y+0.5,z=pos.z-1.5}) - minetest.chat_send_player(name,"Game Over") - deathcount = 0 - end - end + else + local vec = {x=p.x-s.x, y=p.y-s.y, z=p.z-s.z} + local yaw = (math.atan(vec.z/vec.x)+math.pi/2) + if p.x > s.x then + yaw = yaw + math.pi end - end, - }) + -- face player and move towards him + self.object:setyaw(yaw) + self.set_velocity(self, gamestate.speed) + end + end, + + -- This function should return the saved state of the entity in a string + get_staticdata = function(self) + return self.gameid or "" + end, + + -- This function should load the saved state of the entity from a string + on_activate = function(self, staticdata) + if staticdata and staticdata ~= "" then + self.gameid = staticdata + end + end + }) end -- cgit v1.2.3